rysh-cli-code

module
v0.2.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: Apache-2.0

README

rysh-cli-code

The Rysh CLI: an agentic terminal multiplexer written in Go. Tabs, panes, splits, and vim/htop working exactly as you expect — except every pane is also an agent that can answer prompts and call tools.

This repository holds the CLI itself. It depends on rysh-cli-shared.

Building or contributing? Start at rysh-cli-parent — it carries the Makefile, the Go workspace, and CI, and wires this module to a local checkout of the shared one.

Secrets stay on your machine

SecretNAT is on by default. Secrets are substituted with tokens in the request body before it leaves the machine, and a response carrying a live credential in plaintext is reported into the pane. Responses are not rewritten — by design.

The mapping is reversible locally, so ##snat get <token> hands you back the real value in your own pane, and the model only ever saw the token.

Install

Two binaries exist and they are not interchangeable:

this repository the prebuilt distribution
binary name rysh ry
how you get it go install Homebrew, curl, APT, RPM

The names differ so that one machine can carry both. Every command below installs exactly one of them, and a script, alias or doc written for one does not run against the other — which is the whole reason the names differ. Check what you have with rysh version or ry version.

This repository is the rysh half: Apache-2.0, with LICENSE and NOTICE beside the source you are reading.

macOS and Linux

The open-source build, from source:

go install github.com/rysh-ai/rysh-cli-code/cmd/rysh@latest

The binary lands in $(go env GOPATH)/bin as rysh. Requires Go 1.25.3 or newer — the floor declared in this module's go.mod.

The prebuilt distribution — installs ry, not rysh. This is the packaged product, and it is the fastest way to get a working install. It is a separate distribution with its own channels; nothing in it is produced by this repository, so ry --help describing a command is not evidence about the source here. Use it if you want the packaged product; use go install above if you want the build whose source you are reading.

Its install commands are deliberately not reproduced here: this README documents the open-source build. The prebuilt distribution has its own channels — Homebrew, a curl installer, APT and RPM — and its own documentation.

Windows

WSL2 is the supported path. Native Windows compiles and runs, but it cannot open a pane — those are two different claims and both are true:

  • GOOS=windows GOARCH=amd64 go build ./... succeeds — the windows/amd64 target builds clean from this source. This repository's .goreleaser.yml names that archive cli-only on purpose, so the artifact says what it is.
  • It cannot start a session. Rysh's PTY layer has no ConPTY implementation, so platform.PTYSupported is false on Windows and every session-opening command is refused up front with WSL guidance — rather than starting a session and then failing on your first pane (cmd/rysh/pty_preflight.go).
  • What it can do is the pane-less command set, including talking to a session running in WSL from the Windows side: rysh send, rysh exec, rysh prompt, rysh list-sessions, rysh install, rysh eval, rysh doctor.

For a real session, install WSL2 and use the Linux instructions inside it — the Linux build runs unmodified:

wsl --install
# inside WSL
go install github.com/rysh-ai/rysh-cli-code/cmd/rysh@latest   # rysh

Native panes need ConPTY behind the same seam; it is not implemented yet.

Build from scratch

This module alone builds standalone — it carries no replace directive, so the shared module resolves from its published version:

git clone https://github.com/rysh-ai/rysh-cli-code
cd rysh-cli-code
go build ./cmd/rysh          # -> ./rysh

From the superrepo, which is how to develop against both modules at once — its go.work wires the shared module to the sibling checkout, so an edit there is picked up without a release round-trip:

git clone --recursive https://github.com/rysh-ai/rysh-cli-parent
cd rysh-cli-parent
make build       # -> bin/rysh
make install     # -> ~/.local/bin/rysh   (override with PREFIX=)
make test        # both modules

Go 1.25.3 or newer either way.

First run

export ANTHROPIC_API_KEY=sk-ant-...
rysh onboard --provider anthropic --key-env ANTHROPIC_API_KEY
rysh doctor

onboard validates the key, writes a project-local rysh.config.yaml, and opens your session. rysh --help lists the full command surface.

Each pane has an input mode and Esc Esc cycles it: shell (a real PTY) → prompt (goes to the LLM) → rysh (multiplexer commands) → chat (conversation, no tools). Those four are enabled by default; ##mode list shows what a pane has and ##mode new <mode> adds the rest.

The parent repo README has the keybindings, sessions, agents and humanoids.

Three tours

Commands starting with ## are typed into a pane in rysh mode. From outside the session, rysh exec -- '##<cmd>' runs the same thing and prints its output.

