
Built a terminal agent. you say what you want in english; it proposes ONEshell command, explains it in a line, waits for your
y. destructive stuffgets caught before it ever runs. small, local, no servers.What it is / who it's for
shell-sage is a command-line agent for the dev who knows the command exists
but can't recall the exact flags.
undoing a git commit without nuking the work. you type the intent, it hands
back the precise incantation — and the reason it chose it.
but can't recall the exact flags.
tar extract order. find + -exec.undoing a git commit without nuking the work. you type the intent, it hands
back the precise incantation — and the reason it chose it.
it is not a chatbot and not an autopilot. the whole design is one
request → one vetted command → your explicit call. the agent proposes; the
human disposes. that boundary is the point.
request → one vetted command → your explicit call. the agent proposes; the
human disposes. that boundary is the point.
1
2
3
4
5
6
you ──"undo my last commit, keep the changes"──▶ sage
│ bedrock
▼
$ git reset --soft HEAD~1
moves HEAD back one, keeps your edits staged
run it? [y/N] _How i built it
one file.
sage.py, ~190 lines of python, zero framework.- brain: amazon bedrock via the
converseapi (bedrock-runtime). the
system prompt pins the model to STRICT json —{"cmd": "...", "why": "..."}
— so i parse a contract, not prose. default model is claude 3.5 haiku:
cheap, fast, plenty smart for "english → one command." - auth/runtime: plain
boto3. a one-time first-run wizard asks region,
model id, optional profile, writes~/.shell-sage.iniat chmod 600. no
keys in code, no env gymnastics. - no infra: no cloudformation, no api gateway, no lambda, no bucket.
pay-per-call bedrock and your own terminal. nothing to deploy, nothing to
tear down, nothing billing while you sleep.
aws services/tools used: amazon bedrock (claude 3.5 haiku via
boto3, standard aws creds/sso. that's the entire footprint.
converse),boto3, standard aws creds/sso. that's the entire footprint.
the agent loop: read intent → send OS + request to bedrock → parse json →
render command + why → local danger scan → confirm →
render command + why → local danger scan → confirm →
subprocess.run.The delightful detail
the one thing i'm proud of: every command is explained and defused before it
can touch your machine. two layers.
can touch your machine. two layers.
- the model must return a one-line why beside each command, so you never
paste a black box. you seegit reset --soft HEAD~1and "keeps your
changes, drops the commit." - a local regex guard runs before any execution —
rm -rf /,mkfs,dd if=, fork-bombs,chmod -R 777 /,git push --force,DROP TABLE.
a normal command needs oney; a flagged one refuses to auto-run and
demands you typeRUNin full. bare-enter always means No.
how i know it worked: i threw
proposed a destructive
have. for the friendly path,
returned a clean
the first try.
delete everything in root at it. the modelproposed a destructive
rm, the local guard caught it, printed⚠ looks destructive. refusing to auto-run, and sat waiting for a typedRUN i never gave. the dangerous path is gated by muscle memory you don'thave. for the friendly path,
python sage.py "find files over 100mb here"returned a clean
find . -type f -size +100M with a plain-english gloss onthe first try.
proof it works
- repo: https://github.com/dpallavi635/shell-sage
- run it:
pip install -r requirements.txtthenpython sage.py - screenshot:

no deploy step, no url to babysit. clone,
bedrock region you have access to, and talk to your shell in english — with a
seatbelt on.
pip install boto3, point it at abedrock region you have access to, and talk to your shell in english — with a
seatbelt on.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article