Local multi-engine static code scanning, built for AI coding agents.
English | δΈζ
π Feasibility Research
- A skill, not a server. codespot runs entirely on your machine as an AI-agent skill: no SonarQube-style server, no accounts, no code leaves the repo. Any agent that discovers skills under
~/.agents/skillscan use it. - Ten engines, one report. Secrets, Python quality & security, JS/TS, Java (source + bytecode), SQL, cross-language taint analysis, dependency CVEs β all normalized into one severity-ranked report with stable
CS-xxxxxrule ids. - Incremental by default. Scans what you changed (uncommitted β unpushed β full, automatic fallback), which fits the AI-coding loop of "generate, scan, fix, rescan".
- Agent-first output.
report.jsonkeeps full internals (tool / rule / ruleUrl / fixHint) for the agent to fix precisely;report.mdandcodespot showare human-facing, codespot-branded, with secrets always redacted.
- Incremental scan scopes β
auto/uncommitted/unpushed/ref:<ref>/all; findings never change the exit code, so CI can publish reports without failing builds. - AI semantic review (on by default) β every scan writes a review plan; the agent itself reviews what static rules can't catch (logic, concurrency, error-handling gaps, cross-file inconsistencies) and merges validated findings with
codespot ai-scan absorb. - AI fix loop β severity-filtered fix options, agent edits code, rescans to verify (β€3 rounds), summarizes fixed / skipped / remaining; false positives go to ignore lists.
- Secrets detection β 222-rule always-on layer with redacted reporting and a rotate-first workflow; optional TruffleHog deep layer (800+ detectors, liveness verification available but off by default).
- Dependency vulnerabilities (SCA) β OSV-Scanner against requirements/lockfiles/pom/go.mod (live osv.dev queries; network required), with an upgrade target on every finding.
- Rule governance β three config layers (native tool configs >
.codespot/config.jsoncategories > built-in defaults), severity overrides, per-finding ignore lists. - Regression built in β
codespot selftestruns every engine against fixtures;codespot showbrowses findings by severity / file / CS id.
AI-generated code needs more than AI review. Model-based scanning alone is non-deterministic: there is no rule catalog underneath, no CVE database, no secret signatures β hallucinated assurances and silent misses come with the territory. codespot pairs deterministic engines with the agent's semantics: rules, CVEs and secret patterns are checked by tools, and the model only reviews what rules cannot express.
Traditional scanners don't fit this loop either. They assume a CI pipeline and a server to talk to; an agent working locally in a git repo can't call them on demand, and none of them close the "scan β report β fix β rescan" cycle. codespot is a local CLI built for that cycle, driven by natural language ("scan my code").
License hygiene was a design constraint from day one. SonarSource analyzers moved to the non-open SSALv1 (which restricts feeding analyzer output to non-bundled AI), so codespot assembles clean-license engines (MIT / Apache / LGPL), downloads them at runtime from official sources, and never bundles or redistributes them.
Dependency scans always query the live osv.dev database (network required).
Semgrep is the opposite: its rules are cached locally (~/.codespot/semgrep-rules, downloaded by setup on first run, refreshed by codespot update-rules) and are used by default β deterministic and fast (no online rule-pack fetches, no 300s timeouts). If the rules dir is missing, semgrep falls back to online auto.
Critical AI recheck: when findings include criticals, the agent re-verifies each one before presenting fix options β verdicts: confirmed / likely-false-positive / needs-human; likely FPs are excluded from the default fix scope.
In ZCode (or any agent with ~/.agents/skills discovery), just say:
Install the skill from https://github.com/wenhao/codespot.git and scan this repo with codespot
The agent runs the equivalent of:
git clone --depth 1 https://github.com/wenhao/codespot.git ~/.codespot/src/codespot
ln -s ~/.codespot/src/codespot/skill ~/.agents/skills/codespot # skill payload only
~/.agents/skills/codespot/scripts/codespot setup # engines, idempotentThe skill payload is the cross-agent SKILL.md format β one clone serves multiple agents. Symlink it into each agent's skills directory and run setup once:
| Agent | Skills directory | Symlink command |
|---|---|---|
| ZCode / generic agents | ~/.agents/skills |
ln -s ~/.codespot/src/codespot/skill ~/.agents/skills/codespot |
| Claude Code | ~/.claude/skills |
ln -s ~/.codespot/src/codespot/skill ~/.claude/skills/codespot |
| Codex CLI | ~/.codex/skills |
ln -s ~/.codespot/src/codespot/skill ~/.codex/skills/codespot |
After symlinking, ask the agent to "scan my code with codespot" (or invoke /codespot where the agent supports explicit skill calls). Project-level installs work too: drop the symlink into .agents/skills/, .claude/skills/ or .codex/skills/ inside a repo instead of the home directory.
Trigger it in natural language ("scan my code"), or run the CLI:
~/.agents/skills/codespot/scripts/codespot scan --scope autoThe scan also writes .codespot/ai-plan.json; the agent reviews per the plan, writes ai-result.json, then merges:
~/.agents/skills/codespot/scripts/codespot ai-scan absorbRead the results:
cat .codespot/report.md # human-readable, CS ids
~/.agents/skills/codespot/scripts/codespot show --severity critical,majorThe agent then presents fix options (critical / major+ / all / browse details), fixes the code, rescans to verify, and summarizes.
Drop a native config (.ruff.toml, .oxlintrc.json, .sqlfluff, .gitleaks.toml) β codespot uses it instead of its defaults. Or use category switches:
// .codespot/config.json
{
"dialect": "postgres",
"rules": {
"python_lint": { "ignore": ["RUF100"] },
"secrets_deep": { "enabled": true }
}
}git clone https://github.com/wenhao/codespot.git && ln -s "$(pwd)/codespot/skill" ~/.agents/skills/codespotUpdate with git -C ~/.codespot/src/codespot pull + re-run setup; uninstall by removing the symlink and ~/.codespot/.
| Category (config key) | Engine | Requires | Notes |
|---|---|---|---|
secrets (always on) |
gitleaks 8.30 | β | dir mode, redacted reports |
python_lint |
ruff 0.16 | β | JSON output keeps fix suggestions |
python_security |
bandit | python3 (venv) | |
js_lint |
oxlint 1.85 | β | fast layer |
js_lint (deep) |
ESLint + eslint-plugin-sonarjs | node/npm | graceful fallback to fast layer |
java |
PMD 7.27 | JRE 8+ | source-level, no compile needed |
java (deep, optional) |
SpotBugs 4.10 + FindSecBugs 1.14 | mvn/gradle + JDK | skipped when project isn't buildable |
sql |
SQLFluff | python3 (venv) | dialect auto-detection chain |
semantic |
Semgrep CE 1.177 (1.136 on py3.9) | python3 (venv) | Go/C#/Kotlin/Ruby/PHP/Rust/Terraformβ¦; rules fetched from the official registry |
dependencies |
OSV-Scanner 2.6 | network (live osv.dev queries) | scans requirements/lockfiles/pom/go.mod for known CVEs |
secrets_deep (opt-in) |
TruffleHog 3.97 | β | --engine trufflehog; --no-verification by default |
ai_review (on by default) |
the AI agent itself | β | plan β analyze β ai-scan absorb; disable via rules.ai_review.disabled |
Counts are what codespot actually enables (verified against installed engines, 2026-09-23).
| Language | Quality / style | Security | Dependency |
|---|---|---|---|
| Python | ruff: 503 enabled (of 970) | ruff S-family + bandit (32 plugins) | OSV-Scanner |
| JavaScript / TypeScript | oxlint: 335 + sonarjs: ~215 | same + Semgrep | OSV-Scanner |
| Java | PMD: 213 | SpotBugs ~470 + FindSecBugs 144 (CWE-tagged) | OSV-Scanner |
| SQL | SQLFluff: ~48 (of 68) | β | β |
| Go / C# / Kotlin / Ruby / PHP / Rust / Swift / Scala | β | Semgrep auto packs (2800+) |
OSV-Scanner |
| Secrets (any language) | β | gitleaks 222; TruffleHog 800+ (opt-in) | β |
De-duplication is by design: eslint-plugin-oxlint disables every ESLint rule the oxlint layer already owns; sonarjs contributes only unique Sonar rules; PMD (source) and SpotBugs (bytecode) are complementary layers; ruff-S and bandit-B intentionally coexist (different semantics, distinct rule ids).
| Command | Description |
|---|---|
codespot setup [enginesβ¦] |
Install engines (idempotent, version-locked; per-engine failures don't block others) |
codespot scope --scope <tier> |
Print the file list a scan would use |
codespot scan --scope <tier> [--engine nameβ¦] |
Run matching engines + any requested opt-in engines; writes both reports and the AI review plan |
codespot show [--severity s1,s2] [--file prefix] [--rule CS-xxxxx] [--limit N] [--all] |
Browse issue details from the last report |
codespot ai-scan absorb |
Validate & merge agent-written AI review results into the last report |
codespot report |
Print the last report.json |
codespot update-rules |
Refresh local Semgrep rules (offline defaults) |
codespot selftest |
Fixture-based regression across all engines |
Three layers, highest priority first:
- Native config files β
.ruff.toml/ruff.toml/[tool.ruff]in pyproject,.oxlintrc.json,.sqlfluff,.gitleaks.toml. When present, codespot uses them instead of its built-in defaults (full parameter power). .codespot/config.jsonβ category switches (disabled/ignore/enabled), SQLdialect,semgrep_config. Categories:secrets,python_lint,python_security,js_lint,java,sql,semantic,dependencies,secrets_deep,ai_review.- Built-in defaults in
skill/assets/.
A .codespotignore file at the repo root excludes files/folders from every scan scope, using gitignore-subset syntax β one pattern per line, # comments, trailing / for directories only, patterns containing / anchored to the repo root (otherwise matching at any depth), * / ? / ** wildcards, and ! negation where the last matching pattern wins:
# generated artifacts
*.log
dist/
docs/generated/**
# keep this one
!keep.logBuilt-in excludes always apply and cannot be re-included with !: .git/, .codespot/, .codespotignore, node_modules/, vendor/, dist/, build/, binary files.
Severity tuning: .codespot/severity-overrides.json ({"ruff": {"rules": {"RUF100": "info"}}}). One-off false positives: .codespot/ignore ([{"tool": "ruff", "file": "src/app.py", "rule": "PLW0603"}]); secrets use .gitleaksignore fingerprints.
- OSV-Scanner is online-only: dependency scans query the live osv.dev database (network required). Offline vulnerability DBs are not used (dropped 2026-09-30).
- Semgrep rules cache under
~/.semgrep/; delete the cache to force a refresh, or pointsemgrep_configat a local rules dir for strict-offline setups. - Engine upgrades: bump the
versionfield inskill/scripts/engines/registry.jsonand re-runsetup; reset an engine withrm -rf ~/.codespot/engines/<name>-<version>.
- Write
skill/scripts/engines/engine_<name>.pyimplementing the adapter contract:--workdir <root> --files <list.json> --out <result.json>; exit0with a JSON array of issues,2with the failure reason on stderr. - Emit the unified issue schema (
common.make_issue); severity normalizes viarules-severity.json. - Register it in
registry.json(install form, version, languages, category) and add fixtures totests/fixtures/+expected.json.
codespot/
βββ skill/ # installable skill payload (symlink this)
β βββ SKILL.md # agent workflow & triggers
β βββ scripts/
β β βββ codespot # main CLI
β β βββ scope.py # git scope calculation
β β βββ setup_engine.py # installer (binary/zip/npm/venv/raw)
β β βββ rules-severity.json # severity mapping
β β βββ engines/ # common.py + engine_*.py adapters + registry.json
β βββ assets/ # default engine configs (ruff / oxlint / eslint / pmd)
β βββ assets/ # default engine configs (ruff / oxlint / eslint / pmd)
βββ tests/fixtures/ # selftest fixtures (dev asset, not installed)
βββ docs/ # research, reports & branding (not part of the skill)
β βββ feasibility-research.md # feasibility study
β βββ project-report.md / .html # project report
β βββ validation-report.html # validation report
β βββ assets/logo.svg # product logo
βββ openspec/ # spec-driven development history
βββ config.yaml # openspec configuration
βββ specs/ # capability specs (one dir per capability)
βββ changes/archive/ # archived change proposals (proposal / design / tasks / specs)
- After
setup,update-rulesand one warm-up scan (once, online), everything except dependency scanning works offline; dependency scans need osv.dev. - Windows: supported and continuously validated by the GitHub Actions matrix on
ubuntu/macos/windows(setup Γ2, selftest, smoke scan) β see the CI badge above. Every engine works natively except Semgrep, which has no Windows build: codespot skips it with a console notice, so thesemanticcategory needs WSL2. - Windows install: symlinks need developer mode/admin, so a plain copy works too β
robocopy skill "%USERPROFILE%\.agents\skills\codespot" /E(or into.claude\skills/,.codex\skills/), then run the CLI aspython ...\scripts\codespot setup.
- Type-aware JS/TS rules are off (need tsconfig); SpotBugs layer needs a buildable project (PMD still covers source-level).
- Dockerfile (no extension) isn't language-detected; cover via
semgrep_config. - SQLFluff on py3.9 machines runs the 3.x line (4.x needs python β₯ 3.10).
Internal use only. Engines are downloaded at runtime from official sources and never bundled; Semgrep CE registry rules are used under the Semgrep Rules License "internal business purposes" terms, and TruffleHog is AGPL-3.0 β do not sell or externally distribute codespot with these engines enabled. See README.zh.md for the full Chinese documentation.