The terminal.write() method from @xterm/headless is async - the data
isn't in the buffer yet when we call serializeAsHTML() immediately
after. This caused empty or partially rendered output in the browser.
Now using the callback form of terminal.write(data, callback) to wait
for the write to complete before serializing and broadcasting to SSE
clients. This ensures the terminal buffer is fully updated before we
generate HTML from it.
Removed the ansiCarryovers Map from server.ts since terminal emulation
now handles all ANSI sequence buffering internally. Marked ansi.ts and
ansi-carryover.ts as deprecated with JSDoc comments, but kept them for
backward compatibility and potential rollback.
When a dashboard connects via SSE, it now receives the current terminal
state for all active sessions. This allows dashboards to immediately
display the full terminal content without waiting for new output.
The output handler now:
- Writes raw data to terminal emulator
- Stores raw data in DB (unchanged)
- Serializes terminal state as HTML
- Broadcasts serialized HTML via SSE
This replaces the ansiToHtml() + splitAnsiCarryover() approach with
proper terminal emulation. The terminal emulator handles all ANSI
sequences internally, including incomplete sequences across chunks.
Creates new module providing terminal session management using @xterm/headless:
- createTerminal(): spawn headless terminal emulator instances
- serializeAsHTML(): export terminal state as HTML
- disposeTerminal(): clean up resources
This replaces stateless ANSI processing with proper VT emulation that tracks
cursor position, screen buffer, and terminal attributes across output chunks.
- Read CLAUDE_REMOTE_SECRET and CLAUDE_REMOTE_SERVER from env
- Make -- separator optional (all args pass through to claude)
- Add --help support (shows wrapper info, passes to claude if configured)
- Update README with binary build/install instructions
- Add binary to .gitignore
Add parsing of structured JSON events from Claude Code hooks in PTY
output. State events track session lifecycle (ready/thinking/permission/
question/complete/interrupted). Stats events provide session metrics
(prompts, completions, tools, thinking time, etc).
Events are detected by parsing each line of PTY output, extracting valid
JSON objects with a type field, and forwarding state/stats events to the
server via WebSocket while preserving all output passthrough.