Skip to content

docs(reference): repair broken in-page anchors for custom columns and default_branch object - #4688

Merged
max-sixty merged 2 commits into
max-sixty:mainfrom
viwe-monai:docs/fix-reference-anchors
Nov 6, 2026
Merged

max-sixty merged 2 commits into
max-sixty:mainfrom
viwe-monai:docs/fix-reference-anchors

Conversation

@viwe-monai

Copy link
Copy Markdown
Contributor

What

Nine in-page anchor links in the reference docs point at fragments that no heading generates:

  • ](#custom-columns) - the heading is ### Custom columns [experimental] (skills/worktrunk/reference/list.md:123, #### Custom columns [experimental] at skills/worktrunk/reference/config.md:231), so the generated fragment is #custom-columns-experimental. 6 links updated (list.md x2, config.md x1, plus the plugins/worktrunk/ synced copies).
  • ](#default-branch-object) - the heading is ### default_branch object (skills/worktrunk/reference/list.md:331, docs/src/content/docs/list.md:347), so the fragment is #default_branch-object (underscore, not hyphen). 3 links updated (skills + plugins list.md, docs list.md).

The docs/src/content/docs/list.md copy of the custom-columns links was left alone: its own heading is ### Custom columns (no [experimental] suffix), so #custom-columns resolves there.

Why

Readers of the Columns table and the JSON object docs click these links and land nowhere. The default_branch link is especially easy to miss since head-object / worktree-object next to it do resolve.

How it was verified

  • Every heading was read from the current main files; fragment names follow the GitHub slugger ([ ] stripped, spaces to hyphens, _ kept).
  • An anchor checker over all 91 markdown files found exactly these nine dead fragments (plus three template placeholders like {{ env.LINK }} and literal ... / @/... ellipses, which are intentional and untouched).
  • The skills/worktrunk/reference/ and plugins/worktrunk/skills/worktrunk/reference/ copies were kept byte-identical.

Follow-ups deliberately left out

  • The [experimental] suffix in the headings leaks into the fragments; renaming headings would produce cleaner anchors but changes existing inbound links elsewhere, so only the links were repaired.

@worktrunk-bot worktrunk-bot 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.

Every line this PR edits is in a generated region. The source is after_long_help in src/cli/mod.rs ([custom columns](#custom-columns) appears three times there, and [default_branch object](#default-branch-object) once), and test_docs_are_in_sync regenerates all five files from it. Running cargo test --test integration test_docs_are_in_sync on this head fails and reverts every change, so the PR can't land as-is (per docs/AGENTS.md: "Never edit generated regions or mirrors directly").

Moving the edit into src/cli/mod.rs won't work either. The site and the skill copies are generated from the same text but use different slug rules:

  • Site: slugHeading in docs/src/plugins/stable-heading-ids.mjs replaces every run of non-letter/number characters with -, so ### default_branch object gets the id default-branch-object. The original link was correct on worktrunk.dev, and the change to docs/src/content/docs/list.md breaks it (see inline). The site renderer also moves [experimental] off the heading into a badge, so #custom-columns resolves there too.
  • Skill copies (GitHub slugger): these keep _ and the [experimental] suffix, so the two links you found really are dead there.

A single fragment can't satisfy both renderers. The fix belongs in the skill-mirror generation in tests/integration_tests/readme_sync.rs. One option is to move [experimental] off heading lines the way src/help.rs already does for the site, which fixes the custom-columns links. The default_branch link would still need a fragment rewrite, or a heading without the underscore. Which of these to do is a maintainer call. The dead anchors are a real catch.

Comment thread docs/src/content/docs/list.md Resolved
@viwe-monai

Copy link
Copy Markdown
Contributor Author

Thanks for the fast and precise review — accepting the analysis fully. To summarize what I understand and propose:

What I got wrong: I hand-edited generated regions (against docs/AGENTS.md: "Never edit generated regions or mirrors directly") and, worse, the docs/src/content/docs/list.md fragment change breaks a link that works on worktrunk.dev (slugHeading turns _ into -, and the site already moves [experimental] into a badge so #custom-columns resolves there). A single fragment can't satisfy both the site slugger and the GitHub slugger used by the skill mirrors.

What is still true: in the skill-mirror copies (GitHub slugger), (#custom-columns) points at ### Custom columns [experimental] (= #custom-columns-experimental) and (#default-branch-object) points at ### default_branch object (= #default_branch-object) — those fragments are dead there, 9 links across the five files. The template placeholders ({{ env.LINK }}, ...) were left alone as intentional.

Proposal, pending your call: move the fix into the skill-mirror generation in tests/integration_tests/readme_sync.rs, as you suggest — e.g. move [experimental] off heading lines in the mirror output the way src/help.rs already does for the site, which repairs the #custom-columns links without touching the source text. For the default_branch link you named two options (fragment rewrite in the mirror generation vs. a heading without the underscore); since that is a maintainer call I have not picked one:

  1. mirror-generation rewrites (#default-branch-object) to (#default_branch-object) in the skill copies only (site untouched), or
  2. rename the heading to ### default branch object so both sluggers agree (changes the heading's inbound links).

Happy to implement whichever you prefer (option 1 is the smaller diff and keeps the JSON key literal in the heading). I have left the branch as-is for reference; feel free to close this PR if you would rather land the generator fix yourself — I can also reopen as a fresh PR against readme_sync.rs once the direction is chosen.

@worktrunk-bot

Copy link
Copy Markdown
Collaborator

Your summary matches what I found. One correction to option 2: renaming the heading to ### default branch object wouldn't break any inbound links. The site's slugHeading already produces default-branch-object for the current heading, so the site anchor stays the same, and the skill mirrors would then match the existing (#default-branch-object) link. The cost is losing the literal JSON key default_branch from the heading.

There's a third option that avoids special-casing either link. finalize_skill_content in tests/integration_tests/readme_sync.rs could rewrite in-page fragments from the site slug to the GitHub slug, for every heading where the two differ. That covers both #custom-columns and #default-branch-object, keeps src/cli/mod.rs and the headings unchanged, and also fixes any future heading that contains _ or [experimental]. It's more code than option 1, but it fixes the whole class of bug instead of one link.

I'd lean toward that general rewrite, or toward option 1 if it should stay minimal. Choosing between them is the maintainer's call, so I'll leave that to them. Either way, the change belongs in the generator, and cargo test --test integration test_docs_are_in_sync regenerates the five mirror files from it.

@max-sixty

Copy link
Copy Markdown
Owner

Let's fix the class in the generator: have finalize_skill_content in tests/integration_tests/readme_sync.rs rewrite in-page fragments from the site slug to the GitHub slug wherever they differ, and drop the hand edits to generated regions. Thanks for digging into this.

This was written by Claude Code on behalf of max-sixty

@max-sixty

Copy link
Copy Markdown
Owner

@worktrunk-bot want to make those changes?

…lugs

Help text links headings by their worktrunk.dev id, which drops the
[experimental] badge and turns _ into -. The skill mirrors render with
GitHub's slugger, so #custom-columns and #default-branch-object were dead
there. finalize_skill_content now maps each heading's site slug to its
GitHub slug and rewrites in-page links that differ, replacing the hand
edits to generated regions.

Co-authored-by: viwe-monai <viwe-monai@users.noreply.github.com>
@worktrunk-bot

worktrunk-bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Done in 504f839 (pushed to this branch).

  • finalize_skill_content in tests/integration_tests/readme_sync.rs now calls a new rewrite_fragments_for_github. For each heading outside code fences, it maps the site slug (computed with [experimental] stripped, since the site badge has no text) to the GitHub slug (which keeps _ and the suffix). It then rewrites any in-page ](#…) link whose fragment differs.
  • The hand edit to docs/src/content/docs/list.md is reverted, so the site keeps #custom-columns and #default-branch-object. The four skill-mirror files are now generator output, and they come out with the same 9 link repairs the PR originally made.
  • test_skill_fragments_follow_github_slugs covers both cases plus a link that's already correct. cargo test --test integration readme_sync (including test_docs_are_in_sync) passes, and clippy is clean.

@max-sixty
max-sixty merged commit d022f76 into max-sixty:main Nov 6, 2026
37 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.

3 participants