Skip to content

Commit 6ad18a0

Browse files
committed
docs: add README and MIT license for runcode-cli
1 parent ae51943 commit 6ad18a0

2 files changed

Lines changed: 197 additions & 0 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 RunCode
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# runcode
2+
3+
**The RunCode cloud workspace CLI.** Connect your local coding agents (Claude Code,
4+
Codex), editors (VS Code Remote, JetBrains), and tools (`git`, `rsync`, `ssh`) to a
5+
[RunCode](https://runcode.io) cloud development workspace over SSH — with short-lived,
6+
workspace-scoped keys and your `~/.ssh` left untouched.
7+
8+
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
9+
![Go](https://img.shields.io/badge/Go-1.25%2B-00ADD8)
10+
![Platforms](https://img.shields.io/badge/platforms-linux%20%7C%20macOS%20%7C%20windows-555)
11+
12+
A single static binary, no runtime dependencies beyond an OpenSSH client. It mints a
13+
fresh throwaway SSH keypair on your machine, registers only the public key with the
14+
RunCode gateway for a short window, and pins the gateway host key — so there is no
15+
first-connect prompt and no man-in-the-middle window. Your private key never leaves
16+
your computer.
17+
18+
It is also built for agents: every command takes `--json`, returns a stable error
19+
`code`, and uses disciplined exit codes, so a coding agent can drive a workspace
20+
programmatically.
21+
22+
## Install
23+
24+
**Linux / macOS (script):** downloads the right archive from GitHub Releases and
25+
verifies its sha256 against `checksums.txt` before installing.
26+
27+
```sh
28+
curl -fsSL https://raw.githubusercontent.com/runcode-io/runcode-cli/master/install.sh | sh
29+
```
30+
31+
**Homebrew:**
32+
33+
```sh
34+
brew install runcode-io/tap/runcode
35+
```
36+
37+
**Windows:** download `runcode_windows_amd64.zip` (or `arm64`) from the
38+
[latest release](https://github.com/runcode-io/runcode-cli/releases/latest), unzip,
39+
and put `runcode.exe` on your `PATH`. You also need the OpenSSH client
40+
(*Settings → Apps → Optional features → OpenSSH Client*).
41+
42+
**From source** (Go 1.25+):
43+
44+
```sh
45+
go build -o runcode . # produces ./runcode
46+
```
47+
48+
**Via the agent plugin:** if you use the
49+
[RunCode agent plugin](https://github.com/runcode-io/runcode-agent-plugin) for Claude
50+
Code or Codex, you don't install this directly — the plugin downloads and verifies a
51+
pinned release of this binary on first use.
52+
53+
## Quickstart
54+
55+
```sh
56+
runcode login # opens your browser once, saves a token locally
57+
runcode list # your workspaces (running = SSH-connectable)
58+
runcode connect my-workspace # attach a workspace (--start boots a stopped one)
59+
runcode exec -- pytest -q # run a command on the attached workspace
60+
```
61+
62+
A successful `connect` attaches one *sticky* workspace, so `exec`, `put`/`get`,
63+
`context`, and `statusline` all target it without naming it again — until you
64+
`disconnect`.
65+
66+
## Commands
67+
68+
**Authentication**
69+
70+
| Command | Description |
71+
|---------|-------------|
72+
| `login` | Authenticate in the browser and save an API token |
73+
| `logout` | Remove the saved API token |
74+
75+
**Workspaces**
76+
77+
| Command | Description |
78+
|---------|-------------|
79+
| `list` | List your workspaces |
80+
| `connect <ws>` | Mint a session and attach a workspace (`--start` boots a stopped one, `--wait` blocks until SSH answers) |
81+
| `start <ws>` | Power a workspace on without attaching (`--no-wait` returns early) |
82+
| `stop [ws]` | Power a workspace down (compute billing pauses; storage persists) |
83+
| `open <ws>` | Open the workspace browser IDE (or print its URL with `--print`) |
84+
| `create` | Create a new workspace |
85+
| `delete <ws>` | Delete a workspace (irreversible) |
86+
| `current` | Show the attached workspace |
87+
| `status` | List cached sessions |
88+
| `disconnect` | Detach the sticky workspace (does **not** power it off) |
89+
90+
**Run commands**
91+
92+
| Command | Description |
93+
|---------|-------------|
94+
| `ssh <ws> [-- <cmd>]` | Open a shell on a workspace, or run one command with `-- <cmd>` |
95+
| `exec -- <cmd>` | Run a command on the attached workspace (no name needed; preferred for agents) |
96+
| `context [ws]` | Print a workspace digest (cwd, git state, project markers, tool versions) |
97+
98+
**Files & ports**
99+
100+
| Command | Description |
101+
|---------|-------------|
102+
| `put <local> <remote>` | Upload a local file to the attached workspace |
103+
| `get <remote> [--out <local>]` | Download a file from the attached workspace |
104+
| `write <remote> [--file <local>]` | Write a file on the attached workspace from stdin or `--file` |
105+
| `port-forward <port>` | Forward a workspace port to localhost (`--local`, `--to`, `--cancel`) |
106+
107+
**Editor integration**
108+
109+
| Command | Description |
110+
|---------|-------------|
111+
| `config-ssh` | Write a managed `~/.ssh/config` block so your own editor / git reach workspaces as `runcode.<name>` (`--remove` to undo) |
112+
| `install-statusline` | Wire the workspace status line into your Claude Code settings |
113+
| `statusline` | Print a one-line status segment for the current session |
114+
115+
**Maintenance**
116+
117+
| Command | Description |
118+
|---------|-------------|
119+
| `doctor` | Diagnose the local setup (OpenSSH client, token, API base, reachability) |
120+
| `install-path` | Add `runcode` to your shell `PATH` |
121+
| `clean [ws]` | Remove cached session material |
122+
123+
Every command accepts `--json` for machine-readable output. Run `runcode <command> --help`
124+
for full flags.
125+
126+
## How it works
127+
128+
Three steps run automatically each time you connect:
129+
130+
1. **A key is born on your machine.** `runcode` generates a fresh, throwaway SSH keypair
131+
locally and sends only the *public* key to RunCode. The private key never leaves your
132+
computer.
133+
2. **RunCode returns a short-lived pass.** The backend registers the key with the gateway
134+
for a short window (about 30 minutes) and returns a connection bundle with a *pinned*
135+
host key — no first-connect prompt, no MITM window.
136+
3. **Your tools connect through the gateway.** `ssh`, `git`, `rsync`, VS Code Remote, and
137+
your local coding agent reach the workspace through the RunCode gateway using an
138+
isolated config. Your `~/.ssh` is untouched and your personal keys are never offered.
139+
140+
`config-ssh` is the one opt-in exception: it writes a clearly delimited, reversible block
141+
to `~/.ssh/config` (one host per workspace) so your own tools can reach a workspace as
142+
`runcode.<name>`. The short-lived key refreshes on every connect, so the entry never
143+
goes stale.
144+
145+
## Configuration
146+
147+
- **Token.** `runcode login` saves an API token to `${XDG_CONFIG_HOME:-~/.config}/runcode/token`
148+
(mode `0600`). You can also supply it for one invocation via the `RUNCODE_TOKEN`
149+
environment variable.
150+
- **Endpoints.** Defaults to the RunCode control plane at `https://app.runcode.io` and the
151+
web app at `https://runcode.io`.
152+
- **Session material** (per-workspace bundles, generated keys, known_hosts) lives under
153+
`${XDG_CONFIG_HOME:-~/.config}/runcode/ws/<id>/` and is cleared by `runcode clean`.
154+
155+
## Security
156+
157+
- Only the public key is sent; the server never sees, stores, or can use your private key.
158+
- The gateway host key arrives pinned in the bundle — no TOFU prompt, no MITM window.
159+
- Sessions are short-lived (~30 min, server-capped) and scoped to a single workspace.
160+
- The CLI uses its own ssh config, so your personal keys are never offered. `config-ssh`
161+
is the one opt-in, fully reversible exception.
162+
- The control plane is HTTPS-only; the CLI refuses a non-HTTPS endpoint, so the token
163+
never rides over cleartext and the bundle can't be downgraded.
164+
- You land as the same user you already have in the browser IDE, so no new privilege is
165+
created.
166+
167+
## Development
168+
169+
```sh
170+
go build ./... # build
171+
go test ./... # tests
172+
```
173+
174+
## License
175+
176+
[MIT](./LICENSE) © 2026 RunCode

0 commit comments

Comments
 (0)