Files
devdesk/README.md
T
jaredandClaude Opus 5.5 527cb1fda2
build-deb / Lint, test, package (push) Successful in 2m0s
build-deb / Notify on failure (push) Skipped
feat: free-form sessions, rename/end from the panel, live Claude Context (0.2.0)
- Sessions no longer need a project folder: any name works and starts in
  DEVDESK_DEFAULT_DIR unless it matches a project; `devdesk new NAME [PROJECT]`.
- Rename (✎) and end/forget (×) sessions from the Sessions panel, plus
  `devdesk rename`. The browser runs them as `devdesk attach --new|--rename|--end`
  through ttyd. Renames keep the running Claude and its recorded conversation:
  the hook, the run-wrapper and the statusline ask tmux for the current name.
- Claude Context panel is live: devdesk-statusline snapshots model,
  context-window use, cost and edits per session, which --list reports;
  Claude's footer gets a one-line summary. The panel now sits under Sessions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 03:03:09 -04:00

77 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DevDesk
A persistent browser terminal for Claude Code, at **https://dev.lotusguild.org**.
- **Persistent sessions:** closing the tab, restarting the web service or upgrading the package never stops Claude.
- **Survives reboots:** after a reboot, every named session resumes its own conversation.
- **Styling:** uses the LotusGuild Terminal Design System ([web_template](https://code.lotusguild.org/LotusGuild/web_template)).
- **Packaging:** ships as a `.deb` from Gitea's apt registry.
```
Browser ─https─▶ NPM (wildcard cert, Authelia two_factor, injects ttyd credential)
─http─▶ ttyd :7681 [devdesk.service] ── /ws?arg=<name> → `devdesk attach <name>` (tmux client)
tmux server [devdesk-tmux.service] ── one session per project:
window "claude": devdesk-claude-run → claude --resume <recorded id>
window "shell"
```
## Why two units
The tmux server runs in its own unit, so every Claude process lives in **that** unit's cgroup.
- ttyd (`devdesk.service`) only starts tmux *clients* (`tmux -N` never starts a server). It can restart freely, and does so on package upgrades.
- `devdesk-tmux.service` is installed with `--no-stop-on-upgrade`, so apt never touches it.
- **Only `systemctl stop devdesk-tmux` (or removing the package) ends the sessions.**
## Sessions
- **Any name works.** Sessions don't have to be repo work:
- A name matching a project folder (`tinker_tickets`, or `test-code` for `test code`) starts there.
- Anything else (`pbs-upgrade`, `ceph-check`) starts in `$DEVDESK_DEFAULT_DIR`, which is `/root/code` by default.
- `main` is the projects root.
- **Opening one:**
- `https://dev.lotusguild.org/?arg=<name>` opens or creates that session.
- With no `?arg=`, an fzf picker opens, listing running (●), dormant (○) and new (+) sessions.
- The **Sessions** panel's form takes any name plus an optional project folder.
- **Rename / end:** the ✎ and × buttons on each session in the panel. Renaming keeps the session, its running Claude and its recorded conversation. Ending stops Claude; the conversation stays in Claude's history.
- **Windows:** each session has a `claude` window (0) and a `shell` window (1).
- **Conversation tracking:** a Claude `SessionStart` hook records each session's conversation ID in `/var/lib/devdesk/registry.json`. After a reboot the session resumes *that* conversation, even when other Claude instances, such as code-server, use the same directory.
- **Claude Context panel:** a Claude `statusLine` command (`devdesk-statusline`) snapshots each session's model, context-window use, cost and edits to `/var/lib/devdesk/context/<session>.json`. The panel shows the current session's numbers, and Claude's own footer shows a one-line summary. Sessions started before 0.2.0 need Claude restarted (`/exit`, then ⏎ in the menu) before they report.
- **SSH:** `devdesk attach <name>`, `devdesk new <name> [project]`, `devdesk rename <old> <new>`, `devdesk end <name>`, `devdesk ls`, `devdesk pick`.
## Keys
| Key | Action |
|---|---|
| Shift+Enter | Newline in Claude's prompt (sends Ctrl+J) |
| Esc | Interrupt Claude |
| Ctrl-b 0 / 1 | Claude window / shell window |
| Ctrl-b s | Switch session (the URL follows) |
| Ctrl-b d | Detach (the session keeps running) |
| Shift+drag | Native browser selection (plain drag goes to tmux copy-mode, which copies via OSC 52) |
| Ctrl+Shift+C / V | Copy selection / paste |
Use the **Full** button for fullscreen. In Chromium it also captures Ctrl+W/Ctrl+T, which browsers otherwise keep for themselves.
## Configuration
- `/etc/devdesk/env` (conffile):
- port, bind address, projects root and `DEVDESK_DEFAULT_DIR`
- `CLAUDE_BIN` and `CLAUDE_ARGS`
- `DEVDESK_REMOTE_CONTROL=1`, which also starts each session with Claude Remote Control so it can be continued from the Claude app
- `/etc/devdesk/secret.env` is generated on install. It holds the ttyd credential that NPM must inject; see [docs/DEPLOY.md](docs/DEPLOY.md).
- `/etc/devdesk/tmux.local.conf` is optional and is sourced after the packaged `tmux.conf`.
## Build
Needs Node ≥ 18, `debhelper`, `bats`, `tmux`, `jq`, `shellcheck`:
```bash
make # dist/index.html (single inlined page) + build/ttyd (pinned, sha256-verified)
make lint test
dpkg-buildpackage -us -uc -b && lintian ../devdesk_*_amd64.deb
apt install ../devdesk_*_amd64.deb
```
CI (`.gitea/workflows/build-deb.yml`):
- Every push lints, tests, builds and smoke-tests the package and uploads it as an artifact.
- A `v*` tag also publishes to `https://code.lotusguild.org/api/packages/LotusGuild/debian` and creates a release.
## Roadmap
- **v1.1:** `devdesk-api` sidecar for the Repo/CI panel, Matrix notifications when you're away, and auto-deploy.
- **v2:** Ops Alerts (Grafana) with "Ask Claude" prompts, and file drop.