# Changelog
## 0.5.10
### Bug Fixes
- **Reflow on resize:** when the primary screen changes width, the built-in core rewraps soft-wrapped lines in scrollback and on screen together, instead of cutting each row at the new width and dropping the rest. Wide characters stay paired and the cursor stays in its line. The alternate screen still truncates, as other terminals do (#240).
- **WorkerCore theme colors:** `WorkerCore` now has `setThemeColors()`, so OSC 10 and OSC 11 queries answer with the page's theme colors instead of the core's defaults, as the built-in and Ghostty cores already do. The worker applies the colors in order with writes (#278).
- **Ghostty scrollback lines:** with `scrollbackLines` set, `@wterm/ghostty` keeps the requested number of lines for styled output. Output with many colors, graphemes, or hyperlinks used to keep fewer, such as 91,166 of 100,000 colored log lines at 80 columns. History memory is capped at twice what plain text needs at the same width, so very dense output can still keep fewer lines (#286).
### Contributors
- @Railly
- @ctate
## 0.5.9
### New Features
- **WebGL2 renderer:** `renderer: "webgl"` in `@wterm/dom` paints live output with one instanced WebGL2 draw per frame from a shared glyph atlas. All terminals on a page share one WebGL2 context, so pane grids are not limited by the browser's cap on live contexts. DOM text stays the source for selection, find, and screen readers, and catches up when output goes idle. Without WebGL2 it falls back to `"dom"` (#250).
- **Scrollback in lines:** the `scrollbackLines` option, `setScrollbackLines()`, and a `scrollbackLines` prop in React, Vue, and Svelte set how much history a terminal keeps, in lines, for every core. The built-in core's history grows toward its limit instead of reserving 1000 rows up front, and lowering the limit drops older rows for good (#263).
- **modifyOtherKeys level 2:** both cores track and report xterm `modifyOtherKeys` level 2, and the DOM input encodes keys whose legacy encoding loses a modifier as `CSI 27 ; modifier ; code ~`. Vim and other apps can tell Ctrl+Shift+E apart from Ctrl+E. `TerminalCore.modifyOtherKeys()` exposes the level (#254).
### Documentation
- **ACP agent example:** `examples/acp-agent` shows one terminal per tool call in an agent UI, with terminals that start when a card scrolls into view and pause off screen. The configuration guide adds a section on many terminals on one page (#270).
### Contributors
- @Railly
## 0.5.8
### New Features
- **WebMCP:** terminals can register tools that in-page agents call to list terminals, read output, type commands, and press keys, instead of scraping the DOM. Opt in with the `webmcp` option in `@wterm/dom` or the `webmcp` prop on the React, Vue, and Svelte components, and change it later with `setWebMCP()`. `readOnly` lets agents read without typing. It does nothing in browsers without a WebMCP provider (#261).
### Contributors
- @ctate
## 0.5.7
### New Features
- **Grapheme clusters:** the built-in core keeps ZWJ emoji, flags, and combining marks in one cell instead of splitting them across cells, and widens emoji presentation and flag pairs to two cells. `WasmBridge` exposes the full cluster as `CellData.chars` (#241).
- **WorkerCore:** `@wterm/core/worker` runs the built-in core in a Web Worker so parsing leaves the main thread, and many busy terminals can use more than one CPU core. Opt in with `WorkerCore.load()`; replies and other effects of a write arrive one message later (#252).
- **Theme color queries:** OSC 10 and OSC 11 queries are answered with the foreground and background the page's CSS shows at query time, so apps like Vim and Neovim pick a matching light or dark theme. `setThemeColors()` overrides them and `setThemeColors(null)` returns to CSS (#253).
### Improvements
- **Canvas cell painting:** block characters and cell backgrounds paint into one canvas behind the text rows instead of one styled span per cell. Dense truecolor output keeps up: 16 terminals playing Doom go from about 6.6 to 36 frames per second each, and chafa video at 160x50 goes from 14.5 to 60 frames per second (#256).
- **Shared render frame:** all terminals on a page render in one animation frame that reads layout before any writes, and rows that only scrolled are moved instead of rebuilt. 64 terminals streaming colored `ls` go from 12.7 to 15.9 frames per second each, and style recalculation drops from 18% to 6% of main-thread time. Custom cores can opt in with the optional `getRowId` and `isRowContentDirty` methods (#257).
- **Ghostty write fast paths:** `@wterm/ghostty` handles Kitty image payloads, plain CSI sequences, and plain UTF-8 text before the byte-by-byte parser, and cell reads no longer touch WASM memory per cell (#251).
### Contributors
- @Railly
- @lahfir
## 0.5.6
### Improvements
- **Built-in core scrolling:** advance full-screen scrolls without copying the grid on every line (#242).
- **Terminal output throughput:** write eligible ASCII and UTF-8 runs directly into the current row while preserving parser fallbacks (#243).
### Bug Fixes
- **Truecolor output:** preserve exact RGB foreground and background colors in the built-in core, with palette fallback when the color table is full (#239).
- **Restored cursor bounds:** clamp saved cursor positions after resizing to prevent writes outside the grid (#248).
- **iOS keyboard visibility:** resize auto-sized terminals to keep the cursor row above the software keyboard (#244).
### Contributors
- @Railly
## 0.5.5
### Documentation
- Updated **WebMCP integration** in the docs site with the Geistdocs MCP adapter and route-contract coverage (#190)
### Contributors
- @Railly
## 0.5.4
### Bug Fixes
- **Glyph rendering:** preserve italic and fallback glyph overhang without shifting adjacent terminal columns.
- **Cursor appearance:** keep the cursor active while the mouse is pressed inside the terminal, preserving native text selection.
- **Row spacing:** preserve fractional CSS row heights during terminal initialization.
### Contributors
- @ctate
## 0.5.3
### Improvements
- **History scrolling:** reuse unchanged history content and keep the mounted row window during small scrolls, reducing repeated rendering and layout work.
- **Terminal redraws:** preserve unchanged cell spans and update existing text nodes when styles and column widths match, reducing work for Unicode output while preserving selection, links, and text decorations.
- **Startup memory:** allocate Ghostty screen pages as needed and measure auto-sized terminal hosts before creating the grid, avoiding unused pages and unnecessary initial resizes.
- **WASM loading:** stream compilation where supported and reuse compiled modules across terminals for both cores, while keeping each terminal's state and memory independent.
- **Built-in WASM downloads:** import the embedded binary only on first use. With code splitting, Ghostty and custom-URL applications skip its JavaScript chunk; applications using the built-in core must deploy all generated assets.
### Bug Fixes
- **Scrollback spacing:** update spacer heights when the row height changes, even when the same history rows remain mounted.
### Contributors
- @ctate
## 0.5.2
### New Features
- **Local workspace controls:** view up to four shells in adjustable split panes, zoom and focus panes, and save appearance, font size, and custom keyboard shortcuts.
- **Local session recovery:** resume briefly disconnected shells with output replay and input delivery acknowledgments, and restore sessions, split layouts, and focus after reload when saved output and server sessions remain available. Recovery uses bounded storage and a 30-second server grace period.
- **Shell integration:** expose Ghostty shell command state, exit codes, and working-directory reports; show them in the local workspace and navigate between retained shell prompts.
- **Rectangular selection:** Alt/Option-drag selects columns from logs and tables, preserving selected spaces and complete Unicode cells when copied.
- **Application clipboard requests:** forward Ghostty OSC 52 writes to an opt-in host callback; the local workspace offers a text preview and explicit Copy action.
### Improvements
- **Terminal responsiveness:** pause painting for inactive panes, reuse unchanged scrollback rows, reduce query-scanning and full-history search work, and batch local PTY output with browser acknowledgments and bounded queues.
- **Terminal appearance:** preserve Ghostty underline styles and colors, honor application foreground, background, and cursor overrides, and update host theme colors without restarting terminals.
- **Build and performance checks:** verify reproducible Ghostty WASM builds and add sustained-output, history-search, and keyboard-to-echo measurements, including real PTYs under output load.
### Bug Fixes
- **Ghostty page initialization:** clear reused WASM page memory so new terminal pages do not inherit stale state from earlier contents.
### Contributors
- @ctate
## 0.5.1
### New Features
- **Terminal history search and selection:** search retained output, navigate matches, select all history or by word and logical line, preserve selections across scrolling and reflow, and copy selected terminal text faithfully.
- **Accessible output and navigation:** add opt-in terminal output announcements, a stable text view of retained output, accessible naming for terminal input, and Escape then Tab navigation out of terminal input.
- **Expanded terminal interaction:** report X10, UTF-8/urxvt, SGR pixel-coordinate, and any-motion mouse events; expose terminal bell events and IME preedit; and support application cursor shapes and blinking.
- **Just-Bash editing and history:** add Ctrl-R/Ctrl-S history search, Ctrl-C interruption, Ctrl-Y restoration of erased input, completion at the cursor, and common navigation, deletion, word movement, and Unicode grapheme editing.
### Improvements
- **Terminal compatibility:** answer more device, status, and DEC private-mode queries; grow built-in grids on demand; expose Ghostty row-wrap metadata and OSC window titles; and render DEC line-drawing characters with connected box-drawing strokes.
- **Documentation and validation:** move the docs site to Geistdocs 2 Labs and add real-PTY, cross-browser workload, and public Ghostty WebAssembly API coverage.
### Bug Fixes
- **Keyboard, pointer, and touch input:** preserve AltGr text in Kitty mode, encode legacy control and navigation modifiers, keep scrollback usable with mouse tracking, prevent raw key leakage during IME composition, and keep touch input usable on iOS.
- **Rendering and sizing:** fix wide-character editing and right-edge printing, align fallback glyphs to terminal columns, prevent edge-cell backgrounds from repainting rows, and report applied grid dimensions.
- **Shell behavior:** prevent duplicate command execution and restore the current draft after history navigation.
- **Homepage terminal startup:** keep startup and theme synchronization working together.
### Contributors
- @ctate
- @Railly
## 0.5.0
### New Features
- **Svelte support:** added `@wterm/svelte` with a Svelte 5 `` component, callbacks, imperative controls, SSR-safe initialization, and shared DOM/core exports, plus documentation and an example.
### Bug Fixes
- **Focused cursor visibility:** cell foreground and background styles are now overridable by the cursor rule, keeping the focused cursor visible over colored, wide, block, and blank cells.
### Contributors
- @ctate
- @jaredevans
## 0.4.1
### New Features
- **Local terminal workspace:** the local example now supports multiple independent shell sessions with an accessible sidebar for creating, switching, and closing sessions, plus live working-directory labels.
- **Kitty image sizing and geometry:** DOM terminals answer Kitty pixel-geometry queries, configurable image bounds preserve aspect ratio, and the local PTY forwards browser dimensions so Kitty clients can detect image support.
### Improvements
- **Implicit image flow:** auto-sized Kitty images align with the terminal content and reserve their rendered height, keeping following shell prompts visible below the image.
- **Local example core switching:** built-in and Ghostty terminal sessions share the workspace while the Ghostty route enables bounded Kitty image rendering.
### Contributors
- @ctate
## 0.4.0
### New Features
- **Kitty keyboard protocol:** the built-in and Ghostty cores negotiate Kitty keyboard reporting, while the DOM renderer encodes browser keyboard events using the active terminal state.
- **Kitty terminal images:** Ghostty-backed terminals render bounded direct PNG, RGB, and RGBA graphics through the optional terminal graphics API and a scroll-aware canvas overlay.
### Bug Fixes
- **Fractional scroll ownership:** the DOM renderer preserves follow mode when browser reclamping changes the scroll position during terminal updates.
### Contributors
- @ctate
- @Railly
## 0.3.4
### New Features
- **Native OSC 8 hyperlinks:** the built-in and Ghostty cores preserve hyperlink metadata through rendering, scrollback, reflow and resets. The DOM renderer exposes safe absolute HTTP(S) links as native anchors, with Command-click activation on macOS and Control-click on Windows/Linux while plain clicks remain terminal-owned (#116)
### Bug Fixes
- **Complete Ghostty grapheme strings:** combining marks and ZWJ sequences now cross the WASM boundary as complete clusters in both the viewport and scrollback instead of being truncated to a base codepoint (#111)
- **Ghostty theme color responses:** OSC 10 and OSC 11 queries now return the configured foreground and background colors with the original BEL or ST terminator (#113)
- **Atomic Ghostty synchronized output:** Ghostty exposes DEC mode `?2026` state and block generations so the DOM scheduler holds intermediate frames and paints the completed burst once (#114)
- **Bounded scrollback DOM:** history rows are virtualized with viewport overscan, preserving native selection and the visible history position across rollover and resize while keeping mounted rows bounded (#115, #61)
### Improvements
- **Direct animation-frame scheduling:** normal writes request an animation frame without an intermediate timer while retaining one pending render per frame and synchronized-output cancellation semantics (#112)
### Contributors
- @Railly
## 0.3.3
### Bug Fixes
- **Pixel-aligned block gradients** — vertical fractional block glyphs now snap their gradient stops to whole pixels, preventing horizontal rules from jogging between cells at fractional row-height boundaries (#104, #81)
- **Ordered terminal query responses** — the built-in core queues every response instead of overwriting a single pending value, and the DOM adapter drains them in order even when writes arrive in chunks or an `onData` callback throws (#105)
- **Atomic synchronized output** — DEC mode `?2026` now holds intermediate paints and exposes one completed frame, with a fixed one-second recovery ceiling for unterminated blocks and generation-aware deadlines for consecutive blocks (#106, #57)
- **Browser mouse and focus reporting** — the DOM adapter now emits SGR press, drag, release and wheel events for modes `1000`, `1002` and `1006`, reports focus for mode `1004`, and preserves native Shift selection (#107, #55)
- **Viewport history across vertical resize** — shrinking pushes only the rows above the cursor into scrollback, growing refills from the newest history, and wrapped rings are indexed from their write position. Growing now consumes restored scrollback rows, so `getLine` offsets can shift across a resize and hosts retaining an offset must re-read it (#108, #43, #89)
- **Terminal responses in `@wterm/ghostty`** — DA1, DSR operating status, CPR and DECRQM queries now produce ordered responses through a bounded FIFO instead of being silently dropped (#109)
### Contributors
- @ivebenfreed
- @Ramalama2
- @Railly
## 0.3.2
### Bug Fixes
- **Wide characters occupied one cell** — CJK, fullwidth forms and emoji painted two columns while the grid gave them one, so every occurrence pushed the rest of the row right and cursor-addressed redraws landed a column early. `CellData` gains `width`, the core advances by it, and the DOM renderer skips continuation cells (#102, #54, #71, #101)
- **Blank scrollback in `@wterm/ghostty`** — `get_scrollback_line` was an unimplemented stub returning 0, so every scrolled-back row rendered empty even though the row count was correct (#98)
- **Style leaking across screens** — `get_viewport` read `RenderState.Cell.style` without checking `style_id`, resurfacing the style of whatever occupied the cell in an earlier render pass, including one against the alternate screen (#96)
- **`GhosttyCore.load()` under bundlers that inline modules** — Bun's dev server resolves `import.meta.url` to a path on the build machine, so a `file:` URL reached the browser and `fetch` reported only `Failed to fetch`. The loader now names the cause and points at `wasmPath`, and reports a non-OK response or a non-WASM body instead of failing inside `WebAssembly.instantiate` (#99)
- **`scrollbackLimit` documented as lines** — ghostty reads it as a byte budget, so an 80-column terminal retains about 1150 rows at the 10000 default, not 10000 (#98)
- **Cell width guessed by Unicode block** — hand-written ranges called 1209 assigned characters wide that Unicode calls narrow, including enclosed alphanumerics, domino tiles and several arrow blocks. The table is generated from East Asian Width data now (#102)
- **Wide pairs split at a narrower width** — a row dropped into scrollback during a resize kept a wide cell whose continuation was left behind, and a scrollback row read into a narrower grid spilled a column past its end (#102)
### Improvements
- **`@wterm/ghostty/ghostty-vt.wasm` subpath export** — the binary is now addressable through the package, so apps on bundlers that cannot resolve the default can serve it themselves (#99)
- **Container WASM build** — `rebuild-wasm:docker` runs the existing build script in Linux, for hosts where Zig 0.15.x cannot link a native build runner. Output is byte-identical to a host build (#98)
### Contributors
- @ctate
- @njbrake
- @Railly
## 0.3.1
### Bug Fixes
- **WASM view invalidation** — cached `DataView` and `Uint8Array` views over WASM memory became detached when the module grew memory mid-call, throwing on `getCell`, `getScrollbackCell` and multi-chunk `writeRaw` (#92)
- **Scrollback colors in `@wterm/ghostty`** — `getScrollbackCell()` packed `fgRgb`/`bgRgb` regardless of `colorFlags`, so cells with no explicit color rendered black instead of the terminal default (#93)
- **`escapeHTML` double quotes** — the DOM renderer's escape helper left `"` unescaped (#94)
### Improvements
- **Test coverage for `@wterm/ghostty`** — the package had no test setup, so `turbo run test` skipped it entirely. It now runs in CI like the other packages (#93)
### Contributors
- @hobostay
- @Railly
## 0.3.0
### New Features
- **Ghostty core** — new `@wterm/ghostty` package with `GhosttyCore` implementing `TerminalCore` via libghostty compiled to WASM, providing an alternative terminal rendering engine (#62)
- **`TerminalCore` interface** — extracted into a standalone module in `@wterm/core` so custom cores (like Ghostty) can be swapped in cleanly (#62)
- **Ghostty example** — minimal vanilla TypeScript example using `@wterm/ghostty` and `@wterm/dom` (#62)
- **Ghostty docs page** — install, quick start, how it works, and switching cores guide (#62)
### Improvements
- **Write coalescing** — output writes are now batched with `setTimeout` in the DOM renderer to reduce animation flashing (#62)
- **innerHTML renderer** — switched to `innerHTML` for fewer DOM operations per frame (#62)
- **Deferred PTY spawn** — PTY is now spawned on first `RESIZE` event to eliminate the stray `zsh %` artifact (#62)
- **Local example routes** — split into `/` (built-in core) and `/ghostty` with a core toggle (#62)
### Contributors
- @ctate
## 0.2.1
### Bug Fixes
- Fixed **npm publish** — `workspace:*` peer dependencies are now resolved to real version ranges in published tarballs (#58)
- Fixed **Vue package missing from releases** — `@wterm/vue` is now included in the release workflow (#58)
### Contributors
- @ctate
## 0.2.0
### New Features
- **Vue support** — added `@wterm/vue` package with `` component, `useTerminal` composable, auto-echo when `onData` is omitted, and `debug` prop (#30, #46)
### Improvements
- **Trusted publisher releases** — CI now uses trusted publisher workflow for npm publishing (#45)
### Contributors
- @ctate
- @posva
## 0.1.9
### Bug Fixes
- Fixed **background rendering** not applying correctly (#34)
- Fixed **bracketed paste security** — ESC bytes are now stripped from pasted content to prevent escape sequence injection (#33)
- Fixed **Zig version** in build configuration (#28)
### Contributors
- @aaronjmars
- @ctate
## 0.1.8
### New Features
- **E2E browser tests** — added Playwright test suite with 11 tests covering rendering, keyboard input, focus, cursor movement, scrollback, and resize (#25)
- **Vite example** — minimal vanilla TypeScript terminal with `@wterm/dom` and `@wterm/just-bash`, no framework needed (#24)
- **Markdown Streaming example** — Next.js app using `@wterm/react`, `@wterm/markdown`, and AI SDK to stream LLM output into a terminal (#24)
- **API Reference page** — single consolidated reference for all terminal options, React props, WTerm methods, imperative handle, WebSocketTransport, and WasmBridge (#25)
- **Just Bash docs** — install, quick start, options, virtual FS, network access, and keyboard shortcuts (#23)
- **Markdown docs** — streaming examples (vanilla + React), supported syntax, and LLM output guide (#23)
- **Core / Advanced docs** — WasmBridge API, types, headless example, and WebSocketTransport with remote shell example (#23)
### Improvements
- **Zig 0.16.0** — migrated build system and rebuilt `wterm.wasm` with Zig 0.16.0
- **Vitest workspace** — 165 unit tests across all five packages with V8 coverage and Turbo integration (#21)
- **Zig CI** — added Zig test step and WASM drift check to CI workflow (#22)
- **WTerm integration tests** — 33 tests for the DOM orchestrator (#22)
### Bug Fixes
- Fixed **just-bash README** — corrected broken usage example (#22)
### Contributors
- @ctate
## 0.1.7
### Improvements
- **Zero-boilerplate usage** — `` and `new WTerm(el)` now work out of the box with no `onData` wiring required. When `onData` is omitted, typed input is echoed back automatically (#16)
- **Simpler getting-started examples** — docs, READMEs, and configuration pages updated to show the minimal one-liner usage first, with `onData` / `useTerminal` documented as an advanced pattern (#16, #17)
- **Faster docs layout** — removed server-side cookie reads from the root layout, making it synchronous; chat panel state is now fully client-driven via `useSyncExternalStore`
### Contributors
- @ctate
## 0.1.6
### Bug Fixes
- Fixed **terminal height** — replaced `maxHeight` with deterministic `height` computed from `rows * rowHeight`, preventing layout drift caused by `getBoundingClientRect()` timing
- Fixed **border rendering** — switched docs terminal borders from CSS `border` to `inset box-shadow` to avoid border-width interference with height calculations
### Improvements
- **Row height variable** — added `--term-row-height` CSS custom property so row and block heights are defined in one place
### Contributors
- @ctate
## 0.1.5
### Bug Fixes
- Fixed **Shift key** producing input in the terminal when pressed alone
- Fixed **focus scroll** — focusing the terminal no longer causes unwanted page scroll
- Fixed **height lock** — `maxHeight` calculation now accounts for `border-box` sizing and border widths
### Improvements
- **Docs tables** — option/property tables on the Vanilla and React pages now use proper HTML `
` elements
- **Docs routing** — the introduction page is now served at `/` with a redirect from `/introduction`
- **Star count cache** — reduced GitHub star count revalidation interval from 24 hours to 1 hour
### Contributors
- @ctate
## 0.1.4
### Bug Fixes
- Fixed **caret focus state** — the cursor now correctly shows/hides based on terminal focus
- Fixed **paste handling** — clipboard paste works reliably in the terminal
- Fixed **Ctrl+A and Ctrl+E** — jump-to-start and jump-to-end key bindings now work correctly
- Fixed **left/right arrow keys** in the just-bash package for proper cursor movement
- Fixed **Cmd+A** — select-all support in the terminal
- Fixed **clear line** — Ctrl+U now properly clears the current input line
### Improvements
- **Line buffering** — input is now buffered per-line for more accurate editing and replay
- Fixed **broken links** in docs and package READMEs
### Contributors
- @ctate
## 0.1.3
### Improvements
- **Embedded WASM binary** — the ~12 KB WASM binary is now base64-inlined into the JS bundle, eliminating the need to copy and serve `wterm.wasm` as a static asset. `wasmUrl` is now optional and only needed when serving the binary separately for caching or CDN use.
- Updated **docs and READMEs** to reflect the zero-setup WASM approach
### Bug Fixes
- Fixed **renderer formatting** — minor code style cleanup in the DOM renderer
### Contributors
- @ctate
## 0.1.2
### Bug Fixes
- Fixed **block element rendering** — Unicode block characters (U+2580–U+259F) now render correctly using CSS gradients and quadrant compositing instead of font glyphs
- Improved **PTY error handling** — shell spawn failures are now caught gracefully with a user-facing error message before closing the connection
### Improvements
- Removed rounded corners in the local example for a cleaner full-screen look
## 0.1.1
### Bug Fixes
- Fixed **scroll** not working correctly
- Fixed **click focus** triggering when text is selected
### Improvements
- Styled **greeting message** with dim text formatting
- Refactored greeting message internals
- Included `wterm.wasm` as a static asset in package configuration
- Added release process workflow
## 0.1.0
Initial release.