Skip to content

About

Stop giving away your code. NeonDIFF is your local-first AI PR reviewer for teams that want professional quality code reviews and issue enrichment without handing every diff to a hosted review SaaS.

Resources

Code of conduct

Contributing

Security policy

Stars

51 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,360 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NeonDiff

NeonDiff is a local-first AI PR reviewer for teams and agents that want the review loop without handing every diff to a hosted review SaaS.

NeonDiff cyberpunk wordmark in toxic green inside a black HUD frame

NeonDiff precision

Use it when you want a GitHub App to review pull requests from a local worker, with your GitHub installation, your provider keys, your repo policy, and public-safe evidence for every live posting decision.

From NeonDiff 1.1.0, review of repositories that GitHub reports as public is free, with no license key, through the GitHub Action, neondiff review-pr --ci, and the self-hosted worker (daemon, run-once, review-pr, providers verify). The Mac app reviews public repositories without a key (choose "Public repositories only" in onboarding); private repositories need Solo or Team. Private, internal, and unknown-visibility repositories need an active NeonDiff license; unknown visibility fails closed. The npm CLI 1.0.x requires API-backed activation for every repository.

Paid licenses are flat, with no per-seat pricing: Solo $9/mo or $90/yr for one developer, Team $290/yr per GitHub organization. Solo comes with a 7-day trial and Team with a 30-day trial. Existing subscribers keep their current price, and legacy lifetime licenses remain honored but are no longer sold. You bring your own model provider key or local model; NeonDiff does not include hosted model credits. NeonDiff is source-available commercial software, not open-source software.

Website · Setup · GitHub App Install · Contributing · Agent Instructions · Security · Code of Conduct · License · License Boundary · Pricing · Providers · Local checkout review · systemd · Docker · CI Runner · Known Limitations · Precision Badge · Roadmap · Repository

Why It Matters

AI-built software has made PR volume and review fatigue worse. NeonDiff is built for the opposite posture: run locally, read only the pull request it is asked to review, post only current-head comments, and keep provider/model cost under the user's control.

The current implementation grew from the internal evaOS review bot. This repo is now the NeonDiff implementation surface; older internal naming is legacy operator history, not the public product name.

What It Does

NeonDiff currently provides:

  • a GitHub App based pull-request reviewer
  • current-head duplicate suppression for {repo, pr, head_sha}
  • dry-run review output before live posting
  • inline finding placement only on current RIGHT-side diff lines
  • secret-looking finding suppression
  • stale-head checks before command-triggered review, planning, and posting
  • local evidence logs with secret redaction
  • repo profile and policy configuration
  • JSON-first operator commands for status, queue, dashboard, cooldowns, and why
  • offline eval packets for comparing seeded defects, CI, human review, and bot findings

It intentionally does not approve PRs, merge branches, push repairs, expand GitHub permissions by profile alone, or claim calibrated review accuracy before evals prove it.

Install

Requirements:

  • Node.js 26 or newer
  • npm
  • a GitHub App installed on the repos you want to review
  • a model/provider path configured locally, such as GLM/Z.ai, Ollama, or a future OpenAI-compatible provider slot

v1.0.5 verification notice: Before relying on v1.0.5, verify npm view neondiff@1.0.5 and the matching non-prerelease GitHub Release plus its typed publication proof. If those identities do not agree, keep using the verified v1.0.4 package; v1.0.3 and earlier do not enforce this boundary.

Recommended package install after v1.0.5 is published and verified:

npm install -g neondiff@1.0.5

If the required v1.0.5 registry and GitHub Release identities do not agree, use the immutable verified predecessor instead:

npm install -g neondiff@1.0.4

Installer script path:

curl -fsSL https://www.neondiff.com/install | sh

The installer script checks for Node.js 26 or newer and installs the same npm package. To preview without changing your machine:

curl -fsSL https://www.neondiff.com/install | sh -s -- --dry-run

The public paid B0 Mac beta uses a separate checksum-bound worker bundle from the same immutable GitHub prerelease as the app rather than an unpublished npm version or an unpinned source checkout. No invitation is required when the versioned public GitHub prerelease is published and the neondiff.com purchase/download path is live. The worker installer requires Node.js 26 or newer resolving through the approved stable path /opt/homebrew/bin/node or /usr/local/bin/node. When the app reports Worker update required, choose Install / Update Local Worker. Verify the outer worker bundle ZIP against the prerelease notes, then verify the extracted release manifest and inner .tgz tarball against the published SHA-256 values before following the dry-run-first update and rollback commands in docs/SETUP.md. Retain each verified worker bundle: rollback is available only after a second checksum-managed candidate has been installed, and requires the prior candidate's exact manifest, published manifest SHA-256, and tarball. The first migration cannot roll back to an unbound original invocation. This preserves the existing config, LaunchAgent identity/environment, provider state, repository allowlist, and credential stores. It is not a public npm, Sparkle, or automatic worker-update claim before that immutable prerelease is published. The installer keeps a stable Homebrew Node command in the LaunchAgent whenever that command resolves to the same binary as process.execPath, including when migrating an existing versioned Cellar path. Routine Homebrew upgrades then do not strand the worker on a removed runtime.

Operator/contributor source checkout fallback:

git clone https://github.com/electricsheephq/evaos-code-review-bot-neondiff.git neondiff
cd neondiff
npm install
npm run build

If you intentionally use the source checkout without the global package, substitute ./dist/src/cli.js anywhere this guide calls neondiff. A source checkout is not a supported B0 worker update and cannot replace the checksum-bound prerelease bundle.

Set Up

For private review-pr --ci, follow the CI license key-file setup; local license activate does not supply the CI key file.

Follow docs/SETUP.md for the CLI-first setup path (the first-run path on non-Mac platforms and the operator/advanced path on Mac). The short version is:

neondiff init --config config.local.json
neondiff dashboard --config config.local.json
export NEONDIFF_GITHUB_APP_ID="<github-app-id>"
export NEONDIFF_GITHUB_APP_CLIENT_ID="<github-app-client-id>"
export NEONDIFF_GITHUB_APP_PRIVATE_KEY_PATH="/absolute/path/to/neondiff.private-key.pem"
neondiff doctor github --config config.local.json --json
neondiff providers list --config config.local.json --json
neondiff providers doctor --config config.local.json --json
neondiff doctor --config config.local.json --json

