Your agent writes SDK code from memory. That memory is eighteen months old.
Airblander blocks the write until the agent has fetched today's docs — every session, before a single line. Not docs from yesterday. Not docs it vaguely remembers. Docs it pulled ten seconds ago.
The whole idea
Same prompt — "add Stripe payments." The only thing that changes is whether the agent looked things up first.
✗ from memory stripe.charges.create({ amount: 2000, currency: "usd" })
// Charges API — no 3-D Secure, no SCA. Ships, then fails in the EU.
✓ after reading docs stripe.paymentIntents.create({ amount: 2000, currency: "usd" })
// current. handles 3DS/SCA. the thing you actually wanted.
The model isn't wrong on purpose. It's confidently repeating an API that was current when it was trained. Airblander makes it check before it writes — so you get the second line, not the first.
What you actually see
You say "add Twilio SMS to this endpoint."
Instead of guessing at RestClient (gone in v4), the agent
hits a wall:
airblander: BLOCKED — docs not yet fetched for: twilio
Fetch current docs before writing SDK code:
• twilio: fetch https://www.twilio.com/docs
or use Context7 query: "twilio"
After fetching, re-attempt the write.
It fetches the docs, learns what's current, and writes the file. One extra step you never have to ask for — and consistently correct code on the other side.
How it works
No model, no magic — three small hooks and one state file. Reading your prompt, gating the write, clearing the SDK once docs are in.
You type: "add stripe payments"
↓
resolve.js → sees "stripe" in your message, marks it pending
↓
Agent tries to write payment.ts (import stripe ...)
↓
detect.js → stripe not cleared → BLOCKED (exit 2)
↓
Agent fetches stripe.com/docs
↓
clear.js → stripe marked cleared ✓
↓
Agent writes the file → allowed
State resets every session. Docs fetched yesterday don't count — the library may have
changed overnight. SDKs not in the watchlist are still caught, and you can add them
permanently with /airblander-add.
Install
Two commands in your terminal. Done.
claude plugin marketplace add bardock-2393/airblander
claude plugin install airblander@airblander
Commands
| Command | What it does |
|---|---|
/airblander |
Toggle enforcement on/off for this session |
/airblander-add <sdk> <url> |
Add a new SDK to the watchlist |
/airblander-status |
Show which SDKs are cleared this session |
/airblander-watchlist |
List all tracked SDKs |
/airblander-review |
Scan your codebase for SDK imports and report coverage gaps |
/airblander-deprecated |
Detect deprecated API patterns across the codebase |
/airblander-update <sdk> |
Re-fetch docs for an SDK mid-session |
/airblander-help |
Quick reference |
Watched SDKs · 9
| SDK | Keywords | Deprecated patterns caught |
|---|---|---|
| anthropic | claude, anthropic, claude api |
completions.create, claude-2, claude-v1
|
| openai | openai, openai api | ChatCompletion.create, text-davinci-003 |
| stripe | stripe, stripe api | charges.create, sources.create |
| twilio | twilio, twilio sms, twilio voice | Twilio.RestClient( |
| google-genai | gemini, google genai | chat-bison, gemini-pro (1.0) |
| aws-bedrock | aws bedrock, bedrock | anthropic.claude-v2, claude-instant |
| livekit | livekit, livekit-agents | RoomServiceClient( |
| pipecat | pipecat, pipecat-ai | — |
| azure-communication | azure communication, acs sms | @azure/communication-sms |
A few questions people ask
Does it slow the agent down?
One Node process at prompt time, one before each write. Both finish in under 100ms.
What if I'm offline?
Toggle off with /airblander, work, toggle back. The
toggle persists across that session.
Why reset every session?
Because a fetch from last week is stale by now. Per-session is the only contract that actually means something.
Can I permanently clear an SDK?
No. Fetch the docs. It takes five seconds.