Unix-style ruleset reviewer:
targets + rulesets -> findings
reviewer reads reviewable input, applies one or more rulesets, and writes findings as NDJSON to stdout. Progress and diagnostics go to stderr.
pnpm add -D @hardeep/reviewerOr run from a local checkout while developing:
pnpm install
pnpm build
pnpm link --globalReview one prose document from stdin:
reviewer narrative < chapter.mdReview one source file by reference. Reviewer sends the path/URI to the agent and instructs it to read the file as needed:
reviewer architecture source.tsReview structured file references with supplemental producer context such as changed lines:
printf '%s\n' \
'{"id":"src/auth.ts","kind":"file","uri":"file://'$PWD'/src/auth.ts","context":"Changed lines: 12-35"}' \
'{"id":"src/user.ts","kind":"file","uri":"file://'$PWD'/src/user.ts","context":"Changed lines: 8-19"}' |
reviewer architecture --input-format ndjsonFilter findings with standard tools:
reviewer architecture --input-format ndjson < targets.ndjson |
jq 'select(.severity == "error")'Git is just another producer:
git diff main | reviewer code-reviewreviewer RULESET < input
reviewer RULESET file-one.md file-two.md
reviewer --ruleset narrative --ruleset clarity < chapter.md
reviewer architecture --follow source.ts
reviewer init
reviewer create ruleset narrative
reviewer doctorThe default command is review. Subcommands are limited to setup and diagnostics.
Reviewer has three input modes. They are intentionally different.
Plain stdin is always one inline document target. Use it for generated text or for piping a single file's contents.
reviewer narrative < chapter.mdInternally this becomes one target:
{"id":"stdin","kind":"inline","context":"...","mediaType":"text/plain"}Override the target ID:
reviewer narrative --id chapter-01.md < chapter-01.mdPlain stdin is never interpreted as a list of file paths.
File arguments are file reference targets, not embedded content. Reviewer does not read the file body into the prompt. It passes the target ID/URI and instructs the agent to read the referenced file as needed.
reviewer architecture src/auth.ts src/user.tsEach file target is reviewed in its own agent invocation for each selected ruleset. This keeps context clean and makes coverage auditable.
Directories are not traversed and globs are expanded by your shell, not Reviewer.
Use NDJSON when a wrapper or producer needs structured targets, stable IDs, file references, and extra context without materializing full file contents.
reviewer architecture --input-format ndjson < targets.ndjsonExample file reference records:
{"id":"src/auth.ts","kind":"file","uri":"file:///repo/src/auth.ts","context":"Changed lines: 12-35","metadata":{"producer":"git-diff"}}
{"id":"src/user.ts","kind":"file","uri":"file:///repo/src/user.ts","metadata":{"changedLines":[8,9,10]}}context is supplemental producer context: diff hunks, changed lines, notes, or other hints. For file targets it is not a replacement for the file itself; the agent should still read the referenced file as needed.
Inline NDJSON targets are also supported for non-file documents:
{"id":"draft","kind":"inline","context":"Document text...","mediaType":"text/markdown"}Each record must include a unique nonempty id. Optional fields are kind, uri, mediaType, context, and object metadata.
Findings are NDJSON by default and each line is independently parseable:
{"target":"stdin","ruleset":"narrative","severity":"warning","message":"..."}Diagnostics, progress, pretty logs, RPC follow output, and errors are written to stderr so stdout remains pipe-safe. Use --follow to run the agent in RPC mode and stream live progress while findings remain NDJSON on stdout.
0 = review completed; no findings met the failure threshold
1 = findings met or exceeded --fail-on
2 = invocation/configuration/input error
3 = agent/runtime/output failure
Default failure threshold is error:
reviewer architecture --fail-on warning source.ts
reviewer architecture --fail-on none source.tsreview-rulesets.yaml is optional. Defaults:
rulesetDir: review-rulesets/rulesets
agent:
command: pi
args:
- --print
- --no-session
- --approve
timeoutSeconds: 900
concurrency: 4Rulesets live at:
review-rulesets/rulesets/<name>/SKILL.md
Reviewer invokes each selected ruleset once per target. File targets are references; the agent reads files as needed. Plain stdin and inline NDJSON targets provide their text as context.
import { review } from '@hardeep/reviewer'
const findings = await review({
targets: [{ id: 'chapter-01.md', kind: 'inline', context: chapter }],
rulesets: ['narrative'],
config: {
configDir: process.cwd(),
rulesetDir: 'review-rulesets/rulesets',
concurrency: 4,
agent: { command: 'pi', args: ['--print', '--no-session', '--approve'], timeoutSeconds: 900 },
},
})The API does not read Git state, write reports, log to stdout, or exit the host process.
The old repository-scoped workflow has been removed. These settings are retired and now produce configuration errors: baseRef, reportDir, latestReportDir, mandatoryRulesets, artifacts, and piPackages.
Wrappers such as Signal 360 should prefer NDJSON file reference targets with optional context for diff hunks, changed lines, or producer context. Do not send every full file body as NDJSON context for --all-files; Reviewer will invoke the agent once per target and the agent can read referenced files as needed.
Rich reports and rewrite workflows should consume Reviewer findings as downstream tools:
reviewer narrative < chapter.md | reviewer-report > review.mdreviewer-report, file-targets, and Git adapters are examples of composable external tools, not built-in commands in this package.
Default tests use fake agents and do not call a provider. The opt-in integration suite calls a real model, including a TypeScript file review that should raise an eval() security finding. To run it:
pnpm test:integrationThe integration suite uses the repository-root review-rulesets.yaml directly via --config; agent command, args, timeout, and env are configured there. These tests may spend tokens and require provider authentication.
reviewer runs locally, but it invokes the configured agent command. Supplied target context, target references, ruleset prompts, tool output, and findings may be sent to that configured agent/provider.
The package does not operate a hosted service. Data exposure depends on your configured agent command, provider, rulesets, and logs/artifacts you choose to store or share.