goodbot-ai
v0.13.0
Published
Auto-generate AI agent guardrail files for your project. Train your AI to be a good bot.
Downloads
2,530
Maintainers
Readme
Why goodbot
AI agents are powerful but they don't know your rules. Without guardrails, they create god files, mix business logic into UI components, bypass your layer boundaries, and drift across agents (your CLAUDE.md says one thing, your .cursorrules says another).
goodbot solves three problems:
- Generate once, use everywhere. One source of truth →
CLAUDE.md,.cursorrules,.windsurfrules,AGENTS.md,CODING_GUIDELINES.md. - Make the rules adaptive. Scans your actual codebase for framework conventions, architectural layers, and real violations — so guardrails match your code, not a generic template.
- Detect when they go stale. As your codebase evolves, goodbot tracks drift between what the guardrails claim and what the code actually looks like.
Install & run (60 seconds)
npx goodbot-ai init # interactive, or add --preset recommended
npx goodbot-ai generate # writes CLAUDE.md, CODING_GUIDELINES.md, etc.That's it. On first run goodbot scans your project, runs an architectural analysis, detects your framework's conventions (e.g. NestJS modules, React hooks), and generates guardrail files tailored to what it found. It saves an analysis snapshot so future runs can show you what's changed.
Skip the prompts with a preset (safe for CI):
npx goodbot-ai init --preset recommended --on-conflict merge| Preset | What you get |
|--------|-------------|
| strict | Barrel imports enforced, interface contracts, all agent files, tight thresholds |
| recommended | Balanced defaults — barrel imports recommended, all agent files |
| relaxed | Minimal guardrails — just the basic generated files |
Run goodbot presets to see a side-by-side comparison.
The goodbot lifecycle
goodbot is designed to fit into your team's workflow at four moments:
1. Day 1 — Onboard the codebase
npx goodbot-ai init --preset recommended
npx goodbot-ai generate
git add CLAUDE.md CODING_GUIDELINES.md .cursorrules .windsurfrules AGENTS.md .cursorignore .goodbot/config.json .goodbot/.gitignore
git commit -m "Add AI agent guardrails"goodbot detects whether you're building an API, a UI, a full-stack app, or a library, and applies the right stability ordering (Stable Dependency Principle) for that system type. For a NestJS API: controllers depend on services depend on repositories depend on domain. For a React app: screens depend on hooks depend on services depend on types.
Your team's AI agents now have a shared understanding of:
- Which layers exist and their ordering
- Where business logic belongs vs where it doesn't
- Framework-specific red flags (e.g. "business logic in NestJS controllers")
- SOLID and design principles framed for your specific framework
- Current architectural health (grade + top issues)
Safe re-runs: if CLAUDE.md (or any agent file) already exists, goodbot wraps its content in
<!-- goodbot:start/end -->markers and prepends at the top — your team notes below are preserved.
2. Day 2+ — AI agents stay aligned
No action needed. Your agents read the generated files automatically. If you tweak a rule (e.g. add a line to conventions.customRules in .goodbot/config.json), re-run generate:
npx goodbot-ai generate # fast — reuses cached snapshotQuick re-runs reuse the last analysis snapshot so the Current Health block still renders without a full scan. Pass --analyze to refresh the analysis:
npx goodbot-ai generate --analyze3. On every PR — catch drift in CI
Install git hooks locally, add a CI step, and goodbot catches new violations before they merge:
# Local — once per dev machine
npx goodbot-ai hooks install# .github/workflows/goodbot.yml
on: [pull_request]
jobs:
guardrails:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx goodbot-ai check --strict # drift + stale suppressions
- run: npx goodbot-ai freshness # health claims still accurate?
- run: npx goodbot-ai diff --freshness # did THIS PR move the grade?Or use the official GitHub Action for PR comments with emoji bars:
- uses: timeritual/goodbot-ai@main
with:
mode: diff
comment: 'true'
fail-on-grade: C4. Periodically — audit and refresh
Once a month (or when the analysis snapshot is 7+ days old), run:
npx goodbot-ai freshness # what's stale? what's degraded?
npx goodbot-ai generate --analyze --force # refresh guardrailsfreshness compares the snapshot goodbot saved at generation time against the current state of the codebase — and tells you exactly which claims have drifted:
Guardrail Freshness Report (generated 12 days ago)
───────────────────────────────────────────────────────
Health grade A → B+ ⚠ stale
Circular dependencies 0 → 2 ✗ degraded (+2)
Dead exports 0 → 3 ✗ degraded (+3)
Barrel violations 5 → 3 ↑ improved (-2)
✗ Your guardrails are stale. Run `goodbot generate --analyze --force` to update.5. When things change — re-init safely
Framework upgrade? Added a new top-level directory? Run init again:
npx goodbot-ai init --preset recommendedYour customizations are preserved. goodbot refreshes only the scan-detected fields (framework, layers, system type) and keeps everything you've hand-edited (verification commands with custom flags, custom rules, suppressions, thresholds, budgets). A diff of what changed prints before the save. Pass --force only if you want to blow everything away.
What gets generated
| File | Read by | Contents |
|------|---------|----------|
| CODING_GUIDELINES.md | All agents + humans | Single source of truth — architecture diagram, SOLID + design principles, business logic rules, detected framework conventions, "Known Issues" list, verification checklist |
| CLAUDE.md | Claude Code, Claude in IDEs | Quick reference + current health snapshot, points to CODING_GUIDELINES.md |
| .cursorrules / .windsurfrules / AGENTS.md | Cursor / Windsurf / Codex | Point to CODING_GUIDELINES.md — eliminates cross-agent drift |
| .cursorignore | Cursor | Keeps build artifacts, secrets, noise out of AI context |
Plus internal state in .goodbot/:
| File | Commit? |
|------|---------|
| .goodbot/config.json | Yes — your shared team config |
| .goodbot/.gitignore | Yes — auto-created, ignores the rest |
| .goodbot/snapshot.json, checksums.json, history.json | No — local analysis state |
Essential commands
| Command | What it does |
|---------|--------------|
| goodbot init | Set up .goodbot/config.json. Merges into existing config by default (preserves customizations); --force overwrites. |
| goodbot generate | Write/refresh the guardrail files. Safe to re-run — preserves user content via markers. |
| goodbot check | Verify generated files haven't drifted. --strict also fails on stale suppressions. CI-friendly (exit 1). |
| goodbot freshness | Compare snapshot claims to current reality. Tells you what's stale. |
| goodbot analyze | Full architectural audit — dependency graph, SOLID, layer violations, health grade. |
| goodbot diff | Show violations introduced by the current branch (vs base). Great for PR review. |
| goodbot hooks install | Install git hooks that warn on stale guardrails. |
| goodbot suppress | List detected violations with content-based IDs; emit paste-ready suppression JSON. --apply --reason "..." writes to config. |
| goodbot unsuppress <id> | Remove a suppression from analysis.suppressions by its content-based ID. |
| goodbot score | One-line health grade. Fast enough for pre-commit hooks. |
| goodbot presets | Side-by-side comparison of the strict/recommended/relaxed presets. |
Run any command with --help for full flags. Other commands available but less frequently used: scan, watch, fix, pr, onboard, trend, sync, report, ci.
Framework support
goodbot auto-detects your framework and applies a canonical layer ordering + framework-specific conventions.
| Framework | System type | Canonical layers | |-----------|-------------|------------------| | React / React Native | UI | types → utils → api → services → state → hooks → components → screens → navigation | | Angular | UI | types → services → pipes → directives → interceptors → guards → components → NgModules → pages | | Vue | UI | types → services → stores → composables → plugins → components → layouts → pages → router | | Next.js / Nuxt | Mixed | Combines API and UI layers — server routes at low level, pages at top | | NestJS | API | domain → config → repositories → infrastructure → services → modules → cross-cutting → controllers | | Express / Node | API | domain → config → services → routes/middleware → controllers |
Plus reasonable defaults for Django, Flask, FastAPI, and Go (framework detection works; deep analysis is TypeScript/JavaScript only for now).
For NestJS specifically, goodbot also detects decorator-based patterns (*.controller.ts, *.module.ts, *.entity.ts, guards, interceptors, pipes) and surfaces them in CODING_GUIDELINES.md so agents follow your project's real conventions.
Unknown framework? goodbot treats it as a library and still produces sensible guardrails.
Configuration
All config lives in .goodbot/config.json. It's meant to be committed and shared across the team. The key sections:
{
"project": { "name": "...", "framework": "...", "language": "..." },
"architecture": { "systemType": "api", "layers": [...], "barrelImportRule": "recommended" },
"businessLogic": { "allowedIn": ["services"], "forbiddenIn": ["controllers", "guards"] },
"verification": { "typecheck": "npm run typecheck", "lint": "npm run lint", "test": "npm test" },
"conventions": { "mainBranch": "main", "customRules": ["Project-specific rule"] },
"analysis": {
"thresholds": { "maxFileLines": 300, "maxBarrelExports": 15 },
"budget": { "circular": 0, "srp": 10 },
"exclude": { "circularDep": ["**/entities/**"] }, // analysis-scoped exclusions — singular keys match `suppressions[].rule`
"suppressions": [{ "rule": "layerViolation", "file": "src/scripts/migrate.ts", "reason": "..." }]
},
"output": { "cursorignore": { "paths": ["dist", "build"], "sensitiveFiles": [".env"] } }
}Old configs with ignore.paths, analysis.ignore, or plural circularDeps keys still load — goodbot auto-migrates them and prints a deprecation warning. Re-save the config to persist the canonical shape.
Edit directly or re-run goodbot init to regenerate (merges by default, preserves your edits).
Managing violations
Four knobs, pick based on intent:
| Knob | Scope | When to use |
|------|-------|-------------|
| analysis.suppressions | Exact file/cycle + rule + required reason | You accept this specific violation intentionally. Shows as (N suppressed) in output. |
| analysis.exclude.* | Glob pattern per check category | Well-known false positives (TypeORM entity cycles, generated code). Doesn't appear at all. |
| .goodbot/ignore | File paths → all checks | Legacy / vendored code you never want analyzed. |
| Violation budgets | Per-category threshold | Known debt you want visible but not failing CI until it grows past a limit. |
ignore.paths in config only affects .cursorignore output — it does NOT suppress analysis. Use one of the four knobs above.
Use goodbot suppress to add suppressions safely. IDs are content-based and stable — the ID for a cycle stays the same while the cycle exists, and disappears when you fix it. No more hand-typing Unicode ↔ or cycle patterns.
$ goodbot suppress
[cycle-app-database] cycle: app → database → app
[layer-src-scripts-migrate] src/scripts/migrate.ts (L4 → L5)
[oversized-src-generated-schema] src/generated/schema.ts: File has 6000 lines
$ goodbot suppress cycle-app-database --reason "Bootstrap wiring" --apply
✓ Added suppression to .goodbot/config.json
$ goodbot unsuppress cycle-app-database
✓ Removed suppression: circularDep cycle="database ↔ app"--apply requires a real --reason (min 8 chars, no literal TODO: placeholders) so nothing undocumented reaches main.
Goodbot also warns loudly on every analyze/generate about any suppression that matches no detected violation — so typos / stale entries can't silently disable guardrails. If a CI script references cycle-app-database and the cycle is fixed, the next run errors clearly ("No violation with that id") instead of silently suppressing the wrong thing.
What's new in 0.13
analysis.ignorerenamed toanalysis.exclude. Disambiguates fromoutput.cursorignore— the word "ignore" now only appears in the filename-scoped cursorignore. Oldanalysis.ignorestill loads, auto-migrates on save with a deprecation warning.
What's new in 0.12
goodbot check --strictfor CI enforcement. Orphaned suppressions (entries that no longer match any detected violation) previously only printed a warning — CI wouldn't catch them. Nowgoodbot check --strictruns the analysis, verifies every suppression still targets a real violation, and exits 1 if any are orphaned. Add it to your CI pipeline so stale suppressions can't silently reachmain.
What's new in 0.11
goodbot unsuppress <id>closes the loop. Adding a suppression was one command; removing one required hand-editing JSON. Now both use the same content-based IDs —goodbot unsuppress cycle-app-databaseremoves the matching entry cleanly.--applyrequires a real--reason. Empty, literalTODO:placeholders, and too-short (<8 chars) reasons are rejected before writing to config. No more "TODO: explain why..." placeholders reaching main.- Husky v9 hooks install fix.
goodbot hooks installnow correctly installs into.husky/(user-facing) when husky v9 is detected, instead of.husky/_/(husky's internal regenerated dir). Previously goodbot's hooks were wiped silently on the nextnpm install.
What's new in 0.10
- Consistent singular rule names.
analysis.ignore.*keys now matchanalysis.suppressions[].rule— both use singular (circularDep,layerViolation,oversizedFile). Old plural keys still work and are auto-migrated on load with a deprecation warning. output.cursorignorereplaces top-levelignore. The oldignore.pathsfield (which only affected.cursorignore, not analysis — a frequent source of confusion) is nowoutput.cursorignore.paths. Auto-migrated on load.- Stable content-based suppression IDs. The IDs emitted by
goodbot suppressare now content-based and invariant (e.g.cycle-app-database,layer-src-scripts-migrate,oversized-src-user-service) instead of positional (c0,l0). As long as the violation exists, the ID stays the same. When you fix it, the ID simply disappears — CI scripts that reference a fixed violation's ID fail loudly instead of silently suppressing the wrong thing.
What's new in 0.9
- Orphaned-suppression warnings. Suppressions that match no detected violation (typo in cycle pattern, renamed/deleted file, already-fixed bug) are flagged loudly on every
analyzeandgenerate. No more silently-dead suppressions lurking in config. goodbot suppresscommand. Lists suppressible violations with IDs and emits paste-ready JSON.goodbot suppress <id> --reason "..." --applywrites to config for you. No need to hand-type the Unicode↔character anymore.- Broader cycle syntax.
analysis.suppressions[*].cyclenow accepts all common forms:a → b,a ↔ b,a -> b,a <-> b,a,b,a > b, and the human-natural loop forma → b → a. All normalize to the same canonical cycle.
What's new in 0.8
- Re-init preserves customizations.
goodbot init --preset recommendedno longer clobbers hand-edited fields. Refreshes scan-detected fields (framework, layers), preserves everything else.--forcefor full overwrite. - Per-rule suppressions with reasons. Accept a specific violation intentionally via
analysis.suppressions. Each entry needs arule + file(orrule + cycle) and areason. Shows as(N suppressed)in output. - Next-step prompts. After
initandgenerate, the CLI surfaces the highest-value next actions (generate, install hooks, check freshness, add to CI) instead of a single-line hint. - Cached snapshot reuse. Quick
generatere-runs render the Current Health block from the last snapshot without re-scanning — pass--analyzeto refresh.
Supported agents
Works with anything that reads one of the standard guardrail files:
- Claude Code, Claude in Cursor / VS Code / IDE extensions — via
CLAUDE.md - Cursor — via
.cursorrules+.cursorignore - Windsurf — via
.windsurfrules - OpenAI Codex — via
AGENTS.md - GitHub Copilot / any other agent — via
CODING_GUIDELINES.md(the single source of truth all other files point to)
Why "goodbot"?
AI coding agents are like eager interns — fast, capable, and in desperate need of clear rules. goodbot is obedience training for your AI: set the rules once, enforce them everywhere, catch drift before it ships.
Contributing
git clone https://github.com/timeritual/goodbot-ai.git
cd goodbot-ai
npm install
npx tsx src/index.ts --help # run in dev modeIssues and PRs welcome.
License
MIT
