Skip to content

timeritual/goodbot-ai

Repository files navigation

npm version node version license supported agents

goodbot

Train your AI to be a good bot.
Auto-generate guardrail files that keep Claude, Cursor, Windsurf, Codex and Copilot aligned with your project's conventions — then detect when they go stale.

npx goodbot-ai init && npx goodbot-ai generate


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:

  1. Generate once, use everywhere. One source of truth → CLAUDE.md, .cursorrules, .windsurfrules, AGENTS.md, CODING_GUIDELINES.md.
  2. 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.
  3. Detect when they go stale. As your codebase evolves, goodbot tracks drift between what the guardrails claim and what the code actually looks like.

New here? Read HOW_IT_WORKS.md for a plain-English walkthrough with a diagram of the full pipeline — what goodbot reads from your project, what it writes, and how drift detection works.


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 snapshot

Quick 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 --analyze

3. 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: C

4. 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 guardrails

freshness 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 recommended

Your 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.ignore renamed to analysis.exclude. Disambiguates from output.cursorignore — the word "ignore" now only appears in the filename-scoped cursorignore. Old analysis.ignore still loads, auto-migrates on save with a deprecation warning.

What's new in 0.12

  • goodbot check --strict for CI enforcement. Orphaned suppressions (entries that no longer match any detected violation) previously only printed a warning — CI wouldn't catch them. Now goodbot check --strict runs 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 reach main.

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-database removes the matching entry cleanly.
  • --apply requires a real --reason. Empty, literal TODO: 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 install now 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 next npm install.

What's new in 0.10

  • Consistent singular rule names. analysis.ignore.* keys now match analysis.suppressions[].rule — both use singular (circularDep, layerViolation, oversizedFile). Old plural keys still work and are auto-migrated on load with a deprecation warning.
  • output.cursorignore replaces top-level ignore. The old ignore.paths field (which only affected .cursorignore, not analysis — a frequent source of confusion) is now output.cursorignore.paths. Auto-migrated on load.
  • Stable content-based suppression IDs. The IDs emitted by goodbot suppress are 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 analyze and generate. No more silently-dead suppressions lurking in config.
  • goodbot suppress command. Lists suppressible violations with IDs and emits paste-ready JSON. goodbot suppress <id> --reason "..." --apply writes to config for you. No need to hand-type the Unicode character anymore.
  • Broader cycle syntax. analysis.suppressions[*].cycle now accepts all common forms: a → b, a ↔ b, a -> b, a <-> b, a,b, a > b, and the human-natural loop form a → b → a. All normalize to the same canonical cycle.

What's new in 0.8

  • Re-init preserves customizations. goodbot init --preset recommended no longer clobbers hand-edited fields. Refreshes scan-detected fields (framework, layers), preserves everything else. --force for full overwrite.
  • Per-rule suppressions with reasons. Accept a specific violation intentionally via analysis.suppressions. Each entry needs a rule + file (or rule + cycle) and a reason. Shows as (N suppressed) in output.
  • Next-step prompts. After init and generate, 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 generate re-runs render the Current Health block from the last snapshot without re-scanning — pass --analyze to 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)

Troubleshooting

I already have a CLAUDE.md with my team's notes — will goodbot overwrite it?

No. Goodbot wraps its content between <!-- goodbot:start --> / <!-- goodbot:end --> markers and prepends at the top. Your content below the markers is preserved across every re-run. On regeneration, only the marker section is replaced. You can change this via agentFiles.existingFileStrategy in config (merge / overwrite / skip) or pass --on-conflict to init.

Running init a second time wiped my custom typecheck command.

It shouldn't, as of 0.8.0. Re-running init now merges the preset into your existing config — only scan-detected fields (framework, layers, systemType) get refreshed, everything you've hand-edited (verification commands, custom rules, suppressions, thresholds) is preserved. If you want a full reset, pass --force. If you're on an older version, upgrade: npm install -g goodbot-ai@latest.

My CI passes but a stale suppression is hiding a real violation.

Add --strict to goodbot check in CI — it fails when any analysis.suppressions entry no longer matches a real detected violation, so stale entries can't silently disable guardrails.

- run: npx goodbot-ai check --strict

Locally, goodbot suppress (no args) lists current violations with IDs, and goodbot analyze flags orphaned suppressions loudly in stderr.

Circular dependency count is inflated by ORM entity relationships (TypeORM, Mongoose).

The recommended preset for NestJS / Express / Node / FastAPI / Django / Flask automatically adds analysis.exclude.circularDep: ["**/entities/**", "**/models/**", "**/schemas/**"], which drops cycles whose files all match the pattern. If you have entities in a different directory, add your path to that list.

For a specific cycle you want to accept (with a reason), use goodbot suppress cycle-<modules>.

Goodbot installed git hooks but npm install seems to overwrite them.

Fixed in 0.11.0. Husky v9 sets core.hooksPath=.husky/_ (husky's internal dir, regenerated on every install). Goodbot now detects this and installs into .husky/ (user-facing) instead, so changes survive husky reinstalls. Upgrade to 0.11.0+ if you're hitting this.

The freshness report says "stale" even though my changes improved the codebase.

"Stale" means "your snapshot no longer reflects reality" — regardless of direction. Improvements are tracked too (look for ↑ improved rows in the report). After major improvements, re-run goodbot generate --analyze --force to refresh the snapshot so the baseline reflects your new state.

Main branch detected as "main" but ours is "development".

As of 0.6.3, goodbot detects the default branch via (in order): local origin/HEADgit ls-remote --symref origin HEAD (authoritative network call, 5s timeout) → commit-count heuristic across main/master/development/develop/trunk. If ls-remote fails (e.g. private repo without credentials in the CLI context), it falls back to the branch with the most commits — which for GitFlow-style repos correctly picks development.

You can always edit conventions.mainBranch directly in .goodbot/config.jsoninit will preserve that on re-runs.


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 mode

Two docs to orient:

  • HOW_IT_WORKS.md — end-user mental model (what goodbot does, what state it keeps, how drift detection works).
  • ARCHITECTURE.md — contributor map (subsystem layout, key design decisions, extension points).

Issues and PRs welcome.


License

MIT

Built by timeritual

About

Auto-generate AI agent guardrail files for your project. Train your AI to be a good bot.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors