board-terminal
v1.9.2
Published
Local helper that bridges the Altajer Board web app to a real terminal (Claude Code / shell) and a file editor (the IDE dock) on your own machine.
Maintainers
Readme
board-terminal
A tiny local helper that lets the Altajer Board web app
(board.altajer.app) drive a real terminal on your own machine — Claude
Code by default, or any shell.
Browser (board app, xterm.js) ──WebSocket──► board-terminal ──► PTY ──► claude / shell
draws + input (this process) real terminal on YOUR pcThe browser can't touch your OS — this helper can, because it runs natively on your computer.
It also powers the board's IDE dock (a file tree + editor): the same helper
serves a second WebSocket path, /fs, that lists/reads/writes files on your
machine — and reports git status for the open folder — over the same origin +
pairing-code gate. Pair once — the Terminal and the Editor share the code and port.
Browser (board app, Monaco) ──WebSocket /fs──► board-terminal ──► fs list/read/write + git statusUse it
You need Node.js 18+ installed. Then:
npx board-terminalIt prints a pairing code like 7F3K-9QME. Open board.altajer.app, go to
Terminal, paste the code, and click Connect. The terminal in the page is
now Claude Code running on your machine (with your own auth — you pay for your
own usage, not the site).
Options
npx board-terminal # auto-runs `claude`
npx board-terminal shell # plain shell, no auto-run
npx board-terminal "npm run dev" # run any commandEnvironment overrides:
| Var | Default | Meaning |
|-----|---------|---------|
| BOARD_TERMINAL_PORT | 7681 | WebSocket port |
| BOARD_TERMINAL_CMD | claude | command to auto-run (shell = none) |
| BOARD_TERMINAL_ORIGINS | — | extra allowed origins, comma-separated |
| BOARD_TERMINAL_IDLE_TIMEOUT | 600000 | ms to keep a shell alive after the last tab detaches (re-attach window) |
| BOARD_TERMINAL_SCROLLBACK | 262144 | bytes of scrollback buffered per session for replay on re-attach |
| BOARD_TERMINAL_TOKEN | — | fixed pairing code (not written to disk) |
| BOARD_TERMINAL_TOKEN_FILE | ~/.board-terminal | where the saved code lives |
| BOARD_TERMINAL_ROTATE | — | set to generate a new saved code |
| BOARD_TERMINAL_EPHEMERAL | — | set for a fresh random code each run (nothing saved) |
| BOARD_TERMINAL_CWD_FILE | ~/.board-terminal-cwd | where the last working directory is remembered |
| BOARD_TERMINAL_NO_CWD | — | set to disable directory memory (always start at HOME) |
Install once (no npx each time)
npm i -g board-terminal # one-time install; `board-terminal` is now on PATH
board-terminal # run it directlyPair once — the code is saved
By default the helper saves its pairing code to ~/.board-terminal and reuses
it every run. So you paste it into the board only once: the board remembers the
code and (with the reconnect below) re-connects automatically afterwards — even
across reboots.
- Rotate the code: delete
~/.board-terminal, or run withBOARD_TERMINAL_ROTATE=1. - Pin a code yourself:
BOARD_TERMINAL_TOKEN=ABCD-1234(not saved to disk). - Old behavior (fresh code each run):
BOARD_TERMINAL_EPHEMERAL=1.
Security: a saved code is a long-lived local secret (file mode
600, your user only). Anyone who has it and can reach the board origin could open a shell as you. On a shared machine, preferBOARD_TERMINAL_EPHEMERAL=1.
Run automatically at login
board-terminal autostart # Windows: adds a hidden Startup entry
board-terminal autostart:remove # undoCombined with the saved code, the helper is then always running and the board
re-connects on its own — no npx, no starting it, no pasting.
- Windows —
autostartdrops a hidden.vbsin your Startup folder that launchesboard-terminal(make surenpm i -g board-terminalran first so it's on PATH). It runs with no visible window; to see logs or the code, runboard-terminalmanually in a terminal. - macOS — create
~/Library/LaunchAgents/app.altajer.board-terminal.plistwith aProgramArgumentsof theboard-terminalpath andRunAtLoad, thenlaunchctl loadit. - Linux — a
systemd --userunit runningboard-terminal, thensystemctl --user enable --now board-terminal.
Sessions survive a reload
Each board terminal tab carries a stable session id. The helper keeps that
shell's process alive across WebSocket disconnects (a browser reload, closing
and reopening the dock, navigating away), so reconnecting re-attaches to the
same running terminal and replays its scrollback — your claude session keeps
going. A tab that stays detached is reaped after BOARD_TERMINAL_IDLE_TIMEOUT
so closed tabs don't leak processes. (Sessions do not survive restarting the
helper itself or a reboot — the process is genuinely gone then, and you get a
fresh shell on the next connect.)
New terminals open where you left off
A newly opened terminal starts in the last directory you were in, not always
at your home folder — so the auto-run claude picks up your project without a
cd every time. The helper learns your current directory from a small
shell-integration hook it adds to your prompt (it re-sources your own profile
first, so your setup is untouched) and saves the latest to
~/.board-terminal-cwd. First run — or if the hook can't report — it falls back
to your home folder. Disable it with BOARD_TERMINAL_NO_CWD=1.
Security
This helper is safe to expose to a public website because of two gates enforced during the WebSocket handshake, before any terminal is spawned:
- Origin allow-list — only
https://board.altajer.app(and the board's localhost dev origin) may connect. Any other website is rejected403. - Pairing code — a fresh random token each run; the browser must send it or
it's rejected
401. Comparison is constant-time and case/format-insensitive.
It binds to 127.0.0.1 only, so nothing off your machine can reach it. The
terminal runs with your user permissions — never share your pairing code
while the helper is running.
Browser note (HTTPS → ws://localhost)
board.altajer.app is HTTPS and the helper is plain ws://127.0.0.1. Loopback
addresses count as "potentially trustworthy," so browsers don't block this as
mixed content — Chrome may show a one-time "allow local network" prompt. If a
stricter browser blocks it, run the helper behind a locally-trusted TLS cert
(mkcert) and connect via wss://.
Develop / publish (maintainers)
This helper's source lives inside the altajer-board repo (board-terminal/),
but it's a standalone npm package — its own package.json + native deps
(node-pty), deliberately not a workspace, so it never enters the web app's
dependency tree or bundle.
From the repo root:
npm run terminal:install # install this folder's deps (node-pty, ws)
npm run terminal:start # run it locally (same as npx board-terminal)
npm run terminal:publish # npm publish so anyone can `npx board-terminal`Or work in the folder directly: cd board-terminal && npm install && node index.js.
