You ask Claude Code for ten improvements to your project. It answers with a tidy numbered list. Then the real work starts: you scroll, you type "do 1 and 3, skip 2 because we tried that, maybe 5 later," and you hope the agent maps your sentence back to the right items. Next week, in a new session, it proposes number 2 again.
So I built ar-board, a Claude Code plugin that turns the list into cards on a local page. You judge each card with one key (approve, reject, or maybe) and a short reason. The agent gets back an exact list of what you approved, and your reasons go into a preferences file it reads before it proposes anything next time. One Python file, standard library only, MIT licensed.
The panel opens in English, and an EN/PT toggle in its header switches it to Portuguese. The cards are in whatever language you and the agent are using. You can try a sketch of the board in your browser before installing.
What it does
You ask in plain language, for example: "Give me 10 architecture improvements as an AR board." Claude then:
- reads your past preferences from
.ar-board/preferences.md, so it knows which patterns you have already rejected; - writes the proposals to
batch.jsonand starts the panel on127.0.0.1; - waits while you judge each card from the keyboard (
Aapprove,Rreject,Mmaybe) and add a comment saying why; - reads your decisions with the
summarycommand, acts only on the approved items (anything rejected, marked maybe, or left undecided counts as "no"), and asks you to confirm the preference rules it inferred from your comments.
Each card carries more than a title: what changes, why, a risk level, and any extra fields the agent wants to show. Pressing the same key again undoes the decision, and holding a key down never judges several cards in a row.
Install
Inside Claude Code:
/plugin marketplace add dvwinck/capybara-toolbox
/plugin install ar-board@capybara-toolbox
Restart Claude Code, then ask for an AR board or run /ar-board:ar-board. Add .ar-board/ to your .gitignore, because your comments may contain internal details.
Bonus: question-board
The same plugin also ships question-board, a one-screen form for when the agent needs several independent answers before it can continue. Keys 1 to 9 pick an option; a recommended option is marked but never preselected.
How it's built
One file, no dependencies. Validation, the HTTP server, the CLI, and the HTML/CSS/JS page all live in ar_board.py (1,512 lines, much of it the embedded page). There is no pip, no Node, and no outbound network traffic: the only socket is the panel's listener on loopback. It needs Python 3.9 or later.
The channel between agent and panel is a file. The panel writes decisions.json atomically: a private temp file with mode 0600, moved into place with os.replace. The agent reads the file with the wait and summary commands, which ignore any file from another batch or round, so a previous round's approvals never reach it.
Rounds, not overwrites. A refinement round keeps the same batch_id and sets round: N+1. When the server starts the new round, it archives the old decisions as decisions.rN.json and never overwrites an earlier archive.
It learns from your reasons, but only with your sign-off. The agent appends your comments to preferences.md, quoting what you said and marking its own interpretations as "to be confirmed." Only the rules you confirm become firm constraints for future batches.
Hardened, even on localhost. The panel binds 127.0.0.1 on a free port the OS assigns, with a fresh 128-bit token per run, required on every request. Writes must carry the token in an X-AR-Token header, which a cross-origin page cannot send without a CORS preflight the server never answers. Any Host other than 127.0.0.1 or localhost is rejected, to block DNS rebinding. Card text and comments are HTML-escaped, and the page's CSP forbids framing. Images get a sandbox CSP, so an SVG cannot run scripts.
Custom labels and a second press for risky cards. A board can rename the three decisions and give each a tone (green, amber, or red), for example Delete / Keep / Later, with Delete in red. A card can also require a second press before an approval counts. This guards against a reflexive keypress; it is not a security boundary. A sibling plugin, tidy-board, uses this to delete stale git branches, worktrees, and stashes: anything not provably merged needs the second press and gets a backup first, and every approved item is rechecked right before deletion.
No localhost? Use offline mode. In a cloud or remote session, the build command writes a self-contained board.html instead. You make your decisions in that file and paste the result back into the chat.
Tested. The ar-board suite has 249 tests, including security regression tests for the token, the Host check, path traversal, a symlink that points outside the batch folder, and a symlink planted at the temporary file used to save decisions.json. CI runs them on Ubuntu and macOS with Python 3.9, 3.11, 3.13, and 3.14.
Limitations
- It is a single-user tool for your own machine. The token sits in the URL, so it ends up in your browser history. There is no HTTPS; traffic stays on loopback.
- "Act only on what I approved" and "learn from my comments" are instructions to the model, not code. The board makes your decisions unambiguous; it cannot force the agent to follow them.
- Windows is not tested yet.
Credits
The "AR board" idea comes from the video Minha NOVA SKILL Favorita do Claude Code by the Maestros da IA channel. This is an independent implementation: it uses no code or material from the original skill and is not affiliated with the channel.
ar-board is part of Capybara Toolbox, a small set of MIT-licensed Claude Code plugins. If it breaks for you, please open an issue. And a question for the comments: what do you do today when an agent hands you ten proposals at once?

Top comments (3)
This is exactly the friction I've been feeling — typing "do 1 and 3, skip 2" gets old fast. Love that you built a proper board for it instead of just accepting the back-and-forth.
One thing I learned the hard way: an approval UI only actually saves time if the agent remembers what you rejected. Otherwise you're re-approving the same bad suggestion every session. What worked for me was persisting rejections as a tiny deny-list right in the repo (just a JSON file the agent reads at startup). Keeps it portable and versioned.
Also, keep the board to one decision at a time. Throwing five options at once creates approval fatigue real quick — you start rubber-stamping just to get through it. Single choice, clear context, move on. Way smoother.
Great points! Thanks for sharing!
Before building a batch, the skill tells the agent to check the rejection file and avoid patterns that were already rejected. But it's still pretty limited. Now that you mention it, evolving this into a proper persistent deny-list makes a lot of sense.
As for approval fatigue, yeah, that's something I'm still struggling with. I sometimes catch myself just clicking through to keep things moving, without really thinking through the options. And, unsurprisingly, that's already come back to bite me a few times when I had to revisit bad decisions.
I haven't really cracked this one yet. Maybe it's not just about reducing the number of decisions, but also figuring out how to keep the UI from nudging us into mindlessly rubber-stamping stuff.
This is such a practical idea. I like that it’s not just about making approvals easier, but also helping the agent learn from past decisions. The simple keyboard workflow is a nice touch too. Great work keeping it lightweight and dependency-free!