SPB Git

Repository Public

13 entries at the root
History

Latest commit Web redesign: light theme by default, phone Home, new toolbar, node cards; theme settings 4432bc5

NameLast commitUpdated
apps Web redesign: light theme by default, phone Home, new toolbar, node cards; theme settings
deploy adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
docs Web redesign: light theme by default, phone Home, new toolbar, node cards; theme settings
packages Web redesign: light theme by default, phone Home, new toolbar, node cards; theme settings
scripts adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
.env.example adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
.gitignore adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
.prettierrc adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
package.json adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
pnpm-lock.yaml Web redesign: light theme by default, phone Home, new toolbar, node cards; theme settings
pnpm-workspace.yaml adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
README.md Docs: architecture, security, operations, deliverables status
tsconfig.base.json adopt: état déployé sur M5M36 adopté comme source de vérité (remote-first, 2026-11-10)
README.md View source

# Claude Remote — MacLustr Command Center

A private, single-administrator web application that exposes the real Claude Code CLI, running inside tmux on a Mac Studio of the MacLustr cluster, to any browser. Nothing is simulated: the browser terminal is an xterm.js view attached to a tmux session in which claude (or a login shell) runs.

Production instance: https://claude.spboucher.ai → node M5M36 (deployed 2026-11-10).

This README is a summary. Every statement about behaviour is backed by the source; anything that is not implemented or not verified is listed under Limitations and in the "Limitations / not verified" section of each document.

# Architecture

text
 browser (desktop / phone)
    │  HTTPS + WSS
    ▼
 Caddy on the public gateway (BHS64) ── TLS termination, reverse proxy
    │  WireGuard tunnel (the node dials out; no inbound port on the LAN)
    ▼
 M5M36 ─ apps/server   Fastify, port 8620
    │      auth (password + passkey/TOTP), REST + WebSocket API /api/v1,
    │      static web app (apps/web/out), PostgreSQL 17 (loopback), audit, notifications
    │
    │  unix socket (0600, dir 0700) + bearer token — HTTP and WebSocket
    ▼
         apps/runtime  no TCP listener; the only process that spawns anything
    │      tmux sessions, node-pty attach, durable tasks, file/git operations,
    │      Claude Code introspection, host metrics, hook endpoint
    ▼
         tmux server (socket `-L claude-remote`)
           cr-<uuid>   one per terminal session: `claude …` or a login shell
           crt-<uuid>  one per background task (local, or `ssh <allow-listed node>`)

Details: docs/architecture.md, docs/network-architecture.md, binding engineering contract: docs/CONTRACT.md.

# Repository layout