For the Mac customer journey, the native macOS app (apps/neondiff-desktop) is the human first-run surface. The local HTML dashboard is an operator/diagnostic surface for CLI-first and non-Mac setups, not the product UI. It shows license status, GitHub App status, daemon status, and provider readiness, and its provider card includes a Verify API Key control that reports redacted pass/fail output. The managed native path binds activation and private-repository token issuance to the same Keychain-backed broker device identity and exact GitHub-selected repository. The raw Activation Key remains Keychain-owned: it crosses bounded stdin for activation and the fixed-origin broker HTTPS request body for private token issuance only, and is never placed in argv, config, logs, or broker storage. That production path remains behind its rollout kill switch until the paid-beta canaries pass. The native source now composes the managed broker only when a release bundle carries the exact paid-mac-beta-v1 Info.plist contract, fixed production broker origin, and explicit broker-enable marker. Those public build values are absent by default, so ordinary/debug bundles stay quarantined; the server kill switch and every broker/entitlement decision still fail closed. The public paid B0 BYO beta build uses a separate exact paid-mac-beta-byo-v1 release contract with NeonDiffBYOGitHubEnabled=true and no managed-broker fields. That contract enables the existing local direct/BYO path and API-backed native activation without a hidden defaults mutation. It supports keyless public-only review; private repositories need Solo or Team. The signed release app contains a sealed NeonDiff worker built from the exact reviewed source and a pinned, SHA-256-verified official Node runtime. A clean Mac therefore does not need a global CLI or separate worker install for the native setup and review path. The separate checksum-bound bundle remains available for the customer-owned local-agent path; its explicit first-install command installs only its verified CLI in a private current-user version directory, writes a credential-free installation marker, and creates or loads no LaunchAgent. After repository, provider, App-access, and any required activation verification, the signed app can install a secret-free LaunchAgent whose executable is the signed NeonDiff app. Before releasing either Keychain secret, the app validates its exact Developer ID signature and the running sealed worker process, then pipes one bounded JSON envelope to that process's stdin. The plist contains only the public App ID, config path, launchd label, the non-secret broker device ID used by the existing API-backed activation, and the signed app path—never a key value or key-file path. The headless app re-derives that device ID from its Keychain identity and rejects a mismatched plist before releasing credentials. Review and daemon readiness remain separate gates. The background worker reviews new pull requests on the repositories you enrolled and posts its reviews; in dry-run mode it writes them to local evidence instead. The daemon may also run the independently admitted issue-enrichment lane. A heartbeat proves service liveness only and never authorizes a PR post. Issue-enrichment success requires lane-specific result evidence. One-off native live PR posting outside the background worker uses only the exact scoped review-pr dry review plus explicit same-head confirmation; the matching approval is consumed atomically. The immutable published prerelease and clean-Mac artifact proof remain distribution gates. Unsigned development builds still require an executable global or checksum-managed worker before native first run exposes Initialize Local Config (non-destructive; never force-overwrites), Add Repository, Apply Repository, and Verify App Access without a terminal or operator config edit. Apply Repository writes both the selected pilotRepos allowlist and an enabled policy profile for each selected repository, preserving any existing per-repository policy fields. When the verified account has no bot yet, the app allocates that isolated new-bot plan before it presents the initialization action; it never initializes the _unselected placeholder. If the customer quits during that setup, the next launch restores the same pending bot and config path when its saved selection is still current. If an older build or manual rollback selected a verified existing bot under the same account, the app keeps that authoritative bot selected and resumes the validated pending setup only after the customer explicitly chooses NEW BOT. A new native config receives bot-isolated runtime, state, evidence, and license paths beside that config instead of reusing the packaged worker's placeholder /tmp/neondiff tree. If one exact checksum-managed local worker already exists for the selected LaunchAgent label, the app may reuse it for non-secret legacy commands. Credential-bearing commands always use the sealed worker; the app never sends Keychain material to a global, customer-writable, or checksum-marker-only executable. A verified legacy LaunchAgent remains supported without migrating or exporting its existing credential environment. This source path does not prove customer-safe private-key custody, a compatible published CLI, signing, billing, canaries, or release readiness. After Checkout displays a one-shot NeonDiff Activation Key, return to the native License pane and paste it there. Buy an Activation Key opens the public pricing page without hiding that secure existing-key field, so returning from the browser does not require a second purchase or an operator-only state change. The app stores the key through its existing Keychain-only activation path and clears the plaintext field after the customer continues. When the signed-in account already contains a verified bot and its App identity matches a local launchd/config candidate on this Mac, the native app reuses that authoritative account/bot intersection instead of asking the user to initialize or re-enter the existing worker credentials. It may show GitHub, provider, entitlement, and repository setup as configured while still requiring fresh, repository-scoped GitHub and activation verification before new review work. If that existing worker monitors more than one repository, the native app keeps the full allowlist intact and asks the user to choose one Review Target. Native activation and current-access verification bind to that exact target; the app uses the bounded doctor github --repo owner/repo form rather than rescanning the worker's complete allowlist. Selecting it does not remove, disable, or rewrite the worker's other repositories. The app may reuse the exact matched LaunchAgent's App ID and private-key file coordinate only inside the child process for that config; it never copies the key into the app, Keychain, arguments, logs, or UI. Overview can then run review-pr for one selected repository and pull request through the configured provider. Live posting remains disabled until that exact target and config revision return a successful dry-run head and the user confirms the pinned head. A transport failure revokes that approval instead of permitting a blind retry. For a customer multi-repository worker, daemon-wide start remains blocked; a verified internal-admin worker may start it and then reviews its whole allowlist, with license admission checked for every pull request. The selection and dry-run approval fail closed if the config, target, pull request, workspace, or head changes. The same Verify existing access action then runs credential-free license status --refresh true through that exact matched worker and config. It does not read, copy, migrate, or prompt for the worker's Activation Key. Useful work unlocks only when GitHub reports the exact repository visibility and the live API response returns an active entitlement covering that visibility; missing, unknown, expired, revoked, malformed, or offline proof fails closed. During launch it shows a bounded restoring state while that authorized account/bot/config intersection is checked; it does not flash empty first-run setup or claim that the existing configuration is missing. Local config alone can never invent account membership or unlock a review. This source composition is not proof that the production broker is enabled, that billing is live, or that a signed customer artifact exists. Update, rollback, daemon admission, and live-review behavior still require exact signed candidate validation before distribution. The native Providers pane reads the active review runtime from the inspected config. When codexRuntime.enabled is true, it shows the exact Codex CLI path, model, and reasoning effort and treats that existing authenticated CLI session as the review execution backend; NeonDiff never reads or stores its OAuth material. Otherwise the pane reads and edits the saved providers registry, not the legacy desktop.openAICompatibleEndpoint field. Load config, Preview, and Apply the exact selected provider before Verify is enabled; verification pins both the provider ID and inspected config revision. A provider with authMode: zcode-app-config or none does not use a NeonDiff-stored API key, so the native app reports its loaded config without showing a false missing-key state. api-key-env providers retain the Keychain and verification gate.

