https://github.com/superbereza/claude-remote-launcher
Launch Claude Code Remote Control sessions in a detached tmux pane and get the claude.ai/code URL — skill + CLI
https://github.com/superbereza/claude-remote-launcher
ai-tools claude-code cli remote-control shell skills tmux
Last synced: 21 days ago
JSON representation
Launch Claude Code Remote Control sessions in a detached tmux pane and get the claude.ai/code URL — skill + CLI
- Host: GitHub
- URL: https://github.com/superbereza/claude-remote-launcher
- Owner: superbereza
- Created: 2026-05-08T19:03:14.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-02T08:28:55.000Z (22 days ago)
- Last Synced: 2026-06-02T10:22:59.098Z (22 days ago)
- Topics: ai-tools, claude-code, cli, remote-control, shell, skills, tmux
- Language: Shell
- Size: 27.3 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# claude-remote-launcher
A tiny skill + CLI that spawns a Claude Code [Remote Control](https://code.claude.com/docs/en/remote-control) session in a detached `tmux` pane. By default it just confirms the session started (the remote chat appears on your device); pass `--url` to also print the `claude.ai/code` link.
Designed so an agent (or you) can launch fresh Claude sessions in existing or brand-new project folders without leaving the current session. The skill is wired up for **Claude Code, Cursor, Codex and Gemini** from one source (see [Install](#install)).
## Install
Three ways — pick one. All end with the same `claude-remote` CLI and skill.
### 1. Standalone (clone + symlinks)
```bash
git clone https://github.com/superbereza/claude-remote-launcher ~/dev/claude-remote-launcher
cd ~/dev/claude-remote-launcher
./install.sh
```
`install.sh` creates two symlinks:
- `~/.local/bin/claude-remote` → `bin/claude-remote` (`~/.local/bin` must be on `PATH`)
- `~/.claude/skills/claude-remote` → `skills/claude-remote`
### 2. As a Claude Code plugin (this repo is its own marketplace)
```text
/plugin marketplace add superbereza/claude-remote-launcher
/plugin install claude-remote@claude-remote-launcher
```
### 3. From an aggregate marketplace
```text
/plugin marketplace add superbereza/superbereza-skills
/plugin install claude-remote@superbereza-skills
```
### Other agents
The same `skills/` directory is exposed to **Cursor** (`.cursor-plugin/`), **Codex** (`.codex-plugin/`) and **Gemini** (`gemini-extension.json` → [`AGENTS.md`](AGENTS.md)). One skill, one source — see [`AGENTS.md`](AGENTS.md).
## Usage
```bash
# Existing folder — chat title defaults to the folder name
claude-remote ~/dev/myproject
# New folder (auto-created and pre-trusted)
claude-remote ~/dev/scratch-experiment
# Custom session name (= the remote-control chat title, used verbatim)
claude-remote ~/dev/myproject debug-auth
# Also print the claude.ai/code URL
claude-remote ~/dev/myproject --url
```
Default output (status only):
```
SESSION: cc—myproject
STATUS: remote-control active
ATTACH: tmux attach -t 'cc—myproject'
```
With `--url` the `STATUS` line becomes `URL: https://claude.ai/code/...`. Exit code is `1` if the remote-control URL doesn't appear within 30s.
## Subcommands
| Command | Action |
|---------|--------|
| `claude-remote [name] [--url]` | Spawn (default; same as `spawn`) |
| `claude-remote spawn [name] [--url]` | Spawn, explicit |
| `claude-remote ls` | List running `cc—` tmux sessions |
| `claude-remote kill ` | Kill one |
| `claude-remote kill --all` | Kill all `cc—` sessions |
| `claude-remote refresh ` | Re-issue `/remote-control` inside an existing pane → fresh URL, same chat |
| `claude-remote --version` | Print version |
The session `name` is the remote-control chat title, **used verbatim** — nothing is
prepended automatically, so include a `device/` prefix yourself if you use that
convention (e.g. `claude-remote ~/dev/x "mac-mini/x"`).
Disconnecting from claude.ai/code only drops the remote view; the local `claude` process keeps running until you kill the tmux session. The trust entry written to `~/.claude.json` is left in place after killing sessions, so re-launching in the same folder is fast.
## How it works
1. Resolves the absolute path and detects whether the folder is new.
2. Creates the folder with `mkdir -p` if missing.
3. **Pre-trusts the folder** by atomically writing `hasTrustDialogAccepted: true` into `~/.claude.json` under the project entry.
4. Starts a detached tmux session in the folder.
5. Runs `claude --dangerously-skip-permissions` inside the pane (interactive TUI).
6. Waits for `bypass permissions on` (bottom-bar indicator) — the TUI is ready. Trust dialog is skipped thanks to step 3.
7. Sends `/remote-control ` slash command to enable Remote Control (name defaults to the folder).
8. Polls `tmux capture-pane` (with `-J` to join wrapped lines) for `https://claude.ai/code/...` (timeout 30 s) to confirm it came up.
9. Prints the status (or the URL with `--url`). Tmux session keeps running after the script exits.
## Why slash command, not server mode
`claude remote-control` (server mode) bundles all sessions inside a single process — when the server's OAuth token rotates (~24 h), the daemon dies and takes every session with it (see [#53635](https://github.com/anthropics/claude-code/issues/53635), [#53563](https://github.com/anthropics/claude-code/issues/53563)).
The slash-command approach this script uses keeps the conversation as a plain Claude session backed by `.jsonl`. If Remote Control drops, run `claude-remote refresh ` to re-issue `/remote-control` inside the existing tmux pane — fresh URL, history preserved. If the `claude` process itself dies, you can `claude --resume --dangerously-skip-permissions` and `/remote-control` again.
## Requirements
- `claude` ≥ 2.1.51 (Remote Control support), logged in with a Claude subscription
- `tmux`
- `python3` (used for absolute-path resolution and atomic JSON edits)
## Uninstall
```bash
./scripts/uninstall.sh
```
Removes the symlinks. Repo and `~/.claude.json` are not touched.
## OpenCode
This skill also supports [OpenCode](https://opencode.ai) — see [`.opencode/INSTALL.md`](.opencode/INSTALL.md).