# Terminal

> Full-featured terminal widget (xterm.js + node-pty): local shell with configurable font, theme, shell, cwd, scrollback and startup commands.

| | |
|---|---|
| Version | 1.0.1 |
| Category | Dev Tools |
| Permissions | process.spawn, process.control, shell.exec |
| Depends on | ai-chat |

# Terminal

Full-featured terminal widget (xterm.js + node-pty): local shell with configurable font, theme, shell,
cwd, scrollback and startup commands. Extracted from the app's built-in terminal into a self-contained,
removable plugin.

**Type:** `backend` (needs a long-lived PTY process). Local shell only — no SSH.

## Architecture

`xterm.js (webview) ↔ invoke/on bridge ↔ main/index.ts (Electron main) ↔ main/pty-host.js (node-pty)`

node-pty (a native module) runs in a child process. `main/index.ts` spawns `main/pty-host.js` using the
app's own Electron binary in Node mode (`process.execPath` + `ELECTRON_RUN_AS_NODE=1`) and talks to it
over newline-delimited JSON on stdin/stdout. This needs NO system `node` on PATH; node-pty's prebuild
loads under Electron's ABI (verified). node-pty lives in the host's shared npm store, passed to pty-host
via NODE_PATH + argv. See `.claude/features/terminal-plugin.md` for the full write-up.

## Files

- `manifest.json` — `mainEntry`, `defaultSettings`, `defaultWidgetConfig`, permissions.
- `package.json` — declares `node-pty` (host runs `npm install --omit=dev` into the install dir on install).
- `main/index.ts` (+ compiled `main/index.js`) — Electron main. Channels `plugin:terminal:create|write|resize|kill`,
  manages one pty-host process, forwards output via `ctx.broadcast('plugin:terminal:event', …)`.
- `main/pty-host.js` — runs under system `node`, spawns node-pty; receives shell/cwd/name/args from main.
- `vendor/xterm.js` + `xterm.css` + `xterm-addon-fit.js` — UMD builds loaded as global scripts (no bundler).
- `widget.html` / `js/widget.js` / `css/widget.css` — multi-tab terminal UI (one xterm + PTY session per
  tab, file-explorer-style tab bar with `+`/`×`/middle-click-close) + self-contained "⚙" settings overlay
  and "↻" restart (active tab).
- `settings.html` / `js/settings.js` / `css/settings.css` — same fields as the widget overlay
  (intentionally duplicated), used by the Plugin Manager screen and the pop-out window.
- `locales/en.json5` / `locales/vi.json5` — UI strings, `widget.*` / `settings.*` namespaces.
- `icon.svg` — `>` prompt + cursor on a dark slate gradient.

## Default settings

- `shell` — `"default"` (default | cmd | powershell | pwsh | bash | git-bash | custom)
- `customShellPath` — `""` (used when shell = custom)
- `cwd` — `""` (empty = home folder)
- `fontSize` — `13`
- `fontFamily` — `"Consolas, 'Courier New', monospace"`
- `theme` — `"dark"` (dark | light | solarized-dark | monokai)
- `cursorBlink` — `true`
- `scrollback` — `9999`
- `termType` — `"xterm-256color"` (xterm-256color | dumb)
- `startupCommands` — `""` (one command per line)
- `startupDelay` — `500` (ms between startup commands)

Live-applied (no restart): font size/family, theme, cursor blink, scrollback.
Needs restart (↻): shell, cwd, terminal mode.

## Requirements & test

No system `node` needed (uses the app's Electron binary via `process.execPath` + `ELECTRON_RUN_AS_NODE`).
After editing `main/index.ts`, recompile: `npx tsc -p tsconfig.plugins.json` (from the project root).

Open Kazuo AI → Plugin Manager — this plugin appears automatically (the host scans `plugins-library/`) →
Install (host installs node-pty) → Enable.
