Commits
Fish 4.x sends a DA1 (Primary Device Attribute) query at startup
and blocks for up to 10s waiting for a response. Add a CSI handler
in PtyServer that intercepts the query and writes back a VT220
response. Add shell integration tests for bash, zsh, and fish.
Closes #5
Based on the approach by @schickling-assistant in #5
New public API covering every CLI feature: SessionConnection for
bidirectional attach without stdin/stdout, sendData/peekScreen as
Promise-based alternatives, events, keys, stats, and protocol types.
Refactor spawnDaemon to options object with optional rows/cols.
Detect when pty run is invoked inside an existing session via
PTY_SESSION env var and exec the command directly (-d bypasses).
Add CPU, memory, and PID reporting to pty stats for both the
child process and daemon.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Track mouse mode (1000/1002/1003) via CSI parser on local and
attached handles, exposed as readonly mouseMode property
- Add cursorRow/cursorCol properties (from xterm buffer cursor)
- Accept scrollback option in createPty/attachPty (default 0)
- Add bufferLength/baseY properties for scrollback navigation
- Support readCells(scrollOffset) to read into scrollback history
- Fix readXtermCells to read from baseY (was reading from line 0,
masked by scrollback:0)
- Re-export spawnDaemon from tui index
pty wrap claude creates ~/.local/pty/bin/claude that runs
pty run -a -- /real/path/to/claude "$@"
pty unwrap claude removes the wrapper
pty wrap --list shows wrapped commands
Uses PTY_BIN_PATH env var (default ~/.local/pty/bin/). Warns
if the directory isn't in PATH.
Fix stale screen content on reattach by tracking last resize time and
delaying serialization when a resize recently occurred. After sending
the serialized screen, nudge the child process with a SIGWINCH to
trigger a fresh redraw, eliminating visual artifacts from the serialize
addon's ECH/CUF approximation.
Create session directory with mode 0o700 and chmod sockets to
0o600 after creation. Prevents other local users from connecting
to sessions on systems where home directories are world-readable
(e.g., Debian/Ubuntu with default 0o755 home dirs).
- app() now calls onEnter/onLeave on screen transitions, overlay
changes, and shutdown. Fixes tick timers, PTY cleanup, and
spinner leaks across screen switches.
- Interactive create wizard spawns via sh -c instead of splitting
on whitespace. Quoted args, pipes, and env vars now work.
- Reject pty peek -f --plain — follow mode streams raw ANSI,
incompatible with plain output.
Interactive list:
- Fuzzy matching for session filter (fzf-style, characters in order)
- Name matches scored 10000+ above cwd/command matches
- ▸ selection indicator on the active item
- Ctrl+G cycles through all themes, name shown in footer
- Theme preference saved to ~/.local/state/pty/theme
Themes:
- Light variants of all 5 themes (coolBlueLight, warmAmberLight, etc.)
- New "terminal" theme: null colors, uses terminal's own fg/bg
- Terminal theme is the default — works on any color scheme
- Theme type widened to allow null (renderer already handled it)
Framework fix:
- Text nodes inside panels now preserve the panel's background color
instead of clearing to null. Previously invisible on dark themes
but caused white bleed-through on light terminals.
Sessions are now auto-named from directory + command when no name is
given: `pty run -- node server.js` creates `myapp-node-server`. Use
`--name` for explicit names. Old positional syntax still works with
a hint to migrate.
The interactive wizard auto-generates the name as you type the
command. Manually editing the name stops auto-generation. Filter
results now rank name matches above path/command matches.
Fix: add postinstall script to chmod +x node-pty's spawn-helper
binary. npm strips the executable bit during install, causing
posix_spawnp to fail on global installs.
Fix: move @preact/signals-core from optional peer dependency to
regular dependency — the CLI now uses it since the interactive
list rewrite.
The EXIT packet handler in attach() didn't set exitHandled, so the
socket close event called onExit a second time, which added a
duplicate stdin listener via resumeTui → setupInput.
Added regression test that types after session exit and verifies
characters aren't doubled.
Node refuses to run .ts files from node_modules/. The CLI and daemon
now run from dist/ (compiled by tsc). Tests and exports updated to
use dist/ for subprocess spawning.
npm run build is now required before using the CLI locally.
Node refuses to type-strip .ts files under node_modules/, so
`pty` failed after `npm install -g`. The CLI entry point is now
bundled to a single bin/cli.js via esbuild during prepublishOnly.
The testing and TUI exports remain .ts — consumers' toolchains
handle those.
TUI framework (src/tui/):
Declarative UI with reactive signals, two-pass layout engine,
cell-buffer diffing, and 5 color themes. Exported as ptym/tui.
Includes text wrapping with word-boundary breaking and a
highlight callback for per-character span styling.
Demo apps (demos/):
Three standalone apps that showcase the framework and the
PTY testing library:
- file-browser: two-pane directory tree + file preview with
soft-wrap and markdown highlighting
- reminders: full CRUD backed by .md files with YAML frontmatter,
three views (grouped list, kanban board, calendar), overlays
- agent-teams: live dashboard of a simulated AI agent hierarchy
with real-time timeline, inter-agent messages, progress bars
Each demo has unit tests and PTY integration tests that verify
actual rendered screen output — not just string presence, but
layout correctness (gutter alignment, panel sizing, selection
indicators, overlay compositing).
Testing improvements:
- JSDoc on all Session methods and type fields
- docs/testing.md: server-mode API (attach, reconnect, resize,
connectToExisting, hasExited)
- Fix timing-sensitive filter test (waitForText instead of sleep)
README:
- Beta notice
- Expanded testing library section with realistic example
- TUI framework alpha notice with demo descriptions
Also: vitest.config.ts, demos/run convenience script.
Resize to the smallest dimensions across all connected writable clients
Fish 4.x sends a DA1 (Primary Device Attribute) query at startup
and blocks for up to 10s waiting for a response. Add a CSI handler
in PtyServer that intercepts the query and writes back a VT220
response. Add shell integration tests for bash, zsh, and fish.
Closes #5
Based on the approach by @schickling-assistant in #5
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Track mouse mode (1000/1002/1003) via CSI parser on local and
attached handles, exposed as readonly mouseMode property
- Add cursorRow/cursorCol properties (from xterm buffer cursor)
- Accept scrollback option in createPty/attachPty (default 0)
- Add bufferLength/baseY properties for scrollback navigation
- Support readCells(scrollOffset) to read into scrollback history
- Fix readXtermCells to read from baseY (was reading from line 0,
masked by scrollback:0)
- Re-export spawnDaemon from tui index
Fix stale screen content on reattach by tracking last resize time and
delaying serialization when a resize recently occurred. After sending
the serialized screen, nudge the child process with a SIGWINCH to
trigger a fresh redraw, eliminating visual artifacts from the serialize
addon's ECH/CUF approximation.
- app() now calls onEnter/onLeave on screen transitions, overlay
changes, and shutdown. Fixes tick timers, PTY cleanup, and
spinner leaks across screen switches.
- Interactive create wizard spawns via sh -c instead of splitting
on whitespace. Quoted args, pipes, and env vars now work.
- Reject pty peek -f --plain — follow mode streams raw ANSI,
incompatible with plain output.
Interactive list:
- Fuzzy matching for session filter (fzf-style, characters in order)
- Name matches scored 10000+ above cwd/command matches
- ▸ selection indicator on the active item
- Ctrl+G cycles through all themes, name shown in footer
- Theme preference saved to ~/.local/state/pty/theme
Themes:
- Light variants of all 5 themes (coolBlueLight, warmAmberLight, etc.)
- New "terminal" theme: null colors, uses terminal's own fg/bg
- Terminal theme is the default — works on any color scheme
- Theme type widened to allow null (renderer already handled it)
Framework fix:
- Text nodes inside panels now preserve the panel's background color
instead of clearing to null. Previously invisible on dark themes
but caused white bleed-through on light terminals.
Sessions are now auto-named from directory + command when no name is
given: `pty run -- node server.js` creates `myapp-node-server`. Use
`--name` for explicit names. Old positional syntax still works with
a hint to migrate.
The interactive wizard auto-generates the name as you type the
command. Manually editing the name stops auto-generation. Filter
results now rank name matches above path/command matches.
Fix: add postinstall script to chmod +x node-pty's spawn-helper
binary. npm strips the executable bit during install, causing
posix_spawnp to fail on global installs.
Fix: move @preact/signals-core from optional peer dependency to
regular dependency — the CLI now uses it since the interactive
list rewrite.
TUI framework (src/tui/):
Declarative UI with reactive signals, two-pass layout engine,
cell-buffer diffing, and 5 color themes. Exported as ptym/tui.
Includes text wrapping with word-boundary breaking and a
highlight callback for per-character span styling.
Demo apps (demos/):
Three standalone apps that showcase the framework and the
PTY testing library:
- file-browser: two-pane directory tree + file preview with
soft-wrap and markdown highlighting
- reminders: full CRUD backed by .md files with YAML frontmatter,
three views (grouped list, kanban board, calendar), overlays
- agent-teams: live dashboard of a simulated AI agent hierarchy
with real-time timeline, inter-agent messages, progress bars
Each demo has unit tests and PTY integration tests that verify
actual rendered screen output — not just string presence, but
layout correctness (gutter alignment, panel sizing, selection
indicators, overlay compositing).
Testing improvements:
- JSDoc on all Session methods and type fields
- docs/testing.md: server-mode API (attach, reconnect, resize,
connectToExisting, hasExited)
- Fix timing-sensitive filter test (waitForText instead of sleep)
README:
- Beta notice
- Expanded testing library section with realistic example
- TUI framework alpha notice with demo descriptions
Also: vitest.config.ts, demos/run convenience script.