Create or install the GitHub App before expecting PR reviews to run. The App must be installed on the same selected repositories listed in pilotRepos; see docs/github-app-setup.md for the permission set and selected-repo install path. The rollout-disabled managed desktop source uses the broker-issued GitHub App install/OAuth URL and keeps polling its device-bound completion state while authorization is pending. A fresh installation callback wins without asking the customer to authorize twice. The unshipped source still contains Device Flow as an existing-install fallback. Before B1 release, #613 must move that managed customer path to broker-hosted web OAuth with state and PKCE; Device Flow remains only an optional CLI/headless fallback. Both paths must verify the exact user-authorized installation/repository intersection, and installation tokens remain the only review credential. Legacy direct-install builds still read their public client ID from local config.

Do not store the GitHub App private key, provider API key, license key, tokens, or customer data in this repository. Keep local config, secrets, state DBs, and evidence outside git.

Platform operator paths:

Platform Daemon path Status
macOS launchd with docs/launchd.md Tested beta operator path
Linux systemd with docs/systemd.md Packaged and covered by Ubuntu smoke tests
Docker Compose recipe with docs/docker.md Packaged for local/self-hosted workers
CI runners One-shot review or dry-run with docs/ci-runner.md Documented for Ubuntu-style runners
Windows CLI-only source/package usage Untested; no supervised daemon claim

On Linux (hosts, Docker and CI runners), Codex checkout reads need unprivileged user namespaces, which Ubuntu 23.10 and later block by default. NeonDiff checks this before using checkout reads and falls back to diff-only with a warning; see Codex sandbox on Linux to enable them.

Provider Resources And Compatibility

NeonDiff is local-first for checkout state, credentials, config, evidence, and operator control. Model egress depends on the provider you choose: local or self-hosted endpoints can keep prompts and diffs on your machine or network, while hosted providers such as GLM/Z.AI through ZCode or hosted OpenAI-compatible gateways receive the review prompt and diff context required to answer.

For setup details, see docs/providers.md. Useful provider resources:

Small NeonDiff compatibility matrix:

Provider or resource NeonDiff status Egress posture
GLM/Z.AI through ZCode Default beta path; tested by NeonDiff as the current live review route Hosted provider receives prompts and diffs
Ollama on localhost Compatible by interface; provider doctor/smoke only until adapter proof promotes live review No-egress only when endpoint and model are local
LM Studio, vLLM, or local gateways Compatible by interface; tracked for provider proof before live promotion No-egress only for local/self-hosted endpoints
Hosted OpenAI-compatible BYOK gateways Compatible by interface; remote smoke and live review proof required Hosted provider receives prompts and diffs
Free-provider catalogs Resource only; untested by NeonDiff unless a provider has its own proof issue Usually hosted; check each provider

For the blunt launch-facing matrix, including macOS/Linux and backend limits, see docs/known-limitations-and-provider-status.md.

First Dry-Run Review

Run a dry-run review before any live posting. Replace --repo owner/name and --pr 123 below with a repo already listed in your local config's pilotRepos and an open PR number on that repo — review-pr fails with "repo must be present in configured repos" if the repo is not in pilotRepos:

neondiff review-pr \
  --config config.local.json \
  --repo owner/name \
  --pr 123 \
  --expected-config-revision <verified-config-revision> \
  --dry-run true \
  --zcode true

Use the exact configRevision returned by the successful provider verification. Inspect the JSON result and evidence path. Only switch to --dry-run false after setup checks, focused tests, and the relevant GitHub issue record the exact repo, PR, head SHA, config path, and public-safe evidence.

