TermFlow Roadmap
Status: 2026-05-01 · Current release: 0.4.0 · Working towards 1.0.
Stages 1–3 are complete. Stage 4 (1.0 stabilisation) is nearly done: §3.2 (sample apps), §3.3 (killer demo, hosted in
llm4s), §3.4 (Grid
- Border layouts), and §3.5 (migration guide — "no migration needed for 0.2.x → 1.0") have all landed, and §4.1 / §4.3 / §4.4 / §4.5 / §4.6 / §4.7 / §4.8 / §4.9 / §4.10 of the pre-1.0 release-hardening checklist are closed. §4.2 (release-doc sweep) is the last open item before cutting
v1.0.0-RC1. MiMa (§3.1) was deferred to the post-1.0 cycle (baseline = 1.0.0).This document is forward-looking: it describes the work left, not the history of the work done.
1. Vision
Pure-FP TUIs for Scala. Deterministic, golden-tested, type-safe — with mouse, themes, and modal dialogs when you need them.
TermFlow's defensible niche is the Elm Architecture done well in
Scala: immutable model, pure update, declarative view, async via
Cmd/Sub, plus a snapshot test harness no other Scala TUI library
offers.
Non-goals
- A Lanterna port. No mutable widgets, no shared GUI thread, no listener callbacks as the primary event mechanism.
- A general-purpose toolkit. TermFlow targets interactive CLIs, REPLs, dashboards, installers, chat clients, and admin tools — not full-screen text editors or game engines.
- Curses parity. Just enough primitives to render and diff correctly.
2. Current state (0.4.0)
What ships today:
- Five published modules —
termflow-terminal/-screen/-app/-widgetsplus the umbrellatermflowartefact, andtermflow-testkitfor tests. Maven Central asorg.llm4s::*. - Elm-style runtime —
TuiApp[Model, Msg],Cmd,Sub,RuntimeCtx, 60-fps frame-diffed ANSI renderer with capability downgrade. - Capability detection — true-colour / 256-colour / 16-colour / 8-colour / mono, bracketed paste, mouse (SGR-1006), extended modifier parsing, SIGWINCH-driven resize, terminal-attention notifications (iTerm2 OSC 9 / 1337, kitty OSC 99, VTE OSC 777, BEL fallback).
- 20+ widgets —
TextField,MultiLineInput,Button,CheckBox,RadioGroup,Select,Autocomplete,ListView,Table,Tree,Tabs,SplitPane(drag-resize),Separator,ScrollBar,ProgressBar,Spinner,StatusBar,LogView,MenuBar,Form. PlusLayoutDSL (Row/Column/Fill/Zone),HitTest[Id],Theme+BorderChars. - Seven dialog helpers —
message,confirm,textInput,listSelect,waiting,fileDialog,directoryDialog,actionList. - Grapheme-aware text editing — UAX #29 cluster boundaries via
BreakIterator, wide-cell math viaWCWidth. - Testkit —
TuiTestDriver,KeySim,MouseSim,GoldenSupport. Published astermflow-testkit. - ~22 sample apps — counter, async counter, clock, dashboard, echo, hello, forms, wizard, dialog, file-dialog, themes, unicode, stress, sine, hub, input, tabs, task, catalog, widgets, showcase, tree, editor, chat.
- Docs site — live at
https://llm4s.github.io/termflowwith Introduction, four tutorials, eight layer guides (including Accessibility), ten cookbook recipes (including the rolling-console / agent-UI walkthrough), a thread-model reference, and aggregated Scaladoc.
No outstanding architectural debts for 1.0. Remaining work is in §3 and the pre-1.0 release-hardening checklist in §4.
3. Stage 4 — Stabilisation (target: 1.0.0)
The lock-in stage. Goal: produce an API stable enough to keep unchanged for years.
3.1 MiMa for binary compatibility — deferred to post-1.0
Originally planned as a 1.0 gate, but moved out of the critical path
(decision: 2026-04-30). The simpler workflow is to ship 1.0 first, then
wire sbt-mima-plugin against 1.0.0 as the baseline so every
subsequent release (1.0.x, 1.1.0, …) is checked.
Why the change:
- 0.2.0 is already API-stable, so the 0.2.0 → 1.0 filter list would mostly be noise.
- Avoids the bookkeeping cost of maintaining
mimaBinaryIssueFiltersduring the 0.2.x → 1.0 window. - Removes the chicken-and-egg between §3.1 and §3.5 — see §3.5 for the simplified migration-guide stance.
Plan once 1.0 ships:
- Add
sbt-mima-plugintoproject/plugins.sbt. - Set
mimaPreviousArtifacts := Set("org.llm4s" %% name % "1.0.0")on each oftermflow-terminal,termflow-screen,termflow-app,termflow-widgets,termflow, andtermflow-testkit. - Append
mimaReportBinaryIssuesto theciCheckalias.
This becomes part of the 1.0.1 / 1.1.0 release prep, not 1.0.
3.2 Sample app catalogue gaps — ☑ landed
All three planned samples shipped (#188 / #189 / #190): tree/
(file-tree explorer over the Tree widget), editor/ (multi-buffer
text editor exercising MultiLineInput + SplitPane + MenuBar),
and chat/ (streaming chat with scrollback per the
streaming-output cookbook recipe).
Catalogue now stands at 22 apps.
3.3 Killer demo — ☑ landed
The llm4s streaming chat client shipped at
modules/samples/.../chat/tui
in the llm4s repo. It exercises the headline TermFlow surface — live
streaming via the LogView auto-tail pattern, mouse-wheel scrollback,
slash commands (/help, /clear, /theme), light/dark theme toggle,
and a pinned bottom prompt — against a real Anthropic-API backend.
Termflow's README now leads with the chat client screenshot
(docs/assets/chat-ui-screenshot.png) plus a "Built with TermFlow —
source at llm4s/llm4s/.../chat/tui" link, exactly as the §3.6 DoD asks.
The original handover spec
(docs/design/chat-tui-demo-spec.md
in llm4s) and the implementation plan that grew out of it remain
useful reference material; the live source supersedes them as the
canonical example.
3.4 GridLayout + BorderLayout — ☑ landed
Shipped in #187. Layout.Grid(columns, rowGap, colGap, cells) with
GridCell row/column spans, and Layout.Border(top, left, center, right, bottom) with five-zone resolution. Both flow through
Layout.resolveTo so existing resolve callers are unchanged.
LayoutGridSpec and LayoutBorderSpec cover sizing, gaps, spans,
and zone omission.
3.5 Migration guide
With MiMa deferred (§3.1), there is no automated source of breakage data for 0.2.0 → 1.0. The guide page stays useful as a hand-written record of any deliberate API changes during the run-up to 1.0.
For 1.0:
- Walk the public API by hand, note any intentional breaks, and write before/after recipes for each.
- If nothing broke, collapse the page to "no migration needed; 1.0 is source-compatible with 0.2.0."
- Once §3.1 is wired post-1.0, future entries are driven by MiMa filters as originally intended.
3.6 Definition of done for 1.0
- ☑ Docs site live at
https://llm4s.github.io/termflow. - ☑ Tutorial ladder complete (Hello World, Counter, Async, Forms).
- ☑ Sample app count ≥ 20 (22 today, including
tree,editor,chat). - ☑
Layout.Grid+Layout.Bordershipped (§3.4). - ☑ Migration guide populated —
docs/reference/migration.mdcarries the explicit "no migration needed for 0.2.x → 1.0" statement plus the additive-changes catalogue (§3.5 / §4.3). - ☑ README headline screenshot is the llm4s chat client (§3.3 — demo
hosted in
llm4s, screenshot + link in this README). - ☑ Pre-1.0 release-hardening checklist complete (§4) — interim release-doc sweep at 0.4.0 finished §4.2; the final 0.4.0 → 1.0.0 bump rides with the release PR itself.
MiMa (§3.1) was originally on this list; it is now scheduled for the
1.0.1 / 1.1.0 cycle with 1.0.0 as the baseline.
4. Stage 5 — Pre-1.0 release requirements
Final hardening before tagging v1.0.0. These are not new feature
tracks; they are release-quality gates for the current library surface.
4.1 User-visible error path — ☑ landed
Cmd.TermFlowErrorCmd now reaches the user. SimpleANSIRenderer
overlays a red, bold banner across the top row of the next frame and
clears it on the following render — long messages truncate with an
ellipsis. SimpleANSIRendererSpec covers banner content, styling,
truncation, and frame immutability. TuiTestDriver.observedErrors
gives tests the same assertion path without a real terminal. The
app-layer guide has a new "How errors reach the user" section that
shows the rendered banner and the testkit hook.
4.2 Version and release-doc sweep — ☑ landed (interim 0.4.0 pass)
Every copy-pasteable coordinate in the published docs has been bumped
from 0.2.0 to the current released baseline (0.4.0): README quick-
start, all four layer guides, the testkit guide, the install page, the
Hello-World tutorial, and the API reference module table. Migration
notes acknowledge 0.2.0 / 0.3.0 / 0.4.0 → 1.0 as the no-migration
window, and the new reduced-motion entry is catalogued. The roadmap
headline now reads Current release: 0.4.0. Release-instructions still
describe the v[0-9]* tag path, which already covers v1.0.0.
A second, narrower sweep happens at 1.0 tag time: bump every 0.4.0 →
1.0.0, drop the "no migration needed" wrapper from migration.md
(or re-cast it as historical), and update the §2 "Current state"
heading. That bump is mechanical — same files, same patterns — and is
deferred to the release PR rather than landed pre-emptively, so the
coordinates always reflect what's actually on Maven Central.
Historical mentions of 0.2.0 / 0.3.0 are kept in places where they
describe the migration story (e.g. early-semver examples in the README,
the pre-1.0 cycle catalogue in migration.md, 0.2.0 → 1.0
references in §3.5 / §4.7 of this roadmap) — those are intentional and
explained in context.
4.3 Public API and docs example audit — ☑ landed
Walked the public-facing APIs and every tutorial / guide / cookbook
snippet against the source. Eight signature drifts and dead-code blocks
in the docs were corrected (Cmd.asyncResult, Sub.TerminalResize,
Cmd.FCmd type params, MultiLineInput.handleKey curried form,
Capabilities.notifications, missing RootNode.input arg, mistyped
Cmd.FCmd in the file-picker recipe, orphaned Layout.column block
in the full-screen-layout recipe). Cmd.RequestAttention and
Cmd.Notify are now reflected in the app-layer Cmd table.
docs/reference/migration.md is populated with the explicit
no-migration-required statement plus a catalogue of additive changes
since 0.2.0. mdbook build (with linkcheck) is green. SPI markers on
TuiRenderer / CmdConsumer / CmdBus / EventSink / EventSource
were already in place; any further Scaladoc polish belongs in §4.8.
4.4 Layout ergonomics audit — ☑ landed
Layout.toBudgetedRootNode(width, height, input) now expresses the
deferred form alongside the existing eager toRootNode, putting the
layout into RootNode.layout so the renderer resolves it against the
frame's full budget at render time. toRootNode keeps its eager
semantics; its Scaladoc flags the trap and points at the budgeted form.
A new cookbook recipe (full-screen-layout.md) walks the header / fill
/ footer pattern, the eager-vs-deferred trade-off, and the both-fields
composition seam. LayoutSpec covers both forms with a Fill-collapses
vs Fill-expands comparison.
4.5 Rolling console / agent UI recipe — ☑ landed
docs/cookbook/rolling-console.md walks the Claude-Code / Cursor-style
transcript pattern end-to-end: model shape (Vector[String] buffer +
scrollOffset + autoTail), auto-tail logic, key routing (Arrow /
PageUp / PageDown / End / Ctrl+C), mouse-wheel scrollback through
LogView.scrollDelta, view composition with LogView + an InputNode
prompt, and the Layout.Border alternative for resize-clean layouts.
The recipe is explicit that TermFlow owns an in-app scrollback viewport
inside the alternate buffer; native terminal scrollback is the post-1.0
§5.3 idea, not the default runtime contract. Linked from
docs/cookbook/index.md, docs/SUMMARY.md, and the LogView section
of the widgets guide. ChatStreamApp (sbt chatDemo) is the live
worked example referenced from the recipe.
4.6 Mouse-wheel scrolling for LogView-style views — ☑ landed
LogView.scrollDelta(event, viewport, ticksPerDetent) plus
LogView.Viewport(at, width, height) map a MouseEvent.Scroll onto a
clamp-friendly scroll delta when the wheel lands inside the viewport,
returning None for outside-the-rect or non-scroll events. chatDemo
wires it in (3 lines per detent, ignored over prompt / status row).
LogViewSpec exercises every helper branch; ChatStreamAppSpec adds
two MouseSim.scrollUp tests for the in-pane and out-of-pane paths.
The streaming-output cookbook recipe documents the pattern next to the
keyboard fallbacks.
4.7 Test coverage review and quick wins — ☑ landed
Because TermFlow is mostly deterministic UI logic, coverage should be
higher than a typical terminal integration project. Run sbt --batch coverageLib, inspect the lowest-covered files/branches, and take the
low-risk wins before 1.0.
Current local coverage snapshot (2026-04-30, post a971a94):
termflow-terminal: 87.79% statements / 90.48% branches.termflow-screen: 90.76% statements / 77.45% branches.termflow-app: 86.99% statements / 81.20% branches.termflow-widgets: 92.69% statements / 85.23% branches.
The coverage-uplift branch (a971a94) lifted termflow-terminal from
66.04% → 87.79% statements (63.32% → 90.48% branches), termflow-screen
from 71.81% → 90.76% statements (65.22% → 77.45% branches), and
termflow-app from 80.29% → 86.99% statements (68.61% → 81.20%
branches). All four published modules are now ≥87% statement coverage,
with termflow-terminal and termflow-screen — the §4.7 priority
targets — both above 87%.
Acceptance:
- Add focused tests for pure/render/update logic with obvious gaps.
- Prefer deterministic tests over brittle real-terminal integration.
- Record any accepted low-coverage areas with rationale (JLine/raw TTY integration, shutdown-hook paths, genuinely platform-specific code).
- Keep
coverageLibgreen and ensure the combined trend moves up, with particular attention totermflow-terminalandtermflow-screen.
4.8 Zero-warning build and Scaladoc polish — ☑ landed
sbt --batch ciCheck is warning-free across all published modules and
the sample/testkit projects.
sbt --batch unidoc is clean of unresolved-link warnings: five Scaladoc
[[…]] references that pointed at out-of-scope or unqualified members
were corrected — [[InputKey]] / [[InputKey.Tab]] now spell
KeyDecoder.InputKey…, Theme.box's [[chars]] / [[border]]
references the slot via [[Theme.chars]] / [[Theme.border]],
[[Move]] and friends in MouseEvent are qualified as
[[MouseEvent.Move]] etc., and TerminalBackend.onResize's JLine
Terminal.Signal.WINCH reference dropped its broken [[…]] wrapper
(JLine is on the runtime classpath but not a unidoc target). A
non-exhaustive match warning in Keymap.renderKey (missing the
InputKey.NoOp case) was closed at the same time.
The remaining [warn] Flag -classpath set repeatedly is a structural
sbt-unidoc / Scala-3-doctool quirk (the doc invocation receives
-classpath once from sbt-unidoc and once from the dotty front-end).
It is not an unresolved-link warning and there is no in-tree fix; track
upstream if it becomes load-bearing.
mdBook/linkcheck stay green; the docs site builds unchanged.
4.9 Reduced-motion flag — ☑ landed
A TERMFLOW_REDUCED_MOTION=1 env var (and TermFlowConfig field
defaulting to it) that disables cosmetic animation: Spinner renders
a static frame, indeterminate ProgressBar stops ticking, and apps
can read the flag to drop their own animation. Useful for vestibular
accessibility, screen-reader environments, and bandwidth-constrained
sessions.
Acceptance:
- Env var honoured at runtime construction.
Spinnerrenders a static frame when the flag is set.- Indeterminate
ProgressBarticks slow or become static. - Apps can query the flag via
RuntimeCtx. - Documented in an
accessibility.mddocs page (also a home for any future a11y notes).
Tracked as #139.
4.10 Thread-model documentation — ☑ landed
A docs/reference/thread-model.md (or a new section in the app-layer
guide) explaining the runtime's thread topology — runtime thread,
input producer, Sub.Every scheduler, Future executor, CmdBus —
and the invariants apps and widget authors can rely on (update /
view always run on the runtime thread; Cmd.FCmd continuations
return via the bus; Sub callbacks run off their respective threads;
don't close over mutable state inside FCmd; don't block the runtime
thread).
Doc-only; no code changes. Pairs naturally with §4.5.
Tracked as #134.
5. Stage 6 — Alternative backends and renderers (post-1.0, speculative)
Each backend or renderer is opt-in. None are on the 1.0 critical path.
5.1 Telnet backend
termflow-backend-telnet. Bind a port, accept connections, each
connection becomes a TerminalBackend. Telnet option negotiation
(NAWS for size, ECHO suppression, binary). Small library; medium
effort.
Use case. Self-hosted admin consoles, MUDs, BBS-style apps, oncall debug shells. Not encrypted — operators wrap it in stunnel / WireGuard / SSH-jumphost for production.
5.2 Web backend (xterm.js over WebSocket)
termflow-backend-web. Serve xterm.js plus a WebSocket; the WS
frames become the terminal stream. Run a TUI in a browser tab.
Effort. Large but cleanly bounded. Probably the most "wow factor" of the bunch — a Scala TUI in the browser is unique.
5.3 Rolling console renderer
A constrained normal-buffer renderer/runtime mode for agent and command runner apps that want native terminal scrollback: output appends to the terminal's real history while a live prompt/status area remains pinned near the bottom.
This should not try to support arbitrary full-screen TermFlow VDOM. The current default runtime enters the alternate buffer and the default renderer diffs fixed frames by absolute coordinates; native scrollback needs a different contract built around append-only transcript events, prompt repainting, cursor save/restore, and possibly terminal scroll regions.
Use case. Claude Code / Cursor-style agents, build runners, REPLs, and long-running command logs where users expect their terminal emulator's own scrollbar, copy/search behaviour, and shell history context to keep working.
Shape. Likely a dedicated RollingConsoleApp or renderer API, not
a flag on SimpleANSIRenderer. It should support bounded app-side
history for replay/testing, normal-buffer append, fixed bottom prompt,
keyboard input, resize handling, and a graceful fallback when terminals
handle scroll regions poorly.
Effort. Medium-large and compatibility-sensitive. Worth prototyping after 1.0, but too risky to make part of the 1.0 contract.
5.4 Explicitly not planned (third-party PRs welcome)
- Swing / AWT emulator backend — desktop window with a TUI emulator inside. Skipped because §5.2 covers most of the same use cases at similar effort and reaches more users.
- SSH backend — wrap Apache MINA SSHD or sshj. Skipped because key management, auth, and connection state are a perpetually-supported surface area we don't want to own. Compose §5.1 Telnet behind an external SSH jump host instead.
The TerminalBackend trait stays public so external contributors
can ship either as a separate artefact.
6. Open questions
- Native image.
sbt-native-imagebuild forgraalvm-native-image? The shutdown hook + JLine reflection make this non-trivial. Investigate post-1.0. - Cross-publish for Scala 2.13. Already on
legacy-213-track. Keep parity through 1.0, then re-evaluate based on adoption. - Resizing semantics. When the terminal shrinks, do we clip or rewrap? Currently clip. The Layout pass makes rewrap cheap if we want to switch.
- i18n. Right-to-left text? Bidi? Probably out of scope for 1.0; document as a known limitation.
- Accessibility. Screen readers don't really hit a TUI — they read the terminal directly. Worth an "Accessibility notes" docs section before 1.0.
- Windows native. Currently relies on JLine for cmd.exe /
Windows Terminal. May need a JNA-backed
WindowsConsoleBackendif JLine's behaviour proves insufficient.
7. Lanterna comparison reference
The original 0.1.x roadmap was structured around a comparison with
Lanterna. That comparison drove
Stages 1–3, and almost every Lanterna component now has a TermFlow
equivalent (TextField ≈ TextBox, ListView ≈ ActionListBox,
SplitPane ≈ SplitPanel, etc.). Two Lanterna things we deliberately
don't match:
- The shared GUI thread / listener-callback event model. Replaced
by the Elm-style
updateloop. Not coming back. - Mutable widgets. Replaced by stateless renderers + state on the app's model. Not coming back.
Two TermFlow-only wins worth preserving through 1.0:
- Golden-snapshot testing (
TuiTestDriver+GoldenSupport). HitTest[Id]cache built from the layout pass — Lanterna has no equivalent.
8. Recent decisions (rolling, last ~3 months)
- 2026-05-01 — Stage 4 §4.2 closed (interim 0.4.0 pass): every
copy-pasteable install coordinate in README + layer guides +
tutorials + install page + API reference now reads
0.4.0instead of0.2.0. Migration notes acknowledge0.2.0 / 0.3.0 / 0.4.0 → 1.0as the no-migration window. Roadmap headline + §2 heading + cookbook / guide counts updated to reflect the post-§4.5 / §4.10 / a11y state. The final0.4.0 → 1.0.0mechanical bump is deferred to the release PR. With this, §3.6 DoD is complete and 1.0-RC1 is unblocked. - 2026-05-01 — Stage 4 §3.3 closed: the llm4s chat client shipped at
modules/samples/.../chat/tuiin the llm4s repo. Termflow's README now leads with the screenshot (docs/assets/chat-ui-screenshot.png) and links to the source. The §3.6 DoD's "README headline screenshot" box is ticked. - 2026-04-30 — Stage 4 §4.5 closed: rolling-console / agent-UI
cookbook recipe landed at
docs/cookbook/rolling-console.md. Walks the buffer +scrollOffset+autoTailpattern with key routing, mouse-wheel scrollback, and bounded history;ChatStreamAppis the worked example. Native terminal scrollback explicitly stays a post-1.0 §5.3 idea, not the default contract. - 2026-04-30 — Stage 4 §4.9 closed: reduced-motion flag landed.
TERMFLOW_REDUCED_MOTIONenv var (and HOCONtermflow.accessibility.reduced-motion) flows throughRuntimeCtx.config.accessibility.reducedMotion;SpinneracceptsreducedMotion: Booleanand pins toframes(0)when true. Newdocs/guide/accessibility.mdpage covers the colour, motion, and predictable-structure stance. - 2026-04-30 — Stage 4 §4.10 closed: thread-model documentation
landed at
docs/reference/thread-model.md. Diagrams the topology (runtime thread, InputKey producer, Sub.Every scheduler, FCmd executor, resize listener, shutdown hook) and the invariants apps can rely on (`update` / `view` always on the runtime thread, FCmd continuations come back via the bus, subs lazy-start, CmdBus serialises, etc.). - 2026-04-30 — Issue triage: 25 completed issues closed; #154
(relative-coordinate VDom), #119 (Layout v1→v2 migration guide),
#116 (horizontal scroll), and #117 (partial left-edge clip) all
closed as superseded — the first two because the current Layout DSL
already supplies the relative-coordinate tree and there are no v1
users; the latter two because
Layout.Scroll/Layout.Cliponly ever existed on the abandonedfeature/layout-cookbookbranch and never shipped publicly. Two new entries added to §4 as 1.0 scope: §4.9 (reduced-motion flag — #139) and §4.10 (thread-model documentation — #134). #141 (TuiRuntime error-path tests) scoped down to two remaining gaps (Sub mid-stream exception, CmdBus overflow); not a 1.0 blocker. - 2026-04-30 — Stage 4 §4.7 closed: coverage-uplift branch merged
(
a971a94).termflow-terminal66% → 88% stmts / 63% → 90% branches,termflow-screen72% → 91% stmts / 65% → 77% branches,termflow-app80% → 87% stmts / 69% → 81% branches. All four published modules now ≥87% statement coverage; the priority targets (-terminal,-screen) are both above 87%. - 2026-04-30 — Stage 4 §4.8 closed:
ciCheckis warning-free andunidocclean of unresolved-link warnings. Five Scaladoc[[…]]references rewritten to qualified forms; a non-exhaustiveKeymap.renderKeymatch closed by adding theInputKey.NoOparm. The remainingFlag -classpath set repeatedlyis a structural sbt-unidoc / Scala-3-doctool warning with no in-tree fix. - 2026-04-30 — Stage 4 §4.3 closed: public-API and docs-example audit
swept eight signature drifts out of the tutorials, guides, and cookbook;
docs/reference/migration.mdpopulated with the explicit "no migration required for 0.2.x → 1.0" statement plus a catalogue of additive changes.mdbook build(with linkcheck) clean. - 2026-04-30 — Killer demo (§3.3) will live in
llm4s, not in this repo. Reason: llm4s already depends on termflow for samples, so hosting an llm4s-backed demo here would create a sibling cycle even if the published-artifact graph stays acyclic. Termflow's README will link to the demo and show its screenshot. - 2026-04-30 — Stage 4 §4.1 closed:
SimpleANSIRenderernow overlays a red, bold banner forCmd.TermFlowErrorCmdand clears it on the next frame; testkit captures the same path viaobservedErrors. - 2026-04-30 — Stage 4 §4.4 closed:
Layout.toBudgetedRootNodeis the deferred sibling to the eagertoRootNode; new full-screen-layout cookbook recipe explains when each form is appropriate. - 2026-04-30 — Stage 4 §4.6 closed:
LogView.scrollDelta+LogView.Viewportgive apps a one-call hook for mouse-wheel scrollback; wired intochatDemoand covered withMouseSim. - 2026-04-30 — Terminal-attention notifications shipped:
Cmd.RequestAttentionandCmd.Notify(title, body)with detection for iTerm2 (OSC 9 / 1337), kitty (OSC 99), VTE (OSC 777), and a BEL fallback. Override viaTERMFLOW_NOTIFICATIONS=off|bell|auto. Wired through the showcase Help tab and a newnotificationscookbook recipe. - 2026-04-30 — Added rolling console renderer (§5.3) as a post-1.0 idea: native terminal scrollback for agent / command-runner UIs via a constrained normal-buffer runtime, not the default full-screen renderer.
- 2026-04-30 — Added Stage 5 (§4) as the pre-1.0 release-hardening checklist: user-visible errors, release-doc accuracy, API/docs audit, layout ergonomics, rolling-console UX, mouse-wheel scrollback, coverage quick wins, and zero-warning builds.
- 2026-04-30 — MiMa (§3.1) deferred to post-1.0; baseline becomes
1.0.0. Reason: 0.2.0 is already API-stable, so the 0.2.0 → 1.0 filter list would be mostly noise, and decoupling §3.1 from §3.5 removes a chicken-and-egg dependency. - 2026-04-30 — Stage 4 §3.2 closed:
tree/(#188),editor/(#189), and streamingchat/(#190) sample apps landed. Catalogue at 22. - 2026-04-30 — Stage 4 §3.4 closed:
Layout.Grid+Layout.Bordershipped in #187 withLayoutGridSpec/LayoutBorderSpeccoverage. - 2026-04-29 — Docs site launched (Stage 4 §3 complete except for migration guide). mdBook + sbt-unidoc on GitHub Pages.
- 2026-04-28 — Stage 3 final components landed:
actionListdialog,ScrollBar,Separator,SplitPanedrag-resize, hit-test cache (HitTest[Id]+Layout.Zone+resolveTracked), grapheme-aware navigation,MultiLineInput. - 2026-04-28 —
Cmd.FCmddecision: stay onscala.concurrent.FutureResult[A]; nocats-effect/ziomodules planned. Apps bridge toFutureat theCmdboundary.
- 2026-04-27 — Stages 1 and 2 closed. Module split shipped early as Stage 4 prep so MiMa filters can be wired per-module on day one.
- 2026-04-26 — Decision to deprioritise Swing/AWT and SSH backends (now §5.4); Telnet (§5.1) and Web (§5.2) remain.