I've been reviewing pull requests for most of my career.
At some point the queue got bad enough that I stopped asking "which PR should I review first?" and started asking "why does this keep happening?"
The answer was that I had no system. Just a flat list of open PRs, a vague sense of urgency, and two hours a day I couldn't account for.
So I built a tool. caught a real bug in the streaming implementation I published — one that's easy to miss because it fails silently. decoder.decode(value) gives you whatever bytes arrived in that read, which doesn't always align with SSE event boundaries. If a chunk ends mid-line, chunk.split('\n') drops the tail and the next read starts without that continuation. The result is occasional token drops that look like the model cutting itself short. The fix is a line buffer that carries incomplete fragments across reads:
// streaming with chunk boundary fix
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = ''; // accumulate incomplete lines across reads
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
// Keep the last (potentially incomplete) line in the buffer
buffer = lines.pop();
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const data = line.slice(6);
if (data === '[DONE]') continue;
try {
const parsed = JSON.parse(data);
const token = parsed.choices[0]?.delta?.content || '';
chrome.tabs.sendMessage(tabId, { type: 'AI_TOKEN', token });
} catch (e) {
// malformed chunk — skip
}
}
}
Separately, on the previous article — and he's right. When a user says "this AI summary is wrong," I need to answer: what diff was sent, what prompt was used, what did the provider return? Currently I log all three in IndexedDB, but there's no UI to inspect it. The fix I'm building: a rolling debug view of the last 20 AI calls — prompt, diff, raw response — that turns "wrong summary" from a support ticket into a self-serve investigation.
The specific error messages reduced API key support tickets by ~60%:
if (response.status === 401)
return { valid: false, error: 'Invalid key — check you copied it completely, no trailing spaces.' };
if (response.status === 429)
return { valid: false, error: 'Rate limit — you\'ve hit the free tier ceiling.' };
if (response.status === 403)
return { valid: false, error: 'Permission denied — this key may not access this model tier.' };
The decision I'm most uncertain about in retrospect: the one-time payment model. It's philosophically right — I don't want to charge monthly for something that doesn't recur. But it means no recurring revenue. Every month starts at zero. I wrote the full reasoning in — free, open-source code review checklist. 51 items, live readiness score, no account required. MIT licensed.
— post a PR, review one in return. Open through July.
One more decision I didn't cover: what to keep closed-source. PR Focus is the paid product, so its code stays private. TabCost Pro and ChainTrace are also private. The open-source layer — , the Review Swap — is where I put the methodology, the decisions, and the community infrastructure. That separation has held up better than I expected.
Five decisions in the article.
A sixth one found by a reader in the comments of the last article.
A seventh one I hadn't seen until someone named it for me.
That's probably the honest ratio for any tool in production:
the ones you found yourself, and the ones you needed someone else to find.
Which of these have you hit building your own tools? The service worker state one I hear from almost everyone who's shipped an MV3 extension — curious if the <all_urls> permissions problem is as common.
And if you've shipped something — what's the one decision you'd reverse if you could? Drop it in the comments. I'd genuinely like to know.
SOCIAL SHARE CARD GENERATOR