Until now bleep was something you typed after a command failed. This release
is about the moments before and around that: the return key, the coding agent
running commands for you, the repository you just cloned, the corrections you
have been making by hand for years. It is the largest release since the fork,
and it went through a review of the whole codebase before it shipped.
uv tool install --upgrade thebleep # or: pipx upgrade thebleepCorrecting without typing bleep
eval "$(thebleep --ambient)" binds return in zsh and fish to one check: a
first word the shell has never heard of is offered to the command-only rules
before anything runs. A correction replaces the line, with a message
underneath saying what changed, so return runs the fixed command and undo puts
yours back. Known commands are accepted exactly as before, by whatever return
was bound to. In bash the not-found handler runs in a subshell, so the fix
waits in readline at the next prompt instead. PowerShell gets both this and the
Esc Esc inline edit the other shells already had.
The check has to be fast enough that nobody notices it. Starting Python costs
about sixty milliseconds; thebleep --serve keeps one warm, listening on a
Unix socket in a directory only you can enter, and answers in a few
milliseconds. It runs nothing, keeps nothing between questions, and leaves
after half an hour idle. With warm_server = True zsh's bindings use it through
zsh/net/socket and start it when it is not there. Off by default.
Running without asking, when there is enough to go on
auto_run_confidence = 0.9 lets the first suggestion run unasked when its
confidence reaches the threshold and the risk scan finds no sudo, no
destructive command, no safety bypass and no side effect. The scores are the
ones ? and --json already showed: a correction you taught, a rule that read
the tool's own output, a rule that saw the command alone. Everything else asks
as before, and the line printed under an unasked run says what let it through.
Off by default, and a correction that came with a repository is never let
through, for the reason below.
Suggestions as a list
The prompt now shows up to three rows with the chosen one marked, the words
that differ from what you typed highlighted, and each row's confidence and its
basis at the right edge. The first row still appears as soon as the first rule
answers. When nothing is offered, a dim line says how many rules were tried
and how many needed output that was not read, so "no correction" is no longer
silent about why.
Rules that read the machine rather than the message
not_on_path—cargo buildwhere cargo is in~/.cargo/binand the
shell does not know. Installers' directories, language version managers'
shims, Homebrew, snap, flatpak and the project's ownnode_modules/.bin,
.venv/binandtarget/debugare looked in; the rule offers the command
with the path written out and the same command with the directory put on
PATH, in your shell's syntax. An exact name offPATHbeats a guess one
edit away, so it runs beforeno_command.wrong_directory— the command was right and the directory was not.
When git, npm, make, cargo, mvn, docker compose, just, uv, poetry, terraform
and friends report there is no project here, the rule looks around for the
one that has the project file, and where a script or target was named, the
one that declares it, and offerscd app && npm run build.- Vocabulary from the manual. Long options and subcommands are read from
the program's man pages and installed fish completions, cached.option_typo
uses it for the parsers that print nothing worth reading (Go'sflag, Ruby's
optparse, Perl's Getopt::Long, argparse), sogit log --onelienis no
longer a known miss and--helpis run less often.unknown_subcommand
uses the same source forgo biuldanddocker psswhen the program named
the broken word and offered nothing.
Learning from what you already know
--learn-from-historyfinds the corrections you have been making by
hand, a line followed by the same line with one word fixed, in your shell
history, shows each with how often it was seen, and learns the ones you say
yes to.- A repository can ship corrections.
.thebleep/corrections.jsonat the
root, a list ofbefore/afterpairs, applies below that root for everyone
who clones it. Data, not code, and?names the file as the source. A
shipped pair may only change the program to a bare name already onPATH,
and trust mode never runs one unasked: a clone must not be able to turn a
typo into running its own script. --statscounts what was accepted, edited and run unasked, the slips
fixed most often and the rules that fixed them. Local, bounded, and
--stats resetstarts over.
For the agents running your commands
thebleep --hook claude-code and --hook cursor print hook settings. Before
an agent's shell command runs, a misspelled program is refused with the
correction as the reason, so the agent re-issues it fixed instead of spending
a turn on command not found. After a command fails, the suggestion, its
confidence and any --why diagnosis are attached beside the result.
THEBLEEP_HOOK_DECISION chooses between refusing, asking and only annotating.
--why can now also ask a program of your choosing (why_command) when its
own deterministic diagnosis abstains, and marks the answer as coming from a
non-deterministic source. Never used by the API or MCP.
Instant mode reads the terminal's own marks
The recording is now read by the OSC 133 semantic prompt marks terminals use
for prompt navigation, which the shell hooks emit for bash and zsh and fish 4
emits itself. Output boundaries are exact, no prompt has to be recognised, and
a prompt framework that rebuilds PS1 no longer switches instant mode off.
The review
Every file in the codebase was read before this release, and what came out is
in the changelog under Fixed. The ones worth knowing about: the tmux, kitty,
WezTerm and Zellij pane readers looked for a bare prompt after the failed
command and never found one, because the capture happens while bleep itself
is on that line; long_form_help repeated the tool's Try 'x --help' line
into the suggestion verbatim, which a build whose output somebody else controls
could have abused; some thirty rules raised on odd output where they should
have said nothing, which the framework hides, so they looked like rules with
nothing to say; and the test suite wrote into the real ~/.config/thebleep.
Full detail: CHANGELOG.md