Cross-reference linking parity for fastmcp & argparse components#57
Merged
Conversation
why: Resource, prompt, and resource-template directives already register
canonical std-domain labels, so they land in objects.inv and resolve via
{ref} — but no test guarded it. Issue #56's acceptance criterion #2 (resources
reachable via intersphinx as std:label) was unverified, leaving the behavior
free to regress silently.
what:
- Add tests/ext/fastmcp/test_component_linking.py with a synthetic project that
documents one prompt, resource, and resource template
- Assert each canonical label lands in the built objects.inv as a std:label
…emplate why: Only fastmcp-tool honored the standard :no-index: flag. A prompt, resource, or resource template shown on more than one page had no way to opt a secondary appearance out of label registration, so its canonical cross-reference home was nondeterministic (last page read wins). Issue #56 requests this parity. what: - Add :no-index: to option_spec on FastMCPPromptDirective, FastMCPResourceDirective, and FastMCPResourceTemplateDirective - Skip canonical label registration + note_explicit_target when set, marking the section fastmcp_no_index so the doctree-read pass mirrors the skip - Thread no_index through the shared _build_resource_card helper - Cover two-page no-index behavior in test_component_linking.py
why: Tools had {tool}/{toolref} inline cross-reference roles, but resources,
prompts, and resource templates had none — prose could only link them via the
verbose canonical {ref}`fastmcp-resource-<slug>`. Issue #56's follow-on asks
for the same chip affordance.
what:
- Add a kind-agnostic _component_ref_placeholder + role factories in _roles.py
for {resource}/{resourceref}/{prompt}/{promptref}, targeting the canonical
fastmcp-<kind>-<slug> label (resources/prompts carry no bare-slug alias)
- Add resolve_component_refs (doctree-resolved) mirroring resolve_tool_refs
without the safety-badge branches; {resource} resolves against both the
resource and resource-template id families; unresolved names degrade to a
bare literal
- Register the four roles and connect the resolver in setup()
- Cover role resolution, template fallback, and graceful degradation in tests
…rgets why: The argparse directive was the only auto-directive in the workspace without :no-index:. A parser documented on more than one page registered its options, program, and subcommands on every appearance, polluting objects.inv and the per-domain index with duplicate cross-reference targets and giving the parser no single canonical xref home. what: - Add :no-index: to ArgparseDirective.option_spec; set RenderConfig.register_xref_targets from it in _build_render_config - Gate _register_argument / _register_program / _register_subcommand and the implicit section names on register_xref_targets, keeping HTML anchors intact - Cover objects.inv suppression and intact rendering in a new integration test
why: The tutorial showed only the {tool}/{toolref} inline roles and never
mentioned that prompts, resources, and templates support :no-index:. Readers
had no pointer to the new cross-reference affordances.
what:
- Show {resource}/{resourceref}/{prompt}/{promptref} inline-role usage, noting
{resource} resolves both fixed resources and resource templates
- Document the :no-index: flag for multi-page prompt/resource/template cards
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #57 +/- ##
==========================================
+ Coverage 92.38% 92.42% +0.03%
==========================================
Files 256 258 +2
Lines 20188 20334 +146
==========================================
+ Hits 18651 18793 +142
- Misses 1537 1541 +4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Member
Author
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code |
…string why: The docstring said the resolver "targets the canonical fastmcp-<kind>-<slug> id directly" — accurate for prompts but wrong for resources, where the resolver tries fastmcp-resource-<slug> then fastmcp-resource-template-<slug>. what: - Describe the per-kind candidate families: prompt -> single canonical id; resource -> resource then resource-template, so one spelling links either
why: The :no-index: test hand-rolled a Sphinx() build and a private _Result
NamedTuple, while the sibling component-linking test added in the same work uses
tests/_sphinx_scenarios.py. Use the shared harness so both follow one pattern.
what:
- Replace _build/_Result/_purge_parser_module with SphinxScenario +
build_shared_sphinx_result (module-scoped, purge_modules=("myparser",))
- Read objects.inv from result.outdir and the rendered card via read_output;
assertions (no argparse:* / std:cmdoption, empty progoptions, card renders)
are unchanged
…nfig field why: The new _make_component_ref_role factory shipped without a doctest or NumPy parameter docs, and RenderConfig's class doctest didn't assert the new register_xref_targets default — gaps relative to the doctest-everything norm. what: - Add NumPy Parameters/Returns and a doctest to _make_component_ref_role asserting the placeholder's refkind/refslug/reftext - Assert register_xref_targets in the RenderConfig class doctest
why: Record the forthcoming version's user-visible deliverables in the
0.0.1a31 unreleased block.
what:
- What's new: {resource}/{resourceref} and {prompt}/{promptref}
cross-reference roles for sphinx-autodoc-fastmcp
- What's new: :no-index: on the fastmcp prompt/resource/resource-template
and argparse directives
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
{resource}/{resourceref}/{prompt}/{promptref}inline cross-reference roles tosphinx-autodoc-fastmcp, giving non-tool components the same prose-linking affordance tools already had via{tool}/{toolref}.{resource}resolves both fixed resources and resource templates; an unknown name degrades to a plain literal instead of a dangling link.:no-index:support to thefastmcp-prompt,fastmcp-resource, andfastmcp-resource-templatedirectives (previously tool-only), so a component shown on more than one page can keep a single canonical cross-reference home.:no-index:to theargparsedirective — the only auto-directive in the workspace that lacked it — suppressingargparse:*/std:cmdoptioninventory targets on secondary appearances while keeping the rendered card and its HTML anchors intact.std:labels inobjects.inv, closing issue sphinx-autodoc-fastmcp:{fastmcp-resource}and{fastmcp-resource-template}don't register cross-reference labels (no{ref}, absent from objects.inv) #56's acceptance criterion that resources be intersphinx-reachable.:no-index:flags in the fastmcp tutorial.Closes #56.
Context
Issue #56 reported that
fastmcp-resource/fastmcp-resource-templatenever register astd:label, leaving resources un-{ref}-able and absent fromobjects.inv. Investigation showed the load-bearing registration already happens inside the shared_build_resource_card()helper (and has since before the issue was filed) — a controlled build confirmsfastmcp-resource-*,fastmcp-prompt-*, andfastmcp-resource-template-*labels land inobjects.inv. What was genuinely missing were the issue's explicitly-optional follow-ons (a role family,:no-index:parity) and any regression test guarding the inventory behavior. This PR delivers those, plus the analogous:no-index:gap found in argparse during the cross-package audit.Changes by area
sphinx-autodoc-fastmcp_roles.py: kind-agnostic_component_ref_placeholdernode + role factories for the four new roles, targeting the canonicalfastmcp-<kind>-<slug>label (resources/prompts carry no bare-slug alias, unlike tools)._transforms.py:resolve_component_refs(doctree-resolved) mirrorsresolve_tool_refswithout the safety-badge branches;{resource}tries both the resource and resource-template id families._directives.py::no-index:option_spec+ handling on the prompt/resource/template directives; threadsno_indexthrough_build_resource_card, marking the sectionfastmcp_no_indexso the doctree-read pass mirrors the skip.__init__.py: registers the four roles and connects the resolver.sphinx-autodoc-argparsedirective.py::no-index:option_spec; setsRenderConfig.register_xref_targetsfrom it.renderer.py: gates_register_argument/_register_program/_register_subcommandand the implicit sectionnamesonregister_xref_targets, keeping per-sectionids(anchors/TOC) intact.Docs
tutorial.md: documents the component roles and the:no-index:flag.Design decisions
fastmcp-<kind>-<slug>with no alias-collision risk.{resource}covers templates too: rather than a separate{resource-template}role, the resolver falls back fromfastmcp-resource-<slug>tofastmcp-resource-template-<slug>, so one spelling links either.reference[literal](like{toolref}), so nogp-sphinx-*class is introduced and the CSS self-containment rule is unaffected.:no-index:keeps anchors: only cross-reference targets (domain entries + implicit section labels) are suppressed;idsremain so the card still renders and links within the page.Test plan
tests/ext/fastmcp/test_component_linking.py— component labels inobjects.inv; role resolution incl. template fallback; unknown-name degradation; two-page:no-index:keeps a single canonical home with no duplicate-label warningtests/ext/autodoc_argparse/test_no_index_integration.py—:no-index:argparse block emits noargparse:*/std:cmdoptionentries and an emptyprogoptions, while the card still rendersuv run ruff check ./uv run ruff format .uv run mypy(full workspace)uv run pytest(full suite)just build-docs(clean build, no new warnings)