Files
devdesk/README.md
T
jaredandClaude Opus 5.5 531b640ae9
build-deb / Lint, test, package (push) Successful in 2m16s
build-deb / Deploy to CT 126 (push) Successful in 3m4s
build-deb / Notify on failure (push) Skipped
feat: auto-deploy tagged releases to CT 126 via signed webhook (0.3.1)
CI's new deploy job (tags only) sends the house HMAC webhook to CT 126; the
listener runs /usr/lib/devdesk/devdesk-deploy, which waits for the version in
the apt registry and upgrades devdesk with --force-confold. Running sessions
are untouched. Hook setup is documented in docs/DEPLOY.md.

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

79 lines
5.2 KiB
Markdown
Raw 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
- **Put your changes in `/etc/devdesk/env.local`.** It's read after the packaged `env` and never shipped, so `apt upgrade` never asks about it. Example: `DEVDESK_REMOTE_CONTROL=1`.
- `/etc/devdesk/env` holds the packaged defaults; don't edit it. Its keys:
- port, bind address, projects root and `DEVDESK_DEFAULT_DIR`
- `DEVDESK_GITEA_URL` / `DEVDESK_GITEA_ALIASES` for the Repo/CI panel. Public repos need no token; for private ones put a `read:repository` token in `/etc/devdesk/gitea-token`
- `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`, creates a release, and auto-deploys to CT 126. A signed webhook runs `devdesk-deploy`, which upgrades the package; see [docs/DEPLOY.md](docs/DEPLOY.md).
## Roadmap
- **Next:** Matrix notifications when you're away (needs the Ci-Alert hookshot URL).
- **v2:** Ops Alerts (Grafana) with "Ask Claude" prompts, and file drop.