Documentation
Quickstart
Install rune, run your first PTY command, and override the timeout.
Get rune running in under a minute. It's a single Ruby gem with zero runtime
dependencies: nothing to configure beyond an optional fledge plugin install.
Requirements
- Ruby >= 3.0 on
PATH. - No other runtime dependencies: rune is stdlib-only (
pty,timeout,shellwords,optparse,json,io/wait,io/console).
Install
From source (the rune gem name is already taken on the public RubyGems.org
registry by an unrelated package, so a plain gem install rune there installs the
wrong thing, so use one of these instead):
git clone https://github.com/CorvidLabs/rune.git
cd rune
bundle install
ruby bin/rune version Or as a fledge plugin:
fledge plugins install rune
fledge rune run --json git status 1. Run any command through the PTY runner
rune run spawns any CLI command or interactive TUI inside a real pseudo-terminal,
strips ANSI escape sequences, disables pagers, and measures execution time:
rune run -- git status
rune run --json -- npm test
rune run --ndjson -- fledge lanes run check 2. Override the timeout
Every rune run invocation has a 30-second default timeout. Override it with
--timeout=SECONDS, placed before the -- separator so
it isn't mistaken for a flag belonging to the wrapped command:
$ rune run --json --timeout=1 -- sleep 3
{"status":"ok","data":{"command":"sleep 3","exit_code":124,
"clean_output":"\n[rune] Execution timed out after 1 seconds",...}}
A timed-out command returns exit code 124 with a message appended to the captured
output: it's still a normal Result, not an exception.
3. Watch a session live
rune run buffers a command's entire output and only returns once it finishes,
which is great for scripting but no good if you actually want to sit at the keyboard and drive
an interactive program while something else observes the session. rune watch is
built for that: it puts your terminal in raw mode, forwards every keystroke you type to the
child live (including raw escape sequences like arrow keys, not just whole lines), streams
the child's output to your screen as it happens, and logs every chunk as an NDJSON event to a
temp file (path announced once, up front) so an agent can tail -f it live while a
human drives the session:
rune watch -- some-interactive-cli
# [rune watch] live event log: /tmp/rune-watch-12345-1700000000.ndjson
# or point the log somewhere specific
rune watch --log=/tmp/session.ndjson -- some-interactive-cli
Each log line is a JSON object: {"event":"start","command":"...","pid":...},
then one {"event":"output","bytes":N,"text":"..."} per chunk as it streams,
then {"event":"exit","exit_code":N} when the child exits. See the
reference for the full --log=PATH flag details.
4. Parse structured text
Rune::Parsers::TableParser and KeyValueParser turn unstructured
terminal output into Ruby hashes:
require 'rune'
Rune::Parsers::TableParser.parse(<<~TABLE)
NAME STATUS VERSION
fledge-plugin active 1.0.0
TABLE
# => [{ name: 'fledge-plugin', status: 'active', version: '1.0.0' }]
See the CLI & parsers reference for the full flag and
method surface, including TableParser's format: override and its
documented heuristic limitations.