Path Content
packages/shared @cr/shared: zod schemas and types — state machines, browser DTOs, WebSocket wire formats, runtime IPC types
apps/runtime Runtime daemon (Fastify on a unix socket): tmux, PTY attach, scrollback mirror, tasks, hooks, fs/git, skills, MCP, metrics. bin/cr-hook is the Claude Code hook relay
apps/server Browser-facing server: authentication, API, WebSocket proxy, static files, migrations (migrations/*.sql)
apps/web Next.js App Router static export (xterm.js, Monaco, React Query). dev/mock-server.mjs is a mock API used only by the Playwright suite; e2e/, e2e-real/
deploy/ make-manifest.py (mld manifest generator), backup.sh, restore.sh
scripts/ dev-up.sh, dev-down.sh (local run), ci.sh (local CI gate)
docs/ Documentation set (index below)
.env.example Every configuration variable, without secrets

# Quick start (local development, macOS)

Requirements: Node ≥ 24, pnpm, tmux, a local PostgreSQL with psql/createdb on PATH, and the claude CLI on PATH if you want Claude sessions (shell sessions work without it).

bash
pnpm install
pnpm --filter @cr/web build      # optional: without it dev-up serves the API only
scripts/dev-up.sh                # builds shared/runtime/server, creates + migrates claude_remote_dev,
                                 # starts both processes on http://localhost:8620
cat /tmp/cr-dev-data/setup-token # one-time token for the first-run page (/setup/)
scripts/dev-down.sh              # stops both and kills ONLY the dev tmux server (claude-remote-dev)

dev-up.sh uses /tmp/cr-dev-data (data), /tmp/cr-dev-workspace (workspace root), database claude_remote_dev and its own tmux socket. It never sets CR_INSTALL_CLAUDE_HOOKS, so your ~/.claude/settings.json is not modified and sessions do not report WAITING_FOR_INPUT in this mode.

# Tests

Command What runs
scripts/ci.sh build shared → typecheck all → runtime tests → server tests → web unit tests → full build
scripts/ci.sh --e2e the above + Playwright (apps/web/e2e, against the dev mock server)
pnpm --filter @cr/runtime test runtime suite (real tmux, real claude binary, never sends a prompt)
pnpm --filter @cr/server test server suite (one temporary Postgres database per file; integration/real-runtime.test.ts starts the real runtime)
pnpm --filter @cr/web test web unit tests
pnpm --filter @cr/web exec playwright test -c playwright.real.config.ts 2 flows against a real backend started with scripts/dev-up.sh (web export built with NEXT_PUBLIC_E2E=1)

Last recorded results (laptop, 2026-11-10): runtime 209 passed · server 175 passed (17 against the real runtime) · web unit 12 passed · Playwright 19 passed against the mock (15 Chromium desktop, 4 WebKit iPhone 15 emulation) and 2 passed against the real backend · scripts/ci.sh green.

# Deployment summary

Deployed with the cluster orchestrator mld from the gateway (M1M32), pinned to M5M36:

  • PM2 processes claude-remote-runtime, claude-remote-server (port 8620), claude-remote-backup (nightly, 03:35);
  • PostgreSQL 17 on loopback (role and database claude_remote);
  • code in ~/apps/claude-remote (git clone; the node directory is the source of truth), data in ~/claude-remote-data (0700), workspace root ~/workspace;
  • public route https://claude.spboucher.ai → Caddy (BHS64) → WireGuard → M5M36:8620.

Updating is done on the node (edit, build, migrate, restart, commit, push): see docs/deployment.md.

# Status of the 17 deliverables

Detail, files, tests and limitations per item: docs/deliverables-status.md.

# Deliverable Status
1 Working production web application Deployed and verified (health, auth refusals, headers); no administrator created yet
2 Real Claude Code PTY runtime Implemented; real claude 2.1.322 rendered in tmux on the node; Claude not yet authenticated
3 Secure private authentication Implemented and tested; passkeys verified with a software authenticator only
4 Persistent terminal sessions Implemented and tested for every failure mode except a real host reboot (simulated by killing the tmux server)
5 Polished desktop interface Implemented; 15 Playwright tests (Chromium, mock API) + 2 against the real backend
6 Tested mobile interface Implemented; tested in WebKit iPhone 15 emulation only
7 Project management Implemented; create/existing tested end to end, clone not tested against the real git server from the app
8 File browsing and editing Implemented and tested end to end
9 Skills and MCP management Implemented; listings tested against the real CLI, mutations tested with mocks/fakes only; registry install returns 501
10 Authorized MacLustr integration Implemented (agentd telemetry, allow-listed SSH tasks); in-app remote tasks tested with a fake ssh only
11 Background task management Implemented and tested end to end (local tasks)
12 Real observability Implemented (system status, host metrics, audit trail, cluster view); no external alerting
13 Deployment configuration Done (mld manifest generator, PM2, tunnel route, git adoption)
14 Backup and recovery procedures Nightly encrypted backup + restore drill succeeded; backups are not yet copied off the node
15 Security documentation Written (docs/security.md)
16 Automated tests 396 unit/integration tests + 21 Playwright tests, local gate scripts/ci.sh; no hosted CI
17 Demonstrated laptop-independence test Not yet demonstrated — pending the owner (laptop off, phone on cellular)

# Documentation index

Document Subject
docs/architecture.md Processes, data flows, state machines, storage
docs/security.md Threat model, implemented controls mapped to tests, residual risks
docs/authentication.md First-run setup, login flows, sessions, throttling
docs/terminal-runtime.md tmux sessions, attach, scrollback mirror, hooks, backpressure
docs/session-persistence.md Exact guarantees per failure
docs/cluster-integration.md agentd telemetry, remote tasks, git server, local models
docs/mobile-experience.md Phone layout, key toolbar, gestures, PWA shell
docs/deployment.md mld manifest, PM2, environment, first run, remote-first updates
docs/operations-runbook.md Routine checks and procedures
docs/troubleshooting.md Symptoms → causes → actions
docs/backup-recovery.md Backup content, restore, disaster recovery
docs/api.md API conventions; reference is /api/v1/openapi.json
docs/implementation-log.md Chronological build log
docs/deliverables-status.md The 17 deliverables in detail
docs/CONTRACT.md · infrastructure-inventory · node-selection · network-architecture · deployment-plan · migration Earlier design documents (kept as written)

# Limitations / not verified

  • Not verified on a real iPhone (Safari or installed PWA); emulation only.
  • The laptop-independence test has not been run.
  • Passkey login has not been exercised in a real browser.
  • WAITING_FOR_INPUT has not been observed from a real (paid) Claude conversation; the hook relay itself is tested end to end with the real hook script.
  • Web Push is not implemented (in-app notifications only). Skills-registry install is not implemented (501).
  • There is no dedicated LaTeX / Jupyter / research feature; a PDF file preview exists in the editor, nothing more. TeX is not installed on the node.
  • No local model endpoint exists on the cluster; the Local Models panel is empty by design.
  • The application runs under the cluster operator's macOS account, not a dedicated OS identity (see docs/security.md).
  • Single host: if M5M36 is down the service is down. Backups currently stay on M5M36.
  • No hosted CI; scripts/ci.sh is run by hand. The root lint script references ESLint, which is not configured in this repository.

Clone claude-remote

Anonymous clone and fetch. Pushing requires the owner's personal access token.

Snapshot of main

Files main
Menu

Theme