March 29, 2026
7 pull requests merged across 2 repos
bahdotsh/indxr
- Shorten all tool/param descriptions (~50-70% shorter) — no behavior change, pure text trimming
- Conditional
memberparam — only injected when serving a multi-member workspace, saving ~624 tokens/round for single-project repos - Default tool set reduced from 23 → 15 — 8 specialized tools (
get_hotspots,get_health,get_type_flow,get_dependency_graph,get_diff_summary,get_token_estimate,list_workspace_members,regenerate_index) moved behind--all-toolsflag. They still work if called, just not advertised intools/list
Why
Benchmark showed tool definitions accounted for ~438K tokens of overhead across 40 questions — 139% of the total delta vs baseline. The 23 tool schemas cost ~3,500 tokens per API round vs ~370 for baseline's 3 tools. This overhead compounded across 3.5 avg rounds per question was the dominant cost, not the tool responses themselves.
Impact
| Metric | Before | After (default) | Reduction |
|---|---|---|---|
| Tool schema tokens/round | ~3,500 | ~1,270 | 64% |
| Projected savings across 40 benchmark questions | — | ~312K fewer tokens | — |
Test plan
- All 325 existing tests pass
- 3 new tests:
test_tool_definitions_all_tools,test_tool_definitions_default_excludes_extended,test_tool_definitions_member_param_only_in_workspace - Verified default serves 15 tools with no
memberparam - Verified
--all-toolsserves all 23 tools - Re-run accuracy benchmark to confirm token reduction:
python -m bench --runs 1
bahdotsh/mdterm
- Remove redundant bullet before checkboxes: Task list items were rendering with both a bullet (
•) and the checkbox symbol (✓/○). TheTaskListMarkerhandler now strips the bullet from the preceding span, keeping only indentation for nested items. - Make checkboxes interactive: Clicking a task list item toggles its checked/unchecked state, writes the change back to the source markdown file, and rebuilds the view. A new
LineMeta::TaskItemvariant distinguishes task items from regular list items, carrying checked state and a document-wide task index. Supports all three markdown list markers (-,*,+).
Files changed
src/style.rs— AddedTaskItemvariant toLineMeta, updated wrap propagationsrc/markdown.rs— Strip bullet for task items, track task state, emitTaskItemmetadatasrc/viewer.rs—toggle_task()handler: finds Nth task marker in source, flips[x]↔[ ], writes to disk, rebuildstest.md— Added standalone checkboxes section
Test plan
-
cargo clippy— no warnings -
cargo test— all 123 tests pass -
cargo run -- test.md— task items render without bullet prefix (just✓ Task/○ Task) - Click a checkbox — toggles visually and persists to source file
- Verify
cat test.mdreflects toggled state after click - Test with stdin (
echo "- [ ] task" | cargo run) — toggle works visually, no file write attempted - Test nested task lists — indentation preserved after bullet removal
- Fix links inside markdown tables being rendered as plain text instead of interactive links (fixes #26)
- The
Event::Texthandler checkedin_tablebeforein_link, so link URL/styling was silently discarded for table cell content - Added
in_linkcheck inside the table branch to apply link color, underline, andlink_urlmetadata
Test plan
-
cargo run -- test.md— verify the "Links in Tables" section shows colored, underlined links - Press
f(LinkPicker) — verify table links (crates.io, docs.rs, #math-rendering anchor) appear in the list - Click a table link — verify it opens correctly
-
cargo clippyandcargo testpass cleanly
— pop-up menus (TOC, Link Picker, Fuzzy Heading) flickered when navigating with arrow keys because render_frame() ran unconditionally on every event loop iteration, even when nothing changed.
- Add dirty flag to
ViewerState—render_frame()only executes whendirtyis true. For overlay key handlers, state is snapshot before/after dispatch; if nothing changed (e.g. pressing Up at the top of a list), the redraw is skipped entirely. - Suppress images during all overlay modes — previously only Help mode suppressed Kitty image delete-all + re-transmit. Now all overlays (TOC, LinkPicker, FuzzyHeading, Help) suppress images, avoiding expensive escape sequences every frame.
Test plan
- Open a markdown file with headings →
ofor TOC → hold Up/Down at boundaries → verify no flicker - Navigate within TOC normally → verify selection updates → Enter jumps correctly
- Open Link Picker (
f) → same boundary tests - Open Fuzzy Heading (
:) → type, navigate, boundary tests - Open Help (
F1) → scroll up/down → no regression - Normal scrolling (no overlay) → no regression, images still render
- Resize terminal while overlay open → verify correct re-layout
- File watching: edit file externally while viewer is open → verify reload works
- Toast: copy a code block → verify toast appears and disappears
— long blockquote text that wraps to multiple lines now preserves the ┃ bar prefix on all continuation lines.
- Add
LineMeta::BlockQuote { bar_color }variant sowrap_linescan identify blockquote lines - Strip the prefix, wrap content at reduced width (
width - 4), and re-add the prefix to every wrapped line - Fix trailing bar-only empty line that appeared at the end of blockquotes
Test plan
-
cargo test— all 122 tests pass (including 2 new blockquote wrapping tests) -
cargo clippy— no warnings -
cargo fmt— clean - Visual verification: run
cargo run -- <file.md>with a long blockquote at a narrow terminal width and confirm all continuation lines show the┃bar
- Replace number-typing input in the link picker with arrow key and vim key (j/k) cursor navigation, matching the TOC and fuzzy heading overlay UX
- Add visual selection highlighting (▸ marker + highlighted background) and viewport scrolling for long link lists
- Show position indicator in title (
Links (3/12)) and updated footer hints
Closes #28
Test plan
- Open a markdown file with links (
cargo run -- README.md) - Press
fto open the link picker - Verify j/k and arrow keys move the selection highlight
- Verify PageUp/PageDown jump by page
- Verify g/G go to first/last entry
- Verify Enter opens the selected link
- Verify Esc closes without opening
- Test with a file that has more links than fit in the viewport to verify scrolling
- Fixes slide mode rendering content from subsequent slides beyond the current slide's boundary (#30)
- Computes
slide_endfromslide_boundaries[current_slide + 1]and gates allwrapped.get()calls with.filter(|_| line_idx < slide_end)so lines past the boundary fall through to the existing blank-row path - Applies the same guard to both image rendering passes (inline and block) to prevent images bleeding across slides
- Removes the unused
_display_lines/_display_offsetvariables that had a partial, never-wired-up version of this fix
Test plan
- Create a markdown file with
---separators (3+ slides with varying content lengths) - Run
mdterm --slides file.mdand verify each slide only shows its own content - Verify slide navigation (arrow keys, space, h/l/j/k) still works correctly
- Verify status bar still shows correct "Slide X/Y" indicator
- Verify slides with images don't bleed image content across boundaries
-
cargo testpasses (120/120) -
cargo clippyandcargo fmt --checkclean
Closes #30