Releases: joshrotenberg/roba
Releases · joshrotenberg/roba
v0.7.1
v0.7.0
Added
- roba config lint -- static config checks with typed exit (closes #266) (#301)
- resolve a short session-id prefix for -c/--resume, git-style (closes #304) (#305)
- default-on single-turn agent advisory + orchestrator hand-off docs (closes #302, #303) (#306)
Fixed
- agent-check stall warning requires resolved write tools (closes #264) (#265)
- derive builtin-subcommand names from the clap tree (closes #268) (#277)
- audit batch -- four verified findings (closes #269, #272, #273, #275) (#278)
- shell-quote alias args interpolated into $() regions -- SECURITY (closes #287) (#290)
- render structured output on the --json-schema default path (closes #280) (#291)
- validate --session-id; document + explain the optional-value swallow (closes #284, #285) (#292)
- --quiet suppresses the spinner, matching its contract (closes #282) (#293)
- dim the [roba] session: line so it reads as metadata, not conversation (closes #294) (#295)
- prompt.rs robustness -- idle-stdin hang, {{VAR}} warn, attach size-guard (closes #288, #286, #271) (#296)
- --show-permissions surfaces --add-dir and resolves allow/deny conflicts (closes #283) (#297)
- remove session_id from the Profile schema -- per-invocation only (closes #270) (#298) (BREAKING)
- show --wait timeout exits 4, not generic 1 (closes #289) (#299)
Maintenance
v0.6.0
Added
- footer model/effort segment + alias-list AGENT column polish (closes #250, closes #251) (#252)
- roba alias draft -- claude-assisted, parse-validated alias generation (closes #254) (#257)
- roba profile draft -- claude-assisted, parse-validated profile generation (closes #255) (#259)
- roba config init -- claude-assisted per-project roba.toml bootstrap (closes #256) (#261)
- --detach -- fire a run that survives the caller, print the handle (closes #260) (#262)
Documentation
- add roberview slide deck (snapshot @ v0.5.0) (#253)
- the survivable hand-off -- --detach + show --wait (closes #258) (#263)
Fixed
v0.5.0
Added
- unambiguous doctor auth + documented --json envelope schema (closes #214) (#215)
- add --session-id pass-through flag (refs #222, #37) (#225)
- add --max-turns + --max-budget-usd guardrail flags (refs #222) (#226)
- add --json-schema validated structured output (refs #222) (#227)
- add --mcp-config + --strict-mcp-config pass-through (refs #222) (#228)
- add --add-dir, --fallback-model, --no-session-persistence (refs #222) (#229)
- add roba worktree list read-only subcommand (closes #217) (#230)
- add roba show read-only result handle + --metrics (refs #220) (#231)
- add roba history --worktree filter (closes #218) (#232)
- uniform {version:1} --json envelope for cost/history/doctor (closes #221) (#233) (BREAKING)
- add roba show --wait poll-until-complete (closes #220) (#236)
- merge piped stdin as context when a prompt is present (closes #242) (#243)
Documentation
- sharpen positioning to claude -p sugar; remove use-roba skill; add cost + worktree notes (closes #223, #224, #209) (#234)
- tighten README to a factual voice (cut fluff, anecdote, prose) (#235)
- README tables -- install options, vs claude -p, agents ABI (clearer scan) (#239)
- add contributor-facing AGENTS.md (#240)
- fix verified-example drift (footer illustration, placeholder quoting, stdin-dropping err.log example, -C/-f ordering note) (#241)
- pre-release help-audit fixes (22 edits incl. two behavior gates) (#244)
Maintenance
v0.4.0
v0.3.1
v0.3.0
v0.2.2
CI
- fix live-test install step failing under bash -e (#176)
Documentation
- slim roba --help into a scannable short/long split (#180)
- make --help a self-contained colored reference (#181)
- consolidate to README + --help + sample + skill; retire the book (#182)
Fixed
Maintenance
- drop MSRV, add rustfmt pre-commit hook (bleeding-edge binary) (#183)
Tests
v0.2.1
Initial public release. The CLI surface, exit codes, config schema,
and --json envelope are intended to be stable across 0.2.x;
breaking changes that landed before this release (e.g. flag
renames, schema renames) are listed under Removed.
Added
Surface
- Prompt sources: positional argument,
-p, --prompt TEXT
(explicit prompt string; mutually exclusive with the positional
argument -- the escape hatch when the positional form would be
ambiguous against an optional-value flag like-cor-w, e.g.
roba -c -p "follow up"), stdin (-or piped),-f FILE,
-e(compose in$EDITOR/$VISUAL),--editor-history N
(last N responses included as reference block in the editor). - Composition:
--prepend FILEand--append FILE
(repeatable),--attach GLOB(repeatable, embeds files with
File: PATHframing),--git-diff,--git-log [N],
--git-status,--var K=Vtemplate substitution. - Output:
--json(versioned envelope on stdout),--quiet
(answer only, no metadata),--code [LANG](extract fenced
blocks),-o, --out PATH(write to file AND stdout, extension
drives format),--stream(TTY-only progress indicator),
--show-thinking(extended-thinking blocks live on stderr,
requires--stream),--trace PATH(writes spawned claude
streaming events to PATH as JSONL; observability handle for
in-flight runs),--echo(print resolved prompt),--plain
(master kill-switch: no markdown render, no color, no spinner). - Dispatch session id on stderr: when the streaming pipeline
is active (--streamor--trace), roba prints[roba] session: <id>to stderr as soon as the spawned session id
becomes known (first event). Gives orchestrators a stable handle
to the session JSONL without requiring--traceto be set
upfront. Suppressed by--quiet. - Sessions:
-c [ID](bare = continue most recent in cwd;
-c IDor-c=ID= resume specific session by id),--fork
(branch a resumed session; requires an explicit id,-c ID --fork),--pick(interactive fuzzy chooser),--fresh(force
new session, cancels env/profile continue),--agent NAME(pin a
specific Claude Code subagent for the run),-w, --worktree [NAME](run in a fresh git worktree; named or auto-generated). - Permissions:
--readonly(Read/Glob/Grep only -- the
default),--writable(adds Edit/Write),--allow-tool TOOL
(repeatable),--deny-tool TOOL(repeatable),--full-auto
(bypass everything),--permission-mode MODE(pass a specific
claude permission mode --plan,dontAsk,auto,
acceptEdits,default,bypassPermissions-- orthogonal to
the allowlist shortcuts; the shortcuts set the allowlist, this
sets the mode),--show-permissions(preview the
effective allow/deny set with per-entry provenance and exit 0
without calling claude),--no-agent-check(suppress the
agent frontmatter permission check). - Agent frontmatter permission check: when
--agent NAMEis
set, roba parses the agent'stools:field from its YAML
frontmatter and warns on stderr if any declared tools are not
covered by the resolved allowlist. GranularBash(git:*)allows
count as covering bareBash. The check is best-effort and
non-blocking -- dispatch proceeds regardless. Suppressed by
--full-auto,--quiet, and--no-agent-check; also
honoured viaROBA_NO_AGENT_CHECKenv var andno_agent_check = truein a profile. Closes the silent partial-capability trap
when a lower-layer profile doesn't grant what the agent needs. - Other dispatch flags:
-C, --cwd PATH(run as if invoked
from a different directory),--model NAME(override the model
per call),--no-retry(disable wrapper-level auto-retry on
transient failures; deterministic for orchestrator scripts),
--effort LEVEL(cost/quality tradeoff --low,medium,
high,xhigh,max),--bare(minimal-overhead mode: skip
hooks, LSP, plugin sync, CLAUDE.md auto-discovery, auto-memory,
and keychain reads -- for non-interactive dispatches),
--system-prompt TEXT(replace the default system prompt) and
--append-system-prompt TEXT(append to it; when both are set,
replace runs first),--dispatch(preset for unattended
file-mutating workers -- implies--full-auto,--worktree,
and--fresh, each individually overridable; warns when
--agentis unset). - Cost in dollars:
roba costnow reports a dollar figure
alongside tokens, computed from a bundled per-model rate table
(src/rates.toml, baked in viainclude_str!). Per-project
breakdown (--by-project) gains aCOSTcolumn and--json
gains acost_usdfield (rollup + per project) plus an
input/output/cacheusagebreakdown. Dollars also appear in
the per-call footer. Override the table with--rates-file PATH
(orROBA_RATES_FILE), or suppress dollars with--no-dollars
when the bundled rates are stale; the table carries anas_of
date surfaced on the report. Models the table doesn't cover are
listed as "rates unknown" rather than costed at a misleading $0. - Subcommands:
roba history [--paths [N]](list recent
sessions;--pathsemits the JSONL session file paths,
most-recent first, for shell composition and corpus mining),
roba last(reprint last run),roba cost [--by-project] [--project SLUG] [--json] [--rates-file PATH] [--no-dollars]
(token + dollar usage rollup),
roba profile {list,show,init,path,active},
roba alias {list,show,path}(user-defined aliases from
roba.toml). see_alsoerror-envelope field: additive v1 field on the
--jsonerror envelope (error.see_also, a list of doc URLs).
Omitted from the JSON when empty, so the v1 shape is unchanged for
errors with no doc pointer.
Config
roba.tomlconfig file with layered resolution:
CLI > env (ROBA_<PARAM>) > active profile overlay >
top-level keys > built-in default > claude default. Project
files walk up to the git root; closer-to-cwd wins per key;
lists concat across files; vars merge per key.- Profiles:
[profile.NAME]overlays in anyroba.toml;
defaultprofile auto-applies when none is named (suppressed
via--no-default-profileorROBA_PROFILE=). - User-defined aliases:
[alias.NAME]shortcuts. Each alias
is invoked asroba NAME [args]and expands to a prompt
template (with positional${1}/${@}, named${pr}via the
argsschema,$$for literal$, and$(command)shell
substitution) plus defaultflags. Aliases can pin a subagent
(agent = "NAME") and override CLI flags. Lookup order:
built-in subcommand first, then alias, then unknown-alias
suggestions (Levenshtein top-3). - Env-var override layer: every CLI knob is settable via
ROBA_<PARAM>(uppercased,-->_, prefixedROBA_).
Lists comma-separated; vars per-key viaROBA_VAR_<KEY>.
Output discipline
- stdout = the answer; stderr = metadata (cost footer, tool calls,
refusal warnings, spinner, errors). - Auto-detect: rich on a TTY, plain on a pipe.
NO_COLOR=1
honored. - Versioned JSON envelope (
--json):- Success:
{ "version": 1, "result": { QueryResult }, "refusal": bool } - Error:
{ "version": 1, "error": { kind, message, exit_code, chain } } - V1 contract: top-level
versionalways present;resultxor
error; inner fields preserved across additive changes;
breaking shape changes bump the version.
- Success:
- Refusal signal (
refusal: boolin the success envelope) for
non-TTY consumers; exit code stays 0 on refusal (the call
succeeded, the heuristic labels the body). - Structured JSON error envelope: runtime failures emit a
parseable{ "error": {...} }object on stderr instead of plain
anyhow text.kindmirrors the typed exit code.
Permissions precedence + cross-layer suppression
- CLI
--readonlyactively suppresses lower-layerwritable = trueandfull_auto = true. CLI--writablesuppresses
lower-layerfull_auto = true. Mutual-exclusion holds across
layers, not just within the CLI parse. allow_tool/deny_toollists accumulate across files;
closer-to-cwd entries concat on top of farther-from-cwd.
CLI / env replace the resolved list; profile concats.- Deny wins when the same tool appears in both lists.
Failure modes
- Typed exit codes: 0 ok, 1 generic, 2 auth (re-login needed), 3
budget exceeded, 4 timeout. - Fail-fast on interactive flags without a TTY:
-e,--pick,
and--editor-history N > 0exit 1 with a clear message
instead of hanging on input that can't arrive. --no-retryflag andROBA_NO_RETRY=1env var disable
wrapper-level auto-retry for the run.
Changed
- Permissions precedence model documented in
README.md
(## Permissions->### Precedence) anddocs/profiles.md.
Spells out the CLI > env > profile overlay > top-level >
built-in default layering, thewritable/full_auto
interaction, the concat-vs-replace behavior for tool lists, and
the deny-wins rule. --quietvs--plainhelp text disambiguated. They're
orthogonal:--quietis the metadata kill-switch (suppress
footer, spinner, tool markers);--plainis the decoration
kill-switch (no markdown render, no color, no spinner).--readonlyis now an active suppressor rather than a
no-op marker. Passing--readonlyon the CLI cancels a
writable = trueorfull_auto = truecoming from a profile
or env var.--streamdocumented as a TTY-only nicety, never
load-bearing on a pipe; the agent-ABI surface (--json, typed
exit codes, error envelope) is the contract for non-TTY
consumers.- Security audit moved off the PR critical path to a daily
scheduled job (.github/workflows/security-audit.yml) + manual
workflow_dispatch. PR CI feedback no longer waits on the
audit's full dep-tree scan. - **BREAKIN...
v0.2.0
Initial public release. The CLI surface, exit codes, config schema,
and --json envelope are intended to be stable across 0.2.x;
breaking changes that landed before this release (e.g. flag
renames, schema renames) are listed under Removed.
Added
Surface
- Prompt sources: positional argument,
-p, --prompt TEXT
(explicit prompt string; mutually exclusive with the positional
argument -- the escape hatch when the positional form would be
ambiguous against an optional-value flag like-cor-w, e.g.
roba -c -p "follow up"), stdin (-or piped),-f FILE,
-e(compose in$EDITOR/$VISUAL),--editor-history N
(last N responses included as reference block in the editor). - Composition:
--prepend FILEand--append FILE
(repeatable),--attach GLOB(repeatable, embeds files with
File: PATHframing),--git-diff,--git-log [N],
--git-status,--var K=Vtemplate substitution. - Output:
--json(versioned envelope on stdout),--quiet
(answer only, no metadata),--code [LANG](extract fenced
blocks),-o, --out PATH(write to file AND stdout, extension
drives format),--stream(TTY-only progress indicator),
--show-thinking(extended-thinking blocks live on stderr,
requires--stream),--trace PATH(writes spawned claude
streaming events to PATH as JSONL; observability handle for
in-flight runs),--echo(print resolved prompt),--plain
(master kill-switch: no markdown render, no color, no spinner). - Dispatch session id on stderr: when the streaming pipeline
is active (--streamor--trace), roba prints[roba] session: <id>to stderr as soon as the spawned session id
becomes known (first event). Gives orchestrators a stable handle
to the session JSONL without requiring--traceto be set
upfront. Suppressed by--quiet. - Sessions:
-c [ID](bare = continue most recent in cwd;
-c IDor-c=ID= resume specific session by id),--fork
(branch a resumed session; requires an explicit id,-c ID --fork),--pick(interactive fuzzy chooser),--fresh(force
new session, cancels env/profile continue),--agent NAME(pin a
specific Claude Code subagent for the run),-w, --worktree [NAME](run in a fresh git worktree; named or auto-generated). - Permissions:
--readonly(Read/Glob/Grep only -- the
default),--writable(adds Edit/Write),--allow-tool TOOL
(repeatable),--deny-tool TOOL(repeatable),--full-auto
(bypass everything),--permission-mode MODE(pass a specific
claude permission mode --plan,dontAsk,auto,
acceptEdits,default,bypassPermissions-- orthogonal to
the allowlist shortcuts; the shortcuts set the allowlist, this
sets the mode),--show-permissions(preview the
effective allow/deny set with per-entry provenance and exit 0
without calling claude),--no-agent-check(suppress the
agent frontmatter permission check). - Agent frontmatter permission check: when
--agent NAMEis
set, roba parses the agent'stools:field from its YAML
frontmatter and warns on stderr if any declared tools are not
covered by the resolved allowlist. GranularBash(git:*)allows
count as covering bareBash. The check is best-effort and
non-blocking -- dispatch proceeds regardless. Suppressed by
--full-auto,--quiet, and--no-agent-check; also
honoured viaROBA_NO_AGENT_CHECKenv var andno_agent_check = truein a profile. Closes the silent partial-capability trap
when a lower-layer profile doesn't grant what the agent needs. - Other dispatch flags:
-C, --cwd PATH(run as if invoked
from a different directory),--model NAME(override the model
per call),--no-retry(disable wrapper-level auto-retry on
transient failures; deterministic for orchestrator scripts),
--effort LEVEL(cost/quality tradeoff --low,medium,
high,xhigh,max),--bare(minimal-overhead mode: skip
hooks, LSP, plugin sync, CLAUDE.md auto-discovery, auto-memory,
and keychain reads -- for non-interactive dispatches),
--system-prompt TEXT(replace the default system prompt) and
--append-system-prompt TEXT(append to it; when both are set,
replace runs first),--dispatch(preset for unattended
file-mutating workers -- implies--full-auto,--worktree,
and--fresh, each individually overridable; warns when
--agentis unset). - Cost in dollars:
roba costnow reports a dollar figure
alongside tokens, computed from a bundled per-model rate table
(src/rates.toml, baked in viainclude_str!). Per-project
breakdown (--by-project) gains aCOSTcolumn and--json
gains acost_usdfield (rollup + per project) plus an
input/output/cacheusagebreakdown. Dollars also appear in
the per-call footer. Override the table with--rates-file PATH
(orROBA_RATES_FILE), or suppress dollars with--no-dollars
when the bundled rates are stale; the table carries anas_of
date surfaced on the report. Models the table doesn't cover are
listed as "rates unknown" rather than costed at a misleading $0. - Subcommands:
roba history [--paths [N]](list recent
sessions;--pathsemits the JSONL session file paths,
most-recent first, for shell composition and corpus mining),
roba last(reprint last run),roba cost [--by-project] [--project SLUG] [--json] [--rates-file PATH] [--no-dollars]
(token + dollar usage rollup),
roba profile {list,show,init,path,active},
roba alias {list,show,path}(user-defined aliases from
roba.toml). see_alsoerror-envelope field: additive v1 field on the
--jsonerror envelope (error.see_also, a list of doc URLs).
Omitted from the JSON when empty, so the v1 shape is unchanged for
errors with no doc pointer.
Config
roba.tomlconfig file with layered resolution:
CLI > env (ROBA_<PARAM>) > active profile overlay >
top-level keys > built-in default > claude default. Project
files walk up to the git root; closer-to-cwd wins per key;
lists concat across files; vars merge per key.- Profiles:
[profile.NAME]overlays in anyroba.toml;
defaultprofile auto-applies when none is named (suppressed
via--no-default-profileorROBA_PROFILE=). - User-defined aliases:
[alias.NAME]shortcuts. Each alias
is invoked asroba NAME [args]and expands to a prompt
template (with positional${1}/${@}, named${pr}via the
argsschema,$$for literal$, and$(command)shell
substitution) plus defaultflags. Aliases can pin a subagent
(agent = "NAME") and override CLI flags. Lookup order:
built-in subcommand first, then alias, then unknown-alias
suggestions (Levenshtein top-3). - Env-var override layer: every CLI knob is settable via
ROBA_<PARAM>(uppercased,-->_, prefixedROBA_).
Lists comma-separated; vars per-key viaROBA_VAR_<KEY>.
Output discipline
- stdout = the answer; stderr = metadata (cost footer, tool calls,
refusal warnings, spinner, errors). - Auto-detect: rich on a TTY, plain on a pipe.
NO_COLOR=1
honored. - Versioned JSON envelope (
--json):- Success:
{ "version": 1, "result": { QueryResult }, "refusal": bool } - Error:
{ "version": 1, "error": { kind, message, exit_code, chain } } - V1 contract: top-level
versionalways present;resultxor
error; inner fields preserved across additive changes;
breaking shape changes bump the version.
- Success:
- Refusal signal (
refusal: boolin the success envelope) for
non-TTY consumers; exit code stays 0 on refusal (the call
succeeded, the heuristic labels the body). - Structured JSON error envelope: runtime failures emit a
parseable{ "error": {...} }object on stderr instead of plain
anyhow text.kindmirrors the typed exit code.
Permissions precedence + cross-layer suppression
- CLI
--readonlyactively suppresses lower-layerwritable = trueandfull_auto = true. CLI--writablesuppresses
lower-layerfull_auto = true. Mutual-exclusion holds across
layers, not just within the CLI parse. allow_tool/deny_toollists accumulate across files;
closer-to-cwd entries concat on top of farther-from-cwd.
CLI / env replace the resolved list; profile concats.- Deny wins when the same tool appears in both lists.
Failure modes
- Typed exit codes: 0 ok, 1 generic, 2 auth (re-login needed), 3
budget exceeded, 4 timeout. - Fail-fast on interactive flags without a TTY:
-e,--pick,
and--editor-history N > 0exit 1 with a clear message
instead of hanging on input that can't arrive. --no-retryflag andROBA_NO_RETRY=1env var disable
wrapper-level auto-retry for the run.
Changed
- Permissions precedence model documented in
README.md
(## Permissions->### Precedence) anddocs/profiles.md.
Spells out the CLI > env > profile overlay > top-level >
built-in default layering, thewritable/full_auto
interaction, the concat-vs-replace behavior for tool lists, and
the deny-wins rule. --quietvs--plainhelp text disambiguated. They're
orthogonal:--quietis the metadata kill-switch (suppress
footer, spinner, tool markers);--plainis the decoration
kill-switch (no markdown render, no color, no spinner).--readonlyis now an active suppressor rather than a
no-op marker. Passing--readonlyon the CLI cancels a
writable = trueorfull_auto = truecoming from a profile
or env var.--streamdocumented as a TTY-only nicety, never
load-bearing on a pipe; the agent-ABI surface (--json, typed
exit codes, error envelope) is the contract for non-TTY
consumers.- Security audit moved off the PR critical path to a daily
scheduled job (.github/workflows/security-audit.yml) + manual
workflow_dispatch. PR CI feedback no longer waits on the
audit's full dep-tree scan. - **BREAKIN...