Agent And Maintainer Workflow

If you are contributing as an AI coding agent:

  1. Read AGENTS.md.
  2. Reuse or create a GitHub issue before meaningful work.
  3. Write a failing test, smoke, or docs/eval gate before implementation.
  4. Keep the PR linked to the issue with Closes #<issue> or Related: #<issue>.
  5. Record validation and evidence without raw secrets, raw customer data, or private logs.

For public issue intake and launch-influx handling, use docs/triage-policy.md.

Useful public-product issues:

Safety Boundaries

Default behavior:

  • review only configured repos
  • skip draft PRs by default
  • at most one review per {repo, pr, head_sha}
  • never submit APPROVE
  • request changes only for validated high-severity findings
  • rank findings by severity, then validated confidence; the inline-comment cap keeps the highest-confidence findings
  • suppress same-run near-duplicate findings and secret-looking findings instead of posting them
  • learned signals (confidence floors, category precision floors, repo-memory false-positive suppression, self-consistency refutation) only ever make the review quieter — they demote or suppress, never escalate
  • re-fetch PR state before live operations
  • keep ZCode/model tools read-only during review
  • periodically prune only stale, clean, inactive NeonDiff review worktrees; cleanup is configurable and fails closed when open-handle safety cannot be proven
  • fail closed when credentials, provider readiness, repo policy, or current-head proof is missing

Not claimed:

  • not claimed: public launch is complete
  • final legal/license adequacy
  • hosted review service
  • auto-merge or branch repair
  • generic GitHub issue mutation
  • enterprise or customer-ready security
  • calibrated confidence display (stays redacted until the evidence gate in docs/calibration-loop.md passes and a human flips it)
  • desktop client readiness

Precision Badge

NeonDiff's precision badge is public-safe by default: the generated Shields endpoint at docs/badges/precision.json shows a gray calibrating (n=...) state until the calibration aggregate passes the existing public-confidence gate and a human flips confidenceCalibration.publicDisplay.mode to "calibrated". Below that gate, no public percentage is displayed.

Copy-paste README badge snippet, replacing the branch if you publish from somewhere other than main:

[![NeonDiff precision](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Felectricsheephq%2Fevaos-code-review-bot-neondiff%2Fmain%2Fdocs%2Fbadges%2Fprecision.json)](docs/precision-badge.md)

The badge JSON is generated from NeonDiff's own aggregate evidence; the tool does not accept a public-percent override and does not flip calibrated display mode. See docs/precision-badge.md for the review rules behind that contract.

Roadmap Vs Shipped

The current repo is the source-available NeonDiff implementation. The public roadmap is tracked in #103. Provider registry, .neondiff.yml, desktop client signing/appcast, wiki exports, and marketplace packaging each have separate issues and must not be treated as shipped until their PRs and proof gates close.

The ranking/scoring and calibration program (#278) is shipped: confidence-aware ranking and caps, validated-category precedence, same-run near-duplicate suppression, robust false-positive learning, opt-in self-consistency re-checks, risk-weighted queue priority, and the full calibration loop (post-merge outcome observer → label aggregation → human-gated promotion — see docs/calibration-loop.md and docs/vision.md). Shipping the loop's tooling does not flip the calibrated display: that remains off until the evidence gate passes on real review volume and a human applies it. See CHANGELOG.md for the per-version record.

Use LICENSE.md and docs/license-boundary.md as the canonical public license language. Do not copy older issue comments or release notes into public product surfaces when these files are more recent.

For live release operation, use docs/beta-release-runbook.md and docs/release-governance.md. Documentation-only changes do not restart launchd or promote a release by themselves.

For public release readiness, use docs/public-release-manifest.json with neondiff release-status --public-release-manifest docs/public-release-manifest.json --expected-public-version <public-version-tag>. Replace <public-version-tag> with the actual semver tag, such as v1.0.0; the CLI rejects literal placeholders. The manifest is the compact version/alignment surface for setup docs, release notes, license API state, and update-channel readiness.

About

Stop giving away your code. NeonDIFF is your local-first AI PR reviewer for teams that want professional quality code reviews and issue enrichment without handing every diff to a hosted review SaaS.

Resources

Code of conduct

Contributing

Security policy

Stars

51 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages