feat: in-app documentation viewer#1677
Conversation
Adds a Documentation footer page that fetches the docs/ folder from the repository, renders markdown with the existing Markdown.Avalonia control, and handles internal navigation, external links, and relative images. - Fetch docs tree via new Refit IGitHubContentApi (GitHub git/trees) - DocumentationService groups pages into humanized sections (README first), caches the tree listing and page markdown to disk (1 day TTL) and serves from cache on network failure - DocumentationPathResolver: pure helpers for humanizing names and resolving relative .md links / image URLs (unit tested) - DocumentationMarkdownViewer routes hyperlink clicks through a command (relative .md navigates in-app, http(s) opens in the browser) and rewrites relative image paths to raw URLs - Loading, offline/error (with Retry), and "docs not available yet" states Owner/repo/branch live as consts in DocumentationConstants (branch "main"). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces an in-app documentation viewer feature, adding a new Avalonia DocumentationPage view and DocumentationViewModel, a custom DocumentationMarkdownViewer control, and a DocumentationService that fetches and caches markdown content from GitHub. The review feedback focuses on improving robustness, performance, and preventing race conditions. Key recommendations include handling potential race conditions during rapid page selection, wrapping cache-writing operations in try-catch blocks to prevent network-success paths from failing on disk errors, replacing inefficient string-splitting allocations with LastIndexOf, and adding exception handling around file system checks and reads to prevent crashes.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Replace pageCts synchronously before any await so rapid page selections
can't leak a stale load that overwrites newer content
- Cache write failures after a successful fetch no longer fail the operation
(nested try-catch, logged as warnings)
- Unreadable/corrupt cached tree listing now falls back to network instead
of throwing
- Match Engine as IMarkdownEngine2 (the getter's actual type; upgraded
wrappers don't implement IMarkdownEngine)
- Avoid Split('/') allocations in hot-ish path helpers
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The app already ships Octokit; Git.Tree.GetRecursive covers what the hand-rolled IGitHubContentApi + GitHubTreeResponse did, so both are removed along with their Refit registration. Page markdown still comes from raw.githubusercontent.com, which is not subject to the anonymous API rate limit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…olling From GUI smoke-test feedback: - Sidebar is now a TreeView (CheckpointsPage pattern): sections as expandable parent nodes (expanded by default), pages as leaves, root README hoisted to a top-level leaf; selection stays synced with link-driven navigation - Sections and pages ordered to match the docs site nav (preferred section order, overview-first within sections) instead of alphabetical - Documentation footer entry moved above Support Us so the pre-existing footer cluster keeps its muscle-memory positions; navigates by type since it left FooterPages - In-page ToC anchor links now scroll to their heading: GitHub-style slugs matched against rendered Heading1-6 blocks, measurement deferred to a layout pass; cross-page page.md#anchor links navigate then scroll - New-style partial observable property on the shared nav-node base Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Browser-style zoom (50-200%, persisted in settings): the document wrapper is re-parented into a LayoutTransformControl inside the internal scroll viewer, so content scales but the scrollbar doesn't; compact zoom overlay in the bottom-right corner - 18px right inset between content and the overlay scrollbar - Links whose text is inline code (the docs breadcrumbs, e.g. [`Home`](../README.md)) rendered as literal text — Markdown.Avalonia can't parse code spans inside link text, so strip the backticks in a fence-aware preprocessing pass before rendering Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
FluentIcons SymbolIcon measures greedily when given only FontSize, so the zoom in/out buttons expanded to the full height of the content pane. Constrain the icons with explicit Width/Height (the pattern used elsewhere in the app). Verified with a headless render of the page. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a "Documentation" page to the footer nav (above Settings): master-detail docs browser rendering the repo''s
docs/tree in-app.How it works
git/treesAPI ondocs/(Refit, matching sibling API clients), sections humanized from folder names, README.md as the landing page,images//.gitkeepexcluded.Cache/Docs), serve-from-cache on network failure, friendly error + Retry, and a dedicated "docs not available yet" state (docs/ isn''t on main until the upstream docs PR lands — the page degrades gracefully until then).BetterMarkdownScrollViewer(Markdown.Avalonia), withHyperlinkCommandinterception — relative.mdlinks navigate in-app, external links open the browser — and relative image URLs rewritten to raw URLs.DocumentationConstants.cs(currentlyLykosAI/StabilityMatrix@main).dotnet build: 0 errors, 0 new warnings. Husky formatting applied.Needs before undraft
Smoke-test round (2367c1d)
From the first GUI pass: sidebar is now a TreeView (CheckpointsPage pattern — expandable sections, root README hoisted to a top-level leaf, selection synced with link navigation); sections/pages ordered to match the docs site nav (overview-first) instead of alphabetical; the footer entry moved above Support Us so the heart/Discord/Activity/Settings cluster keeps its muscle-memory positions; and ToC
#anchorlinks now scroll to their heading — GitHub-style slugs matched against the rendered heading blocks (no library API needed after all), including cross-pagepage.md#anchorlinks (navigate, then scroll after load). 31 unit tests pass.Round 2 (7306974): browser-style content zoom (50–200%, persisted in settings, compact overlay control bottom-right — scales the document via a LayoutTransformControl inside the internal scroll viewer, so the scrollbar doesn't scale); 18px right inset so the overlay scrollbar no longer covers the rightmost text; and a fence-aware preprocessing pass fixing links with inline-code text (the docs breadcrumbs, e.g.
Home) which Markdown.Avalonia otherwise renders as literal text. 35 unit tests pass.v1 scope cuts
Image loading synchronous via the library default; flat-file cache rather than LiteDB.
Follow-up idea (roadmap): contextual
?icons in settings/env-var/data-dir UI deep-linking into this page.🤖 Generated with Claude Code