70 lines
3.9 KiB
Markdown
70 lines
3.9 KiB
Markdown
# 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
|
||
|
|
- **How the session is chosen:**
|
||
|
|
- `https://dev.lotusguild.org/?arg=<name>` opens session `<name>` and creates it on demand in `$DEVDESK_PROJECTS_ROOT/<name>`. `main` uses the root itself, and folders with spaces are reached by slug (`test code` → `test-code`).
|
||
|
|
- With no `?arg=`, an fzf picker opens, listing running (●), dormant (○) and new (+) sessions.
|
||
|
|
- **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.
|
||
|
|
- **SSH:** `devdesk attach <name>`, `devdesk ls`, `devdesk pick`, `devdesk end <name>`.
|
||
|
|
|
||
|
|
## 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 and projects root
|
||
|
|
- `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 and Claude Context panels, Matrix notifications when you're away, and auto-deploy.
|
||
|
|
- **v2:** Ops Alerts (Grafana, GANDALF) with "Ask Claude" prompts, and file drop.
|