No description
The server's serializeAsHTML() returns the full terminal screen state, not incremental chunks. Updated the dashboard to: 1. Handle initial_state event to receive current terminal state on connection 2. Replace output instead of appending (output event now replaces session.output) 3. Simplify renderSessionOutput() to always do full innerHTML replacement This fixes the issue where output was being duplicated/appended incorrectly. |
||
|---|---|---|
| data | ||
| docs | ||
| public | ||
| src | ||
| .dockerignore | ||
| .gitignore | ||
| biome.json | ||
| bun.lock | ||
| Caddyfile.example | ||
| CLAUDE.md | ||
| compose.yml | ||
| Dockerfile | ||
| justfile | ||
| package.json | ||
| README.md | ||
| TODO.txt | ||
| tsconfig.json | ||
clarc
Self-hosted remote control for Claude Code. Wraps CLI in PTY, streams output to server, approve prompts from phone.
quick start
# 1. start the server
just dev
# 2. create a device (one-time setup)
just seed dev "My Phone"
# 3. build the binary + symlink to ~/bin
bun build --compile src/cli.ts --outfile clarc
ln -sf $(pwd)/clarc ~/bin/clarc
# 4. set your secret
export CLAUDE_REMOTE_SECRET=dev # add to .bashrc/.zshrc
# 5. use it like claude
clarc
clarc -r
clarc --dangerously-skip-permissions
# 6. open browser/phone
open http://localhost:7200
usage
server
just dev # development with hot reload
just start # production
just check # lint + typecheck + test
Server runs on port 7200 (configure via PORT env var).
create device
just seed <secret> <name>
Creates a device with the given secret and name. The secret is used to authenticate the CLI wrapper.
Default if you just run just seed:
- secret: "dev"
- name: "dev device"
run claude
With the binary installed and CLAUDE_REMOTE_SECRET set, just use clarc like claude:
clarc # interactive
clarc -r # resume
clarc --help # shows help
clarc -p "explain this" # print mode
All arguments pass through to claude.
configuration
Environment variables (add to .bashrc/.zshrc):
export CLAUDE_REMOTE_SECRET=dev # required
export CLAUDE_REMOTE_SERVER=ws://localhost:7200/ws # optional, this is the default
Or use flags to override:
clarc --secret other-device --server ws://remote:7200/ws
shell aliases
alias cr='clarc'
alias crr='clarc -r'
alias crd='clarc --dangerously-skip-permissions'
alias crdr='crd -r'
view output
Open http://localhost:7200 in browser or phone to:
- see live terminal output
- approve/reject permission prompts
- answer questions
docker
just build # build image
just up # compose up
just down # compose down
just logs # compose logs
architecture
Pure Bun stack:
- bun-pty for PTY wrapper
- bun:sqlite for persistence
- Bun.serve() for HTTP + WebSocket + SSE
- plain text output (mobile-friendly)
Target: ~1000-1500 lines total.