Skip to content

fix(memory-wiki): skip fenced code blocks when extracting wiki links#68852

Closed
altierac wants to merge 3 commits into
openclaw:mainfrom
altierac:fix/wiki-lint-code-block-false-positives
Closed

fix(memory-wiki): skip fenced code blocks when extracting wiki links#68852
altierac wants to merge 3 commits into
openclaw:mainfrom
altierac:fix/wiki-lint-code-block-false-positives

Conversation

@altierac

@altierac altierac commented Apr 19, 2026

Copy link
Copy Markdown

Problem

extractWikiLinks() runs MARKDOWN_LINK_PATTERN against the full page body including fenced code blocks. Python code like:

stream = anyio.create_memory_object_stream[SessionMessage](0)

triggers false-positive Broken wikilink target \0`lint warnings becauseSessionMessagematches thetext` markdown link regex.

Fix

Strip fenced code blocks (backtick fences of 3+ chars) before running both the Obsidian and markdown link regexes. This follows the existing pattern of stripping RELATED_BLOCK before extraction.

One new regex constant, one additional .replace() call, no behavioral change for links outside code blocks.

Tests

Added 7 test cases for extractWikiLinks:

  • Obsidian-style wikilinks
  • Markdown-style links
  • Links inside fenced code blocks (ignored)
  • Links inside longer fences (ignored)
  • Mixed: links outside code blocks still extracted
  • External URLs skipped
  • Anchor-only links skipped

🤖 AI-assisted: Authored by Claude Opus 4.6 (1M context), reviewed by GPT-5.4. Edge cases found and fixed via code review pass. Human in the loop.

@greptile-apps

greptile-apps Bot commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a false-positive lint warning in extractWikiLinks by stripping fenced code blocks (3+ backtick fences) before running the Obsidian and Markdown link regexes. The fix is minimal — one new FENCED_CODE_PATTERN constant and one additional .replace() call — and follows the existing pattern used for RELATED_BLOCK_PATTERN. Seven new test cases provide solid coverage of the code-block-stripping behavior.

Confidence Score: 5/5

Safe to merge — the change is narrow, well-tested, and introduces no behavioral change for links outside code blocks.

