Releases: ryanoneill/envision
v0.16.0
Diagram Component
The flagship feature of 0.16.0 is the Diagram component — a world-class graph visualization engine built from scratch with no external dependencies.
Features
- Two layout algorithms: Sugiyama hierarchical (with barycenter crossing minimization) and Fruchterman-Reingold force-directed
- Spatial navigation: arrow keys select the nearest node visually, not by insertion order
- Edge following: Enter jumps along edges, with multi-target picker for nodes with multiple outgoing edges
- Node search:
/to filter nodes by ID or label - Clusters: group nodes with expand/collapse
- Minimap: bottom-right overview for large graphs
- Viewport: pan (H/J/K/L), zoom (+/-), fit-to-view (0)
- Edge styles: solid, dashed, dotted with arrowheads and corner characters
- Node shapes: rectangle, rounded rectangle, diamond
- Performance: 100 nodes in ~250µs, layout cached and only recomputed on data changes
Breaking Changes
DependencyGraphremoved — fully replaced byDiagram.GraphNode,GraphEdge,GraphOrientation, and allDependencyGraph*types are gone.NodeStatusis now indiagram::types.
Other Improvements
- 24-bit RGB color support in ANSI parser
- Property-based testing (proptest) on ANSI parser and Sugiyama layout
- 500-node stress tests for Diagram
- Interactive terminal_output example with RGB color demo
- SECURITY.md updated with ANSI parser hardening details
- Audit grade: A (4.09 GPA), scorecard 9/9
Full Changelog: v0.15.1...v0.16.0
v0.15.1
Quality & Polish Release
Audit scorecard: 9/9 checks passing. Overall audit grade: A (4.02 GPA).
Added
- Audit scorecard subcommand with 9 pass/fail quality metrics (#429)
- 16 missing getter methods for accessor symmetry (#433)
CalendarStateDefault impl (#432)- 107 doc tests bringing coverage to 100% (1713/1713 public methods) (#428, #431, #434, #435)
Fixed
- Windows 1.85 CI stack overflow in merged doctest binary (#428)
- 6 clippy lints from newer stable toolchain (#433)
- Audit tool false positives for generic manual trait impls (#432)
- Audit tool scope to correctly scan all public API files (#433, #436)
Internal
- 8 components refactored under 1000-line limit (#430)
- Standard trait derives: Debug/Clone/Default/PartialEq 72/72 (#432)
- Accessor symmetry gaps: 0 (#433)
Full Changelog: v0.15.0...v0.15.1
v0.15.0
Breaking Changes
Message Clone bound removed
Component::Message,Component::Output, andApp::Messageno longer requireClone. The bound was a phantom — declared but never exercised. Existing#[derive(Clone)]keeps compiling; non-Clone payloads (file handles, channels, large buffers) are now usable.
12 Runtime constructors deleted
new_terminal(),virtual_terminal(),with_backend()and all their config/state variants are removed. Use the newRuntimeBuilder:let rt = Runtime::<MyApp, _>::terminal_builder()?.build()?; let vt = Runtime::<MyApp, _>::virtual_builder(80, 24).build()?; let rt = Runtime::<MyApp, _>::builder(backend).state(s, cmd).config(c).build()?;
ConversationView::view_from() removed
- The public
MessageSourcetrait is internalized. No known callers; customer who evaluated it passed.
with_markdown() requires the markdown feature
- Calling
with_markdown(true)orset_markdown_enabled(true)without themarkdownCargo feature is now a compile error. Sharp edge #4 from 0.11 — finally closed after three review rounds.
API consistency sweep — 11 renames
collapsible::expanded()→is_expanded()tab_bar::active/set_active→selected/set_selectedlog_viewer::with_regex→with_use_regexmulti_progress::with_percentages→with_show_percentages,with_auto_remove→with_auto_remove_completeddiff_viewer::with_show_line_numbers→with_line_numberschart::with_legend→with_show_legendconversation_view/status_log/log_viewer::with_timestamps→with_show_timestampsconversation_view::with_role_labels→with_show_role_labels
Features
RuntimeBuilder—Runtime::terminal_builder()?.theme(t).tick_rate(d).build()?envision::terminal::restore()— standalone terminal cleanup for panic handlers, completing the crossterm encapsulation storydocs/CHOOSING.md— component decision tree ("I want a list of things — which component?")InputMode::{Desktop, Readline}onLineInput— Ctrl-A/E/W/K readline bindingsStepIndicator::with_step_style(index, style)— per-step-index style overridesStepIndicator::with_status_style(status, style)— per-status style overrides
Documentation
- Complete MIGRATION.md — v0.14→v0.15 section with before/after for every breaking change
- Complete CHANGELOG — all 8 PRs documented
Internal
- 16,276 tests (7057 unit + 7215 integration + 2004 doc), 0 failures
- 0 files over 1000 lines, 0 clippy suppressions, 0 unsafe in library code
- Public API reduced by 12 items (constructor cleanup)
- Audit GPA: 3.99 (A) — up from 3.57 at session start
Full changelog: https://github.com/ryanoneill/envision/blob/main/CHANGELOG.md
Migration guide: https://github.com/ryanoneill/envision/blob/main/MIGRATION.md
Component guide: https://github.com/ryanoneill/envision/blob/main/docs/CHOOSING.md
v0.14.1
Fixed
Event::key_with()now normalizesKey::Charlike all other constructors. Previouslykey_with(Key::Char('G'), Modifiers::CONTROL)produced uppercaseChar('G')violating the invariant that letter keys are always lowercase. Now routes throughKeyEvent::new()then ORs in the additional modifiers.
Found by customer's adversarial verifier during the 0.14.0 migration. Last constructor that could produce un-normalized Key::Char.
Full changelog: https://github.com/ryanoneill/envision/blob/main/CHANGELOG.md
v0.14.0
Breaking Changes
RenderContext consolidation
Component::viewsignature changed from(state, frame, area, theme, ctx)to(state, ctx: &mut RenderContext<'_, '_>).ViewContextrenamed toEventContext(used only byhandle_event).Overlay::viewalso migrated to&mut RenderContext.RenderContextprovideswith_area()for sub-area rendering andrender_widget()convenience.
Envision-owned input types
- Crossterm event types replaced with envision-owned types:
KeyCode→Key,KeyModifiers→Modifiers. - ASCII letter keys normalized to lowercase;
raw_charpreserves the terminal character for text input. BackTabreplaced byKey::Tabwithmodifiers.shift().KeyEventfield renamed fromkeytocode(key.codereads naturally).KeyEvent::new()normalizes uppercase letters, matchingchar()andfrom_crossterm_key.- All crossterm types removed from public API.
Worker module
ProgressSenderis now generic:ProgressSender<P>— use anySend + 'statictype for progress.send_percentage()andsend_status()removed. Usesender.send(YourType).- Added
try_send()for non-blocking fire-and-forget progress. - Added
Command::subscribe()for dynamic subscription registration fromupdate(). - Added
ProgressSender::new(tx)public constructor.
Features
RenderContextbundles frame, area, theme, focus, and disabled state.EventContext(renamed fromViewContext) for event handling.AppShelllayout helper for consistent header/content/footer splits.- Per-role style overrides in
ConversationViewviawith_role_style(). - Per-step-index style overrides in
StepIndicatorviawith_step_style(index, style). - Per-status style overrides in
StepIndicatorviawith_status_style(status, style). StepIndicator::with_show_border(false)for inline breadcrumbs.Command::subscribe()— register subscriptions from withinupdate().MouseEventKindandKeyEventKindre-exported at crate root and prelude.
Bug Fixes
ConversationViewmarkdown rendering now honors role colors and custom themes. Previously usedTheme::default()instead of the caller's theme.KeyEvent::new(Key::Char('G'))now normalizes to lowercase + SHIFT, fixing silent test/prod divergence.- g/G/End scroll pattern now uses consistent three-arm form across all 9 scrollable components.
Documentation
- MIGRATION.md — best-in-class migration guide with before/after examples for every breaking change, including
cmd.and(Command::subscribe())pattern for on-demand workers. - README component list fully rewritten — all 73 components listed (was missing 31+, listed deleted
ChatView). - Cross-reference docs between confusing component pairs (Tabs↔TabBar, CommandPalette→SearchableList).
with_markdown(true)documented as no-op without themarkdownfeature.- 270+ doc tests added across sessions, bringing coverage from 63.6% to 84.6%.
Internal
- 16,264+ tests (7056 unit + 7214 integration + 1994 doc), 0 failures
- 0 files over 1000 lines, 0 clippy suppressions, 0 unsafe in library code
- Audit tool improvements: detects manual trait impls, feature flag cfg gates, prelude imports
- Customer feedback from two customers drove priorities throughout
Full changelog: https://github.com/ryanoneill/envision/blob/main/CHANGELOG.md
Migration guide: https://github.com/ryanoneill/envision/blob/main/MIGRATION.md
v0.13.1
Bug Fixes
ConversationViewmarkdown rendering now also recolors spans withfg: None(in addition to spans with the theme default foreground), defending against future markdown renderer changes (#395)
Features
- Memory benchmarks for
SelectableList,Table, andTreerendering plus state creation scaling (1000/5000/10000 items) using a counting global allocator wrapper (#400) focus_managerexample demonstrating focus coordination with Tab/Shift+Tab navigation — brings example coverage to 73/73 (100%) (#398)- Missing accessor getters for
FlameGraphState::search(),TabBarState::active(),TooltipState::duration(),TreemapNode::color()(#396) PartialEqderives onDependencyGraphState,FlameGraphState,SpanTreeState, andFocusManager(#397)- Terminal escape sequence handling documented in
SECURITY.md(#399)
Documentation
- ~265 new doc tests across 21 components (#391, #402, #406)
- Doc test coverage raised from 63.6% → 84.4%
# Errorsand# Panicssections added to public methods with non-obvious failure conditions (#393)
Code Quality
- All 16 clippy suppressions removed from component code (10
too_many_argumentsvia parameter struct refactor in #401, 6 stale suppressions in #403) - Zero files exceed 1000 lines: split
chart/tests.rs(#392),line_input/mod.rs, andtree/mod.rs(#405)
Internal
- 16,136 tests passing (7000 unit + 7158 integration + 1978 doc), 0 failures
- Audit tool improvements: feature flag cfg gate detection, benchmark parameterization, manual
impl Trait forblock detection, prelude-aware example coverage (#404)
Audit Grade
Library audit GPA improved from 3.57 → 3.83 this release cycle. Engineering Quality category moved to A+ (zero unsafe, zero clippy suppressions, real tracing integration).
Full changelog: https://github.com/ryanoneill/envision/blob/main/CHANGELOG.md
v0.13.0
Features
- Per-role style overrides in
ConversationView— customize colors for User, Assistant, System, Tool, or custom roles viawith_role_style()/set_role_style()(#394) AppShelllayout helper — define(header, content, footer)layout once, call.split(area)from views and overlays to eliminate off-by-one drift (#390)StepIndicatorborderless mode —with_show_border(false)for inline breadcrumbs in single-row layouts (#388)DistributionMapconvenience API for visualizing distribution evolution over time via Heatmap (#387)ChartGridconvenience component for multi-chart dashboard layouts (#386)- Structured semantic output for
CaptureBackendfor AI consumption (#385) - Chart enhancements: point annotations (#384), time-axis labels (#383), multi-series bar charts with grouped/stacked modes (#381), error bars (#382), area fill (#378), XY-pair support (#377), grid lines (#374), categorical labels (#361)
- Heatmap enhancements: Viridis/Inferno/Plasma perceptual scales (#380), diverging color scales (#373)
- Histogram: adaptive binning (Sturges, Scott, Freedman-Diaconis) (#379)
- Chart palette expanded from 8 to 20 Tableau-inspired colors (#375)
Breaking Changes
Sparklinedata type changed fromu64tof64for scientific/ML use cases (#376). UpdateSparklineState::new()andwith_data()calls to usef64values.
Bug Fixes
ConversationViewmarkdown rendering now honors role colors (#389). Previously, body text rendered in terminal default color regardless of role when markdown was enabled.
Documentation
- Added doc tests to 12 under-documented components, bringing coverage from 63.6% to 74.3% (#391)
- Added
# Errorsand# Panicsdocumentation to public methods (#393)
Internal
- 15,975 tests (7000 unit + 7158 integration + 1817 doc), 0 failures
- Split chart/tests.rs to stay under 1000-line limit (#392)
- Chart rendering polish: legend, alignment, formatting (#358)
Full changelog: https://github.com/ryanoneill/envision/blob/main/CHANGELOG.md
v0.12.0
Breaking Changes
FocusableandDisableabletraits deleted. Focus/disabled state is now exclusively viaViewContextpassed tohandle_event()andview(). One source of truth, zero ambiguity.Component::handle_eventtakes(state, event, ctx: &ViewContext)— same fordispatch_eventChatViewdeleted — useConversationViewinstead- Instance method bridges deleted —
state.handle_event()andstate.dispatch_event()removed; use staticComponent::handle_event(&state, &event, &ctx) #[non_exhaustive]removed from all Output enums — exhaustive matching restored- Edition 2024 / MSRV 1.85
Features
MessageSourcetrait —ConversationView::view_from()renders from external message storesConversationView::set_status()— status line inside the borderLanguage::Hcl— HCL/Terraform syntax highlighting- Horizontal scroll in CodeBlock — Left/Right/h/l key bindings
- Chart improvements — braille lines, axis ticks, log scale, LTTB downsampling, crosshair
MetricsDashboard::widget_by_label()— lookup by namerender_diff()/render_to_string()test utilities- Prelude re-exports —
FileEntry,FileSortField,Language
Bug Fixes
- StatusBar overflow: center truncates with ellipsis
- Calendar panic replaced with safe fallback
Internal
- cargo-nextest in CI (Windows: 21min → 9min)
- 15,137 tests, zero clippy warnings, zero unsafe code
- 4 oversized test files split into submodules
- Audit grade: A (up from B+)
Stats
- 73 components, 189K lines, 485 files
- Net -13,540 lines deleted (Focusable/Disableable/ChatView removal)
Full Changelog: v0.11.0...v0.12.0
v0.11.0
Breaking Changes
TextAreaState::with_value()andwith_placeholder()are now chainable builders. UseTextAreaState::new().with_value("...")instead ofTextAreaState::with_value("...")SplitPanelState::with_ratio()is now a chainable builder. UseSplitPanelState::new(orientation).with_ratio(0.3)instead ofSplitPanelState::with_ratio(orientation, 0.3)
Features
- 4 Reference Applications — real-world examples demonstrating component integration:
- Log Explorer (#319): LogViewer + EventStream + SplitPanel + CommandPalette
- Dashboard Builder (#320): MetricsDashboard + AlertPanel + Heatmap + Tabs + Gauge + Sparkline
- Chat Client (#321): ConversationView + MessageHandle + TabBar + TextArea + CommandPalette
- File Manager (#322): FileBrowser + CodeBlock + DiffViewer + SplitPanel + Breadcrumb
- Prelude re-exports (#323):
FileEntry,FileSortField,FileSortDirection,SelectionMode,Languagenow available via the prelude - MetricsDashboard (#326):
widget_by_label()andwidget_by_label_mut()for label-based lookups - LogViewerState (#324):
push_entry()is now public
Bug Fixes
- StatusBar overflow (#325): Right section no longer truncated when content exceeds terminal width; center section is truncated first with ellipsis
- VT command dispatch (#327): Reference app examples now use
vt.dispatch()for proper command cascading
Stats
- 1,834 tests passing
- 54 examples
Full Changelog: v0.10.3...v0.11.0
v0.10.3
v0.10.3
Fixed
- Scrollbar off-by-one: ConversationView reserves 1 column for the scrollbar when scrollable, preventing the last character of every line from being hidden.
- Code spans atomic in markdown wrap: Inline code like
us-east5no longer breaks at hyphens across lines.
Full changelog: v0.10.2...v0.10.3