Minimalist dark-themed Git-aware terminal: Electron + TypeScript + Bun + xterm.js + node-pty.
- xterm.js dark theme (
#1e1e1e / #cccccc), fit + web-links + find - node-pty OS shell (pwsh/PowerShell on Windows, zsh/bash elsewhere)
- Footer status bar: Git branch/dirty/ahead/behind/stash + CPU/MEM
- Tabs like Windows Terminal:
Ctrl+Shift+T/W,Ctrl+Tab,Ctrl+1..9,Ctrl+Shift+D - Split panes (binary tree, flat CSS grid) — horizontal
Shift+Alt+D, verticalShift+Alt+V, closeShift+Alt+C - Shell profiles: pwsh / Windows PowerShell / cmd / WSL via + ▾ or palette
- Tab rename (double-click) and drag-reorder
- Theme presets in Settings (custom colors still work)
- Background-pane completion toast when a hidden pane goes idle
- Command palette (
Ctrl+Shift+P) and find (Ctrl+Shift+F) - OpenCode button /
Ctrl+Shift+O— launches OpenCode in the focused pane; click the footerOCwidget to continue the matched session (opencode -s <id>) - Windows Terminal style copy/paste:
Ctrl+Ccopies only with selection; right-click shows a context menu (URL / path / copy / paste) - Session restore, tray, optional quake dropdown (`Ctrl+``)
- Settings at
~/.involvex-term/settings.json(Ctrl+,) - Ctrl+click URLs and local paths; scrollback / scrollbar / font fallback
- Optional Windows 11 mica title-bar backdrop
- Command snippets in the palette; clear buffer / prompt marks
- In-app update check (packaged NSIS/AppImage via GitHub Releases; portable build also published on each release)
- Export / import settings from Settings
- Settings sync via private GitHub Gist (Device Code login; Push / Pull)
- Footer Git menu (branch switch, Explorer, copy remote) + OpenCode session picker
- Agent-aware pane labels — tabs/panes show OpenCode session titles when a pane’s cwd matches a listed session (or after launch/continue); clear when the session ends (Settings → Agent → Pane labels)
- CLI (
@involvex/term) —bunx @involvex/term install, theninvolvex-term sp -d ./ntsplit or open a tab in the running window, wt-style; alsoupgrade/uninstall,context-menu(Explorer “Open in involvex-term”) anddoctor(common-issue checks with--fix/--json) - Explorer context menu — “Open in involvex-term” for folders, folder
backgrounds, and drives (per-user, no admin; installed by setup, toggle in
Settings → Window, or
involvex-term context-menu install; on Windows 11 it lives under “Show more options”) - Local plugins (opt-in, off by default) — command-palette commands,
status-bar text, and read-only pty hooks from
~/.involvex-term/plugins/<name>/; seePLUGINS.mdand the type-only@involvex/term-sdk
bun install # postinstall only applies the node-pty Spectre patch
bun run dev # dev (vite + Electron)
bun run rebuild # FORCE full node-pty rebuild (slow, rarely needed)
bun run build # tsc + vite + node-pty rebuild + electron-builder
# also refreshes release/latest → current win-unpacked
bun run link:desktop # Desktop shortcut → release/latest/involvex-term.exeChecks:
bunx tsc --noEmit
bun run lint
bun run format:checkInstall OpenCode so opencode is on your PATH, then:
- Click OC in the tab bar, or
- Press
Ctrl+Shift+O, or - Use the command palette / Terminal menu, or
- Click the footer OpenCode status to continue that session
involvex-term sends opencode (or opencode -s <id> / opencode -c) + Enter
to the focused pane (after a soft interrupt).
Shell + OpenCode side by side — launch from the tab bar, continue from the footer OC widget.
When OpenCode is the active session provider, involvex-term polls
opencode session list (same source as the footer OC widget) and matches
sessions to panes by cwd. Launch/continue from the UI also binds the focused
pane to that session.
- Tabs show
OC · session title(or keep a custom rename and add anOCbadge). Background tabs update too — not only the focused one. - Split panes get a corner chip with the same title. A green ● marks recently updated (“busy”) sessions; older ones render as idle.
- Labels clear when the session disappears from OpenCode’s list (or the
binding ages out). Toggle under Settings → Agent → Pane labels
(
agent.showPaneLabels, default on).
Pane labels: session title on tabs + chips on splits.
No in-app AI chat — labels only.
Opt-in session environment for any agent CLI (OpenCode or a custom tool in Settings → Agent). Off by default so existing shells are unchanged.
Enable under Settings → Agent → Agent env hooks. New tabs/panes inherit the vars at spawn time; OpenCode launched into that pane sees the same environment.
| Variable | Meaning |
|---|---|
TERM_PROGRAM |
Always involvex-term when hooks are on |
TERM_PROGRAM_VERSION / INVOLVEX_TERM_VERSION |
App version |
INVOLVEX_TERM |
1 |
INVOLVEX_TERM_PANE_ID |
Pane id for this PTY |
INVOLVEX_TERM_CWD |
Spawn working directory |
INVOLVEX_TERM_GIT_* |
Optional git snapshot (ROOT, BRANCH, DIRTY, AHEAD, BEHIND, STAGED, UNSTAGED, UNTRACKED, STASH, REMOTE) when “Include git context” is on and the cwd is in a repo |
INVOLVEX_TERM_CONTEXT |
Single-line JSON (v, program, version, paneId, cwd, git) |
Example (PowerShell):
$env:INVOLVEX_TERM
$env:INVOLVEX_TERM_CONTEXT | ConvertFrom-JsonBuilt-in AI chat is intentionally out of scope — use OpenCode (or your agent) in the pane.
bun run rebuild / bun run build handle the Electron ABI rebuild via
scripts/rebuild-pty.mjs (Python ≤ 3.11 discovery, Spectre patch).
Troubleshooting:
pty.vcxproj/ MSB3202: deletenode_modules/node-pty/buildand rebuild- Electron incomplete install:
node node_modules/electron/install.js
See AGENTS.md for full native-build notes.
bun run build refreshes release/latest → release/<version>/win-unpacked
(Windows junction). Point your Desktop .lnk at the junction once:
bun run link:desktop
# → %USERPROFILE%\Desktop\Involvex-Term.lnk
# Target: D:\repos\involvex\involvex-term\release\latest\involvex-term.exeRe-run bun run link:latest (or just build) after each release — the
shortcut keeps working without editing the .lnk.
Stored at ~/.involvex-term/settings.json (zod-validated, watched live):
{
"theme": {
"bg": "#1e1e1e",
"fg": "#cccccc",
"fontFamily": "...",
"fontSize": 14,
"fontFallback": "..."
},
"startup": {"mode": "session", "profileId": ""},
"terminal": {
"scrollback": 5000,
"scrollbar": true,
"completionBell": true
},
"agent": {
"activeId": "opencode",
"envHooks": {"enabled": false, "includeGit": true},
"showPaneLabels": true
},
"window": {"acrylic": false},
"tabs": {"confirmClose": false, "restoreSession": true}
}electron/
main.ts IPC + window + watchers
preload.ts window.termApi bridge
ptyManager.ts node-pty (1 pty per pane)
cwdTracker.ts OSC7 / OSC633 parser
gitEngine.ts simple-git status
sysEngine.ts CPU/MEM via systeminformation
settingsStore.ts ~/.involvex-term/settings.json
settingsSync.ts private Gist sync (Device Code + portable subset)
hotkeys.ts Menu accelerators
tray.ts / quake.ts
src/
App.tsx
components/ TabBar, PaneLayout, TerminalView, StatusBar, …
lib/ panes, searchRegistry, focusTerm
scripts/ rebuild-pty, patch-node-pty, link-latest, generate-icon, test-osc7
.github/workflows/ ci.yml, release.yml, docs.yml
Portable prefs (theme, hotkeys, snippets, tray/quake, …) can sync through a
private gist using GitHub OAuth Device Flow. Window geometry, start
directory, and custom shell paths stay machine-local. Token + gist id live in
~/.involvex-term/sync.json.
- Create a GitHub OAuth App → enable Device Flow (no client secret needed).
- In Settings → Settings sync, paste the public client ID (or set
INVOLVEX_GITHUB_CLIENT_IDwhen launching). - Sign in with GitHub → Push / Pull. Linked installs pull on startup.
Project site: involvex.github.io/involvex-term
(deployed from docs/ via GitHub Pages) — includes screenshots of
OpenCode split view and agent-aware pane labels.
See ROADMAP.md for Windows Terminal–class parity phases and beyond (Git + OpenCode differentiators).