1. Create a session
rysh create work          # create and attach; add -d to leave it detached
rysh list-sessions        # what is running
rysh attach work          # come back to it later
rysh detach work          # leave it running
rysh stop work            # shut the daemon down

A session is a daemon plus its panes. It outlives your terminal, so closing the window detaches rather than kills.

2. Tabs, lanes, panes and stacks

A tab holds lanes (columns); a lane holds stacks; a stack holds panes, Zellij-style — one expanded, the rest collapsed to a title bar showing [N/M].

##new tab                 a new tab
##new lane                a new lane (column) in the active tab
##new pane                a pane at the bottom of the active lane
##new grid 4              4 panes stacked in the active lane
##new grid 3x4            3 lanes x 4 panes, in the active tab
##new grid 2x3x4          2 tabs x 3 lanes x 4 panes
##new stack 4             4 more stacked panes in the active stack

Look at what you built, and move things around:

##tab list                ##lane list           ##pane list
##panegroup layout        the lane layout, whole
##move pane up|down|left|right      reorder in the stack, or cross to the next lane
##move pane <p> to-lane <lane>      put a live pane somewhere else
##tab name build          ##lane name left      ##pane name builder
3. The agents board, fleets, and a fleet's own board

Panes can run an interactive Claude or Codex, and rysh remembers which, so a session stop/start resumes the same conversation:

##claude                  run claude in this pane, resumed automatically
##codex                   run codex in this pane, same deal
##pane new --claude "start on the parser"    a new pane, already working

The agents board is where those panes talk to each other and to you:

##board open              open the board pane
##board post <text>       post a milestone
##board reply <thread> <text>

An agent inside a pane posts without stealing focus, and reads back:

rysh board post --as "$RYSH_PANE" -- 'parser wiring done'
rysh board tail --limit 20

##board agent up starts a board agent — a hidden pane running Claude that sits in the path, routes messages between agents, and refuses a request it knows is stale. ##board agent visible draws it without moving your focus; ##board agent invisible puts it away while it keeps running.

A fleet is a named group of panes with a board of its own. Registering one opens no panes — it is the cheap half:

##fleet register epic-07 --board epic-07
##fleet state epic-07 up
##fleet list              ##fleet show epic-07
##fleet forget epic-07    drop it; the panes keep running
rysh board tail --fleet epic-07     # that fleet's stream, not the session's

A fleet may be claudes, codexes, or both — the commands are the same either way.

Layout

Path What
cmd/rysh the main package — entry point and command surface
internal/tui the terminal UI
internal/actors workspace / tab / pane / agent actors, proto.actor over NATS
internal/vterm terminal emulation, including a vt10x fork with scrollback
internal/provider LLM provider adapters
internal/platform host capabilities that change what rysh can do (e.g. PTY support)
action/ the setup-rysh composite GitHub Action

Contributing and security

This repository is a one-way export of a tree developed elsewhere, so a commit pushed straight here is overwritten by the next export rather than kept. That does not make patches pointless — CONTRIBUTING.md explains where one actually lands.

Found a vulnerability? Do not open a public issue, PR or discussion. Rysh runs shell commands and holds provider credentials on a developer's machine, so a public report is an exploit notice. SECURITY.md has the private channels.

License

Apache-2.0. See LICENSE and NOTICE.

Directories

