A Stop hook for unfinished Claude Code turns
This walkthrough was generated with AI from Flipback’s published code, replay results and offline tests. Ask a coding agent for three things and you sometimes get one, plus a message that sounds like all three: > Add
This walkthrough was generated with AI from Flipback’s published code, replay results and offline tests.
Ask a coding agent for three things and you sometimes get one, plus a message that sounds like all three:
> Add a slugify() helper to src/text.ts, write tests for it, and update
the README with an example.
Added slugify() to src/text.ts. It lowercases, strips punctuation and
collapses whitespace into hyphens.
Let me now write the tests and update the README.
[turn ends]
Nothing in that message is false. There are also no tests and no README example, and nobody is going to write them, because the turn is over.
What flipback does
flipback is a Claude Code plugin that checks for unfinished work at the end of a turn. When it finds a clear unfinished step, it can ask the agent to continue. In the example above, its reminder could look like this:
The request had three parts and you did one. Your last message
announced the rest, but no tool calls followed. Write the
tests for slugify(), then add the README example.
Use /goal for a big job with a checkable finish line. flipback checks everyday turns where nobody set one. It returns immediately when Claude Code marks a Stop hook continuation as already active.
How it works
It is a Stop hook. When a turn ends, hooks/flipback.mjs reads the end of the transcript: your latest request, the tools used since, and the agent's final message. Then:
- It lets the agent stop with no model call if a stop hook already sent it back, a subagent is due back, the final message is under 40 characters and nothing failed, or you just said stop.
-
A free local check looks for signs of an early stop: the last tool call failed, the message announces work ("let me now run..."), asks you something ("should I..."), mentions a TODO or a placeholder, has unchecked
- [ ]boxes, or files were edited and nothing was run. No match, and the agent stops. -
Only then a small model judges.
claude -p --model haikugets your request, the names of the tools used and the final message. The judge has no tools, no MCP servers and no hooks, and its session is not saved. - Only a clear "incomplete" blocks. The hook exits 2 with the judge's message. A timeout or no answer lets the agent stop.
The agent can stop if the work is done or only a person can unblock it. Claude Code resets its count of consecutive Stop continuations on tool calls. If you combine multiple hooks in an unattended print-mode run, set a finite --max-turns. See the Stop hook reference for the continuation flag and cap.
Measured on real sessions
The replay covered 823 turn endings from 262 of my interactive Claude Code sessions. Flipback’s local check selected which turns went to the Haiku judge. A second model, Claude Opus 5.5, reviewed the 36 turns Flipback would have continued.
- The local check let 86% of turn endings skip the Haiku judge.
- flipback would have asked for another turn on 36 endings (4.4%). The second model marked 30 of those as unfinished (83%). One: "Now let me verify the rest of the screens render correctly, then publish." (turn ends)
- The second model marked the other six as unnecessary nudges. Examples included a token only the person could enter and a status run that had already logged everything.
Try it for one session
With Node.js 18 or newer and the signed-in claude CLI on your path:
git clone https://github.com/fainir/flipback
cd flipback
node --test
claude --plugin-dir .
The tests use a stand-in for the judge, so they run without a model call. They cover a turn that should continue and a turn with a Stop hook already active. In the trial session, try a small task in a scratch folder:
Create
slug.mjswith aslugifyfunction. Addslug.test.mjsto check thatHello, World!becomeshello-world. Runnode --test slug.test.mjsand report the exit status.
Check that both files exist and that the test ran. If Flipback intervenes, compare its reminder with the step Claude still needed to finish.
To install it for future sessions:
claude plugin marketplace add fainir/flipback
claude plugin install flipback@flipback
The plugin uses your existing Claude sign-in. Most turns never make a model call. A flagged turn can make one Haiku request under that account’s usage or billing terms.
Limits
- It is tuned to stay quiet, so it misses some. In a random 50 of the turns the local check let through, 6 were also unfinished, mostly ones whose last message did not announce the next step. For a job that must finish, set a
/goal. - The measurement is one person's sessions, heavily autonomous ones, and the labels come from a model. Turns still waiting on a subagent or other background work were left out.
- Windows is untested.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.