Skip to content
codejunctionPublic

About

Project-first multi-terminal for Windows and Linux. Real shells (PowerShell, cmd, Git Bash, WSL, bash, zsh, fish) grouped by project in your browser, with split or free-floating panes, session restore, git graph, scheduler and code search. One command: sd.

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

shelldeck logo

shelldeck

Your terminals, organised by project. In the browser, on your own machine.

Real shells (PowerShell, cmd, Git Bash, WSL, bash, zsh, fish) grouped by project,
in split or floating panes that survive restarts, with your AI coding agents working side by side.

PyPI Python CI Platforms License: MIT

Install · Features · CLI · Remote access · Security · Contributing

shelldeck with four named terminals in three projects: a git log, Claude Code, Codex asking to trust a folder, and sd top

Install

Windows (PowerShell) Linux
Standalone (default) irm https://raw.githubusercontent.com/codejunction/shelldeck/main/install.ps1 | iex curl -fsSL https://raw.githubusercontent.com/codejunction/shelldeck/main/install.sh | sh
uv tool & ([scriptblock]::Create((irm https://raw.githubusercontent.com/codejunction/shelldeck/main/install.ps1))) -Pip curl -fsSL https://raw.githubusercontent.com/codejunction/shelldeck/main/install.sh | sh -s -- --pip
  • Standalone: a self-contained build, no Python or uv needed. It updates itself from Settings › Updates.
  • uv tool: the Python package (uv tool install shelldeck, pipx install shelldeck, or uvx shelldeck to try it). Update with uv tool upgrade shelldeck. Plugins only work in this mode.
  • macOS (untested) gets the Python package; there is no standalone build for it yet.
  • Needs Windows 10 1809+ (ConPTY) or Linux x64, and a modern browser.
Standalone layout, installer options, updates

The installer downloads shelldeck-<version>-windows-x64.zip or -linux-x64.tar.gz from the latest GitHub release, checks its .sha256, unpacks it into %LOCALAPPDATA%\shelldeck or ~/.local/share/shelldeck and puts that folder on PATH:

shelldeck/
  current.txt              the version in use, e.g. 0.0.12
  sd.cmd, sd               shims that run versions/<current>/sd, so `sd` and agent hooks survive updates
  versions/
    0.0.12/                shelldeck, sd-pty, sd-ui, sd (+ .exe on Windows) and _internal/

Environment variables: SHELLDECK_VERSION=0.0.12 (a specific release, release candidates included), SHELLDECK_ROOT=<dir>, SHELLDECK_NO_MODIFY_PATH=1, SHELLDECK_ARCHIVE=<file> (a downloaded archive). Running the installer again installs the newest release next to the old one.

Updates. Standalone: Settings › Updates (or the Update now toast) downloads the new release, checks its sha256, unpacks it next to the running one and restarts only the web app; terminals and their programs keep running. uv: uv tool upgrade shelldeck, then sd restart. Release candidates: SHELLDECK_VERSION=0.0.13rc1 with the installer, or uv tool install --force shelldeck==0.0.13rc1.

Processes. shelldeck supervises sd-pty, which owns the shells, and sd-ui, the web app, which restarts on its own. Task Manager shows all three. sd restart restarts only the web app; sd stop stops everything.

Quick start

sd                 # start shelldeck in the background and open it in your browser
sd ~/code/api      # add a folder as a project and open a terminal in it

The first visit asks you to create a password. Terminals keep running in the background until you close them, even with the browser closed.

Features

Terminals

  • Real shells per OS. Windows: pwsh, Windows PowerShell, cmd, Git Bash, WSL (any distro). Linux: every shell in /etc/shells.
  • Tiled or free layout. Split, drag titles to split or swap, maximize; or floating windows on a canvas with Tile all.
  • Nothing gets lost. Closing the tab keeps terminals running. After a restart or reboot each terminal reopens in its last folder with its previous text above a "restored" line. Updates restart only the UI, so shells don't even notice.
  • Shell integration (pwsh, PowerShell, cmd, bash, zsh, fish): the pane title shows the last command (red if it failed), Ctrl+Shift+Up/Down jumps between prompts, and your own prompt still loads.
  • Background terminals (Ctrl+Alt+W), replay the last command (Ctrl+Alt+P), port chips for dev servers, clickable paths (src/app.py:12:5, tracebacks) that open in VS Code or the built-in editor.
Command palette filtered to split commands The ? menu at the shell prompt offering Ask for a question
Command palette (Ctrl+Shift+P) ? menu with Ask, right at the prompt
Search all terminals dialog with highlighted matches Built-in editor previewing a markdown file
Search every terminal's output (Ctrl+Shift+F) Built-in editor and markdown viewer (sd edit, sd view)
  • ? menu and Ask. Type ? on an empty prompt for shelldeck's commands, bookmarks and plugin commands at the cursor. Type a question instead and Ask has an installed agent's model (Claude, Codex, Gemini or Devin; Settings › AI agents) write one command for that shell and OS. Enter types it, Shift+Enter runs it. Ctrl+I opens just the Ask box; sd ask "..." prints the command.

Projects

  • Projects sidebar with a color per project (sidebar dot, pane border, background tint), added through a folder browser and reordered by drag.
  • Git at a glance. A ±N chip on projects with uncommitted work; the git dialog shows changed files with their diffs, and the full commit graph with one-click checkout.
  • Machines. The picker above New terminal switches between this computer and your SSH machines (Linux; key, agent or a password typed in the terminal, LDAP names like CORP\jdoe work). Windows machines open as RDP desktops. Test connection checks the network and the login. Passwords are never stored.
Git graph with branches, tags and authors Git changes tab with added and removed lines per file
Git graph with one-click checkout Uncommitted changes and diffs
Machine picker with local, an SSH machine and an RDP desktop Remote systems page listing SSH and RDP machines
Machine picker Remote systems (SSH and RDP)

AI agents, working as a team

  • Detected automatically. A terminal running Claude Code, Codex, Devin, Gemini, Copilot, Cursor Agent, opencode, Aider, Amp, Qwen, Goose, Droid, Crush or Kiro gets an AI chip with the model and how full its context window is.
  • Needs-you alerts. Only when an agent asks something (a permission prompt, a question, a [y/n]): an amber chip, a chime and a toast or desktop notification. The sidebar and Open next rank agents by who needs you.
  • Exact state from hooks. sd integration install hooks Claude Code, Codex, Gemini and Devin so they report working / blocked / done themselves, and can be resumed after a restart. 15 more agents have preview hooks. See docs/agent-integrations.md.
  • Agents talk to each other. Each terminal has a name (Maya, Kofi…). From inside one, sd agents, sd peek, sd tell, sd spawn "task" --model small|medium|large (a sub-agent in a new pane), sd handoff and sd done. A sub-agent's questions go to its parent agent, not to you. shelldeck installs a shelldeck skill so agents know these commands.
  • Context that outlives the agent. Each project keeps a task, next step, facts, decisions and recent activity (commands, tests, edited files from the hooks; never output or secrets) in a local database and in .shelldeck/*.md. A new agent runs sd context and continues. sd recall searches every project; --smart adds keywords from an agent's smallest model. No model runs inside shelldeck.
AI agents page with running agents, integrations and available agent CLIs Context page with the task, facts, decisions and recent activity
AI agents: status, integrations, launch with a model Context: what the project is working on

Everything else

  • Task manager (Ctrl+Alt+M, sd top): CPU, RAM and NVIDIA GPU for the machine and each terminal's process tree, with agents and ports.
  • Bookmarks (insert, or Shift+Enter to run), Scheduler (cron jobs in a project folder, with logs), Tasks (a board with due dates, reminders and Send to agent), Command history with exit codes and durations, Scratchpad (markdown notes; agents add with sd notes).
  • Radio. The top-bar radio plays cliamp channels; your browser streams them directly.
  • Devices. Every signed-in browser, which one is in use, and Sign out.
  • Plugins. Python packages add ? menu and sd commands and react to events. See Plugins.
Task manager with CPU, memory, GPU and per-terminal usage Task board with backlog, to do, in progress and done
Task manager, per terminal Task board
Bookmarks list with commands per project Scheduler board with cron jobs
Bookmarks Scheduler
Command history with exit codes, durations and folders Scratchpad note rendered as a markdown checklist
Command history Scratchpad
Settings dialog with Appearance, Terminal, AI agents, Updates and Password sections Radio menu with cliamp channels and a volume slider
Settings Radio
Share dialog with the terms of sharing Devices page with the signed-in browser
Share over a Cloudflare tunnel Devices

Plugins

A plugin is a Python package with a shelldeck.plugins entry point. Its commands show up in the ? menu (?docker logs web) and the CLI (sd docker logs web), and return text to show or a command line to type.

# pyproject.toml: [project.entry-points."shelldeck.plugins"]  docker = "shelldeck_docker:plugin"
from shelldeck.plugins import Plugin

plugin = Plugin("docker", "0.1.0")

@plugin.command("logs", "Follow a container's logs", usage="<container>")
def logs(args, ctx):  # ctx: session_id, cwd, shell, project
    return {"input": "docker logs -f " + " ".join(args)}

Install into shelldeck's environment (uv tool install shelldeck --with ./examples/shelldeck-docker) and restart. The Plugins page and sd plugin list|enable|disable manage them. Plugins run with your permissions; install only ones you trust. Guide: docs/plugins.md.

Keyboard shortcuts
Keys Action
Ctrl+Shift+P Command palette (Ctrl+K also works outside a terminal)
Ctrl+Alt+N New terminal in the current project
Ctrl+Alt+\ / Ctrl+Alt+- Split right / down
Ctrl+Alt+Arrows Focus the pane in that direction
Ctrl+Alt+1…9 Focus pane 1–9
Ctrl+Alt+Enter Maximize / restore the pane
Ctrl+Alt+Q Close the focused terminal (offers the background when a command runs)
Ctrl+Alt+P Replay the last command
Ctrl+Alt+W Send the terminal to the background (keeps running)
Ctrl+Alt+B Bookmark picker (Space selects several, Shift+Enter runs)
Ctrl+Alt+E Toggle the sidebar
Ctrl+Alt+S / Ctrl+Alt+T Scheduler / Tasks
Ctrl+Alt+M Task manager
Ctrl+Alt+R Command history
Ctrl+Shift+F Search all terminals
? / Ctrl+I (empty shell prompt) Command menu with Ask / just the Ask box
Ctrl+Alt+, Settings
Ctrl+Alt+L Lock
Ctrl+Alt+H Show shortcuts
Ctrl+C / Ctrl+V Copy the selection (otherwise sends Ctrl+C) / paste
Ctrl+F Find in the terminal
Ctrl+Shift+Up / Down Jump to the previous / next prompt

In the sidebar, Ctrl+click or middle-click a terminal to open it in a split. Right-click a project or terminal for its menu.

Settings
Setting Values Default
Theme dark, light, system dark
Terminal colors default (follows theme), Dracula, One Dark, Nord, Gruvbox Dark, Solarized Dark, Solarized Light, GitHub Light default
Terminal font / size any installed monospace font / 8–32 Cascadia or Nerd Font / 13
Pane layout tiled, free tiled
Project colors tint on, off on
Default shell Windows: pwsh, powershell, cmd, gitbash, wsl · Linux: shells from /etc/shells pwsh / $SHELL
WSL distribution any installed distro, or the system default system default
Open file paths with VS Code (at the line), shelldeck's editor, system default app VS Code
Ask agent / Ask model first installed, Claude Code, Codex, Gemini CLI, Devin CLI / that agent's models first installed / its smallest
Smart search off, first installed agent, Claude Code (haiku), Codex, Gemini CLI (flash-lite), Devin CLI off
Resume agent sessions after a restart ask, automatically, never ask
Updates installed and latest version, Update (standalone)
Password created on first visit, changed here (current + new) required

CLI

sd [--port N] [--no-window] [--app]  start the server if needed, print the banner and open the browser (= sd web)
sd PATH / sd open [PATH] [--shell S] add PATH as a project and open a terminal in it
sd list / sd info                    terminals grouped by project / the terminal you're in
sd restart / sd stop                 restart the web app (terminals keep running) / stop everything
sd serve [--host H]                  run the server in the foreground

sd agents [--all]                    AI agents in this project's terminals (--all: everywhere, plus installed CLIs)
sd peek TERMINAL [-n 40]             last lines of another terminal (by name like Maya, id or title)
sd tell TERMINAL "MESSAGE"           type a message into another terminal and press Enter
sd spawn "TASK" [--agent A] [--model small|medium|large|auto|NAME]   sub-agent in a new terminal
sd handoff TERMINAL "TASK" / sd done ID ["SUMMARY"] [--failed] / sd handoffs [--all]
sd answer TERMINAL KEY...            press keys in another terminal (1, y enter, esc)
sd close TERMINAL [--force]          close a terminal; from an agent only its own sub-agents
sd agent status|wait|start|prompt|rename|cmd|explain|resume|report|extract ...   agent lifecycle
sd integration list|detect|status|install|uninstall [AGENT] [--all]   lifecycle hooks
sd events subscribe [--types agent,handoff] [--since ID]   JSON lines of agent.*, handoff.* events

sd init [PATH] [--task TEXT]         set up .shelldeck/ (STATE, TASK, MEMORY, DECISIONS, AGENTS.md)
sd context [PROJECT] / sd resume     task, state, next action, memory, decisions, events
sd remember FACT... / sd discover FINDING / sd decide TITLE [-r REASON] / sd memory
sd task update [STATUS] [--task --step --next --tests --error]
sd recall QUERY [--smart | --agent A [--model M]]   search every project
sd switch AGENT [--note TEXT]        continue this project's task with another agent
sd ask "QUESTION"                    print one command for this terminal's shell and OS

sd notes list|add|append|show|replace|delete   Scratchpad
sd top / sd ps [TERMINAL] / sd kill TERMINAL PID [--force]   Task manager
sd edit FILE / sd view FILE          open a file in shelldeck's editor / viewer
sd search QUERY [--root DIR]         LLM-free code search with ranked snippets
sd render FILE                       pretty-print code or markdown
sd schedule list|add|run|toggle|delete|logs
sd task list|add|move|delete|alarms
sd plugin list|enable|disable|run    plugins; `sd <plugin> <command>` runs one
sd install-skill [AGENT...] [--remove]   teach agent CLIs the sd commands (automatic on start)
sd share [stop] [--new-link]         share over a Cloudflare tunnel (see Remote access)
sd login-link / sd reset-password    emergency, host only
  • Default port 5455 (--port or SHELLDECK_PORT). --app opens a chromeless Edge/Chrome window.
  • Inside a terminal: SHELLDECK_SESSION_ID, SHELLDECK_NICK, SHELLDECK_PORT, SHELLDECK_AGENT_REPORT_TOKEN, and SHELLDECK_PARENT for sub-agents.
  • To let Claude Code sub-agents report back on their own, allow Bash(sd:*) in its permissions.

Remote access

SSH tunnel (recommended). Nothing is exposed:

sd serve                                  # on the VM: stays on 127.0.0.1:5455
ssh -N -L 5455:127.0.0.1:5455 you@vm      # on your machine, then open http://127.0.0.1:5455

sd share (any device, no setup; needs cloudflared, no account), or the Share button in the top bar:

sd share              # prints a QR code and a link; Ctrl+C stops sharing
sd share --new-link   # another one-use link for a second device
sd share stop
  • Each link works once, for 10 minutes, and the device then waits until you allow it on this machine. The device shows a 4-digit code, and the Allow prompt (toast, Devices, sd share) shows the same code: allow only if they match. It still needs your password (12+ characters for sharing).
  • Cloudflare ends TLS, so in a browser it can see the traffic. The iPhone/iPad app encrypts end to end instead (below). For sensitive work in a browser use SSH or Tailscale.
  • The first share asks you to accept the terms. Stopping a share signs out every browser that came through it.

iPhone and iPad app. The native app in ios/ is built and installed from Windows + WSL with xtool. A free Apple ID is enough; no Mac or paid developer account. It has tabs for:

  • Terminals (SwiftTerm) with each agent's state.
  • System usage.
  • Schedule (jobs and tasks).
  • Scratchpad.
  • Settings (several PCs, alert sounds).

On iPad, projects sit in a sidebar with up to four tiled terminals beside it.

shelldeck on iPad: projects in a sidebar and four tiled terminals (an API server log, a test run, a Vite dev server and a Terraform plan)

iPhone: terminals grouped by project iPhone: a terminal with the Esc, Ctrl, Tab and arrow key bar iPhone: CPU, memory and GPU of the PC, and usage per terminal iPhone: a scratchpad note
  • Connecting. Scan the share's QR in the app once and allow the device. From then on it's a trusted device: it finds every new share by itself, with no QR or approval (the password is still asked). The new share address reaches it through ntfy.sh, encrypted with a key only your PC and the device hold.
  • End-to-end encrypted. The share QR also carries the PC's public key, in the part of the link after #, which never leaves the phone. All of the app's traffic (API calls, terminals, your password) goes through one X25519 + AES-256-GCM channel to that key, so Cloudflare and your Wi-Fi only see ciphertext.
  • Several devices. An iPhone and an iPad on the same Apple ID share their trusted PCs through iCloud Keychain.
  • Managing them. The Devices page lists trusted devices and revokes them, and a new one raises an alert on the PC.
  • Limits of a free Apple ID. The app has to be reinstalled every 7 days (ios/scripts/install.sh), and alerts ring only while the app is open.

Setup, prerequisites and installing it for someone else: ios/README.md.

HTTPS on the VM's address: sd serve --host 0.0.0.0 --cert cert.pem --key key.pem. Plain HTTP on a non-local address is refused (--insecure-http overrides). A first visit from another machine also needs the setup code sd serve prints.

On phones, a key bar adds Esc, Tab, Ctrl and arrows, and dialogs open as bottom sheets.

Security

  • Local only. Binds to 127.0.0.1 and rejects requests whose Host or Origin isn't the app, so other websites can't reach your shells. Responses forbid framing, sniffing and referrers.
  • Password required. PBKDF2-SHA256 (600k iterations); logins are HttpOnly, SameSite=Strict cookies stored as SHA-256; failed logins slow down; 30 minutes idle locks the browser.
  • One device at a time. Logging in elsewhere takes over and idles the rest; the Devices page revokes any login.
  • The CLI uses a token file readable only by your account, rotated on every start.
  • Sharing stays shut until you allow a device, after checking that its matching code is the one you see. Through the tunnel, responses send HSTS and the login cookie is Secure. Trusted app devices skip only the approval, never the password; revoke them in Devices.
  • The iPhone/iPad app talks to the PC only through an end-to-end encrypted channel: X25519 + AES-256-GCM, with the PC's key pinned from the share QR. Neither the tunnel nor ntfy.sh can read or forge its traffic.
  • Forgot the password? On the host: sd login-link (one-time URL, 5 minutes) or sd reset-password. Never from the browser.
  • Your data lives in ~/.config/shelldeck/ (SHELLDECK_HOME moves it).

Found a vulnerability? Report it privately; see SECURITY.md.

Development

git clone https://github.com/codejunction/shelldeck && cd shelldeck
uv sync
uv run shelldeck --port 5466 serve     # dev server, http://127.0.0.1:5466
uv run pytest -q                       # includes a real PTY round trip
uv run ruff check

FastAPI and uvicorn, pywinpty (ConPTY) or the stdlib pty, SQLite, and plain HTML/CSS/JS with vendored xterm.js (no build step). See CONTRIBUTING.md.

License

MIT. xterm.js is MIT-licensed too (see shelldeck/static/vendor/LICENSE-xterm.txt).

About

Project-first multi-terminal for Windows and Linux. Real shells (PowerShell, cmd, Git Bash, WSL, bash, zsh, fish) grouped by project in your browser, with split or free-floating panes, session restore, git graph, scheduler and code search. One command: sd.

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages