{"id":45097136,"url":"https://github.com/mauhpr/agentlint","last_synced_at":"2026-05-10T23:02:20.159Z","repository":{"id":339427461,"uuid":"1160371429","full_name":"mauhpr/agentlint","owner":"mauhpr","description":"Real-time guardrails for AI coding agents — code quality, security, and infrastructure safety. 57 rules across 8 packs for Claude Code.","archived":false,"fork":false,"pushed_at":"2026-03-10T19:21:48.000Z","size":373,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-10T20:42:29.061Z","etag":null,"topics":["ai-agents","claude-code","cli","code-quality","developer-tools","guardrails","hooks","linting","python","security"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/agentlint/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mauhpr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-17T21:29:23.000Z","updated_at":"2026-03-10T19:14:08.000Z","dependencies_parsed_at":"2026-02-24T00:01:24.161Z","dependency_job_id":null,"html_url":"https://github.com/mauhpr/agentlint","commit_stats":null,"previous_names":["mauhpr/agentlint"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/mauhpr/agentlint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauhpr%2Fagentlint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauhpr%2Fagentlint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauhpr%2Fagentlint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauhpr%2Fagentlint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mauhpr","download_url":"https://codeload.github.com/mauhpr/agentlint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauhpr%2Fagentlint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30355223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:55:29.454Z","status":"ssl_error","status_checked_at":"2026-03-10T15:54:58.440Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","claude-code","cli","code-quality","developer-tools","guardrails","hooks","linting","python","security"],"created_at":"2026-02-19T19:05:42.905Z","updated_at":"2026-05-10T23:02:20.150Z","avatar_url":"https://github.com/mauhpr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentlint\n\n[![CI](https://github.com/mauhpr/agentlint/actions/workflows/ci.yml/badge.svg)](https://github.com/mauhpr/agentlint/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/mauhpr/agentlint/branch/main/graph/badge.svg)](https://codecov.io/gh/mauhpr/agentlint)\n[![PyPI](https://img.shields.io/pypi/v/agentlint)](https://pypi.org/project/agentlint/)\n[![Python](https://img.shields.io/pypi/pyversions/agentlint)](https://pypi.org/project/agentlint/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nReal-time guardrails for AI coding agents — code quality, security, and infrastructure safety.\n\nWorks with **Claude Code**, **Cursor**, **Kimi**, **Grok**, **Gemini**, **Codex**, **Continue.dev**, **OpenAI Agents SDK**, **MCP hosts**, and custom frameworks.\n\nAI coding agents drift during long sessions — they introduce API keys into source, skip tests, force-push to main, and leave debug statements behind. AgentLint catches these problems *as they happen*, not at review time.\n\nArchitecture overview: [docs/architecture.md](docs/architecture.md)\n\n## Vision\n\nThe short-term problem is code quality: secrets, broken tests, force-pushes, debug artifacts. AgentLint solves that today with 76 rules that run locally in milliseconds.\n\nThe longer-term question is harder: **what does it mean for an agent to operate safely on real infrastructure?** When an agent can run `gcloud`, `kubectl`, `terraform`, or `iptables`, the blast radius is no longer a bad commit — it's a production outage or a deleted database.\n\nWe don't have a mature answer to that yet. Nobody does. The **autopilot pack** is our first experiment in that direction — explicit, opt-in, and clearly labeled as such. The goal is to start building the intuition and tooling for autonomous agent safety at the infrastructure level, and to do it in the open.\n\n## What it catches\n\nAgentLint ships with 76 rules across 8 packs and normalizes tool events across supported AI coding agents. The 23 **universal** rules and 7 **quality** rules work with any tech stack; 4 additional packs auto-activate based on your project files; the **security** pack is opt-in; and the **autopilot** pack is opt-in and experimental.\n\n**v2.2.0 highlights:** Public documentation cleanup, platform-neutral setup flow in the core README, and removal of internal planning/release artifacts from the package repository. Previous: AgentChute-ready team sync, hybrid cloud feeds, privacy-safe event queueing, multi-platform adapter architecture, unified `AgentEvent` taxonomy, `NormalizedTool` cross-platform mappings, session summary dashboard, MCP server, global config defaults, warning suppression, auto-suppress, `diff_only` mode, and `auto-fix` mode.\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `no-secrets` | ERROR | Blocks writes containing API keys, tokens, passwords, private keys, JWTs |\n| `no-env-commit` | ERROR | Blocks writing `.env` files (including via Bash) |\n| `no-force-push` | ERROR | Blocks `git push --force` to main/master |\n| `no-push-to-main` | WARNING | Warns on direct push to main/master |\n| `no-skip-hooks` | WARNING | Warns on `git commit --no-verify` |\n| `no-destructive-commands` | WARNING | Warns on `rm -rf`, `DROP TABLE`, `chmod 777`, `mkfs`, and more |\n| `no-test-weakening` | WARNING | Detects skipped tests, `assert True`, commented-out assertions |\n| `dependency-hygiene` | WARNING | Warns on ad-hoc `pip install` / `npm install` |\n| `max-file-size` | WARNING | Warns when a file exceeds 500 lines |\n| `drift-detector` | WARNING | Warns after many edits without running tests |\n| `no-debug-artifacts` | WARNING | Detects `console.log`, `print()`, `debugger` left in code |\n| `test-with-changes` | WARNING | Warns if source changed but no tests were updated |\n| `token-budget` | WARNING | Tracks session activity and warns on excessive tool usage |\n| `cicd-pipeline-guard` | ERROR | Blocks CI/CD pipeline changes without approval |\n| `package-publish-guard` | ERROR | Blocks `npm publish`, `twine upload`, `gem push` |\n| `file-scope` | ERROR | Restricts file access via allow/deny globs |\n| `cli-integration` | configurable | Runs external CLI tools (ruff, eslint, etc.) on file changes |\n| `git-checkpoint` | INFO | Creates git stash before destructive ops (opt-in, disabled by default) |\n| `no-todo-left` | INFO | Reports TODO/FIXME comments in changed files |\n| `no-compromised-dependency` | ERROR | Blocks installs of packages on AgentChute's compromised-package feed |\n| `no-vulnerable-version-install` | ERROR | Blocks pinned installs of versions known vulnerable in GHSA data |\n| `no-vulnerable-import` | WARNING | Warns when importing packages with active GHSA advisories |\n| `token-burn-against-team-budget` | WARNING | Warns when AgentChute reports team-level budget pressure |\n\n**ERROR** rules block the agent's action. **WARNING** rules inject advice into the agent's context. **INFO** rules appear in the session report.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eQuality pack\u003c/strong\u003e (7 rules) — always active alongside universal\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `commit-message-format` | WARNING | Validates commit messages follow conventional format |\n| `no-error-handling-removal` | WARNING | Warns when try/except or .catch() blocks are removed |\n| `no-large-diff` | WARNING | Warns when a single edit adds \u003e200 or removes \u003e100 lines |\n| `no-file-creation-sprawl` | WARNING | Warns when \u003e10 new files created in a session |\n| `naming-conventions` | INFO | Checks file names match language conventions (snake_case, camelCase, PascalCase) |\n| `no-dead-imports` | INFO | Detects unused imports in Python and JS/TS files |\n| `self-review-prompt` | INFO | Injects adversarial self-review prompt at session end |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ePython pack\u003c/strong\u003e (6 rules) — auto-activates when \u003ccode\u003epyproject.toml\u003c/code\u003e or \u003ccode\u003esetup.py\u003c/code\u003e exists\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `no-bare-except` | WARNING | Prevents bare `except:` clauses that swallow all exceptions |\n| `no-unsafe-shell` | ERROR | Blocks unsafe shell execution via subprocess or os module |\n| `no-dangerous-migration` | WARNING | Warns on risky Alembic migration operations |\n| `no-wildcard-import` | WARNING | Prevents `from module import *` |\n| `no-unnecessary-async` | INFO | Flags async functions that never use `await` |\n| `no-sql-injection` | ERROR | Blocks SQL via string interpolation (f-strings, `.format()`) |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFrontend pack\u003c/strong\u003e (8 rules) — auto-activates when \u003ccode\u003epackage.json\u003c/code\u003e exists\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `a11y-image-alt` | WARNING | Ensures images have alt text (WCAG 1.1.1) |\n| `a11y-form-labels` | WARNING | Ensures form inputs have labels or `aria-label` |\n| `a11y-interactive-elements` | WARNING | Checks ARIA attributes and link anti-patterns |\n| `a11y-heading-hierarchy` | INFO | Ensures no skipped heading levels or multiple h1s |\n| `mobile-touch-targets` | WARNING | Ensures 44x44px minimum touch targets (WCAG 2.5.5) |\n| `mobile-responsive-patterns` | INFO | Warns about desktop-only layout patterns |\n| `style-no-arbitrary-values` | INFO | Warns about arbitrary Tailwind values bypassing tokens |\n| `style-focus-visible` | WARNING | Ensures focus indicators are not removed (WCAG 2.4.7) |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eReact pack\u003c/strong\u003e (3 rules) — auto-activates when \u003ccode\u003ereact\u003c/code\u003e is in \u003ccode\u003epackage.json\u003c/code\u003e dependencies\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `react-query-loading-state` | WARNING | Ensures `useQuery` results handle loading and error states |\n| `react-empty-state` | INFO | Suggests empty state handling for `array.map()` in JSX |\n| `react-lazy-loading` | INFO | Suggests lazy loading for heavy components in page files |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSEO pack\u003c/strong\u003e (4 rules) — auto-activates when an SSR/SSG framework (Next.js, Nuxt, Gatsby, Astro, etc.) is detected\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `seo-page-metadata` | WARNING | Ensures page files include title and description |\n| `seo-open-graph` | INFO | Ensures pages with metadata include Open Graph tags |\n| `seo-semantic-html` | INFO | Encourages semantic HTML over excessive divs |\n| `seo-structured-data` | INFO | Suggests JSON-LD structured data for content pages |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSecurity pack\u003c/strong\u003e (7 rules) — opt-in, add \u003ccode\u003esecurity\u003c/code\u003e to your packs list\u003c/summary\u003e\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `no-bash-file-write` | ERROR | Blocks file writes via Bash (`cat \u003e`, `tee`, `sed -i`, `cp`, heredocs, etc.) |\n| `no-network-exfil` | ERROR | Blocks data exfiltration via `curl POST`, `nc`, `scp`, `wget --post-file` |\n| `env-credential-reference` | WARNING | Warns when `*_FILE` env vars reference local paths (credential leakage risk) |\n| `no-leaked-secret-pattern` | ERROR | Blocks patterns from AgentChute's cloud-curated secret ruleset |\n| `no-malicious-url-fetch` | ERROR | Blocks fetches of known-malicious URLs from URLhaus-derived feeds |\n| `no-blocked-domain-fetch` | ERROR | Blocks fetches from blocked malware/ad/tracker domains |\n| `no-compromised-action` | ERROR | Blocks GitHub Actions pinned to compromised advisories |\n\nThe security pack addresses the most common agent escape hatch: bypassing Write/Edit guardrails via the Bash tool. Enable it by adding `security` to your packs list:\n\n```yaml\npacks:\n  - universal\n  - security  # Blocks Bash file writes and network exfiltration\n```\n\nConfigure allowlists for legitimate use cases:\n\n```yaml\nrules:\n  no-bash-file-write:\n    allow_patterns: [\"echo.*\u003e\u003e.*\\\\.log\"]  # Allow appending to logs\n    allow_paths: [\"*.log\", \"/tmp/*\"]       # Allow writes to temp/log\n  no-network-exfil:\n    allowed_hosts: [\"internal.corp.com\"]   # Allow specific hosts\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAutopilot pack\u003c/strong\u003e (18 rules) — ⚠️ experimental, opt-in\u003c/summary\u003e\n\n\u003e **Alpha quality.** The autopilot pack is an early experiment in agent safety guardrails for cloud and infrastructure operations. Regex-based heuristics will produce false positives and false negatives — a mature framework for this problem doesn't exist yet. Enable it, experiment with it, report what breaks. Use at your own risk in production environments.\n\n| Rule | Severity | What it does |\n|------|----------|-------------|\n| `production-guard` | ERROR | Blocks Bash commands targeting production databases, gcloud projects, or AWS accounts |\n| `destructive-confirmation-gate` | ERROR | Blocks DROP DATABASE, terraform destroy, kubectl delete namespace, etc. without explicit acknowledgment |\n| `dry-run-required` | WARNING | Requires --dry-run/--check/plan preview before terraform apply, kubectl apply, ansible-playbook, helm upgrade/install, and pulumi up |\n| `bash-rate-limiter` | WARNING | Circuit-breaks after N destructive commands within a time window (default: 5 ops / 300s) |\n| `cross-account-guard` | WARNING | Warns when the agent switches between gcloud projects or AWS profiles mid-session |\n| `operation-journal` | INFO | Records every Bash and file-write operation to an in-session audit log; emits a summary at Stop |\n| `cloud-resource-deletion` | ERROR | Blocks AWS/GCP/Azure resource deletion without session confirmation |\n| `cloud-infra-mutation` | ERROR | Blocks NAT, firewall, VPC, IAM, and load balancer mutations across AWS/GCP/Azure |\n| `cloud-paid-resource-creation` | WARNING | Warns when creating paid cloud resources (VMs, DBs, static IPs) |\n| `system-scheduler-guard` | WARNING | Warns on crontab, systemctl enable, launchctl, scheduler file writes |\n| `network-firewall-guard` | ERROR | Blocks iptables flush, ufw disable, firewalld permanent rules, and default route changes |\n| `docker-volume-guard` | WARNING/ERROR | Blocks privileged containers (ERROR); warns on volume deletion and force-remove (WARNING) |\n| `ssh-destructive-command-guard` | WARNING/ERROR | Detects destructive commands via SSH (`rm -rf`, `mkfs`, `dd`, `reboot`, `iptables flush`, `terraform destroy`) |\n| `remote-boot-partition-guard` | ERROR | Blocks `rm` or `dd` targeting `/boot` kernel and bootloader files via SSH |\n| `remote-chroot-guard` | WARNING/ERROR | Detects bootloader package removal and risky repair commands inside chroot |\n| `package-manager-in-chroot` | WARNING | Warns on `apt`/`dpkg`/`yum`/`dnf`/`pacman` usage inside chroot environments |\n| `subagent-safety-briefing` | INFO | Injects safety notice into subagent context on spawn (SubagentStart) |\n| `subagent-transcript-audit` | WARNING | Audits subagent transcripts for dangerous commands post-execution (SubagentStop) |\n\n**Subagent safety:** Parent session hooks don't fire for subagent tool calls — this is a Claude Code architectural property. The autopilot pack addresses this with safety briefing injection (SubagentStart) and post-hoc transcript auditing (SubagentStop). AgentLint's own plugin agents also have frontmatter PreToolUse hooks for real-time blocking. See [docs/subagent-safety.md](docs/subagent-safety.md) for details.\n\nEnable by adding `autopilot` to your packs list:\n\n```yaml\npacks:\n  - universal\n  - autopilot\n```\n\nFeedback welcome — open an issue if a rule blocks something legitimate or misses something it should catch.\n\n\u003c/details\u003e\n\n### Stack auto-detection\n\nWhen `stack: auto` (the default), AgentLint detects your project and activates matching packs:\n\n| Detected file | Pack activated |\n|--------------|----------------|\n| `pyproject.toml` or `setup.py` | `python` |\n| `package.json` | `frontend` |\n| `react` in package.json dependencies | `react` |\n| SSR/SSG framework in dependencies (Next.js, Nuxt, Gatsby, Astro, SvelteKit, Remix) | `seo` |\n| `AGENTS.md` with relevant keywords | Additional packs based on content |\n\nThe `universal` and `quality` packs are always active. To override auto-detection, list packs explicitly in `agentlint.yml`.\n\n## Quick start\n\nPick the AI coding agent you actually use:\n\n```bash\npip install agentlint\ncd your-project\nagentlint setup claude    # Claude Code\nagentlint setup cursor    # Cursor\nagentlint setup codex     # Codex CLI\nagentlint setup gemini    # Gemini CLI\n```\n\nRun `agentlint setup --help` for the full platform list. `agentlint setup` resolves the absolute path to the binary, so hooks work regardless of your shell's PATH — whether you installed via pip, pipx, uv, poetry, or a virtual environment.\n\nWhen AgentLint blocks a dangerous action, the agent sees:\n\n```\n⛔ [no-secrets] Possible secret token detected (prefix 'sk_live_')\n💡 Use environment variables instead of hard-coded secrets.\n```\n\nThe agent's action is blocked before it can write the secret into your codebase.\n\nThe `setup` command:\n- Installs hooks or guardrails for the selected agent platform\n- Creates `agentlint.yml` with auto-detected settings (if it doesn't exist)\n\nTo remove AgentLint hooks:\n\n```bash\nagentlint uninstall\n```\n\n### Installation options\n\n| Platform | Setup command | Integration style |\n| --- | --- | --- |\n| Claude Code | `agentlint setup claude` | Native hooks in `.claude/settings.json` or user settings |\n| Cursor IDE | `agentlint setup cursor` | Native hooks in `.cursor/hooks.json` |\n| Codex CLI | `agentlint setup codex` | Native hooks in `.codex/hooks.json`; Bash coverage is strongest |\n| Gemini CLI | `agentlint setup gemini` | Native hooks in `.gemini/settings.json` |\n| Continue.dev | `agentlint setup continue` | Native hooks in `.continue/settings.json` |\n| Kimi Code CLI | `agentlint setup kimi` | Native TOML hooks |\n| Grok CLI | `agentlint setup grok` | Native JSON hooks |\n| OpenAI Agents SDK | `agentlint setup openai` | Guardrail integration code |\n| MCP hosts | `agentlint setup mcp` | MCP server config |\n| Custom tools | `agentlint setup generic` | Generic normalized HTTP/webhook adapter |\n\nFor platform-specific details, use the setup guides in `docs/`:\n\n- [Claude Code](docs/setup-claude.md)\n- [Cursor](docs/setup-cursor.md)\n- [Codex](docs/setup-codex.md)\n- [Gemini](docs/setup-gemini.md)\n- [Kimi](docs/setup-kimi.md)\n- [Grok](docs/setup-grok.md)\n- [Continue.dev](docs/setup-continue.md)\n- [OpenAI Agents SDK](docs/setup-openai.md)\n- [MCP hosts](docs/setup-mcp.md)\n- [Generic integrations](docs/setup-generic.md)\n\n### Claude Code marketplace plugin\n\nClaude Code users can also install the marketplace wrapper from\n[`mauhpr/agentlint-plugin`](https://github.com/mauhpr/agentlint-plugin). The\nplugin repo contains Claude-specific marketplace metadata, hook files, and\nplugin commands; this repo contains the core engine and cross-platform setup.\n\n## Configuration\n\nCreate `agentlint.yml` in your project root (or run `agentlint init`):\n\n```yaml\n# Auto-detect tech stack or list packs explicitly\nstack: auto\n\n# strict: warnings become errors\n# standard: default behavior\n# relaxed: warnings become info\nseverity: standard\n\npacks:\n  - universal\n  # - security        # Opt-in: blocks Bash file writes, network exfiltration\n  # - python          # Auto-detected from pyproject.toml / setup.py\n  # - frontend        # Auto-detected from package.json\n  # - react           # Auto-detected from react in dependencies\n  # - seo             # Auto-detected from SSR/SSG framework in dependencies\n\nrules:\n  max-file-size:\n    limit: 300          # Override default 500-line limit\n  drift-detector:\n    threshold: 5        # Warn after 5 edits without tests (default: 15)\n  no-secrets:\n    enabled: false      # Disable a rule entirely\n  # Python pack examples:\n  # no-bare-except:\n  #   allow_reraise: true\n  # Frontend pack examples:\n  # a11y-heading-hierarchy:\n  #   max_h1: 1\n\n# Load custom rules from a directory\n# custom_rules_dir: .agentlint/rules/\n```\n\n### AgentChute opt-in\n\nAgentLint runs locally by default. No event data leaves your machine unless you enable AgentChute with a license key and an explicit opt-in:\n\n```bash\nagentlint init --team-key=ac_team_...\n```\n\nThat enables AgentChute in `agentlint.yml` and prints the env vars to add to your shell, CI, or AI tool settings. The plaintext key is not written to repo config.\n\n```yaml\nagentchute:\n  enabled: true\n```\n\n```bash\nexport AGENTCHUTE_LICENSE_KEY=ac_team_...\nexport AGENTCHUTE_ENABLED=true\n# Optional for self-hosted/local API:\nexport AGENTCHUTE_API_URL=http://localhost:8000/v1\n```\n\nWhen enabled, AgentLint sends privacy-safe event summaries only: file paths and lengths for writes/edits, truncated Bash command previews, truncated prompt previews, violation metadata, and rule counts. It never sends raw file contents, full edit strings, or full prompts.\n\n### AGENTS.md integration\n\nAgentLint supports the [AGENTS.md](https://agents.md/) industry standard. Import conventions from your project's AGENTS.md into AgentLint config:\n\n```bash\n# Preview what would be generated\nagentlint import-agents-md --dry-run\n\n# Generate agentlint.yml from AGENTS.md\nagentlint import-agents-md\n\n# Merge with existing config\nagentlint import-agents-md --merge\n```\n\nWhen `AGENTS.md` exists and `stack: auto` is set, AgentLint also uses it for pack auto-detection.\n\n## Discovering rules\n\n```bash\n# List all rules (built-in + custom)\nagentlint list-rules\n\n# List rules in a specific pack (built-in or custom)\nagentlint list-rules --pack security\nagentlint list-rules --pack fintech\n\n# List rules for a different project\nagentlint list-rules --project-dir /path/to/project\n\n# Show current status (version, packs, rule count, session activity)\nagentlint status\n\n# Diagnose common misconfigurations (including custom rules validation)\nagentlint doctor\n\n# Scan changed files for CI pipelines\nagentlint ci --diff origin/main...HEAD\n```\n\n## Custom rules\n\nCreate a Python file in your custom rules directory:\n\n```python\n# .agentlint/rules/no_direct_db.py\nfrom agentlint.models import Rule, RuleContext, Violation, Severity, HookEvent\n\nclass NoDirectDB(Rule):\n    id = \"no-direct-db\"\n    description = \"API routes must not import database layer directly\"\n    severity = Severity.WARNING\n    events = [HookEvent.POST_TOOL_USE]\n    pack = \"myproject\"\n\n    def evaluate(self, context: RuleContext) -\u003e list[Violation]:\n        if not context.file_path or \"/routes/\" not in context.file_path:\n            return []\n        if context.file_content and \"from database\" in context.file_content:\n            return [Violation(\n                rule_id=self.id,\n                message=\"Route imports database directly. Use repository pattern.\",\n                severity=self.severity,\n                file_path=context.file_path,\n            )]\n        return []\n```\n\nThen activate the pack in your config:\n\n```yaml\npacks:\n  - universal\n  - myproject      # activates all rules with pack = \"myproject\"\n\ncustom_rules_dir: .agentlint/rules/\n```\n\nRules whose `pack` is not in `packs:` are loaded but silently skipped. Use `agentlint doctor` to detect orphaned packs.\n\n## Monorepo Support\n\nDifferent subdirectories can use different rule packs:\n\n```yaml\npacks:\n  - universal          # fallback for files outside any project\n\nprojects:\n  frontend/:\n    packs: [universal, frontend, react]\n  backend/:\n    packs: [universal, python]\n  infra/:\n    packs: [universal, security, autopilot]\n```\n\nFiles outside any project prefix use the global `packs:` list. Longest prefix wins for nested paths.\n\n## MCP Server\n\nExpose agentlint to Claude and other MCP clients. Agents can **pre-validate code before writing**, eliminating the block-retry loop where hooks reject code and the agent rewrites multiple times.\n\n```bash\npip install agentlint[mcp]\nagentlint-mcp  # run via stdio\n```\n\n**Tools:**\n- `check_content(content, file_path)` — pre-validate code against rules\n- `list_rules(pack?)` — discover available rules\n- `get_config()` — read current configuration\n- `suppress_rule(rule_id)` — suppress a warning for the session (ERRORs always enforced)\n\n**Resources:** `agentlint://rules`, `agentlint://config`\n\nSee [docs/mcp.md](docs/mcp.md) for the full MCP guide with workflow recipes and troubleshooting.\n\n## CI Mode\n\nRun agentlint in CI pipelines — same rules, same config, different trigger:\n\n```yaml\n# .github/workflows/agentlint.yml\nname: AgentLint\non: [pull_request]\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with: { fetch-depth: 0 }\n      - run: pip install agentlint\n      - run: agentlint ci --diff origin/${{ github.base_ref }}...HEAD\n```\n\nOnly ERROR violations fail the build. Warnings are reported but don't block. Use `--format json` for machine-readable output.\n\n## File-Scope Governance\n\nRestrict which files the agent can access. Deny patterns take precedence over allow:\n\n```yaml\nrules:\n  file-scope:\n    allow: [\"src/**\", \"tests/**\", \"docs/**\"]\n    deny: [\"*.env\", \"credentials/**\", \".github/workflows/**\"]\n```\n\nBlocks Write, Edit, Read, and Bash file operations. Path traversal (`../`) is blocked. If no `file-scope` config is present, the rule is inactive.\n\n## CLI Integration\n\nRun any command-line tool as a PostToolUse check. AgentLint executes the command after Write/Edit and reports non-zero exit codes as violations:\n\n```yaml\nrules:\n  cli-integration:\n    commands:\n      - name: ruff\n        on: [\"Write\", \"Edit\"]\n        glob: \"**/*.py\"\n        command: \"ruff check {file.path} --output-format=concise\"\n        timeout: 10\n        severity: warning\n\n      - name: pip-audit\n        on: [\"Write\", \"Edit\"]\n        glob: \"**/requirements*.txt\"\n        command: \"pip-audit -r {file.path}\"\n        timeout: 30\n        severity: warning\n\n      - name: pytest-related\n        on: [\"Write\", \"Edit\"]\n        glob: \"src/**/*.py\"\n        command: \"pytest tests/ -k {file.stem} -x -q --tb=short\"\n        timeout: 60\n        severity: info\n```\n\n### Available placeholders\n\n| Placeholder | Value | Example |\n|---|---|---|\n| `{file.path}` | Absolute file path | `/home/user/project/src/app.py` |\n| `{file.relative}` | Relative to project | `src/app.py` |\n| `{file.name}` | Filename | `app.py` |\n| `{file.stem}` | Filename without extension | `app` |\n| `{file.ext}` | Extension | `py` |\n| `{file.dir}` | Parent directory | `/home/user/project/src` |\n| `{file.dir.relative}` | Parent dir (relative) | `src` |\n| `{project.dir}` | Project root | `/home/user/project` |\n| `{tool.name}` | Tool that triggered | `Write` |\n| `{session.changed_files}` | All changed files (space-separated) | `src/a.py src/b.py` |\n| `{env.VARNAME}` | Environment variable | _(value of $VARNAME)_ |\n\nCommands with unresolvable placeholders are silently skipped. All placeholder values are shell-escaped (`shlex.quote`) to prevent injection. File paths outside the project directory are rejected.\n\n## How it works\n\nAgentLint normalizes each platform's hook or guardrail payload into a shared event model. Claude Code has the broadest native lifecycle coverage today: all 17 Claude Code hook events are understood, and `agentlint setup claude` registers 7 high-value runtime events out of the box:\n\n| Event | When | Behavior |\n|-------|------|----------|\n| **PreToolUse** | Before Write/Edit/Bash | Can **block** the action |\n| **PostToolUse** | After Write/Edit | Injects warnings into agent context |\n| **UserPromptSubmit** | When user sends a prompt | Evaluates prompt-level rules |\n| **SubagentStart** | When a subagent spawns | Injects safety briefing via `additionalContext` |\n| **SubagentStop** | When a subagent completes | Audits subagent transcript for dangerous commands |\n| **Notification** | On system notifications | Evaluates notification-triggered rules |\n| **Stop** | End of session | Generates a quality report |\n\nCustom rules can target any of the 17 events (SessionStart, PreCompact, WorktreeCreate, TaskCompleted, etc.).\n\nEach invocation loads your config, evaluates matching rules, and returns the protocol response expected by the selected adapter. Session state persists across invocations so rules like `drift-detector` can track cumulative behavior.\n\n### Circuit breaker (Progressive Trust)\n\nWhen a blocking rule fires repeatedly, it automatically degrades to avoid locking the agent in a loop:\n\n| Fire count | Severity | Effect |\n|-----------|----------|--------|\n| 1-2 | ERROR | Blocks the action (normal) |\n| 3-5 | WARNING | Advises instead of blocking |\n| 6-9 | INFO | Appears in session report only |\n| 10+ | Suppressed | Silent until reset |\n\nThe breaker resets after 5 consecutive clean evaluations or 30 minutes without firing.\n\nSecurity-critical rules (`no-secrets`, `no-env-commit`) are exempt — they always block, regardless of fire count. Per-rule overrides are configurable:\n\n```yaml\ncircuit_breaker:\n  enabled: true          # ON by default\n  degraded_after: 3      # ERROR -\u003e WARNING\n  passive_after: 6       # -\u003e INFO\n  open_after: 10         # -\u003e suppressed\n\nrules:\n  max-file-size:\n    circuit_breaker:\n      degraded_after: 5  # Override per-rule\n```\n\n## Comparison with alternatives\n\n| Project | How AgentLint differs |\n|---------|----------------------|\n| guardrails-ai | Validates LLM I/O. AgentLint validates agent *tool calls* in real-time. |\n| claude-code-guardrails | Uses external API. AgentLint is local-first, no network dependency. |\n| Custom hooks | Copy-paste scripts. AgentLint is a composable engine with config + plugins. |\n| Codacy Guardrails | Commercial, proprietary. AgentLint is fully open source. |\n\n## FAQ\n\n**Does AgentLint slow down my AI coding agent?**\nNo. Rules evaluate in \u003c10ms. AgentLint runs locally as a subprocess — no network calls, no API dependencies.\n\n**What if a rule is too strict for my project?**\nDisable it in `agentlint.yml`: `rules: { no-secrets: { enabled: false } }`. Or switch to `severity: relaxed` to downgrade warnings to informational. The circuit breaker also helps — if a rule fires 3+ times in a session, it automatically degrades from blocking to advisory.\n\n**Is my code sent anywhere?**\nNo. AgentLint is fully offline by default. It reads the local hook, guardrail, MCP, or webhook payload and evaluates rules locally. No telemetry, no network requests. AgentChute sync is a separate opt-in path and sends only privacy-safe event summaries.\n\n**Can I use AgentLint outside Claude Code?**\nYes. AgentLint supports real-time blocking hooks on Claude Code, Cursor, Kimi, Grok, Gemini, Codex, and Continue.dev. For OpenAI Agents SDK and MCP hosts, use guardrail-based integration. The CLI also works standalone in any CI pipeline.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauhpr%2Fagentlint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmauhpr%2Fagentlint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauhpr%2Fagentlint/lists"}