neuron-explorer
Steering-first neuron explorer for Qwen3.5-4B: push every MLP neuron, keep every rollout, browse the results
Terminals and coding agents as live nodes on an infinite canvas. macOS & Linux.
Developer toolsTypeScript · CSSGitHub @siimveneOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Termscape — a personal fork of eneskirca/nodeterm, kept for personal use, self-hosting and testing. Terminals and agents as draggable nodes on an infinite canvas. Not a product; use upstream nodeterm.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A personal fork of nodeterm — terminals and agents on an infinite canvas.
Multiple real terminals live as draggable nodes on a single pan/zoom canvas, and every
project doubles as a Trello-style board of live Claude Code sessions. Built for
people with ADHD and scattered workflows: a spatial layout instead of a stack of
hidden tabs.
Termscape is not a product. It is one person's fork of
eneskirca/nodeterm, maintained for personal use,
self-hosting experiments and testing. The engineering is upstream's; the name is shared with
its iOS companion.Read the full README ↗A personal fork of nodeterm — terminals and agents on an infinite canvas.
Multiple real terminals live as draggable nodes on a single pan/zoom canvas, and every project doubles as a Trello-style board of live Claude Code sessions. Built for people with ADHD and scattered workflows: a spatial layout instead of a stack of hidden tabs.
⚠️ Personal use and testing only
Termscape is not a product. It is one person's fork of eneskirca/nodeterm, maintained for personal use, self-hosting experiments and testing. The engineering is upstream's; the name is shared with its iOS companion.
There is no support, no roadmap, no release cadence and no redistribution. If you want the real thing — supported, packaged, and developed in the open — use nodeterm and support that project.
What this fork is · Build & install · Features · Architecture · Credits · License
Stacked terminal tabs hide context — you lose track of what's running where. nodeterm turns that into a map: every shell is a node you can place, group, label, and zoom into. Sessions are spatial and persistent, so your mental model stays intact across restarts. And because the app is built around a clean service seam, the same canvas runs three ways — as the desktop app for macOS, Linux and Windows (beta), as a self-hosted browser app you reach from anywhere (Server Edition), and an iOS companion that attaches to the same live sessions.
📚 Full documentation lives at nodeterm.dev/docs — get started, concepts, agents, remote access, troubleshooting.
Termscape is a private fork of eneskirca/nodeterm (BUSL-1.1, © Enes Kirca), on branch
feat/ungated-selfhost. It runs the Server Edition as the primary core for a personal, always-on, self-hosted setup, and adds a set of multi-account and mobile-companion capabilities on top of upstream. Not for redistribution — see License.
The desktop app shares the Termscape name with its iOS companion, which attaches to these same tmux sessions.
Self-host posture
node out/server/main.cjs) is the always-on core, fronted by
tailscale serve so the desktop app, a browser, and the phone all reach the same live
tmux sessions from anywhere on the tailnet. Layout is committed .nodeterm/project.json,
so a folder-backed project is portable and shareable by design.WatchPaths) mirrors every folder-backed
desktop project into the server's index, so the phone sees the same projects the desktop
does.Multi-account Claude, first class
--resume choreography.
The same conversation continues under the new account's rate limits; copy-before-flip so a
failed copy mutates nothing. Refuses busy / hibernating / remote / recurring-job sessions.Agent-status bridge
iOS companion
Build from this fork, not upstream — the whole point is the modifications above. The npm
commands operate on your local checkout, so they produce your app; upstream is only ever
for pulling fixes, never the source you build.
# 1. Clone THIS fork, self-host branch (not eneskirca/nodeterm)
git clone -b feat/ungated-selfhost https://github.com/siimvene/nodeterm.git
cd nodeterm
npm install # deps + node-pty rebuilt against Electron's ABI (postinstall)
# 2. Desktop app — build an unsigned .dmg and install it
TERMSCAPE_UNGATE=1 npm run dist # → dist/nodeterm-<ver>-arm64.dmg; see "Pro gate" below
npm run rebuild # REQUIRED after dist: the x64 build clobbers node-pty's arm64
# native module that the Server Edition loads — skip it and every
# server-side pty:create fails
# install: open the .dmg and drag to /Applications, or hot-swap a running install:
osascript -e 'quit app "nodeterm"'; sleep 3
rm -rf /Applications/nodeterm.app
ditto dist/mac-arm64/nodeterm.app /Applications/nodeterm.app
open -a /Applications/nodeterm.app
# 3. Server Edition (the always-on core) — build + (re)start (the flag is baked in at build time,
# so it must be set here too; setting it when starting the server does nothing)
TERMSCAPE_UNGATE=1 npm run build && TERMSCAPE_UNGATE=1 npm run server:build
node out/server/main.cjs # or under launchd/systemd; front with `tailscale serve` for remote
Prebuilt (unsigned) desktop .dmgs are attached to this fork's
Releases — first launch: right-click → Open to
clear Gatekeeper (unsigned). The iOS client ships from its own repo
(nodeterm-mobile).
Every fork code change passes a cross-vendor consort review before push (the private fork's own gate), on top of upstream's contribution rules.
Right-click the canvas to open a terminal — or an AI agent. Each runs in its own persistent tmux session, next to sticky notes (link one to feed an agent context), Monaco editors, diff views, and web/video nodes — arranged spatially, like a map. Quit the app, even restart the machine — every session comes back.
Hook-driven status — no output scraping: pulsing RUNNING / NEEDS YOU badges, subagent cards with live transcripts, a per-node context meter, and OS notifications. Click the ping, answer the permission prompt right in the node, and get told the moment the turn is done. On a MacBook, agents live in the notch too.
Every project is a canvas — and also a kanban board. Cards are your live
sessions: drag them across columns while the agent keeps running, open a card into a
live card modal (the real session + members, due date, priority, comments), and
assign teammates. Toggle with ⌘⇧B.
▶ Watch the board video with sound
Pair your phone with one QR — scan with the Termscape iOS app — and the same live session continues in your pocket, E2E encrypted over the relay, not just your LAN. The same canvas also runs self-hosted in any browser (Server Edition).
Hold ⌘⌥, say it, let go. On-device Whisper transcribes it locally and types the
text into the terminal's prompt — you press Enter (nothing auto-submits). Your voice
never leaves the machine.
🖥 Terminal (xterm + tmux, AI naming) · 🤖 Agent (Claude Code / Codex / Antigravity / Gemini / GitHub Copilot / opencode / Grok / Cursor / Pi / custom) · 📝 Sticky note (link to an agent as context) · 🗂 Group (bind to a git worktree for agent-per-branch) · ✏️ Editor (Monaco, ⌘S) · 🔀 Diff · 🌐 Web / Video
claude --resume). The macOS app ships its own tmux, so this works
with nothing installed; a tmux already on your system is always used in preference to it,
and terminals opened before an upgrade stay as they were until you refresh the node.gh sign-in — backed by system git.The same canvas runs headless on a Linux (or macOS) host and is used from any browser — so your terminals, editors, source control, board, and agents live on a server you reach from anywhere. Single-user auth (password + secure cookie), a WebSocket bridge, and the exact same renderer as the desktop app.
npm run server:dev # build + serve; open http://127.0.0.1:8443 and set a password
Terminals, files/editor/diff, the full git panel, the kanban board, and agent-status
badges all work in the browser today. See docs/SERVER.md for the
quickstart, security model, and current limitations.
The same server also runs headless as a background notification host: install it on any Linux box you SSH into, and your phone gets RUNNING / NEEDS YOU push + Live-Activity coverage for the agents running there — with zero open ports (the hook server stays loopback-only and push goes out over HTTPS under a grant your phone drops over SSH).
curl -fsSL https://raw.githubusercontent.com/eneskirca/nodeterm/main/scripts/install-server.sh | bash
One line installs, builds, and runs it as a systemd service (NODETERM_HEADLESS=1); re-run it
to update. See the headless notification host
section for details.
This fork is local build / install only — no Homebrew tap, no auto-update feed, no App Store presence. You build it (or grab the prebuilt binary from Releases) yourself.
npm run dist, or download the unsigned .dmg from
this fork's Releases. Unsigned, so first
launch is right-click → Open. No auto-update — pull + rebuild to upgrade
(see Build & install (this fork)).npm run dist:linux → AppImage + .deb + .rpm in dist/.
The AppImage needs FUSE 2, which Fedora does not install by default: sudo dnf install fuse-libs if it exits with a libfuse.so.2 error.Want the official nodeterm instead — auto-updating builds, Homebrew, the App Store app? That's Enes Kirca's upstream product: nodeterm.dev · eneskirca/nodeterm. This fork is a private, modified self-host build, not those.
Trying it out? Removal is one script — it stops every process nodeterm started, reverts
the status-hook/skill entries it merged into your agent CLIs' config (your own hooks and
credentials are never touched), and deletes all of nodeterm's own state. Run it with
--dry-run first to see the full list of what it found:
curl -fsSL https://raw.githubusercontent.com/eneskirca/nodeterm/main/scripts/uninstall.sh | bash -s -- --dry-run
curl -fsSL https://raw.githubusercontent.com/eneskirca/nodeterm/main/scripts/uninstall.sh | bash -s -- --yes
The full inventory of what nodeterm writes where (and what the script keeps, like the
.nodeterm/ canvas folders inside your own repos) is documented in
docs/uninstall.md.
Building this fork? Use Build & install (this fork) above. The generic commands below build whatever checkout you are in — on
feat/ungated-selfhostthey produce your modified app, not upstream's.
Pro gate. By default a build from this repo gates nodeterm Pro exactly like upstream: Pro features need a signed entitlement from nodeterm.dev. The fork's self-host bypass (
SELF-HOST UNGATEinsrc/core/license.ts) is a build-time opt-in: setTERMSCAPE_UNGATE=1in the environment ofnpm run build/dist/server:buildand it is baked into that artifact. It is off by default so that nothing built from this public source strips the paid tier of upstream's product unless the person building it chooses to, for their own machine. Published Termscape installers are personal builds, not official nodeterm releases.
Requires Node.js 20+ on macOS or Linux (tmux recommended — it's what makes sessions
survive restarts). A source checkout does not carry the bundled tmux: run
node scripts/build-tmux.mjs once on macOS to build it into resources/bin/tmux (the
release job does this automatically), or just install tmux yourself. On Windows, run
bootstrap-windows.bat from a fresh checkout first — it checks for Node, the Visual Studio
C++ build tools and Python 3 (needed to compile node-pty) and points you at the exact
winget commands for anything missing, then runs npm ci.
On Fedora (and any distro shipping GCC 14 or newer), export CFLAGS=-D_GNU_SOURCE for the
install: smart-whisper's bundled whisper.cpp uses GNU-only CPU-affinity calls without asking for
them, and GCC 14 turned that from a warning into an error, so a plain npm install fails while
building it. Packaging additionally wants rpm-build (for the .rpm target) and
libxcrypt-compat (electron-builder's bundled fpm runs a Ruby that still links
libcrypt.so.1, without which both .deb and .rpm fail):
sudo dnf install -y rpm-build libxcrypt-compat
CFLAGS=-D_GNU_SOURCE npm install
npm install # deps + rebuilds node-pty against Electron's ABI (postinstall)
npm run dev # dev mode with renderer HMR
npm run build # production build into out/
npm start # preview the production build
npm run typecheck # fastest correctness gate
npm test # vitest unit + integration suite
npm run dist # local UNSIGNED .dmg into dist/ (smoke test)
npm run dist:linux # AppImage + .deb + .rpm into dist/ (on a Linux host; .rpm needs rpmbuild)
npm run dist:win # unsigned NSIS installer + zip into dist/ (on a Windows host)
npm run server:dev # build + run the browser Server Edition (needs Node 22 + tmux)
These are the defaults — every one of them is remappable in Settings → Keyboard Shortcuts.
| Shortcut | Action |
|---|---|
⌘K | Command palette |
⌘T / ⌘⇧C | New terminal / New Claude Code |
⌘⇧B | Toggle the kanban board |
⌘W | Close the selected node |
⌘← ⌘→ ⌘↑ ⌘↓ | Focus the node left / right / above / below (Ctrl+Shift+arrow off macOS) |
⌘Z / ⌘⇧Z | Undo / Redo |
⌘M | Toggle markdown view (terminal / editor) |
Hold ⌘⌥ (Ctrl+Alt) | Dictate into the focused terminal |
⌘⇧E | File explorer |
⌘, | Settings · ⌘/ Shortcuts |
Right-click | Actions menu (empty space or node) |
Pasting screenshots on macOS: in a terminal, Cmd+V saves the image and pastes its file path. Ctrl+V sends a control key to the foreground program. A local agent with clipboard-image support, such as Claude Code, may attach the image directly at its input prompt; shells and editors give that key other meanings. nodeterm does not detect this capability or retry with the other route. Use Cmd+V for SSH sessions: the image is uploaded and its remote path is pasted. In Server Edition, image paste uploads to the terminal host and depends on browser clipboard access; Ctrl+V does not transfer the browser's clipboard to the host. This distinction also appears in Keyboard shortcuts → Pasting screenshots on macOS and applies to both canvas and kanban terminals.
src/main (the Electron shell), src/preload (the only
bridge, window.nodeTerminal), src/renderer (React UI). src/shared holds the types
and IPC channel names used by all three.CorePlatform seam — every service (PTY, workspace/settings, git, agents, hooks) lives
in src/core behind a small platform interface and never imports electron. Electron is
one implementation of that seam; the browser Server Edition (src/server) is another,
booting the exact same services over a WebSocket-RPC bridge (src/renderer/bridge fills
window.nodeTerminal in the browser). One codebase, one renderer, multiple shells.TerminalTransport abstraction — the renderer depends only on this interface, never on
IPC or node-pty directly. LocalTransport talks to the local host; RemoteTransport talks
to a remote agent over SSH — so remote projects drop in without touching the canvas UI.See docs/SERVER.md for the Server Edition, and the design docs
under docs/ for deeper notes.
Add Claude Science from the main add-menu list beside Claude Code in the dock, canvas right-click, or sidebar + menu, or use the command palette. Allow Science panels when prompted, then sign in with your Claude account inside Science. The same panel opens from a browser card on the kanban board. Reconnect mints a fresh local login link; Stop Science stops the shared instance and its running analyses. Closing a panel keeps the service and saved work. Revoke panel access in Settings → Agents → Claude Science panels.
If Science is missing, click Install Claude Science in the panel. Termscape downloads the
official runtime from Anthropic, verifies its SHA-256 checksum against the official release
manifest, and installs it into <userData>/science-bin without sudo. Each Linux user's
Termscape instance can install its own runtime; an installation under another user's home
is not shared. Restoring a saved panel never starts a download. The first start may take
several minutes while Science prepares its analysis environment. Internet access is required.
The managed installer supports Linux x64, macOS x64/arm64, and Windows x64/arm64; it reports
unsupported platforms rather than downloading another architecture's binary.
You can also install Science yourself using Anthropic's setup guide. Linux requires glibc x64, bubblewrap 0.8 or later, system-installed socat, and permitted unprivileged user namespaces. Termscape preserves Science's sandbox and approval prompts. Science has its own Claude sign-in; Termscape's managed Claude Code accounts are separate.
Each Termscape data directory owns one Science instance, stored in <userData>/science.
All Science panels on that instance share its projects and sign-in. Project files save only the
browser node's browserApp: "claude-science" marker; login links, tokens, and running-service
details are not saved into the project. The native mobile companion / terminal relay does not
embed Science; use the Server Edition in a browser.
Server Edition: Termscape proxies the UI at /apps/claude-science/, through both Termscape
authentication and Science's own login. Only this trusted app gets a same-origin framing policy;
the proxy is disabled until Science panels are allowed. Science's preview server must have a
different origin, since generated HTML must not share the app's credentials. For a Tailscale
deployment, publish the loopback preview port separately:
sudo tailscale serve --bg --https=8444 http://127.0.0.1:8766
Set NODETERM_SCIENCE_APP_ORIGIN=https://your-host.your-tailnet.ts.net and
NODETERM_SCIENCE_PREVIEW_ORIGIN=https://your-host.your-tailnet.ts.net:8444 in the Termscape
server's environment. The app origin is also allowed to frame Science's previews. Restart Termscape and, if it was already running, stop and reopen
Science. The preview listener serves Science's token-protected preview URLs, not Termscape's
application or cookies. Keep it private to the tailnet. Without a configured preview endpoint,
the panel displays a setup notice; remote interactive HTML previews cannot work through the
viewer's localhost. Desktop webviews reach the local preview port directly.
Optional host environment overrides: NODETERM_SCIENCE_BIN (executable path),
NODETERM_SCIENCE_PORT (default 8765), and NODETERM_SCIENCE_PREVIEW_PORT (default 8766).
Use distinct unused ports and adjust the preview proxy if you change them. NODETERM_SCIENCE_BIN
takes precedence and disables the in-app installer. Otherwise Termscape prefers its managed runtime,
then ~/.local/bin/claude-science, then the executable on PATH. Managed launches disable automatic
updates. To update, stop Science, remove its managed executable, and use Install Claude Science
again. This keeps updates explicit and preserves projects and sign-in.
Issues and pull requests are welcome. Start with CONTRIBUTING.md —
setup, the process-boundary rules, and the house rules that come up in review.
CLAUDE.md plus the per-subsystem rule files under
.claude/rules/ are the deep reference behind them (loaded automatically if
you work with an AI coding agent). Questions or bug reports are also happy at
nodeterm.dev/support / [email protected]. nodeterm is licensed under the
Business Source License 1.1 — you can use, modify,
and redistribute it freely, including in production, except offering it as a
competing product or service (see License).
By submitting a contribution (pull request, patch, or code snippet), you agree that it is licensed under the same BUSL-1.1 terms as the rest of the project, and that the project may continue to relicense future versions (including your contribution) as part of its normal licensing model.
Termscape is a rename, not an authorship claim. Essentially all of the engineering here is nodeterm by Enes Kirca — the canvas, the tmux session model, the agent/hook architecture, the Server Edition, the kanban board, the transport seam. This fork adds a handful of self-host and multi-account conveniences on top.
If Termscape is useful to you, the project to star, fund and file issues against is nodeterm, not this fork — upstream takes sponsors via its Sponsor section.
BUSL-1.1 (Business Source License): you may
copy, modify, redistribute, and — under the Additional Use Grant — make production
use of nodeterm; the one thing you may not do is offer it (hosted, embedded, or as a
standalone product/service) in a way that competes with nodeterm or with the
Licensor's products built on it. Each release automatically becomes plain MIT four
years after it is published. See LICENSE for the full terms and
THIRD-PARTY-NOTICES.md for the bundled open-source
components. For a commercial license beyond the grant, contact [email protected].
"Claude" and "Claude Code" are trademarks of Anthropic, and "Trello" is a trademark of Atlassian; nodeterm is not affiliated with or endorsed by either.