Skip to content

Releases: ryanoneill/envision

v0.16.0

20 Apr 04:43
v0.16.0
98804a0

Choose a tag to compare

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

  • DependencyGraph removed — fully replaced by Diagram. GraphNode, GraphEdge, GraphOrientation, and all DependencyGraph* types are gone. NodeStatus is now in diagram::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

19 Apr 03:30
v0.15.1
a99b8d0

Choose a tag to compare

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)
  • CalendarState Default 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

13 Apr 06:50
v0.15.0
6c63e43

Choose a tag to compare

Breaking Changes

Message Clone bound removed

  • Component::Message, Component::Output, and App::Message no longer require Clone. 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 new RuntimeBuilder:
    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 MessageSource trait is internalized. No known callers; customer who evaluated it passed.

with_markdown() requires the markdown feature

  • Calling with_markdown(true) or set_markdown_enabled(true) without the markdown Cargo 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_activeselected/set_selected
  • log_viewer::with_regexwith_use_regex
  • multi_progress::with_percentageswith_show_percentages, with_auto_removewith_auto_remove_completed
  • diff_viewer::with_show_line_numberswith_line_numbers
  • chart::with_legendwith_show_legend
  • conversation_view/status_log/log_viewer::with_timestampswith_show_timestamps
  • conversation_view::with_role_labelswith_show_role_labels

Features

  • RuntimeBuilderRuntime::terminal_builder()?.theme(t).tick_rate(d).build()?
  • envision::terminal::restore() — standalone terminal cleanup for panic handlers, completing the crossterm encapsulation story
  • docs/CHOOSING.md — component decision tree ("I want a list of things — which component?")
  • InputMode::{Desktop, Readline} on LineInput — Ctrl-A/E/W/K readline bindings
  • StepIndicator::with_step_style(index, style) — per-step-index style overrides
  • StepIndicator::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

13 Apr 02:05
v0.14.1
16ffe51

Choose a tag to compare

Fixed

  • Event::key_with() now normalizes Key::Char like all other constructors. Previously key_with(Key::Char('G'), Modifiers::CONTROL) produced uppercase Char('G') violating the invariant that letter keys are always lowercase. Now routes through KeyEvent::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

13 Apr 00:45
v0.14.0
76c8232

Choose a tag to compare

Breaking Changes

RenderContext consolidation

  • Component::view signature changed from (state, frame, area, theme, ctx) to (state, ctx: &mut RenderContext<'_, '_>).
  • ViewContext renamed to EventContext (used only by handle_event).
  • Overlay::view also migrated to &mut RenderContext.
  • RenderContext provides with_area() for sub-area rendering and render_widget() convenience.

Envision-owned input types

  • Crossterm event types replaced with envision-owned types: KeyCodeKey, KeyModifiersModifiers.
  • ASCII letter keys normalized to lowercase; raw_char preserves the terminal character for text input.
  • BackTab replaced by Key::Tab with modifiers.shift().
  • KeyEvent field renamed from key to code (key.code reads naturally).
  • KeyEvent::new() normalizes uppercase letters, matching char() and from_crossterm_key.
  • All crossterm types removed from public API.

Worker module

  • ProgressSender is now generic: ProgressSender<P> — use any Send + 'static type for progress.
  • send_percentage() and send_status() removed. Use sender.send(YourType).
  • Added try_send() for non-blocking fire-and-forget progress.
  • Added Command::subscribe() for dynamic subscription registration from update().
  • Added ProgressSender::new(tx) public constructor.

Features

  • RenderContext bundles frame, area, theme, focus, and disabled state.
  • EventContext (renamed from ViewContext) for event handling.
  • AppShell layout helper for consistent header/content/footer splits.
  • Per-role style overrides in ConversationView via with_role_style().
  • Per-step-index style overrides in StepIndicator via with_step_style(index, style).
  • Per-status style overrides in StepIndicator via with_status_style(status, style).
  • StepIndicator::with_show_border(false) for inline breadcrumbs.
  • Command::subscribe() — register subscriptions from within update().
  • MouseEventKind and KeyEventKind re-exported at crate root and prelude.

Bug Fixes

  • ConversationView markdown rendering now honors role colors and custom themes. Previously used Theme::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 the markdown feature.
  • 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

11 Apr 22:44
v0.13.1
e826e43

Choose a tag to compare

Bug Fixes

  • ConversationView markdown rendering now also recolors spans with fg: None (in addition to spans with the theme default foreground), defending against future markdown renderer changes (#395)

Features

  • Memory benchmarks for SelectableList, Table, and Tree rendering plus state creation scaling (1000/5000/10000 items) using a counting global allocator wrapper (#400)
  • focus_manager example 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)
  • PartialEq derives on DependencyGraphState, FlameGraphState, SpanTreeState, and FocusManager (#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%
  • # Errors and # Panics sections added to public methods with non-obvious failure conditions (#393)

Code Quality

  • All 16 clippy suppressions removed from component code (10 too_many_arguments via parameter struct refactor in #401, 6 stale suppressions in #403)
  • Zero files exceed 1000 lines: split chart/tests.rs (#392), line_input/mod.rs, and tree/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 for block 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

10 Apr 03:27
v0.13.0
af51625

Choose a tag to compare

Features

  • Per-role style overrides in ConversationView — customize colors for User, Assistant, System, Tool, or custom roles via with_role_style() / set_role_style() (#394)
  • AppShell layout helper — define (header, content, footer) layout once, call .split(area) from views and overlays to eliminate off-by-one drift (#390)
  • StepIndicator borderless modewith_show_border(false) for inline breadcrumbs in single-row layouts (#388)
  • DistributionMap convenience API for visualizing distribution evolution over time via Heatmap (#387)
  • ChartGrid convenience component for multi-chart dashboard layouts (#386)
  • Structured semantic output for CaptureBackend for 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

  • Sparkline data type changed from u64 to f64 for scientific/ML use cases (#376). Update SparklineState::new() and with_data() calls to use f64 values.

Bug Fixes

  • ConversationView markdown 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 # Errors and # Panics documentation 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

05 Apr 23:27
v0.12.0
86a0e99

Choose a tag to compare

Breaking Changes

  • Focusable and Disableable traits deleted. Focus/disabled state is now exclusively via ViewContext passed to handle_event() and view(). One source of truth, zero ambiguity.
  • Component::handle_event takes (state, event, ctx: &ViewContext) — same for dispatch_event
  • ChatView deleted — use ConversationView instead
  • Instance method bridges deletedstate.handle_event() and state.dispatch_event() removed; use static Component::handle_event(&state, &event, &ctx)
  • #[non_exhaustive] removed from all Output enums — exhaustive matching restored
  • Edition 2024 / MSRV 1.85

Features

  • MessageSource traitConversationView::view_from() renders from external message stores
  • ConversationView::set_status() — status line inside the border
  • Language::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 name
  • render_diff() / render_to_string() test utilities
  • Prelude re-exportsFileEntry, 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

04 Apr 02:50
v0.11.0
099e298

Choose a tag to compare

Breaking Changes

  • TextAreaState::with_value() and with_placeholder() are now chainable builders. Use TextAreaState::new().with_value("...") instead of TextAreaState::with_value("...")
  • SplitPanelState::with_ratio() is now a chainable builder. Use SplitPanelState::new(orientation).with_ratio(0.3) instead of SplitPanelState::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, Language now available via the prelude
  • MetricsDashboard (#326): widget_by_label() and widget_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

02 Apr 05:58
v0.10.3
36f5cf7

Choose a tag to compare

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-east5 no longer breaks at hyphens across lines.

Full changelog: v0.10.2...v0.10.3