Skip to content

Conversation

@devin-ai-integration
Copy link

@devin-ai-integration devin-ai-integration bot commented Oct 21, 2025

Add navigation tracking and YAML generation to FernRenderer

Summary

Implements navigation tracking and hierarchical YAML generation for the FernRenderer to enable automatic Fern navigation structure creation from Python package hierarchies.

Key changes:

  • Navigation tracking: FernRenderer tracks all rendered packages/modules in _navigation_items as they're rendered
  • YAML generation: New build_navigation_tree() creates hierarchical structure, generate_navigation_yaml() exports to Fern-compatible YAML
  • CLI support: Added --nav-output flag to specify where navigation YAML should be written
  • Single renderer instance: Modified CLI to create one FernRenderer instance and reuse it for all items (required for cross-item tracking)
  • Frontmatter: Added layout: overview to packages/modules (no slug - Fern auto-generates from path)

Navigation format (following nvidia-nemo pattern):

  • Uses page (full_name) and path (file path) only
  • No explicit slugs - Fern generates them from file paths automatically
  • Packages with children become sections with nested contents
  • Hierarchical structure matches Python package structure

Review & Testing Checklist for Human

⚠️ Critical - Must verify before merge:

  • End-to-end test with real Fern site: Generate docs for a Python package with the CLI using --nav-output, integrate the markdown files and navigation YAML into an actual Fern docs site, and verify:

    • Navigation structure appears correctly in sidebar
    • All pages are accessible via navigation
    • Page titles and hierarchy match expectations
    • Preview deployment works properly
  • Verify link integrity: Check that internal markdown links (like [Class](#packageclass)) resolve correctly - navigate between pages and verify anchors work with Fern's auto-generated slugs

  • Test navigation YAML validity: Verify the generated YAML:

    • Parses correctly as valid YAML
    • Matches Fern's navigation format expectations
    • File paths work correctly (assumes ./pages/api-reference/ prefix)
  • Check edge cases: Test with packages that have:

    • Deep nesting (3+ levels)
    • Special characters or underscores in module names
    • Empty packages or modules
    • Mixed packages and modules at same level

Notes

  • Based this on the nvidia-nemo example you shared - navigation uses path only (no slugs)
  • Originally implemented with slugs in frontmatter and navigation, but removed per your feedback after reviewing the nvidia-nemo pattern
  • One type: ignore[assignment] on line 536 due to mypy tuple unpacking limitation - acceptable but worth noting
  • Tests pass locally (test_basic[fern], test_config_options[fern]), ruff and mypy clean
  • File path generation assumes ./pages/api-reference/ prefix - may need adjustment for different directory structures

Devin session: https://app.devin.ai/sessions/a4dda89fec3343f1888ff3e2111e9ccd
Requested by: [email protected] (@Ryan-Amirthan)

- Add navigation tracking to FernRenderer with _navigation_items list
- Implement _track_navigation_item method to track rendered packages/modules
- Add _generate_slug method to create URL-friendly slugs
- Add slug to frontmatter in render_item method for predictable navigation
- Implement build_navigation_tree method to create hierarchical structure
- Add generate_navigation_yaml method to output Fern-compatible YAML
- Modify CLI to support --nav-output flag for navigation YAML generation
- Create single FernRenderer instance in CLI to track across all items
- Add PyYAML dependency to pyproject.toml
- Update test regression files with new expected output
- Fix all ruff linting issues and mypy type checking errors

Co-Authored-By: [email protected] <[email protected]>
@devin-ai-integration
Copy link
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration bot and others added 8 commits October 21, 2025 17:55
- Remove slug field from frontmatter (Fern auto-generates from path)
- Update navigation YAML to use path instead of slug
- Remove _generate_slug method (no longer needed)
- Update test regression files to match new format
- All tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Convert dots and underscores to hyphens in file paths
- Matches actual markdown filename format (e.g., nemo-rl-experience.md)
- Navigation YAML now correctly references the generated markdown files
- Tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Updated subpackage links to use full hyphenated path
- Simplified submodule links to always use hyphenated format
- All cross-page links now match file slugs (e.g., package-a)
- Within-page anchors still use underscores for compatibility
- Tests updated and passing

Co-Authored-By: [email protected] <[email protected]>
- Filenames use Python module names directly (e.g., package.submodule.md)
- Navigation paths now match: ./package.submodule.md
- Cross-page links use full module names (e.g., package.submodule)
- Tests updated and passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Filenames now use hyphens: package-a.md, package-a-c.md
- Navigation paths match: ./package-a.md, ./package-a-c.md
- Cross-page links use hyphens: package-a
- Page names keep original format: package.a (for display)
- CLI updated to write hyphenated filenames for Fern renderer
- All navigation paths verified to match actual files
- Tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Filenames now use underscores: package_a.md, package_a_c.md
- Navigation paths match: ./package_a.md, ./package_a_c.md
- Cross-page links use underscores: package_a, package_a_c
- Existing underscores in module names are preserved
- CLI updated to convert dots to underscores for Fern renderer
- All navigation paths verified to match actual files
- Tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Section names now use full module path: 'package.a' instead of 'a'
- Each section includes its own page as first item in contents
- Matches nvidia-nemo pattern where sections have associated pages
- Cross-page links verified to work: link 'package_a' -> file 'package_a.md'
- Removed unused variable, tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
- Sections now have path field: section + path + contents
- Removed redundant page entry for section's own page
- Matches Fern's section-with-path pattern
- Example: section 'package.a' has path './package_a.md' directly
- Tests passing, ruff and mypy clean

Co-Authored-By: [email protected] <[email protected]>
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.

0 participants