Path Synopsis
cmd
medium-smoke command
medium-smoke is a self-verifying trusted-input smoke test against Medium's story editor.
medium-smoke is a self-verifying trusted-input smoke test against Medium's story editor.
registry-index command
registry-index — builds a publishable rysh package registry from a directory of packages (design 005).
registry-index — builds a publishable rysh package registry from a directory of packages (design 005).
rysh command
rysh-script command
Command rysh-script is a shebang shim: it runs `rysh script` with whatever arguments it was given.
Command rysh-script is a shebang shim: it runs `rysh script` with whatever arguments it was given.
wire-harness command
wire-harness — the reproducible, recordable end-to-end proof that a wrapped agent CLI's provider traffic is governed by rysh (design 001, Phase 0/1 definition-of-done item 3).
wire-harness — the reproducible, recordable end-to-end proof that a wrapped agent CLI's provider traffic is governed by rysh (design 001, Phase 0/1 definition-of-done item 3).
examples
plugins/echo-channel command
Command echo-channel is the reference rysh channel plugin (docs/plugin-authoring.md).
Command echo-channel is the reference rysh channel plugin (docs/plugin-authoring.md).
internal
agentic
Package agentic shared_aliases.go — re-exports rysh-shared/agentic types.
Package agentic shared_aliases.go — re-exports rysh-shared/agentic types.
board
Package board is the agents-board store (design 025): the in-memory model of a threaded, push-based stream of what every agent in a session is doing.
Package board is the agents-board store (design 025): the in-memory model of a threaded, push-based stream of what every agent in a session is doing.
bridge
Package bridge provides NATSBridge for delivering NATS messages to actor mailboxes.
Package bridge provides NATSBridge for delivering NATS messages to actor mailboxes.
browserinstance
Package browserinstance manages persistent Chromium browser profiles for web-mode panes.
Package browserinstance manages persistent Chromium browser profiles for web-mode panes.
bus
cdp
Package cdp is a minimal Chrome DevTools Protocol client used by rysh's headless web mode: it launches a Chromium with --remote-debugging-port, attaches over the browser-level WebSocket (flat session mode), and executes browser_action requests (see actions.go) without needing the desktop app.
Package cdp is a minimal Chrome DevTools Protocol client used by rysh's headless web mode: it launches a Chromium with --remote-debugging-port, attaches over the browser-level WebSocket (flat session mode), and executes browser_action requests (see actions.go) without needing the desktop app.
channels/plugin
Package plugin implements the out-of-process channel plugin SDK (openclaw_roadmap design 002, WS2 P1-P3): a third party ships a channel as a separate process speaking a small wire contract, and the in-core PluginChannelAdapter shim proxies the ChannelAdapter interface to it over stdio JSON-RPC (fallback) or the embedded per-session NATS bus (preferred).
Package plugin implements the out-of-process channel plugin SDK (openclaw_roadmap design 002, WS2 P1-P3): a third party ships a channel as a separate process speaking a small wire contract, and the in-core PluginChannelAdapter shim proxies the ChannelAdapter interface to it over stdio JSON-RPC (fallback) or the embedded per-session NATS bus (preferred).
cli
Package cli implements CLI subcommands that communicate with a running rysh session via NATS.
Package cli implements CLI subcommands that communicate with a running rysh session via NATS.
cron
Package cron holds the pure scheduling domain for rysh's in-daemon cron service: the Job model, schedule parsing/validation (via robfig/cron), and next-run computation.
Package cron holds the pure scheduling domain for rysh's in-daemon cron service: the Job model, schedule parsing/validation (via robfig/cron), and next-run computation.
daemontest
Package daemontest boots a real rysh daemon for tests.
Package daemontest boots a real rysh daemon for tests.
domain
Package domain contains shared data types that are transport-agnostic.
Package domain contains shared data types that are transport-agnostic.
eval
Package eval implements the agent eval harness (design 009): "unit tests for agents." A fixture describes a task and structural assertions; a Result is what running the agent produced; Evaluate checks the Result against the assertions.
Package eval implements the agent eval harness (design 009): "unit tests for agents." A fixture describes a task and structural assertions; a Result is what running the agent produced; Evaluate checks the Result against the assertions.
fleet
Package fleet is the session's registry of agent fleets (design 028 §6.5): which fleets exist, who is in them, and which board each one talks on.
Package fleet is the session's registry of agent fleets (design 028 §6.5): which fleets exist, who is in them, and which board each one talks on.
forge
Package forge ties the Forge pipeline to the live rysh runtime: it stores per-project integration definitions, ingests their specs into the IR, builds tool-packs, and registers the resulting tools into the agent registry under the §5.6 exposure policy.
Package forge ties the Forge pipeline to the live rysh runtime: it stores per-project integration definitions, ingests their specs into the IR, builds tool-packs, and registers the resulting tools into the agent registry under the §5.6 exposure policy.
forge/forgecmd
Package forgecmd implements the `forge` subcommand family (add / generate / list / diff / targets) independently of any particular front-end.
Package forgecmd implements the `forge` subcommand family (add / generate / list / diff / targets) independently of any particular front-end.
forge/gen
Package gen defines the Forge generator framework: a pluggable Generator interface, a registry, and a FileSet output collector.
Package gen defines the Forge generator framework: a pluggable Generator interface, a registry, and a FileSet output collector.
forge/gen/docs
Package docs generates Markdown API reference documentation from the IR.
Package docs generates Markdown API reference documentation from the IR.
forge/gen/gosdk
Package gosdk is a Forge generator that emits a self-contained Go client SDK for an API described by the IR.
Package gosdk is a Forge generator that emits a self-contained Go client SDK for an API described by the IR.
forge/gen/javasdk
Package javasdk is a Forge generator that emits a Java client SDK for an API described by the IR.
Package javasdk is a Forge generator that emits a Java client SDK for an API described by the IR.
forge/gen/mcpserver
Package mcpserver generates a standalone Go MCP server for an API.
Package mcpserver generates a standalone Go MCP server for an API.
forge/gen/pysdk
Package pysdk is a Forge generator that emits a Python client SDK (client.py + pyproject.toml + README.md) for an API described by the IR.
Package pysdk is a Forge generator that emits a Python client SDK (client.py + pyproject.toml + README.md) for an API described by the IR.
forge/gen/tssdk
Package tssdk is a Forge generator that emits a TypeScript client SDK (client.ts + package.json + README.md) for an API described by the IR.
Package tssdk is a Forge generator that emits a TypeScript client SDK (client.ts + package.json + README.md) for an API described by the IR.
forge/ingest
Package ingest converts source API descriptions into the Forge IR.
Package ingest converts source API descriptions into the Forge IR.
forge/ir
Package ir defines the Forge Intermediate Representation: a language- and target-agnostic model of an API.
Package ir defines the Forge Intermediate Representation: a language- and target-agnostic model of an API.
forge/runtime
Package runtime is the shared, cross-cutting machinery a generated tool-pack uses at call time: HTTP request assembly, auth injection, retries/backoff, pagination hints, jq-style response trimming, and a secret-redaction hook.
Package runtime is the shared, cross-cutting machinery a generated tool-pack uses at call time: HTTP request assembly, auth injection, retries/backoff, pagination hints, jq-style response trimming, and a secret-redaction hook.
forge/toolpack
Package toolpack turns an IR into a hot-loadable Rysh tool pack: a declarative manifest of tool definitions plus the live ToolExecutors that back them.
Package toolpack turns an IR into a hot-loadable Rysh tool pack: a declarative manifest of tool definitions plus the live ToolExecutors that back them.
gateway
Package gateway is the daemon half of the LLM gateway's server-side control plane (design 023): it reports governed spend to rysh-server, leases a slice of an org-wide allowance and enforces locally against that slice, and pulls central policy.
Package gateway is the daemon half of the LLM gateway's server-side control plane (design 023): it reports governed spend to rysh-server, leases a slice of an org-wide allowance and enforces locally against that slice, and pulls central policy.
limits
Package limits provides subscription resource limit checking for the rysh daemon.
Package limits provides subscription resource limit checking for the rysh daemon.
llms
Package llms is the file-backed LLM model registry behind the ##llm command.
Package llms is the file-backed LLM model registry behind the ##llm command.
mcp
Package mcp implements a Model Context Protocol (MCP) client for the rysh CLI.
Package mcp implements a Model Context Protocol (MCP) client for the rysh CLI.
metrics
Package metrics implements an in-process metrics sink for the rysh agentic system.
Package metrics implements an in-process metrics sink for the rysh agentic system.
msg
Package msg contains all typed message structs used for inter-actor communication via NATS.
Package msg contains all typed message structs used for inter-actor communication via NATS.
pipeline
Package pipeline provides a thread-safe runtime registry for pipeline prompts.
Package pipeline provides a thread-safe runtime registry for pipeline prompts.
platform
Package platform reports host capabilities that change what rysh can do, so the answer is a compile-time constant rather than a runtime surprise.
Package platform reports host capabilities that change what rysh can do, so the answer is a compile-time constant rather than a runtime surprise.
policy
Package policy implements policy-as-code (design 013 §1): governance rules as a versioned file in the repo (.rysh/policy.yaml), loaded at session start, optionally constrained by an org-level policy file (config `policy.org_file` or RYSH_ORG_POLICY).
Package policy implements policy-as-code (design 013 §1): governance rules as a versioned file in the repo (.rysh/policy.yaml), loaded at session start, optionally constrained by an org-level policy file (config `policy.org_file` or RYSH_ORG_POLICY).
progname
Package progname resolves the name this binary was invoked as, so that user-facing text names the command the user actually has.
Package progname resolves the name this binary was invoked as, so that user-facing text names the command the user actually has.
proxy
Package proxy implements the Universal Agent Governance Proxy (design 001): a loopback HTTP proxy that intercepts the LLM provider traffic of third-party agent CLIs (Claude Code, Codex, aider, …) running inside panes and applies rysh governance to it — SecretNAT redaction on request bodies, token/cost metering into the usage ledger (design 003), and audit — by base-URL environment injection, NOT TLS MITM.
Package proxy implements the Universal Agent Governance Proxy (design 001): a loopback HTTP proxy that intercepts the LLM provider traffic of third-party agent CLIs (Claude Code, Codex, aider, …) running inside panes and applies rysh governance to it — SecretNAT redaction on request bodies, token/cost metering into the usage ledger (design 003), and audit — by base-URL environment injection, NOT TLS MITM.
proxy/wirecheck
Package wirecheck answers one question about one CLI: if rysh points it at the governance proxy, does its provider traffic actually go there?
Package wirecheck answers one question about one CLI: if rysh points it at the governance proxy, does its provider traffic actually go there?
registry
Package registry implements the client side of the rysh agent registry (design 005): install .md agents / loops / recipes / humanoids into a project's .rysh/ tree, reproducibly (lockfile) and with install-time consent (declared tools / channels / env are shown before anything is written).
Package registry implements the client side of the rysh agent registry (design 005): install .md agents / loops / recipes / humanoids into a project's .rysh/ tree, reproducibly (lockfile) and with install-time consent (declared tools / channels / env are shown before anything is written).
relay
Package relay provides a thread-safe in-process registry that maps pane IDs to PTY relay handles.
Package relay provides a thread-safe in-process registry that maps pane IDs to PTY relay handles.
replay
Package replay implements session replay / time-travel (design 006): capture a session's pane output and export it as an asciicast (.cast) file so demos and incidents become reproducible artifacts.
Package replay implements session replay / time-travel (design 006): capture a session's pane output and export it as an asciicast (.cast) file so demos and incidents become reproducible artifacts.
script
Package script turns a .rysh file — a bash script whose statement-position "##" lines are rysh commands — into plain bash (design 021).
Package script turns a .rysh file — a bash script whose statement-position "##" lines are rysh commands — into plain bash (design 021).
tools
Package tools registry.go — re-exports rysh-shared/tools types as aliases.
Package tools registry.go — re-exports rysh-shared/tools types as aliases.
tui
tunnel
Package tunnel publishes a locally-bound rysh web server at a public HTTPS URL through ngrok.
Package tunnel publishes a locally-bound rysh web server at a public HTTPS URL through ngrok.
upstream
Package upstream provides HTTP helpers for fetching workspace-scoped data from the rysh-server using the local upstream API key.
Package upstream provides HTTP helpers for fetching workspace-scoped data from the rysh-server using the local upstream API key.
usage
Package usage holds the cost-observability pricing table (design 003).
Package usage holds the cost-observability pricing table (design 003).
voice
Package voice implements voice prompting for the rysh TUI: it records the microphone via a system recorder, transcribes the audio with a pluggable speech-to-text provider (Deepgram by default, OpenAI Whisper as an alternative), and hands the text back to the caller to drop into the prompt input field.
Package voice implements voice prompting for the rysh TUI: it records the microphone via a system recorder, transcribes the audio with a pluggable speech-to-text provider (Deepgram by default, OpenAI Whisper as an alternative), and hands the text back to the caller to drop into the prompt input field.
vterm
Package vterm wraps a virtual terminal emulator (vt10x) that interprets PTY output into a 2D screen buffer suitable for rendering in the TUI.
Package vterm wraps a virtual terminal emulator (vt10x) that interprets PTY output into a 2D screen buffer suitable for rendering in the TUI.
vterm/vt10x
Package terminal is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference.
Package terminal is a vt10x terminal emulation backend, influenced largely by st, rxvt, xterm, and iTerm as reference.
web
Answering a gated tool from a non-TUI client (E-12b).
Answering a gated tool from a non-TUI client (E-12b).
webauto
Package webauto stores reusable, prompt-based automations ("recipes") for the ##auto command family.
Package webauto stores reusable, prompt-based automations ("recipes") for the ##auto command family.
worktree
Package worktree wraps git-worktree operations for per-agent isolation (design 008): give a pane/agent its own git worktree so parallel agents never collide on the same repo — "N agents, N branches, one tab, zero collisions."
Package worktree wraps git-worktree operations for per-agent isolation (design 008): give a pane/agent its own git worktree so parallel agents never collide on the same repo — "N agents, N branches, one tab, zero collisions."

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL