English · 한국어
Deterministic code-review scaffolding for Claude Code. Give it a pull-request URL;
sereviewparses the diff, bundles the changed files, matches a security-focused rulebook, and emits a review packet. Your existing Claude Code session reads that packet and does the actual line-by-line review.
sereview never calls an LLM and has no model SDK as a dependency. The
only thing that ever talks to a model is the Claude Code session you already run —
so there is no separate API key and no double-billing. A CI guard
(no-llm-sdk) fails the build if an LLM SDK ever
sneaks into the dependencies or the source.
A code-review tool that ships its own model client makes you pay for a second
model on top of the Claude Code session you're already authenticated for. And the
stock /code-review lacks the deterministic token discipline (bundling +
rule pre-filtering) that keeps a large diff affordable. sereview splits the job
in two tiers:
| Tier | Who | What | Calls a model? |
|---|---|---|---|
| Tier 2 | sereview (this package) |
Parse diff → bundle files → match rulebook → packet | No |
| Tier 1 | your Claude Code session | Read the packet, open files with Read/Grep, write findings |
Yes (the one you already pay for) |
PR URL ── gh pr diff ──▶ sereview (parse · bundle · rule-match) ──▶ review packet
deterministic, no LLM │
host Claude Code ◀─────┘
(Read/Grep → findings)
# one-off, no install
npx sereview packet <pr-url>
# or add it to a project / install globally
pnpm add -D sereview
npm i -g sereviewRequires Node ≥ 20 and the GitHub CLI (gh),
authenticated (gh auth status) for fetching PR diffs.
# Build a packet from a GitHub PR (URL or owner/repo#number)
sereview packet https://github.com/owner/repo/pull/123
sereview packet owner/repo#123
# Build from a local unified diff (great for testing / pre-push review)
git diff origin/main... | sereview packet --diff -
sereview packet --diff changes.patch
# Options
sereview packet <pr> --max-bundle-tokens 6000 # tune bundle size (default 8000)
sereview --help
sereview --versionThe command prints a JSON ReviewPacket to stdout. On its own that's just
data — the review happens when a Claude Code session consumes it via the
skill.
bundlesgroup changed files under a token budget; each carries thematchedRulesthe deterministic matcher flagged for it.matchedRulesare hints — "look here for this class of bug" — never verdicts. An empty list does not mean a bundle is clean.skippedrecords files left out of review (binary, lockfiles, …) with a reason, so nothing silently disappears.
The reviewing logic lives in skill/SKILL.md, a Claude Code
skill. Point a session at it (or install it as a plugin skill) and ask it to
review a PR; it runs sereview packet, reads the matched rules, gathers context
with Read/Grep, and returns a ReviewResult — findings anchored to the exact
changed lines, grouped by severity.
Posting comments back to the PR is not part of the MVP and, when added, requires explicit per-review permission — sereview never comments on its own.
sereview's CLI is agent-agnostic — it never calls a model, it only builds the
packet. Any agent that can run a shell command and read files can be the Tier 1
reviewer. For OpenAI Codex, see docs/codex.md (the same
ReviewResult contract, via an AGENTS.md block or a one-shot prompt).
sereview is also a pure library (the . export). Everything is deterministic:
same diff in, same packet out.
import { buildPacket, serializePacket } from "sereview";
const packet = buildPacket({
diff, // unified diff text
source: { kind: "local-diff", ref: "HEAD" },
maxBundleTokens: 8000, // optional (default 8000)
// skip: (f) => f.path.endsWith(".lock") ? "lockfile" : null, // optional
});
console.log(serializePacket(packet)); // pretty JSONOther exports: parseDiff, detectLanguage, estimateTokens,
DEFAULT_MAX_BUNDLE_TOKENS, RULEBOOK_VERSION, and every type
(ReviewPacket, ReviewBundle, MatchedRule, Finding, ReviewResult, …).
See src/core/types.ts.
A security-leaning starter set, used as hints for the reviewer:
| id | category | severity hint |
|---|---|---|
sql-injection |
security | high |
xss |
security | high |
ssrf |
security | high |
path-traversal |
security | high |
secret-exposure |
security | critical |
authz |
security | high |
npe |
correctness | medium |
race |
concurrency | medium |
n-plus-1 |
performance | medium |
Severity scale: critical · high · medium · low · info.
| Open Code Review (Go binary) | sereview |
|---|---|
| model client (API key) | host Claude Code session (no key) |
file_read / code_search |
Claude Read / Grep |
code_comment convention |
skill/SKILL.md output format |
| diff parse · bundle · rule-match (Go) | src/core (TypeScript) |
| plan + review loop (LLM) | the Claude Code session directly |
pnpm install
pnpm typecheck # tsc --noEmit
pnpm test # node --test (native TS, no build step)
pnpm build # tsdown → dist/
pnpm check:no-llm-sdk # enforce the no-key invariantThe test suite runs on Node's built-in runner against TypeScript directly (no transpile). The library and CLI are bundled by tsdown.
Publishing is automated via GitHub Actions (modeled on DaleStudy/daleui): a manual Release PR bumps the version, merging it tags + drafts a GitHub Release, and publishing that release publishes to npm with provenance via OIDC Trusted Publishing (no npm token). See docs/RELEASING.md.
Apache-2.0. The deterministic pipeline design (diff parse · bundle ·
rule-match) is adapted from Open Code Review
(Apache-2.0). sereview's rulebook is a small, security-leaning regex set
re-authored from OCR's review concern areas — not a port of OCR's per-language
rule documents — and sereview removes the model-calling agent entirely. See
NOTICE.
{ "schemaVersion": 1, "source": { "kind": "github-pr", "ref": "owner/repo#123", "title": "Add user lookup", "baseSha": "…", "headSha": "…" }, "bundles": [ { "id": "bundle-1", "files": [ { "file": { "path": "src/db.ts", "status": "modified", "language": "typescript", "additions": 2, "deletions": 1, "binary": false }, "hunks": [ { "header": "@@ -1,2 +1,3 @@", "oldStart": 1, "oldLines": 2, "newStart": 1, "newLines": 3, "lines": [ /* add/del/context lines */ ] } ] } ], "matchedRules": [ { "id": "sql-injection", "category": "security", "severityHint": "high", "title": "SQL injection via string-built query", "guidance": "…", "appliesTo": ["…"] } ], "tokenEstimate": 73 } ], "skipped": [ { "path": "logo.png", "reason": "binary" } ], "stats": { "files": 2, "additions": 2, "deletions": 1, "bundles": 1 }, "rulebookVersion": "sereview-rulebook-1 (2026-06-25)" }