feat(pfm): code line range references, hover preview, sketch Graphviz#692
Merged
Conversation
backnotprop
added a commit
that referenced
this pull request
May 11, 2026
1. Bundle rough.js as npm dep instead of CDN script tag — eliminates supply chain risk from same-origin third-party code execution 2. Fix Rules of Hooks violation in CodeSnippetPreview — move useMemo above conditional return 3. Add sketchDiagrams to getServerConfig return type (TypeScript fix) 4. Preserve :line suffix when using gate.resolved on click — resolved paths were dropping line info so popout opened at file top 5. Pi server parity — add parseCodePath to Pi's /api/doc and /api/doc/exists handlers for line-ref support 6. Pass baseDir to hover preview fetch for relative path resolution in linked doc / annotate flows 7. Remove dead SVG color replacement regex (line 294 was unreachable) 8. Pre-split highlighted lines to avoid O(n²) in preview render
3ebaf7e to
cabe109
Compare
backnotprop
added a commit
that referenced
this pull request
May 11, 2026
- Remove rough.js sketch mode (experimental, not worth the overhead) - Remove sketchDiagrams config setting, Google Font loading - Remove scroll-to-line from CodeFilePopout (shadow DOM issue, deferring) - Fix ambiguous picker dropping line suffix on pick - Fix hoverPreview in useCallback deps causing redundant fetches - Validate lineEnd >= line in parseCodePath (swap if inverted)
Adds support for line ranges in code file references: - `file.ts:42` — single line - `file.ts:10-20` — line range New parseCodePath() in packages/shared/code-file.ts extracts line info. Server strips line suffix before file resolution, returns line info in response. CodeFilePopout scrolls to the referenced line on open. Hovering a code file badge with line info shows a small code snippet popover after 300ms delay. Moved useCodeFilePopout to packages/ui/hooks/pfm/ as the start of organizing PFM-related hooks. Old path re-exports for compatibility.
handleDocExists was passing paths with :line suffixes to resolveCodeFile, causing code file badges with line refs to show as "missing". Also add unmount cleanup for the hover preview timer.
Use hljs.highlight() for syntax coloring in the code snippet popover, with language auto-detected from file extension. Reduced hover delay from 300ms to 150ms. Added smart positioning (show above when near viewport bottom). Preview header shows filename and line range.
Use a 200ms dismiss delay with cancel-on-enter pattern — hovering from the badge to the popover (or back) keeps it alive. The popover only closes when the mouse leaves both the badge and popover for 200ms. Allows scrolling through longer code snippets.
The Graphviz container used a fixed min-height of 20rem regardless of diagram dimensions, causing tiny horizontal diagrams to float in huge empty space. Now computes height from the SVG's aspect ratio, capped at 36rem. Also strips Graphviz's default white background polygon so diagrams are transparent and work with dark mode.
Plain Graphviz diagrams (without user-specified colors) now inherit Plannotator theme tokens: node fills use --card, strokes use --border, text uses --foreground, edges use --muted-foreground. User-specified fill/stroke/fontcolor in DOT source takes precedence via specificity.
CSS overrides clobber user-specified colors from DOT source because CSS fill properties take precedence over SVG fill attributes. Switch to JS-based replacement: only swap known Graphviz defaults (black, #000000, lightgrey) with theme tokens, preserving any user-specified colors like transparency hex values.
Replace hardcoded SKETCH_MODE flag with sketchDiagrams config option in ~/.plannotator/config.json (default: true). Registered in the ConfigStore settings system so it syncs via serverConfig and can be toggled from the Settings UI. Also loads Google Fonts referenced in Graphviz DOT source via <link> tags in the page head.
The outer container had overflow-hidden which clipped content without allowing scroll. Switch to flex column layout with min-h-0 on the code area so the scroll container respects the max-height constraint.
1. Bundle rough.js as npm dep instead of CDN script tag — eliminates supply chain risk from same-origin third-party code execution 2. Fix Rules of Hooks violation in CodeSnippetPreview — move useMemo above conditional return 3. Add sketchDiagrams to getServerConfig return type (TypeScript fix) 4. Preserve :line suffix when using gate.resolved on click — resolved paths were dropping line info so popout opened at file top 5. Pi server parity — add parseCodePath to Pi's /api/doc and /api/doc/exists handlers for line-ref support 6. Pass baseDir to hover preview fetch for relative path resolution in linked doc / annotate flows 7. Remove dead SVG color replacement regex (line 294 was unreachable) 8. Pre-split highlighted lines to avoid O(n²) in preview render
- Remove rough.js sketch mode (experimental, not worth the overhead) - Remove sketchDiagrams config setting, Google Font loading - Remove scroll-to-line from CodeFilePopout (shadow DOM issue, deferring) - Fix ambiguous picker dropping line suffix on pick - Fix hoverPreview in useCallback deps causing redundant fetches - Validate lineEnd >= line in parseCodePath (swap if inverted)
1e1b58f to
ab7f496
Compare
…M text Highlight each line separately instead of splitting a full-snippet highlight — avoids broken spans on multi-line tokens. Added TODO for createPortal on the hover popover. Removed stale "scrolled to that region" claim from PFM reminder since scroll-to-line was deferred.
The popover rendered inline was trapped behind the annotation sidebar's stacking context. Portal to document.body so it layers correctly.
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
Stacked on #690. Three features that enhance PFM rendering:
Code file line range references
file.ts:42(single line) andfile.ts:10-20(range) are now fully supported end-to-end/api/docand/api/doc/existsstrip line suffixes before file resolutionparseCodePath()utility inpackages/shared/code-file.tsuseCodeFilePopoutmoved topackages/ui/hooks/pfm/(re-exported for compatibility)Graphviz improvements
<polygon fill="white"/>Indie Flower) are loaded via<link>tagsSketch mode (rough.js)
<rect>,<path>,<polygon>,<ellipse>,<circle>,<line>to rough equivalentssketchDiagramsconfig setting (default:true), synced via ConfigStoreTest plan
packages/ui/utils/parser.ts:261-286— shows syntax-highlighted TypeScript snippet"sketchDiagrams": falsein config — diagrams render crispdigraph { A -> B }uses theme colors (not black on dark)