jaredandClaude Opus 5.5 03e4a49e78
build-deb / Lint, test, package (push) Successful in 1m51s
build-deb / Deploy to CT 126 (push) Successful in 3s
build-deb / Notify on failure (push) Skipped
feat: session status at a glance, file & image drop, live Ops Alerts (0.4.0)
- devdesk-state-hook (Claude UserPromptSubmit/PostToolUse/Notification/Stop/
  SessionStart/SessionEnd) records whether each session is working, waiting on
  you or idle; --list carries it. The sidebar shows it, the header shows the
  current session's state, and a pulsing "needs you" chip jumps to sessions
  waiting for input. Session refresh no longer depends on the sidebar being open.
- `devdesk attach --upload SESSION FILE BYTES` receives a file as base64
  terminal input (raw mode, exact length, size-checked, sanitised name) into
  /var/lib/devdesk/uploads/<session>/. The UI uploads dropped or pasted files and
  pastes the path into Claude, which attaches images itself.
- `devdesk alerts` / `--alerts`: firing and pending Grafana alert rules with
  severity, instances, summary and a link. The panel's "Ask Claude" types an
  investigation prompt into the current session.

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

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).
  • 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.
  • /etc/devdesk/tmux.local.conf is optional and is sourced after the packaged tmux.conf.

Build

Needs Node ≥ 18, debhelper, bats, tmux, jq, shellcheck:

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.

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.
S
Description
Persistent browser terminal for Claude Code (ttyd + tmux, LotusGuild TDS) at dev.lotusguild.org, packaged as a .deb
Readme MIT
1.9 MiB
2026-11-03 21:23:29 -05:00
Languages
JavaScript 52.9%
Shell 35%
CSS 9.2%
HTML 2.4%
Makefile 0.5%