Skip to content

fix(plugin): make each link in the plugin references resolve - #229

Merged
sourcehawk merged 3 commits into
mainfrom
fix/plugin-reference-links
Oct 6, 2026
Merged

sourcehawk merged 3 commits into
mainfrom
fix/plugin-reference-links

Conversation

@sourcehawk

@sourcehawk sourcehawk commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Description

Fixes #228

About 100 relative links in the reference files of the ocf plugin pointed to files that do not exist, because make sync-plugin copied each doc unchanged into a different skill folder. The sync now rewrites each link for the plugin layout and fails when a link in plugin/ resolves to no file. docs/ does not change.

Changes

  • make sync-plugin runs a new Go command, internal/pluginsync/syncplugin, in place of the cp lines. The table of bundled docs moves from the Makefile to pluginsync.Bundled.
  • A link to a bundled doc becomes the relative path of its copy, anchor kept, for example ../../building-components/references/component.md#persisting-status-with-flushstatus. A link to a doc that the plugin does not bundle (cli.md, getting-started.md) becomes its page on the docs site. This covers inline links with or without a title, and link reference definitions. Links in fenced code and inline code, also a code span over a line break, do not change. Before the copy, the sync removes every <skill>/references folder, so a doc or a skill that is no longer bundled leaves no stale copy.
  • After the copy, the command checks each relative link in every Markdown file under plugin/ and fails with a list of the links that resolve to no file. Then the target formats the copies with prettier, so make lint-md passes on them.
  • The CI job "Validate Claude plugin" now sets up Go, so it runs the new sync and its link check.
  • The regenerated reference files are in this PR. The note in .ai/base.md and .github/copilot-instructions.md says that the sync rewrites links and checks them.

Testing

internal/pluginsync has tests through Sync and CheckLinks for a link to another skill, to the same skill, from a subfolder, into a glob, to a doc that is not bundled, with a title, as a reference definition, in inline and fenced code, to a missing doc, for a glob with no match, and for stale copies and a retired skill. make all passes. After make sync-plugin, a scan of every reference file finds no relative link that resolves to no file. Before the change, the same scan listed about 100.

🤖 Generated with Claude Code

make sync-plugin copied each doc unchanged into a skill folder of the
plugin, but the docs go to different folders. About 100 relative
links, such as component.md in structuring-operators/references,
pointed to files that do not exist there. Links to cli.md and
getting-started.md pointed to docs that the plugin does not bundle.

The sync is now a Go command in internal/pluginsync. It rewrites a
link to a bundled doc to the relative path of its copy, anchor kept,
and a link to any other doc to its page on the docs site. Links in
code do not change. After the copy, it fails when a relative link in
plugin/ resolves to no file, so the CI job "Validate Claude plugin"
catches a new broken link. The target then formats the copies with
prettier, and the CI job now sets up Go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 6, 2026 15:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The Markdown scanner misses valid link forms, mishandles code boundaries, and can retain stale references when a skill is removed.

Review effort: Balanced
Findings: 4 Medium severity

Open (4)
What changed in this PR

Replaces verbatim plugin documentation copies with link-aware synchronization and CI validation.

Changes:

  • Adds tested Go synchronization and link-checking logic.
  • Updates Makefile and CI integration.
  • Regenerates plugin references with corrected links.
File Description
plugin/​skills/​using-primitives/​references/​primitives/​unstructured.md Rewrites cross-skill links.
plugin/​skills/​using-primitives/​references/​primitives/​statefulset.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​serviceaccount.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​service.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​secret.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​rolebinding.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​role.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​replicaset.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​pv.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​pod.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​pdb.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​networkpolicy.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​job.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​hpa.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​deployment.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​daemonset.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​cronjob.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​configmap.md Fixes declared-data link.
plugin/​skills/​using-primitives/​references/​primitives/​clusterrolebinding.md Rewrites component links.
plugin/​skills/​using-primitives/​references/​primitives/​clusterrole.md Rewrites component links.
plugin/​skills/​using-primitives/​references/​primitives.md Rewrites cross-reference links.
plugin/​skills/​testing-operators/​references/​testing.md Rewrites testing-guide links.
plugin/​skills/​structuring-operators/​references/​guidelines.md Rewrites guideline links.
plugin/​skills/​custom-resource-wrappers/​references/​custom-resource.md Rewrites wrapper-guide links.
plugin/​skills/​building-components/​references/​component.md Rewrites component-guide links.
Makefile Runs synchronizer and formatter.
internal/​pluginsync/​syncplugin/​main.go Adds synchronization command.
internal/​pluginsync/​sync.go Implements copying, rewriting, and validation.
internal/​pluginsync/​sync_test.go Tests synchronization behavior.
.github/​workflows/​lint.yml Adds Go setup and link validation.
.github/​copilot-instructions.md Documents synchronization behavior.
.ai/​base.md Updates generated-reference guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/pluginsync/sync.go Resolved
Comment thread internal/pluginsync/sync.go Resolved
Comment thread internal/pluginsync/sync.go Resolved
Comment thread internal/pluginsync/sync.go Resolved
The link pattern saw only inline links with no title, so a titled link
or a link reference definition was neither rewritten nor checked. A
line that started with the fence marker closed a fenced code block also
when text followed the marker. A code span that continued over a line
break was not seen as code, so a link in it was rewritten.

The sync now matches inline links with an optional title and link
reference definitions, closes a fence only on a line of the same marker
with nothing after it, and finds code spans in a whole paragraph. It
also removes every <skill>/references folder before the copy, so a
skill with no bundled doc left keeps no stale copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 6, 2026 15:36
@sourcehawk

Copy link
Copy Markdown
Owner Author

Review round 1. Review base: 6793957.

Finding Kind Disposition
Titled links and reference-style links are not parsed Posted Applied in 02d69fe. A destination with parentheses inside it is still out of scope, and the CheckLinks doc comment names the forms it checks.
A skill with no bundled doc left keeps its stale references folder Posted Applied in 02d69fe.
A fence line with text after the marker closes the fence Posted Applied in 02d69fe.
A code span over a line break is not seen as code Posted Applied in 02d69fe.

The review had no suppressed findings. The new tests fail on 6793957 and pass on 02d69fe.

Comment gate: 0 flagged, 9 listed, 2 removed, 0 not checked. mapOutsideCodeSpans first got a second sentence on code spans over line breaks. The parameter is now named paragraph, which carries that fact, so the comment stays one line. The removed blocks belonged to linkPattern and referenceDirs, which the change removes. The Sync, CheckLinks, and mapLinks comments changed because their old text became false.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Globbed documentation destinations are malformed on Windows because an OS-native path is passed to path.Base.

Review effort: Balanced
Findings: None

Resolved since last review (4)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Use filepath.Base for Windows glob paths

internal/​pluginsync/​sync.go:111

m comes from filepath.Glob, so on Windows it contains backslash separators. path.Base(m) only recognizes / and therefore returns the whole path, causing globbed docs to be written under a malformed destination name. Use filepath.Base for this OS-native path.

filepath.Glob returns OS-native paths, so path.Base returned the whole
path on Windows and wrote the copy under a malformed name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 6, 2026 15:41
@sourcehawk

Copy link
Copy Markdown
Owner Author

Review round 2. Review base: 6793957.

The review posted no findings. Its body had one previously missed finding with no thread:

Finding Disposition
sync.go:111 uses path.Base on an OS-native path from filepath.Glob Applied in e16bb39: it now uses filepath.Base. CI runs on Linux only, so no test shows the Windows case.

Comment gate: 0 flagged, 9 listed, 2 removed, 0 not checked. No comment changed in this round.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Nested Markdown fenced blocks can still have their link-like contents rewritten or reported as broken.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Recognize fenced code blocks nested in Markdown containers

internal/​pluginsync/​sync.go:230

Valid fenced blocks nested in Markdown containers are not recognized because trimmed still starts with the container marker (for example, > ~~~ or - ~~~). A relative-looking link inside such a tilde-fenced block is therefore rewritten by Sync and checked by CheckLinks, violating the contract that fenced code is left unchanged. Handle container prefixes (or use a Markdown block parser) and add a nested-fence test.

@sourcehawk

Copy link
Copy Markdown
Owner Author

Review round 3. Review base: 6793957.

The review posted no findings. Its body had one previously missed finding with no thread:

Finding Disposition
sync.go:230 does not see a fence that opens on the same line as a blockquote or list marker, such as > ~~~ or - ~~~ Declined. No file in docs/ or plugin/ has a fence in that form. If one appears, the result is loud, not silent: CheckLinks fails on a link in it, or the rewrite shows in the diff of the plugin copy. Full container parsing needs a Markdown block parser, which is more than this sync needs today.

No commit in this round. Comment gate: 0 flagged, 9 listed, 2 removed, 0 not checked.

@sourcehawk
sourcehawk merged commit 496afc5 into main Oct 6, 2026
8 checks passed
@sourcehawk
sourcehawk deleted the fix/plugin-reference-links branch October 6, 2026 21:12
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.

Plugin reference files have broken links to other docs

2 participants