Skip to main content

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:

CommandWhat 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 datadirPrint 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 mcpStart 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.

Ask Rune Agent