rubber-duck plugin for Claude Code

It knows the answer. It won't tell you.

A debugging companion that asks one question at a time until you get there yourself.

/rubber-duck:rubber-duck
You

My React component re-renders on every keystroke and it's slow.

Duck

When you say it re-renders — which component, the one with the input, or its children?

You

The children. The list below the input.

Duck

What props are you passing down to that list?

You

An array I filter, and an onSelect handler.

Duck

Of those two, which has the same value across renders, and which is built fresh each time?

You

…the handler is an inline arrow function. It's new every render.

Duck

That's it — a new function reference makes the memoized child see changed props. You found it.

The trade

What does a fast answer cost you?

By default, coding agents solve. You describe a bug and the fix arrives before you have finished thinking about it. That is genuinely useful, and it is also how you end up shipping code you could not have written and cannot debug. Rubber Duck inverts the role. It listens, it asks, it refuses — until you say the thing yourself.

Without

My function returns undefined.

You're missing a return after the loop. Here's the corrected version: …

With

My function returns undefined.

What does the last line of your function return?

Three levels

How much help do you actually want?

The axis is scaffolding, not difficulty. Pass a level when you start, or say so mid-conversation — go ultra, modo lite — and it holds until you change it again.

lite

Learning to code

Warm. Every question says why it is being asked — never what the cause might be. A hint after one stuck exchange.

"A function can hand back undefined for a few different reasons, so let's look at yours before guessing. What does the last line do?"

full

The default

Neutral. Questions stand on their own, no padding. A hint after three exchanges with no progress.

"What does the last line of your function return?"

ultra

You want friction

Terse. No hints, ever — only sharper questions, until you land it or you leave.

"What's the last thing that function does?"

Measured, not asserted

Does telling a model to shut up actually work?

Sixteen cases, run twice against claude-opus-5: once with the skill, once with no system prompt at all. Each case replays a real conversation and grades the reply that follows — mechanical properties in code, judgment calls with an LLM judge. The distance between the two dots is the whole argument.

0% 50% 100%
With the skill, every gradeable assertion: 44/44 Control: 24/43

Pass rate per gate. The control's denominator is smaller because one case came back stop_reason: refusal — the safety classifier declined the prompt, so there was no reply to grade, and refusals are skipped rather than scored as failures.

The row that matters is the first one. The control is not broken when it fails that — solving is what a coding agent is for. The point is that you can now choose.

What these numbers don't tell you
  • The judge for the semantic gates is the same model family being graded. The mechanical gates — question count, code blocks, language — are decided in code and aren't subject to that.
  • The control replays the same transcript, in which the assistant has been asking Socratic questions. Imitation can pull it toward the same style, which shrinks the measured gap rather than inflating it.
  • One criterion was rewritten mid-benchmark, after both arms were marked down for following the spec. It was fixed and that case re-run for both arms rather than dropped. The whole exchange is in the commit log.
  • Sixteen cases is small. It catches whether a behaviour holds at all, not how often it holds at the margins.

Two commands

Where do you want to start?

Requires Claude Code. Restart it once after installing, and the duck shows up under /rubber-duck:.

$claude plugin marketplace add centsandcode/rubber-duck
$claude plugin install rubber-duck@rubber-duck
/rubber-duck:rubber-duck
Start. Add lite, full or ultra to pick a level.
/rubber-duck:duck-off
Stop, and get the answer you were working toward.
/rubber-duck:help
The one-screen reference, in whatever language you've been writing in.

It never activates on its own. "I'm stuck" is an ordinary question and gets an ordinary answer — the duck only shows up when you ask for it. Using Cursor, Copilot or Windsurf instead? Drop AGENTS.md into your project and the same rules apply.