runectl
runectl is Rune's command-line companion: a small CLI that runs as an
external process and communicates with a running Rune workspace as a
plugin. It is the fast path to integrating with Rune. Where a full
extension is the right tool when you want to ship UI, register
commands, or run a long-lived process inside Rune, runectl lets a shell
script, a Makefile target, an editor hook, or a one-off command reach
into the workspace without writing any code.
Because it is just a CLI that reads and writes plain text, it composes
with the rest of your environment: pipe its output through jq, grep,
fzf, or anything else, and pipe other tools' output back into it.
Install
runectl is distributed as a Rune package. Install it from the
Rune shell with:
pkg install runectl
(or shell pkg install runectl from the command prompt). Once installed,
runectl is on your PATH inside Rune's terminals.
How it finds the workspace
Commands you run from a Rune terminal target the right workspace automatically, with no flags or configuration. That is also why hooks and scripts spawned by tools running inside Rune just work.
What you can do
Run runectl help to see every command, or runectl <command> --help
for a specific one. The main groups:
| Command | What it does |
|---|---|
runectl notify <level> <message> | Post a Rune notification (error, warn, info, success). |
runectl open <uri> | Open a resource in the workspace. |
runectl uri <path> | Resolve a filesystem path to a workspace URI. |
runectl datadir | Print the extension data directory. |
runectl exec -- <cmd> [args...] | Run a command through the workspace executor. |
runectl editor ... | Read and edit buffer text, cursors, and location lists. |
runectl wm ... | Window-manager actions: focus, split, float, close. |
runectl lsp ... | Language-server queries: definitions, references, diagnostics, rename, symbols, and more. |
runectl syntax ... | Tree-sitter searches and structural queries across the workspace. |
runectl storage ... | Create, read, update, and delete extension documents. |
runectl llm ... | Talk to the workspace's model router. |
runectl mcp | Start an MCP server over stdio exposing Rune's syntax and LSP tools. |
Most commands accept a -F/--format flag to choose the output format:
table (the default, human-readable), json (for piping into other
tools), or a Go template for custom shaping.
Composing with POSIX tools
The point of runectl is to get things out of Rune and into your
environment, and back. The examples below mix and match the command
groups to show the range.
Notify on a long build, from outside Rune. Kick off a build in a plain terminal and have the workspace tab light up when it lands, even if you have wandered off to another workspace:
make build && runectl notify success "build done" || runectl notify error "build failed"
Code-review the buffer you are staring at. Pull the live text of an
open editor with editor print and send it to the workspace's model
router (llm message takes the prompt as an argument), then read the
review back in your terminal:
runectl llm message gemini/gemini-3.5-flash "Review this Go file for bugs and edge cases: $(runectl editor print ./convert.go)"
Turn diagnostics into a commit gate. Count workspace errors and fail a pre-commit hook if any remain:
errors=$(runectl lsp workspace-diagnostics --format json | jq '[.[] | select(.severity == "error")] | length')
[ "$errors" -eq 0 ] || { runectl notify error "$errors errors, commit blocked"; exit 1; }
Ask the language server about a symbol by name. The lsp
subcommands accept a bare symbol, so you do not need to hunt down a file,
line, and column. Read a type's hover documentation:
runectl lsp hover term.Writer
type Writer interface { // size=16 (0x10)
// Context returns the current context of the Writer.
// This context can be used by tui.Components in combination
// with term.Interrupter.Interrupt(context.Context) to disambiguate
// regular calls to Draw from interrupt-driven calls to Draw.
Context() context.Context
// SetCell sets the contents of the given cell location. If
// the coordinates are out of range, then the operation is ignored.
SetCell(Coordinates, Cell)
// UnionAttributes computes the set union between a and b,
// that is overrides a set of attributes at the given coordinates
// that contain all the bit flags set in a, b or both, and uses the color
// defined in b or if not set, uses the color in a.
UnionAttributes(Coordinates, Attributes)
}
Locate where it is defined, list every reference, or find its
implementations the same way. Each prints the matching locations as
<uri> <start-line>:<start-col>-<end-line>:<end-col>, one per line:
runectl lsp definition term.Writer
runectl lsp references term.Writer
runectl lsp implementation term.Writer
Since those are just locations, pipe one into runectl open to open it
as a tab in the workspace:
runectl lsp definition term.Writer | head -n1 | cut -d' ' -f1 | xargs runectl open
Drive the layout from a script. Split the focused window and open a
file beside your code, using wm focus to target the active window:
runectl wm split "$(runectl wm focus)" ./docs/CHANGELOG.md
Run a build in the workspace's environment, not your shell's. Use the workspace executor so the command sees the same tools and environment Rune does:
runectl exec -- go test ./...
Because every command is line- and JSON-friendly, you can drop runectl
into the same pipelines you already use for everything else.