Skip to content

T-234: Terminal.tsx — xterm.js wrap + input/output binding + exit overlay #129

@mpiton

Description

@mpiton

Goal

Build src/features/terminals/Terminal.tsx: a React component wrapping a single @xterm/xterm instance. Bridges keyboard input → invokeTerminalsWrite, broadcast chunks → term.write(bytes), exit event → "session ended" overlay. Lifecycle handles xterm dispose on unmount; binds FitAddon to a parent ResizeObserver.

Add @xterm/xterm, @xterm/addon-fit, @xterm/addon-web-links via pnpm add (never edit package.json). Tree-shake to keep bundle delta < 200 KB gzipped.

Acceptance criteria

  • <Terminal terminalId={id} /> renders a div with xterm mounted, no SSR (Tauri webview is always client)
  • Keystrokes routed via onData(data => invokeTerminalsWrite(id, encoder.encode(data)))
  • Chunk subscription: store-level listener pipes bytes_base64 → decode → term.write(...)
  • terminal:exited shows a dismissible overlay "Session exited (code N)" + button to close pane
  • FitAddon recomputes cols/rows on parent resize via ResizeObserver, debounced 50 ms (delegated to T-236 hook)
  • Copy/paste keyboard shortcuts wired (Ctrl+Shift+C / Ctrl+Shift+V on Linux, Cmd on macOS)
  • Theme: respect dark/light from existing app theme provider
  • Unit tests with vitest + @testing-library/react:
    • it("should render an xterm instance after mount")
    • it("should call invokeTerminalsWrite when the user types")
    • it("should display exit overlay when terminal:exited fires")
  • Snapshot test for empty mounted state
  • Bundle delta tracked: pnpm build size diff documented in PR

Files to create/modify

  • create src/features/terminals/Terminal.tsx
  • create src/features/terminals/Terminal.test.tsx
  • modify pnpm-lock.yaml via pnpm add @xterm/xterm @xterm/addon-fit @xterm/addon-web-links
  • modify src/styles/ for xterm CSS import (or scoped to component)

References

  • PRD.md F-003 Terminaux xterm parallèles
  • ARCHI.md §11.1 buffer ring + xterm SerializeAddon (defer serialise to follow-up)
  • ARCHI.md §6.5 Composants terminaux

Dependencies

Blocked by T-233.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:P0Priority P0 — must land in sprintscope: frontendReact / Tauri webview / xterm / CodeMirrorsprint:2026-05-14Sprint 2026-05-14 (Sprint 3) — terminals & PTY foundationtrack:CTrack C — frontend (React, Tailwind, Zustand, i18n)type:featureFeature work (new capability)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions