You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(plugin): make each link in the plugin references resolve - #229
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.
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>
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>
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.
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>
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
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #228
About 100 relative links in the reference files of the
ocfplugin pointed to files that do not exist, becausemake sync-plugincopied each doc unchanged into a different skill folder. The sync now rewrites each link for the plugin layout and fails when a link inplugin/resolves to no file.docs/does not change.Changes
make sync-pluginruns a new Go command,internal/pluginsync/syncplugin, in place of thecplines. The table of bundled docs moves from theMakefiletopluginsync.Bundled.../../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>/referencesfolder, so a doc or a skill that is no longer bundled leaves no stale copy.plugin/and fails with a list of the links that resolve to no file. Then the target formats the copies with prettier, somake lint-mdpasses on them..ai/base.mdand.github/copilot-instructions.mdsays that the sync rewrites links and checks them.Testing
internal/pluginsynchas tests throughSyncandCheckLinksfor 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 allpasses. Aftermake 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