The regex is logically correct: the backreference \1 ensures closing-fence length must match the opening fence, the m flag correctly anchors to line boundaries, and .replace() safely resets the stateful lastIndex on each call. All remaining findings are P2 or lower.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(memory-wiki): skip fenced code block..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1091440c3a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/memory-wiki/src/markdown.ts Outdated
@@ -62,6 +62,7 @@ export type WikiPageSummary = {
const FRONTMATTER_PATTERN = /^---\n([\s\S]*?)\n---\n?/;
const OBSIDIAN_LINK_PATTERN = /\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g;
const MARKDOWN_LINK_PATTERN = /\[[^\]]+\]\(([^)]+)\)/g;
const FENCED_CODE_PATTERN = /^(`{3,})[^\n]*\n[\s\S]*?\n\1\s*$/gm;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Accept longer closing fences when stripping code blocks

FENCED_CODE_PATTERN requires the closing fence to be exactly the same backtick length as the opener (\1), but valid Markdown allows a closing fence with at least that many backticks. For a block like ``` ... ```` the replacement does not run, so extractWikiLinks still parses markdown-like text inside code and can reintroduce false broken-link targets (e.g. `objFoo`).

Useful? React with 👍 / 👎.

@altierac
altierac force-pushed the fix/wiki-lint-code-block-false-positives branch from 1091440 to 541e72c Compare April 19, 2026 07:17
extractWikiLinks() matches link patterns against the full page body
including content that should not be treated as links. This causes
false-positive 'Broken wikilink' lint warnings.

Affected non-prose content:
- Fenced code blocks: ```python stream[SessionMessage](0) ```
- HTML comments: <!-- [Old Link](removed) -->
- Image syntax: ![alt](image.png)

All three produce false matches against MARKDOWN_LINK_PATTERN and/or
OBSIDIAN_LINK_PATTERN.

Fix: strip fenced code blocks, HTML comments, and image links before
running both link extraction regexes. This follows the existing
pattern of stripping RELATED_BLOCK before extraction.

Note: inline code spans (`[text](target)`) are intentionally NOT
stripped because links like [`formatWikiLink`](sources/utils) use
backticks inside valid link text. Stripping inline code globally
would break these links. A context-aware inline code strip is left
as future work.

Adds 10 test cases covering false-positive categories, a regression
guard for backtick-in-link-text, and normal link extraction.
@altierac
altierac force-pushed the fix/wiki-lint-code-block-false-positives branch from 541e72c to 8e0364b Compare April 19, 2026 07:21

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e0364b14d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/memory-wiki/src/markdown.ts Outdated
const FRONTMATTER_PATTERN = /^---\n([\s\S]*?)\n---\n?/;
const OBSIDIAN_LINK_PATTERN = /\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g;
const MARKDOWN_LINK_PATTERN = /\[[^\]]+\]\(([^)]+)\)/g;
const FENCED_CODE_PATTERN = /^(`{3,})[^\n]*\n[\s\S]*?\n\1\s*$/gm;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Handle indented fences when removing code blocks

extractWikiLinks still scans links inside valid fenced code blocks that are indented (for example fences nested under list items), because FENCED_CODE_PATTERN only matches fences that start at column 0 and a closing fence with no leading indentation. In those Markdown files, snippets like obj[Foo](0) remain in searchable and produce the same false wiki-link targets this change is trying to prevent.

Useful? React with 👍 / 👎.

- FENCED_CODE_PATTERN now matches closing fences with >= opener backticks
  and fenced blocks indented up to 3 spaces (per CommonMark spec)
- Strip order changed: HTML comments before fenced blocks to prevent
  a fence opener inside a comment from matching a later closing fence
- 3 new edge case tests: longer closing fence, indented blocks,
  fence opener inside HTML comment

Addresses code review feedback.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3aa01b3a94

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/memory-wiki/src/markdown.ts Outdated
Comment on lines +222 to +223
.replace(HTML_COMMENT_PATTERN, "")
.replace(FENCED_CODE_PATTERN, "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Strip fences before HTML comments in link extraction

extractWikiLinks now removes HTML comments before fenced code blocks, so a literal <!-- inside a code fence can start a cross-line HTML_COMMENT_PATTERN match that eats real prose links until the next -->. In a page like html`…`<!--`… followed by [real](sources/good) and then -->, the real link is dropped even though it is outside code and outside any actual HTML comment. This is a regression in link discovery and can hide valid wiki dependencies.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Codex automated review: keeping this open.

Keep this PR open. Current main still extracts wiki links after stripping only the managed Related block, so the reported fenced-code false positive is not implemented on main. The PR is relevant and narrowly scoped, but it still needs maintainer review or revision because the latest diff strips HTML comments before fenced code blocks, matching the live review concern that a literal <!-- inside code can hide a valid prose link later in the page.

Best possible solution:

Keep the PR open as a plausible focused bug fix for extensions/memory-wiki/src/markdown.ts. Maintainers should ask for or make a small revision that strips fenced code before broad HTML comments, or otherwise uses a context-aware Markdown scan, then keep the added extractWikiLinks coverage and add the missing regression case for <!-- inside a code fence followed by a real prose link.

What I checked:

  • Current main still has the reported extraction path: extractWikiLinks on current checkout f0b327cf686e3a957fef8c94985ee6509953a3b7 builds searchable with only markdown.replace(RELATED_BLOCK_PATTERN, ""), then runs both wiki and markdown link regexes over that content. (extensions/memory-wiki/src/markdown.ts:216, f0b327cf686e)
  • Latest remote main also lacks the fix: Read-only remote inspection of d337fa8946590109dbfe3c5eb6f8fa6f22de407c shows the same extractWikiLinks implementation with no fenced-code, HTML-comment, or image stripping and no extractWikiLinks tests in markdown.test.ts. (extensions/memory-wiki/src/markdown.ts:216, d337fa894659)
  • False-positive mechanism is real: A read-only Node probe using the current regex path on the PR's Python fence example extracted ["0"], which is the broken-link target described by the PR. lint.ts consumes page.linkTargets and emits Broken wikilink target ... warnings for unknown targets. (extensions/memory-wiki/src/lint.ts:63, f0b327cf686e)
  • PR remains open and narrowly scoped: The GitHub API reports this PR open at head 3aa01b3a94a219ed7b800c241fa867f3c47de0b3. The files API shows only extensions/memory-wiki/src/markdown.ts and extensions/memory-wiki/src/markdown.test.ts changed, adding parser stripping and focused tests. (extensions/memory-wiki/src/markdown.ts:62, 3aa01b3a94a2)
  • Latest review concern still needs maintainer handling: Live review comments include a latest Codex comment on head 3aa01b3a94a219ed7b800c241fa867f3c47de0b3 warning that stripping HTML comments before fenced code can drop real links. A read-only Node probe of the PR's strip order reproduced that shape: [real](sources/good) between a code-fence-contained <!-- and a later --> was removed from searchable. (extensions/memory-wiki/src/markdown.ts:222, 3aa01b3a94a2)
  • Security review pass: The PR diff modifies only memory-wiki markdown parsing and colocated Vitest coverage. It does not touch CI workflows, action refs, dependency manifests, lockfiles, install/build/release scripts, package publishing metadata, downloaded artifacts, generated/vendor/minified files, permissions, or secret-handling paths. (extensions/memory-wiki/src/markdown.ts:62, 3aa01b3a94a2)

Remaining risk / open question:

  • The PR should not land as-is until the HTML-comment and fenced-code strip-order concern is resolved or explicitly dismissed with a regression test.
  • I did not run the repo test lane because this was a read-only review and the environment lacks pnpm; evidence is from source, remote diff/API inspection, and read-only Node regex probes.

Codex Review notes: model gpt-5.5, reasoning high; reviewed against f0b327cf686e.

Replace separate .replace() calls for fenced code blocks and HTML
comments with a combined alternation pattern (FENCED_OR_COMMENT_PATTERN).

The previous two-pass approach had an ordering problem: stripping HTML
comments first could eat a real link when a <!-- opener appeared inside
a fenced code block, and stripping fenced code first could eat a link
when a backtick fence appeared inside an HTML comment. The single-pass
alternation lets the regex engine pick whichever construct starts first
at each position, matching CommonMark precedence.

Also adds a regression test for the <!-- inside fenced code case and
relaxes the mixed-content link order assertion (extraction order is an
implementation detail, not a contract).

Addresses ClawSweeper review feedback on strip-order concern.
@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge.

What this changes:

The PR updates memory-wiki link extraction to strip fenced code blocks, HTML comments, and image links before scanning wiki links, and adds focused extractWikiLinks unit coverage.

Maintainer follow-up before merge:

This is an open contributor implementation PR with a concrete review finding; the next action is maintainer review or an author revision on the PR branch, not a separate automated replacement branch.

Review findings:

  • [P2] Respect the opening fence length — extensions/memory-wiki/src/markdown.ts:74
Review details

Best possible solution:

Revise the extractor so fenced-code stripping respects the opening fence length, preferably with a small line scanner or a regex that cannot close a four-backtick block on a three-backtick line. Keep the focused extractor tests and add a regression for a longer opening fence containing a shorter internal fence before the real close.

Full review comments:

  • [P2] Respect the opening fence length — extensions/memory-wiki/src/markdown.ts:74
    The new pattern treats any line with at least three backticks as a closing fence. In a valid four-backtick block, an internal triple-backtick line is code content, but this replacement stops there and lets later code lines get scanned as prose links. Track the opener length or use a small scanner, and add a regression for a shorter internal fence before the real close.
    Confidence: 0.91

Overall correctness: patch is incorrect
Overall confidence: 0.9

What I checked:

Likely related people:

  • Peter Steinberger: git blame attributes the current extractWikiLinks implementation and link regex constants to commit 8055e74485e2a5508095ee74d9ed75e53ed9172d; recent memory-wiki search/compile maintenance also appears in commit 3f0039e2ea1a92a9cff05f7aab05de127bac455c. (role: introduced behavior and recent adjacent maintainer; confidence: high; commits: 8055e74485e2, 3f0039e2ea1a; files: extensions/memory-wiki/src/markdown.ts, extensions/memory-wiki/src/query.ts, extensions/memory-wiki/src/compile.ts)

Remaining risk / open question:

  • The proposed implementation remains regex-based Markdown parsing, so the shorter-closing-fence leak may not be the only CommonMark edge case around fenced blocks and HTML comments.
  • No repo test lane was run because this sweep is read-only; validation here is from source inspection, API/raw diff inspection, and a read-only Node regex probe.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8cf724a381a3.

@clawsweeper

clawsweeper Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge.

What this changes:

This PR strips fenced code blocks, HTML comments, and image markdown before memory-wiki link extraction, and adds focused extractWikiLinks coverage for code, comment, image, local-link, external-link, and anchor cases.

Maintainer follow-up before merge:

This is an open contributor PR with a concrete blocking parser edge; maintainers should request or apply a small revision on the PR rather than close it or start an automated replacement lane by default.

Review findings:

  • [P2] Honor opener length when closing fences — extensions/memory-wiki/src/markdown.ts:74
Review details

Best possible solution:

Revise the PR so the prefilter tracks each backtick fence opener and only closes it with a same-type fence of at least the opener length, while preserving the existing outside-code, HTML-comment, image, external-link, and anchor behavior. Add a regression where a four-backtick fence contains a shorter triple-backtick marker before markdown-like code text, then run the targeted memory-wiki markdown test.

Full review comments:

  • [P2] Honor opener length when closing fences — extensions/memory-wiki/src/markdown.ts:74
    The new regex treats any line with 3+ backticks as the closing fence, even when the opener used more backticks. In a valid four-backtick block that contains a literal ``` line before [fake](bad), the replacement ends early and `extractWikiLinks` still extracts `bad`, so `wiki lint` can still report false broken-link targets from fenced code. Track the opener length or use a small fence scanner before extracting links.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

Acceptance criteria:

  • pnpm test extensions/memory-wiki/src/markdown.test.ts
  • pnpm check:changed in Testbox if the final revision broadens beyond the two memory-wiki files

What I checked:

  • Current main link extraction still scans code blocks: extractWikiLinks on current main builds searchable by removing only the managed Related block, then runs the Obsidian and Markdown link regexes over the remaining full markdown body. (extensions/memory-wiki/src/markdown.ts:216, 8cf724a381a3)
  • Broken-link warnings consume extracted targets: collectBrokenLinkIssues iterates page.linkTargets and emits Broken wikilink target ... warnings for targets not found in the wiki target set, so a false extraction becomes the user-visible lint warning described by the PR. (extensions/memory-wiki/src/lint.ts:53, 8cf724a381a3)
  • PR diff is narrow: The PR head changes only extensions/memory-wiki/src/markdown.ts and extensions/memory-wiki/src/markdown.test.ts, adding FENCED_OR_COMMENT_PATTERN, IMAGE_LINK_PATTERN, and new extractWikiLinks tests. (extensions/memory-wiki/src/markdown.ts:73, a010b08e9056)
  • Read-only probe confirms main bug and PR edge case: A Node regex probe produced mainInitial:["0"] for the Python fence example; the PR regex removed that initial false positive but returned ["bad","sources/good"] for a four-backtick opener containing a shorter triple-backtick marker before [fake](bad). (extensions/memory-wiki/src/markdown.ts:74, a010b08e9056)
  • Fence contract checked against CommonMark: The CommonMark fenced-code-block section says the closing fence must use the same marker type and at least as many backticks or tildes as the opening fence; the PR regex accepts any closing run of 3+ backticks.
  • Security review pass: The PR diff is limited to memory-wiki markdown parsing and colocated Vitest coverage. It does not touch workflows, action refs, dependency manifests, lockfiles, install/build/release scripts, publishing metadata, downloaded artifacts, permissions, generated/vendor files, or secret-handling paths. (a010b08e9056)

Likely related people:

  • steipete: The current local history/blame for extensions/memory-wiki/src/markdown.ts and extensions/memory-wiki/src/lint.ts points to Peter Steinberger introducing the memory-wiki markdown/lint path in 8055e74485e2a5508095ee74d9ed75e53ed9172d, with a later same-area maintenance commit in 3f0039e2ea1a92a9cff05f7aab05de127bac455c. (role: introduced behavior and recent adjacent maintainer; confidence: high; commits: 8055e74485e2, 3f0039e2ea1a; files: extensions/memory-wiki/src/markdown.ts, extensions/memory-wiki/src/lint.ts, extensions/memory-wiki/src/query.ts)

Remaining risk / open question:

  • No repo test lane was run because this was a read-only review; the verdict is based on source inspection, the PR diff, upstream Markdown spec text, and read-only regex probes.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 8cf724a381a3.

@altierac

Copy link
Copy Markdown
Author

Closing - keeping fix in fork branch for future reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant