Skip to content

Commit a4edbdb

Browse files
codejunctionclaude
andauthored
fix: restore machine picker and remotes work lost in 0.0.9; v0.0.10 (#18)
* feat: git changes, remote systems, replay, background terminals, agent notes and task manager - git: ±N chip on projects, Changes tab with per-file line counts and diffs - remotes: saved ssh hosts (terminal) and rdp desktops (mstsc/xfreerdp/remmina), validated, no passwords - replay last command (Ctrl+Alt+P, pane button, palette) - send terminal to background (Ctrl+Alt+W, pane button); close offers background while a command runs - sd notes for the scratchpad, live in open pages - sd top / ps / kill for the task manager, only inside shelldeck terminals - skill teaches notes and task manager * feat(machines): machine picker, remote projects, add machine with connection test - picker above New terminal: Local, ssh machines, Add machine, Manage machines - projects, terminals and agents list follow the picked machine - add machine dialog with Test connection (network, then key/agent login; password logins reported) - LDAP/NTID users (CORP\jdoe, jdoe@corp.com) via ssh -l, quoted per shell; key optional - a machine starts with a / project; folders on it are projects; terminals ssh -t and cd there * test(remotes): windows-safe shell kind and process checks * test(remotes): skip ssh tests on windows for now * fix(remotes): no ssh machines on windows for now; windows-safe process test - ssh refused on windows hosts (ssh_unsupported_on_windows), picker hidden, rdp kept - drop cmd quoting from ssh_line - process test spawns the base interpreter: a venv python.exe on windows is a launcher * docs: machines are linux/macos only for now * feat(machines): picker on every host; ssh targets linux, windows targets rdp - undo the windows-host ssh block: windows uses its openssh client - cmd quoting for ssh lines again - rdp desktops listed in the picker menu - ssh tests run on windows again * feat(machines): test connection with a password - password field in add machine, used once via SSH_ASKPASS, never saved or on argv - wrong password reported as refused - verified against a real sshd: test login, then terminal prompts and logs in * chore(release): v0.0.10 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 561ead7 commit a4edbdb

24 files changed

Lines changed: 1717 additions & 50 deletions

‎CHANGELOG.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22

33
All notable changes to shelldeck are listed here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/).
44

5-
## [Unreleased]
5+
## [0.0.10] - 2026-10-06
6+
7+
### Added
8+
9+
- The machine picker (Local / remote machines) is back: it shipped in 0.0.9rc3 but was left out of 0.0.9.
10+
- Git changes at a glance: a `±N` chip on git projects in the sidebar, and a *Changes* tab in the git dialog with branch, ahead/behind, each changed file's added/removed lines and its diff.
11+
- Machines: a picker above *New terminal* on every host (SSH to Linux machines; Windows machines open as RDP desktops from the same menu) (Local, your SSH machines, *Add machine…* with *Test connection*). Projects, terminals and the AI agents list follow the picked machine. A machine starts with a project for `/`; more folders can be added. LDAP/NTID usernames (`CORP\jdoe`, `jdoe@corp.com`) and password logins work; key files are optional.
12+
- Remote systems (*More › Remote systems*): save SSH hosts (open as shelldeck terminals) and RDP desktops (mstsc on Windows, xfreerdp or Remmina on Linux). No passwords are stored.
13+
- Replay the last command: `Ctrl+Alt+P`, the pane's replay button or the palette.
14+
- Background terminals: the pane's eye button and `Ctrl+Alt+W` keep a terminal running off screen (marked *running* in the sidebar while busy); closing a terminal with a running command offers to keep it in the background.
15+
- `sd notes list|add|append|show|replace|delete` for the Scratchpad (open pages update at once), and `sd top`, `sd ps`, `sd kill` for the Task manager (only processes inside shelldeck terminals). The agent skill teaches both.
616

717
## [0.0.9] - 2026-10-05
818

@@ -169,6 +179,7 @@ First public release.
169179
- `sd` CLI with a startup banner, `sd search` (LLM-free code search), and one-line installers for Windows and Linux.
170180

171181
[Unreleased]: https://github.com/codejunction/shelldeck/compare/v0.0.9...HEAD
182+
[0.0.10]: https://github.com/codejunction/shelldeck/releases/tag/v0.0.10
172183
[0.0.9]: https://github.com/codejunction/shelldeck/releases/tag/v0.0.9
173184
[0.0.8]: https://github.com/codejunction/shelldeck/releases/tag/v0.0.8
174185
[0.0.7]: https://github.com/codejunction/shelldeck/releases/tag/v0.0.7

‎CLAUDE.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ uv tool install --force -e . # global sd/shelldeck from this checkout (th
107107
- **File editor.** `/api/fs/file` GET/PUT (2 MB cap, NUL = binary, non-UTF-8 is read-only, CRLF/BOM round-trip, `mtime` as a `st_mtime_ns` string and 409 `changed_on_disk` unless `force`), `/api/fs/raw` (raster images only: SVG or HTML served on this origin would run script), `/api/fs/show` (broadcasts `open_file` for `sd edit/view`; the CLI falls back to `/?file=` when no browser is listening). Relative paths start at the session's cwd (`_abs`).
108108
- **Scratchpad.** `scratch` table (`id`, `body`, times; the title is the first line), `/api/scratch` CRUD, `static/scratch.js` (autosave 500ms, flushed when switching notes).
109109
- `shelldeck/auth.py`: password, setup code, browser sessions (5s cache, idle expiry, throttled `last_seen` writes), CLI token, login rate limit, `reset()`. `scheduler.py` / `runner.py`: APScheduler cron jobs and reminders; jobs run via `subprocess.run` with the default shell.
110-
- `shelldeck/gitgraph.py`: git log parsing + lane layout for the sidebar git popup (`static/gitgraph.js`), and `checkout` (refs starting with `-` refused). `has_git` flags projects in `/api/projects`.
110+
- `shelldeck/gitgraph.py`: git log parsing + lane layout for the sidebar git popup (`static/gitgraph.js`), and `checkout` (refs starting with `-` refused). `has_git` flags projects in `/api/projects`. `changes()` (porcelain v1 `-z` + numstat against HEAD, untracked counted from the file) and `diff()` (only paths `changes()` reports) back the dialog's *Changes* tab; `/api/projects` adds `git_changes` from `_git_count` (cached `GIT_COUNT_S`) for the sidebar `±N` chip.
111+
- **Machines.** SSH targets are Linux machines, reachable from Windows hosts too (OpenSSH); Windows targets are RDP (`S.desktops`, listed in the picker menu, opened with `remotes.connect`). `projects.remote_id`/`remote_path` mark a folder on a saved SSH machine (`db.ensure_remote_project`, path key `ssh://<remote>/<folder>` keeps `path` unique; `/api/projects` reports them `exists` with no git). `POST /api/remotes` (ssh) creates the `/` project; `_remote_line` makes `_attach` type `remotes.ssh_line(r, folder, shell)` on every spawn of such a terminal (`-t` + `'cd <folder> && exec $SHELL -l'`, double quotes for cmd; `check_path` allows no spaces/quotes), and its cwd is the local home. Users go in with `-l` (LDAP/NTID `CORP\user` single-quoted except in cmd). The sidebar picker (`#machine`, `S.machine` in localStorage, `machineProjects()`/`sessionOnMachine()`) filters projects, the agents page and the agents count. `POST /api/remotes/test` (`remotes.test_ssh`): TCP connect, then ssh with throwaway known_hosts: `BatchMode=yes` (key/agent; "Permission denied" means it wants a password), or with the dialog's password through `SSH_ASKPASS` + `SSH_ASKPASS_REQUIRE=force` (`_askpass` writes a helper in a temp dir that prints `SHELLDECK_ASKPASS`; the password is only in ssh's env, never argv, logs or the DB). Deleting a machine deletes its projects and closes their terminals.
112+
- `shelldeck/remotes.py` + `static/remotes.js`: saved remote systems (`remotes` table). `validate()` is the only way values get in (host/user regexes, no leading `-`, port range, key path without shell metacharacters), and connect re-validates stored rows. SSH opens a normal terminal and `_start_agent` types `ssh_line()` after the first prompt; RDP runs `rdp_argv()` (mstsc on Windows, xfreerdp3/xfreerdp/remmina elsewhere) detached, host only (`_host`). No passwords are stored.
113+
- **Background terminals.** `hidePane` (pane eye button, `Ctrl+Alt+W`) only removes the leaf; the PTY and `Term` keep running and the sidebar row shows `bg-chip` while `t.running`. `closeTerminal` (pane ×, sidebar ×, `Ctrl+Alt+Q`) offers *Keep in background* when a command runs. `replayLast` (`Ctrl+Alt+P`) re-sends `t.cmd`, refused while running or when an agent owns the pane.
114+
- **Agents and the UI.** `sd notes` (scratchpad; CLI writes broadcast `{"type":"scratch"}` so an open Scratchpad reloads unless mid-edit; `_text_args` in `_main` passes markdown starting with `-` after `--`), `sd top` (`/api/stats`), `sd ps` / `sd kill` (`/api/sessions/{id}/processes`, `stats.processes` / `stats.end`: only descendants of that terminal's shell, terminate then kill after 3s, zombies count as ended; the CLI also refuses its own ancestors). All are in the skill text.
111115
- `shelldeck/addons/fast_context.py`: vendored single-file LLM-free code search behind `sd search` (own index in `~/.cache/fastcontext`, `FC_CACHE_DIR` overrides). Import it lazily; keep edits to it minimal.
112116
- `shelldeck/cli.py`: Typer CLI.
113117
- The `_main` shim turns `sd <folder>` into `sd open <folder>`.

‎README.md‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ sd ~/code/api # add a folder as a project and open a terminal in it
6363
- **Tiled layout.** Split right or down, drag titles onto edges to split or onto a pane to swap, drag gutters to resize, double-click a title to maximize.
6464
- **Free layout.** Every terminal becomes a floating window on a scrolling canvas. **Tile all** puts them back in a grid.
6565
- **Nothing gets lost.** Closing the tab keeps terminals running, and reopening replays their output. After a restart or reboot, each terminal reopens in its last folder with its history above a "restored" marker.
66+
- **Replay the last command** with `Ctrl+Alt+P` or the pane's replay button (refused while a command runs, or when an AI agent owns the terminal).
67+
- **Run in the background.** The pane's eye button (`Ctrl+Alt+W`) takes a terminal off the screen while it keeps running; it stays in the sidebar, marked *running* while a command is busy, and a click brings it back. Closing a terminal with a running command asks whether to keep it in the background instead.
6668
- **Shell integration** for pwsh, PowerShell, cmd, bash, zsh and fish. Each pane's title shows the last command (red if it failed), `Ctrl+Shift+Up`/`Down` jumps between prompts, and your own prompt (oh-my-posh, starship, …) still loads.
6769

6870
### Projects first
6971

7072
- **Projects sidebar.** Add folders with the built-in folder browser, then drag to reorder. Each project gets its own color on its sidebar dot, pane border and a subtle background tint.
71-
- **Git graph.** A branch icon on every git project opens its full commit graph, with branches, merges and tags drawn as colored lanes. Click a branch or tag, or right-click a commit, to check it out.
73+
- **Git changes at a glance.** A git project with uncommitted work shows a `±N` chip in the sidebar. Click it (or *Git changes* in the palette) to see the branch, ahead/behind, and every changed file with its added/removed lines; click a file for its diff.
74+
- **Git graph.** The branch icon on every git project also opens its full commit graph, with branches, merges and tags drawn as colored lanes. Click a branch or tag, or right-click a commit, to check it out.
7275
- **Clickable paths.** `src/app.py:12:5`, `C:\x\y.ts(3,4)` and Python tracebacks become links that open in VS Code at that line, or in the built-in editor.
7376
- **Built-in editor and viewer.** `sd edit FILE` and `sd view FILE` open a file in shelldeck: line numbers, `Ctrl+S` to save (CRLF and BOM kept, and it won't overwrite a file that changed on disk without asking), rendered markdown and images. *Open file…* in the command palette does the same.
7477
- **Open in editor.** A project's menu opens its folder in VS Code (or the file manager).
@@ -84,7 +87,9 @@ sd ~/code/api # add a folder as a project and open a terminal in it
8487
- **Scheduler** for cron jobs that run in a project folder, with run history and logs.
8588
- **Task board** with due dates and reminder alarms.
8689
- **Task manager** with live CPU, RAM and GPU (NVIDIA) usage for the machine and for each terminal's process tree.
87-
- **Scratchpad** for quick markdown notes that belong to no project, with a preview, saved as you type.
90+
- **Scratchpad** for quick markdown notes that belong to no project, with a preview, saved as you type. Agents (and scripts) add to it with `sd notes`.
91+
- **Machines.** The picker above *New terminal* (on Windows and Linux alike) switches the sidebar between **Local** and your SSH machines; projects, terminals and the AI agents list follow it. *Add machine…* asks for host, user (plain, or LDAP/NTID like `CORP\jdoe` or `jdoe@corp.com`), port and an optional key file, with **Test connection** (network, then a real login with your key/agent, or with the password you type in the dialog for that test; it is never saved). Each machine starts with a project for its root folder `/`; the folder button adds more (`~/code/app`, `/srv/app`). Its terminals run `ssh -t ... 'cd <folder> && exec $SHELL -l'`, so a password is typed in the terminal and never stored. SSH machines are Linux targets (from Windows it uses the built-in OpenSSH client); Windows targets are RDP desktops, listed in the same picker and opened in mstsc. Agents inside an SSH session aren't detected yet.
92+
- **Remote systems.** Save Linux servers (SSH) and Windows machines (RDP) under *More › Remote systems*. *Connect* opens an SSH host as a shelldeck terminal (exit ssh and you're back in a local shell), or a desktop in `mstsc` on Windows (xfreerdp or Remmina on Linux) on the host machine. Passwords are never stored: ssh asks in the terminal (keys and ssh-agent work), the RDP client asks in its window.
8893

8994
### AI agents, working as a team
9095

@@ -140,7 +145,9 @@ sd ~/code/api # add a folder as a project and open a terminal in it
140145
| `Ctrl+Alt+Arrows` | Focus the pane in that direction |
141146
| `Ctrl+Alt+1…9` | Focus pane 1–9 |
142147
| `Ctrl+Alt+Enter` | Maximize / restore the pane |
143-
| `Ctrl+Alt+Q` | Close the focused terminal |
148+
| `Ctrl+Alt+Q` | Close the focused terminal (offers the background when a command runs) |
149+
| `Ctrl+Alt+P` | Replay the last command |
150+
| `Ctrl+Alt+W` | Send the terminal to the background (keeps running) |
144151
| `Ctrl+Alt+B` | Bookmark picker (Space selects several, Shift+Enter runs) |
145152
| `Ctrl+Alt+E` | Toggle the sidebar |
146153
| `Ctrl+Alt+S` / `Ctrl+Alt+T` | Scheduler / Tasks |
@@ -222,6 +229,10 @@ sd knowledge verify ID [--status S] mark knowledge VERIFIED, REVIEWED, STALE or
222229
sd switch AGENT [--note TEXT] checkpoint this project's task and continue it with another agent in a new terminal
223230
sd projects / sd project NAME / sd relate PROJECT known projects, one project, link related projects
224231
sd install-skill [AGENT...] [--remove] teach agent CLIs the sd team commands (automatic on server start)
232+
sd notes list|add|append|show|replace|delete Scratchpad notes ("- bullets" are fine; - reads stdin)
233+
sd top [--json] Task manager: machine CPU/RAM/GPU and each terminal's usage
234+
sd ps [TERMINAL] [--json] processes running in a terminal (default: this one)
235+
sd kill TERMINAL PID [--force] end a process inside a terminal, and its children
225236
sd edit FILE / sd view FILE open a file in shelldeck's editor / viewer
226237
sd search QUERY [--root DIR] LLM-free code search with ranked, highlighted snippets
227238
sd render FILE pretty-print code or markdown

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "shelldeck"
3-
version = "0.0.9"
3+
version = "0.0.10"
44
description = "Project-first multi-terminal for Windows and Linux: real shells, grouped by project, in your browser"
55
readme = "README.md"
66
license = "MIT"

0 commit comments

Comments
 (0)