shorter is a Bash-wrapper alternative to command output optimizers such as
rtk-ai/rtk. RTK uses a Rust proxy plus agent-specific
rewrite hooks. This project keeps the setup smaller: install shell wrapper functions,
add one uniform flag when output should be compact, and give the agent a preference
string telling it when to use that flag.
The filtering itself is RTK-style: command-aware filters run first for high-value commands, then generic line/byte compaction runs as a fallback.
./install.shThe installer copies:
bin/shorterto~/.local/bin/shortershell/shorter.shto~/.local/share/shorter/shorter.sh- a small source snippet into
~/.bashrcor~/.zshrc
It also installs a shorten compatibility symlink so older shell sessions keep
working until they are reloaded.
Useful installer options:
./install.sh --no-rc
./install.sh --shell bash
./install.sh --rc ~/.bashrc
./install.sh --agent-preferences
./install.sh --uninstallAfter installation, the shell wrappers do not change normal command output:
git diff
cat src/app.tsAdd --shorten when you want compact output:
git diff --shorten
cat src/app.ts --shorten
rg "TODO|FIXME" . --shorten
pytest --shortenThe wrapper removes the --shorten flags before running the real command, captures
stdout and stderr, applies semantic filters when available, then applies generic
compaction:
- compacts
git status,git log,git diff, and common git actions - groups
grep/rgmatches by file - groups
find/fdresults by directory - trims listing output from
ls/tree - keeps the useful failure/error lines from common test and diagnostic commands
- strips known boilerplate from
make,terraform,pre-commit,curl,wget - collapses repeated identical lines
- collapses long blank runs
- limits output by lines and bytes, preserving the beginning and end
- optionally compacts full-line comments when requested
You can also call the executable directly without shell wrappers:
shorter git status
shorter cat src/app.ts --shorten-comments=compact$ git status --shorten
* main
M src/app.py
?? scratch.txt
$ git diff --shorten
diff --git a/src/app.py b/src/app.py
--- a/src/app.py
+++ b/src/app.py
@@ -9,3 +9,5 @@ def noisy():
+def dirty_change():
+ return "dirty TODO needle"
summary: 1 file(s), 1 hunk(s), +2 -0
$ rg TODO . --shorten
./README.md
3: This README has TODO references.
./src/app.py
7: # TODO: simplify this helper
13: return "dirty TODO needle"
./src/util.ts
1: // TODO: convert to stricter types
summary: 5 match(es) in 4 file(s)
$ npm test --shorten
> vitest run
FAIL src/app.test.ts > adds numbers
AssertionError: expected 2 to be 3
Test Files 1 failed | 2 passed
Tests 1 failed | 9 passed
$ cargo test --shorten
---- parser::tests::bad stdout ----
thread 'parser::tests::bad' panicked at src/lib.rs:10:5: expected true
test result: FAILED. 2 passed; 1 failed; 0 ignored
$ terraform plan --shorten
Terraform will perform the following actions:
# aws_instance.web will be created
+ resource "aws_instance" "web" {}
Plan: 1 to add, 0 to change, 0 to destroy.
$ pre-commit --shorten
Trim Trailing Whitespace.................................................Passed
Check Yaml...............................................................Failed
- hook id: check-yaml
- exit code: 1
The table below comes from a deterministic side-by-side fixture using RTK 0.42.0
and shorter 0.1.0. exact means byte-for-byte identical output in that fixture;
similar means the same important facts with different formatting.
| Command | RTK bytes | shorter bytes | Result |
|---|---|---|---|
git status |
36 | 36 | exact |
git diff |
176 | 190 | similar |
git log -n 3 |
108 | 66 | similar |
read file / cat file |
255 | 255 | exact |
grep TODO . |
244 | 265 | similar |
find "*.py" . |
39 | 43 | similar |
ls -la |
50 | 48 | similar |
diff file1 file2 |
474 | 457 | similar |
pytest |
152 | 34 | similar |
npm test |
159 | 159 | exact |
cargo test |
167 | 167 | exact |
make |
18 | 18 | exact |
terraform plan |
163 | 163 | exact |
pre-commit |
204 | 204 | exact |
These flags work with every wrapped command:
--shorten
--no-shorten
--shorten-lines=N
--shorten-bytes=N
--shorten-comments=keep|compact|strip
--shorten-mode=auto|plain|code|diff|test
--shorten-stats
--shorten-raw
Defaults can be configured with environment variables:
export SHORTER_LINES=120
export SHORTER_BYTES=12000
export SHORTER_COMMENTS=keep
export SHORTER_AUTO=0Set SHORTER_AUTO=1 if you want installed wrappers to compact output even when the
command does not include --shorten.
The old SHORTEN_* environment variables are still accepted as fallbacks, but new
configuration should use SHORTER_*.
The default wrapper list is:
cat head tail sed awk grep egrep fgrep rg find fd ls tree git gh glab diff pytest py.test python python3 npm npx pnpm yarn bun jest vitest playwright cargo go make cmake ninja docker docker-compose kubectl helm terraform tofu aws curl wget jq yq ps df du wc env psql ruff mypy eslint tsc prettier next prisma golangci-lint rubocop rspec rake bundle dotnet mvn gradle gradlew shellcheck pre-commit
Override it before sourcing the shell integration:
export SHORTER_ALIAS_COMMANDS="cat rg git pytest"
. ~/.local/share/shorter/shorter.sh
shorter_aliasesDespite the function name, shorter_aliases installs wrapper functions rather than
aliases. That preserves native tab completion in zsh: git <TAB> still uses the
normal git completion while git status --shorten still routes through shorter.
In bash, shorter and the old shorten compatibility command get basic
command-name completion; existing per-command completions generally stay attached
to the original command names.
Print the preference string with:
shorter --agent-preferencesCurrent string:
When shell command output is likely to be noisy, prefer the installed shorter wrappers and add the uniform `--shorten` flag to the command. Examples: `git status --shorten`, `git diff --shorten`, `rg "pattern" . --shorten`, `pytest --shorten`, `npm test --shorten`, `terraform plan --shorten`. If wrappers are not loaded in the current shell, call `shorter <command> ...` instead, for example `shorter git diff`. The wrapper removes `--shorten` before running the real command, applies RTK-style command-aware filters when available, then falls back to generic line/byte compaction. Use `--shorten-lines=N` or `--shorten-bytes=N` for tighter limits. Use `--shorten-comments=compact` when reading source files where comments are not important. Use `--shorten-raw` to skip semantic filters but keep generic limits. If exact raw output is required, omit `--shorten` or add `--no-shorten`.
Put that in whichever agent preference file or settings UI you use.
The wrapper captures stdout and stderr together before filtering, so it is best for
agent-facing command output rather than interactive commands. If a real command needs
to receive an argument named --shorten, place it after a literal --.
This is not a line-for-line port of RTK internals. It intentionally keeps the shell wrapper model and implements the same categories of behavior with portable Bash/awk filters.