Home / Skills / Developer Productivity / Caveman Review
Developer Productivity

Caveman Review

Julius BrusseeApache-2.0Skill language: English
License verifiedNo scripts
DemoReal run ยท claude-opus-5-5 ยท October 2026
Please review the diff before I merge it: ```diff --- a/src/orders/service.ts +++ b/src/orders/service.ts @@ -12,14 +12,24 @@ export class OrderService { async getOrderTotal(orderId: string): Promise<number> { - const order = await this.repo.findById(orderId); - return order.items.reduce((sum, i) => sum + i.price * i.qty, 0); + const order = await this.repo.findById(orderId); + let total = 0; + for (let i = 0; i <= order.items.length; i++) { + total += order.items[i].price * order.items[i].qty; + } + return total; } async applyCoupon(orderId: string, code: string) { - const coupon = await this.coupons.find(code); + const coupon = this.coupons.find(code); if (coupon.expiresAt < Date.now()) throw new Error("expired"); - await this.repo.update(orderId, { couponId: coupon.id }); + this.repo.update(orderId, { couponId: coupon.id }).catch(() => {}); } + + async listOrders(userId: string) { + return this.db.query(`SELECT * FROM orders WHERE user_id = '${userId}'`); + } } ```
Skill: caveman-review

I wouldn't merge this yet. There are 3 bugs that will break things, 1 SQL injection, and 1 risk. The original code was correct before this change.

src/orders/service.ts

  • L15: ๐Ÿ”ด bug: the loop runs one step too far. i <= order.items.length reads order.items[length], which is undefined, so .price throws a TypeError on every call. Use <, or keep the original reduce, which was correct and shorter.
  • L22: ๐Ÿ”ด bug: await was removed from this.coupons.find(code), so coupon is now a Promise. coupon.expiresAt is undefined and undefined < Date.now() is false, so the expiry check never fires and expired coupons are accepted. coupon.id is also undefined. Put the await back.
  • L24: ๐Ÿ”ด bug: the update is fire-and-forget and .catch(() => {}) hides any failure. Callers see success even when the coupon was never saved, and nothing is logged. Put back await this.repo.update(...) and let errors reach the caller.
  • L22-23: ๐ŸŸก risk: if find returns null for an unknown code, coupon.expiresAt throws a TypeError instead of a clear error. Add if (!coupon) throw new Error("invalid coupon").

L28: ๐Ÿ”ด security: SQL injection in listOrders. userId is put straight into the SQL string. A value like ' OR '1'='1 returns every user's orders, and with stacked queries an attacker could change or delete data (CWE-89, OWASP A03). Even if userId comes from an auth token today, this function can't assume that, and a single caller passing a request param makes it exploitable. Use a parameterized query, e.g. this.db.query("SELECT * FROM orders WHERE user_id = $1", [userId]) (use whatever placeholder syntax your driver expects).

  • L28: ๐Ÿ”ต nit: SELECT * returns every column and will pick up any column added later. List the columns you need.
  • L27: ๐Ÿ”ต nit: no return type, unlike getOrderTotal. Add Promise<Order[]>.

Real run recorded with claude-code / claude-opus-5-5. Output is shown verbatim, unmodified.

What it does

Writes code review comments in a compact L<line>: <problem>. <fix>. format, ready to paste into a pull request.

How it works

  1. Triggers on /caveman-review, "review this PR" or "review the diff".
  2. Gives each finding one line with the exact line number, symbol names in backticks and a concrete fix, plus an optional severity tag: ๐Ÿ”ด bug, ๐ŸŸก risk, ๐Ÿ”ต nit, โ“ question.
  3. Drops hedging and restating the diff. For security issues, architectural disagreements and onboarding situations it writes a full paragraph instead.

Good for

Reviewing diffs and pull requests when you want findings that are quick to scan.

Worth knowing

It only writes comments. It does not edit code, approve or request changes, or run linters.

Notes & risks

Pure instruction file: no scripts, no network access and no file writes. The package also contains the README, LICENSE and NOTICE from the original repository. Review findings are model output; check them before posting.

SKILL.md original4 files in this package