Power-user workflows¶
This page is for users who want to automate or inspect carrier more deeply.
Script with exit codes¶
carrier run exits with the child command's exit code. That means it can wrap commands in shell scripts, Makefiles, CI-like local checks, and Git hooks without hiding failures.
carrier run go test ./...
case $? in
0) echo "tests passed" ;;
*) echo "tests failed" ; exit 1 ;;
esac
Use --quiet when the wrapper output matters more than carrier status lines:
Use JSON output¶
Most inspection commands support JSON.
carrier last --json
carrier show 42 --json
carrier running --json
carrier history --json
carrier search --json "connection refused"
carrier stats --json
Examples:
carrier last --json | jq -r '.id'
carrier show 42 --json | jq -r '.stdout'
carrier running --json | jq '.[].command'
show --json includes log paths, captured output, metadata, and captured environment when enabled.
Build robust scripts from JSON¶
Prefer JSON over human-readable output for automation. Text output is optimized for terminal scanning and may change formatting; JSON field names are the stable contract.
stderr=$(carrier show "$id" --json | jq -r '.stderr_path // empty')
if [ -n "$stderr" ]; then
less "$stderr"
fi
show --json includes command metadata, argv, cwd, status, duration, output snippets, log paths, Git metadata, labels, session IDs, and captured environment when available.
Keep original argv reliable¶
carrier stores:
- display command in
command - original argv in
argv_json
Display strings are shell-quoted for readability. rerun uses argv_json, not the display string.
Use rerun safely¶
Rerun uses original cwd. If that directory was deleted or changed, behavior may differ.
Edit before rerun:
--edit opens a JSON array in $EDITOR or $VISUAL. The command is aborted if the file is unchanged, invalid JSON, or an empty array.
Triage with the TUI¶
The text UI is useful when the question is "which run was that?" rather than "show run 42".
Useful workflow:
- Filter by a failing command, status, cwd, or label.
- Preview stdout/stderr in the right pane.
- Label the run if it is part of an incident or benchmark.
- Press Enter to rerun the selected command from its original cwd.
Deletion in the TUI removes the run metadata and log files, then prunes unused captured environment rows.
Build interactive pickers¶
Use history with fzf:
Use JSON when you need stable parsing:
Label important runs¶
Labels are useful for deploys, incidents, benchmark baselines, and manual checkpoints.
Labels are stored in SQLite and appear in history, JSON views, and show.
Inspect storage directly¶
Metadata DB:
Example:
sqlite3 ~/.local/share/carrier/carrier.db \
'select id,status,command,cwd,exit_code from runs order by id desc limit 10;'
Warning
Direct DB edits can break carrier. Read-only queries are safest.
Use output paths¶
show --json includes log paths:
Use paths to pass logs to other tools:
Compare two command outputs:
diff -u \
"$(carrier show 41 --json | jq -r '.stdout_path')" \
"$(carrier show 42 --json | jq -r '.stdout_path')"
Tune output retention¶
Set log cap:
Set cleanup policy in a cron job:
Or keep a fixed history size:
Disable redaction for one run¶
Use this only when you are certain output does not contain secrets.
Inspect captured environment¶
Environment capture is enabled by default.
Values are redacted on display. To disable capture entirely:
Use timeouts¶
carrier run can stop commands that hang:
Carrier sends an interrupt first. If the process does not exit, it is killed.
Watch with filters¶
watch runs once immediately, then re-runs on matching file changes:
It recursively watches the current directory and skips .git, node_modules, and vendor.
Watch notes:
- matching is applied to the changed file's base name, not the full path
.git,node_modules, andvendorare skipped during recursive setup- debounce defaults to
200ms; use--debounce 0sonly when immediate reruns are more important than duplicate events - each rerun creates a normal run record, so cleanup policies still apply