agentlint 2.5.2__tar.gz → 2.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentlint-2.5.4/.github/CODEOWNERS +7 -0
- agentlint-2.5.4/.github/dependabot.yml +16 -0
- agentlint-2.5.4/.github/workflows/ci.yml +78 -0
- agentlint-2.5.4/.github/workflows/publish.yml +76 -0
- agentlint-2.5.4/.github/workflows/test-publish.yml +55 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/CHANGELOG.md +49 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/PKG-INFO +12 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/README.md +10 -7
- agentlint-2.5.4/RELEASE.md +83 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/adapters.md +3 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/custom-rules.md +9 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/pyproject.toml +15 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/__init__.py +1 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/__main__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/__init__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/_utils.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/base.py +1 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/claude.py +6 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/codex.py +7 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/continue_dev.py +7 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/cursor.py +7 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/gemini.py +7 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/generic.py +8 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/grok.py +7 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/kimi.py +54 -17
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/mcp.py +34 -14
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/adapters/openai_agents.py +13 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/__init__.py +6 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/client.py +8 -17
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/feeds.py +14 -16
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/policy.py +12 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/queue.py +26 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/settings.py +4 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agentchute/sync.py +5 -12
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/agents_md.py +39 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/circuit_breaker.py +56 -53
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/cli.py +314 -163
- agentlint-2.5.4/src/agentlint/cli_queue.py +101 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/config.py +7 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/core/__init__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/core/models.py +20 -12
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/detector.py +9 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/engine.py +25 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/filters.py +8 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/__init__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/base.py +3 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/claude_hooks.py +29 -17
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/cursor_hooks.py +23 -14
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/gemini_hooks.py +28 -19
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/formats/plain_json.py +7 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/mcp_server.py +4 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/models.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/__init__.py +10 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/__init__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/_dangerous_patterns.py +5 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/bash_rate_limiter.py +8 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/cloud_infra_mutation.py +51 -12
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/cloud_paid_resource_creation.py +46 -9
- agentlint-2.5.4/src/agentlint/packs/autopilot/cloud_resource_deletion.py +142 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/cross_account_guard.py +12 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/destructive_confirmation_gate.py +24 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/docker_volume_guard.py +41 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/dry_run_required.py +3 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/network_firewall_guard.py +16 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/operation_journal.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/package_manager_in_chroot.py +16 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/production_guard.py +57 -33
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/remote_boot_partition_guard.py +20 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/remote_chroot_guard.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/ssh_destructive_command_guard.py +11 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/subagent_safety_briefing.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/subagent_transcript_audit.py +12 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/autopilot/system_scheduler_guard.py +10 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/__init__.py +5 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/_helpers.py +2 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/a11y_form_labels.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/a11y_heading_hierarchy.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/a11y_image_alt.py +3 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/a11y_interactive_elements.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/mobile_responsive_patterns.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/mobile_touch_targets.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/style_focus_visible.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/frontend/style_no_arbitrary_values.py +7 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/__init__.py +4 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_bare_except.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_dangerous_migration.py +5 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_sql_injection.py +7 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_unnecessary_async.py +18 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_unsafe_shell.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/python/no_wildcard_import.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/__init__.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/commit_message_format.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/naming_conventions.py +21 -9
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/no_dead_imports.py +2 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/no_error_handling_removal.py +2 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/no_file_creation_sprawl.py +11 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/no_large_diff.py +45 -19
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/quality/self_review_prompt.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/react/__init__.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/react/react_empty_state.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/react/react_lazy_loading.py +11 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/react/react_query_loading_state.py +3 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/__init__.py +5 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/env_credential_reference.py +21 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_bash_file_write.py +8 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_blocked_domain_fetch.py +1 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_compromised_action.py +4 -15
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_leaked_secret_pattern.py +2 -9
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_malicious_url_fetch.py +2 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/security/no_network_exfil.py +46 -28
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/__init__.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/_helpers.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/seo_open_graph.py +1 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/seo_page_metadata.py +9 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/seo_semantic_html.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/seo/seo_structured_data.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/__init__.py +10 -9
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/cicd_pipeline_guard.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/cli_integration.py +31 -17
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/dependency_hygiene.py +9 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/drift_detector.py +19 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/file_scope.py +16 -13
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/git_checkpoint.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/max_file_size.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_debug_artifacts.py +2 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_destructive_commands.py +6 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_env_commit.py +2 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_force_push.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_nvd_critical_cve_install.py +15 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_push_to_main.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_secrets.py +14 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_skip_hooks.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_test_weakening.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_todo_left.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_vulnerable_import.py +72 -19
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_vulnerable_version_install.py +25 -18
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/package_publish_guard.py +9 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/test_with_changes.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/token_budget.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/token_burn_against_team_budget.py +5 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/recorder.py +16 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/reporter.py +47 -24
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/session.py +3 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/setup.py +25 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/template.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/utils/bash.py +22 -10
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/utils/git.py +2 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/utils/paths.py +1 -0
- agentlint-2.5.4/tests/conftest.py +27 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/security/test_no_blocked_domain_fetch.py +4 -10
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/security/test_no_compromised_action.py +53 -56
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/security/test_no_leaked_secret_pattern.py +44 -37
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/security/test_no_malicious_url_fetch.py +18 -31
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_autopilot_integration.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_autopilot_pack_loads.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_autopilot_post.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_autopilot_pre.py +15 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_cicd_pipeline_guard.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_cloud_infra_mutation.py +34 -11
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_cloud_paid_resource_creation.py +8 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_cloud_resource_deletion.py +8 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_docker_volume_guard.py +7 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_edge_cases.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_env_credential_reference.py +11 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_frontend.py +350 -200
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_git_checkpoint.py +5 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_network_firewall_guard.py +7 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_no_compromised_dependency.py +2 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_no_nvd_critical_cve_install.py +27 -18
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_no_vulnerable_import.py +44 -36
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_no_vulnerable_version_install.py +50 -54
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_package_manager_in_chroot.py +10 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_package_publish_guard.py +1 -0
- agentlint-2.5.4/tests/packs/test_python_post.py +164 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_python_pre.py +423 -252
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_quality_post.py +4 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_quality_pre.py +15 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_quality_stop.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_react.py +138 -78
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_remote_boot_partition_guard.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_remote_chroot_guard.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_security_pre.py +107 -54
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_seo.py +175 -97
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_ssh_destructive_command_guard.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_subagent_safety_briefing.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_subagent_transcript_audit.py +151 -65
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_system_scheduler_guard.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_token_budget.py +57 -43
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_token_burn_against_team_budget.py +2 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_universal_post.py +21 -16
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_universal_pre.py +453 -260
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/test_universal_stop.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_adapter_utils.py +47 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_agentchute_client.py +14 -10
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_agentchute_feeds.py +11 -30
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_agentchute_policy_queue_sync.py +73 -15
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_agents_md.py +2 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_bash_utils.py +5 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_ci.py +35 -9
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_circuit_breaker.py +193 -159
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_cli.py +804 -387
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_cli_integration.py +378 -141
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_codex_adapter.py +17 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_config.py +9 -4
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_continue_adapter.py +27 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_cursor_adapter.py +45 -26
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_custom_rules.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_detector.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_engine.py +149 -74
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_file_scope.py +1 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_filters.py +4 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_gemini_adapter.py +48 -17
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_generic_adapter.py +3 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_git.py +19 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_git_utils_checkpoint.py +18 -8
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_grok_adapter.py +21 -6
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_integration.py +18 -5
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_kimi_adapter.py +61 -29
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_main_module.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_mcp_adapter.py +14 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_mcp_server.py +52 -7
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_models.py +29 -14
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_openai_adapter.py +11 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_packs_loader.py +6 -2
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_paths_utils.py +2 -3
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_quality_new_rules.py +27 -13
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_recorder.py +61 -32
- agentlint-2.5.4/tests/test_release_metadata.py +47 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_reporter.py +52 -39
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_rule_inventory.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_session.py +2 -1
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_setup.py +69 -22
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/test_template.py +1 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/uv.lock +28 -1
- agentlint-2.5.2/.github/workflows/ci.yml +0 -41
- agentlint-2.5.2/.github/workflows/publish.yml +0 -42
- agentlint-2.5.2/src/agentlint/packs/autopilot/cloud_resource_deletion.py +0 -77
- agentlint-2.5.2/tests/conftest.py +0 -12
- agentlint-2.5.2/tests/packs/test_python_post.py +0 -126
- {agentlint-2.5.2 → agentlint-2.5.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/.gitignore +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/.python-version +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/CODE_OF_CONDUCT.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/CONTRIBUTING.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/LICENSE +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/SECURITY.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/agentlint.yml +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/agentlint.yml.example +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/codecov.yml +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/README.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/architecture.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/configuration.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/mcp.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/migration-v2.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-claude.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-codex.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-continue.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-cursor.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-gemini.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-generic.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-grok.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-kimi.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-mcp.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/setup-openai.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/docs/subagent-safety.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/.claude-plugin/plugin.json +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/agents/doctor.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/agents/fix.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/agents/security-audit.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/bin/resolve-and-run.sh +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/commands/lint-config.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/commands/lint-status.md +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/hooks/hooks.json +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/plugin/mcp.json +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/packs/universal/no_compromised_dependency.py +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/py.typed +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/src/agentlint/utils/__init__.py +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/__init__.py +0 -0
- {agentlint-2.5.2 → agentlint-2.5.4}/tests/packs/__init__.py +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: pip
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
groups:
|
|
9
|
+
python-development:
|
|
10
|
+
dependency-type: development
|
|
11
|
+
|
|
12
|
+
- package-ecosystem: github-actions
|
|
13
|
+
directory: /
|
|
14
|
+
schedule:
|
|
15
|
+
interval: weekly
|
|
16
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
quality:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
run: uv python install 3.13
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: uv sync --extra dev --frozen --python 3.13
|
|
28
|
+
|
|
29
|
+
- name: Check formatting
|
|
30
|
+
run: uv run ruff format --check .
|
|
31
|
+
|
|
32
|
+
- name: Lint
|
|
33
|
+
run: uv run ruff check .
|
|
34
|
+
|
|
35
|
+
- name: Build distributions
|
|
36
|
+
run: uv build
|
|
37
|
+
|
|
38
|
+
- name: Smoke-test wheel
|
|
39
|
+
run: |
|
|
40
|
+
uv venv --seed .wheel-venv
|
|
41
|
+
uv pip install --python .wheel-venv/bin/python dist/*.whl
|
|
42
|
+
.wheel-venv/bin/agentlint --version
|
|
43
|
+
|
|
44
|
+
test:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
strategy:
|
|
47
|
+
fail-fast: false
|
|
48
|
+
matrix:
|
|
49
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
50
|
+
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
53
|
+
with:
|
|
54
|
+
persist-credentials: false
|
|
55
|
+
|
|
56
|
+
- name: Install uv
|
|
57
|
+
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
58
|
+
|
|
59
|
+
- name: Set up Python
|
|
60
|
+
run: uv python install ${{ matrix.python-version }}
|
|
61
|
+
|
|
62
|
+
- name: Install dependencies
|
|
63
|
+
run: uv sync --extra dev --frozen --python ${{ matrix.python-version }}
|
|
64
|
+
|
|
65
|
+
- name: Run tests
|
|
66
|
+
run: uv run --python ${{ matrix.python-version }} pytest -v --cov=agentlint --cov-report=term-missing --cov-report=xml
|
|
67
|
+
|
|
68
|
+
- name: Upload coverage to Codecov
|
|
69
|
+
if: matrix.python-version == '3.13'
|
|
70
|
+
uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5.5.5
|
|
71
|
+
with:
|
|
72
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
73
|
+
files: ./coverage.xml
|
|
74
|
+
flags: unittests
|
|
75
|
+
name: agentlint-coverage
|
|
76
|
+
slug: mauhpr/agentlint
|
|
77
|
+
fail_ci_if_error: false
|
|
78
|
+
verbose: true
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: publish-${{ github.event.release.tag_name }}
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
name: Verify and build once
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
20
|
+
with:
|
|
21
|
+
persist-credentials: false
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
25
|
+
|
|
26
|
+
- name: Set up Python
|
|
27
|
+
run: uv python install 3.13
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --extra dev --frozen --python 3.13
|
|
31
|
+
|
|
32
|
+
- name: Verify source
|
|
33
|
+
run: |
|
|
34
|
+
uv lock --check
|
|
35
|
+
uv run ruff format --check .
|
|
36
|
+
uv run ruff check .
|
|
37
|
+
uv run pytest -q
|
|
38
|
+
|
|
39
|
+
- name: Build distributions
|
|
40
|
+
run: uv build
|
|
41
|
+
|
|
42
|
+
- name: Smoke-test wheel
|
|
43
|
+
run: |
|
|
44
|
+
uv venv --seed .wheel-venv
|
|
45
|
+
uv pip install --python .wheel-venv/bin/python dist/*.whl
|
|
46
|
+
.wheel-venv/bin/agentlint --version
|
|
47
|
+
|
|
48
|
+
- name: Upload artifacts
|
|
49
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
50
|
+
with:
|
|
51
|
+
name: distributions
|
|
52
|
+
path: dist/
|
|
53
|
+
if-no-files-found: error
|
|
54
|
+
retention-days: 7
|
|
55
|
+
|
|
56
|
+
publish-pypi:
|
|
57
|
+
name: Trusted publish
|
|
58
|
+
needs: build
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment:
|
|
61
|
+
name: pypi
|
|
62
|
+
url: https://pypi.org/p/agentlint
|
|
63
|
+
permissions:
|
|
64
|
+
contents: read
|
|
65
|
+
id-token: write
|
|
66
|
+
steps:
|
|
67
|
+
- name: Download artifacts
|
|
68
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
69
|
+
with:
|
|
70
|
+
name: distributions
|
|
71
|
+
path: dist/
|
|
72
|
+
|
|
73
|
+
- name: Publish to PyPI
|
|
74
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
75
|
+
with:
|
|
76
|
+
attestations: true
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish to TestPyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: test-publish
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
name: Build test distribution
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
19
|
+
with:
|
|
20
|
+
persist-credentials: false
|
|
21
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
|
22
|
+
- run: uv python install 3.13
|
|
23
|
+
- run: uv sync --extra dev --frozen --python 3.13
|
|
24
|
+
- run: uv run pytest -q
|
|
25
|
+
- run: uv build
|
|
26
|
+
- run: |
|
|
27
|
+
uv venv --seed .test-wheel-venv
|
|
28
|
+
uv pip install --python .test-wheel-venv/bin/python dist/*.whl
|
|
29
|
+
.test-wheel-venv/bin/agentlint --version
|
|
30
|
+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
31
|
+
with:
|
|
32
|
+
name: test-distributions
|
|
33
|
+
path: dist/
|
|
34
|
+
if-no-files-found: error
|
|
35
|
+
retention-days: 7
|
|
36
|
+
|
|
37
|
+
publish:
|
|
38
|
+
name: Trusted test publish
|
|
39
|
+
needs: build
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
environment:
|
|
42
|
+
name: testpypi
|
|
43
|
+
url: https://test.pypi.org/p/agentlint
|
|
44
|
+
permissions:
|
|
45
|
+
contents: read
|
|
46
|
+
id-token: write
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
|
49
|
+
with:
|
|
50
|
+
name: test-distributions
|
|
51
|
+
path: dist/
|
|
52
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
53
|
+
with:
|
|
54
|
+
repository-url: https://test.pypi.org/legacy/
|
|
55
|
+
attestations: true
|
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2.5.4 (2026-07-29) — Quality and Release Hardening
|
|
4
|
+
|
|
5
|
+
This patch release strengthens AgentLint's development and publishing controls
|
|
6
|
+
without intentionally changing its public rule or adapter APIs.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Establishes a repository-wide Ruff formatting and linting baseline and
|
|
11
|
+
enforces it in CI.
|
|
12
|
+
- Enables branch-aware coverage with a 95% combined floor; the release suite
|
|
13
|
+
now contains 2,542 tests and reports 96.2% combined coverage.
|
|
14
|
+
- Extracts the local AgentChute queue command group from the main CLI module,
|
|
15
|
+
creating the first dedicated boundary for continued CLI decomposition.
|
|
16
|
+
- Expands MCP server coverage from 68% to 94%, including generic event checks,
|
|
17
|
+
session tools/resources, and server startup.
|
|
18
|
+
- Pins GitHub Actions to immutable commit SHAs, disables checkout credential
|
|
19
|
+
persistence, uses frozen lockfile installs, and smoke-tests the built wheel.
|
|
20
|
+
- Verifies source, tests, wheel installation, and trusted-publishing artifacts
|
|
21
|
+
before production releases; adds a manual TestPyPI workflow.
|
|
22
|
+
- Adds Dependabot, CODEOWNERS, and regression tests for version consistency,
|
|
23
|
+
immutable workflow actions, and OIDC-only publishing.
|
|
24
|
+
|
|
25
|
+
### Compatibility
|
|
26
|
+
|
|
27
|
+
- Existing configurations, rules, adapters, hook payloads, and CLI command
|
|
28
|
+
names remain compatible.
|
|
29
|
+
- The legacy `agentlint.setup` re-exports remain available.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## v2.5.3 (2026-05-25) — AgentChute Queue Baseline
|
|
34
|
+
|
|
35
|
+
This patch release fixes AgentChute onboarding for existing AgentLint users
|
|
36
|
+
with local event history.
|
|
37
|
+
|
|
38
|
+
- Fixes `agentlint queue flush`, which could crash because the CLI wrapper did
|
|
39
|
+
not pass the newer queue batch/time-budget arguments.
|
|
40
|
+
- Baselines the local AgentChute queue when a machine is paired with a new
|
|
41
|
+
license key, so pre-pairing local history is not uploaded as fresh dashboard
|
|
42
|
+
activity.
|
|
43
|
+
- Adds `agentlint queue discard-pending --yes` for support cases where a user
|
|
44
|
+
intentionally wants to advance the local queue cursor without uploading
|
|
45
|
+
pending events.
|
|
46
|
+
- Improves `agentlint policy explain` by listing active rule IDs, making policy
|
|
47
|
+
template debugging easier.
|
|
48
|
+
- Adds regression coverage for the `block-curl-sh` policy template simulation.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
3
52
|
## v2.5.2 (2026-05-25) — AgentChute Credential Persistence
|
|
4
53
|
|
|
5
54
|
This patch release fixes the first-run AgentChute pairing flow so users can run
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentlint
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.4
|
|
4
4
|
Summary: Real-time quality guardrails for AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/mauhpr/agentlint
|
|
6
6
|
Project-URL: Repository, https://github.com/mauhpr/agentlint
|
|
@@ -30,6 +30,7 @@ Requires-Dist: fastmcp>=3.0; extra == 'dev'
|
|
|
30
30
|
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
31
31
|
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
32
32
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
33
34
|
Provides-Extra: mcp
|
|
34
35
|
Requires-Dist: fastmcp>=3.0; extra == 'mcp'
|
|
35
36
|
Description-Content-Type: text/markdown
|
|
@@ -62,7 +63,7 @@ We don't have a mature answer to that yet. Nobody does. The **autopilot pack** i
|
|
|
62
63
|
|
|
63
64
|
AgentLint ships with 77 rules across 8 packs and normalizes tool events across supported AI coding agents. The 24 **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.
|
|
64
65
|
|
|
65
|
-
**v2.5.
|
|
66
|
+
**v2.5.4 highlights:** Repository-wide Ruff enforcement, branch-aware coverage floors, immutable CI actions, verified release artifacts, stronger MCP tests, and the first extraction from the main CLI module. Previous: local-first AgentChute NVD enforcement, AgentChute onboarding with `agentlint onboard`, dashboard pairing through `agentlint login`, durable queue delivery, safer Codex hook enablement, multi-platform adapters, MCP server support, warning suppression, and auto-fix workflows.
|
|
66
67
|
|
|
67
68
|
| Rule | Severity | What it does |
|
|
68
69
|
|------|----------|-------------|
|
|
@@ -441,6 +442,7 @@ Create a Python file in your custom rules directory:
|
|
|
441
442
|
# .agentlint/rules/no_direct_db.py
|
|
442
443
|
from agentlint.models import Rule, RuleContext, Violation, Severity, HookEvent
|
|
443
444
|
|
|
445
|
+
|
|
444
446
|
class NoDirectDB(Rule):
|
|
445
447
|
id = "no-direct-db"
|
|
446
448
|
description = "API routes must not import database layer directly"
|
|
@@ -452,12 +454,14 @@ class NoDirectDB(Rule):
|
|
|
452
454
|
if not context.file_path or "/routes/" not in context.file_path:
|
|
453
455
|
return []
|
|
454
456
|
if context.file_content and "from database" in context.file_content:
|
|
455
|
-
return [
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
457
|
+
return [
|
|
458
|
+
Violation(
|
|
459
|
+
rule_id=self.id,
|
|
460
|
+
message="Route imports database directly. Use repository pattern.",
|
|
461
|
+
severity=self.severity,
|
|
462
|
+
file_path=context.file_path,
|
|
463
|
+
)
|
|
464
|
+
]
|
|
461
465
|
return []
|
|
462
466
|
```
|
|
463
467
|
|
|
@@ -26,7 +26,7 @@ We don't have a mature answer to that yet. Nobody does. The **autopilot pack** i
|
|
|
26
26
|
|
|
27
27
|
AgentLint ships with 77 rules across 8 packs and normalizes tool events across supported AI coding agents. The 24 **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.
|
|
28
28
|
|
|
29
|
-
**v2.5.
|
|
29
|
+
**v2.5.4 highlights:** Repository-wide Ruff enforcement, branch-aware coverage floors, immutable CI actions, verified release artifacts, stronger MCP tests, and the first extraction from the main CLI module. Previous: local-first AgentChute NVD enforcement, AgentChute onboarding with `agentlint onboard`, dashboard pairing through `agentlint login`, durable queue delivery, safer Codex hook enablement, multi-platform adapters, MCP server support, warning suppression, and auto-fix workflows.
|
|
30
30
|
|
|
31
31
|
| Rule | Severity | What it does |
|
|
32
32
|
|------|----------|-------------|
|
|
@@ -405,6 +405,7 @@ Create a Python file in your custom rules directory:
|
|
|
405
405
|
# .agentlint/rules/no_direct_db.py
|
|
406
406
|
from agentlint.models import Rule, RuleContext, Violation, Severity, HookEvent
|
|
407
407
|
|
|
408
|
+
|
|
408
409
|
class NoDirectDB(Rule):
|
|
409
410
|
id = "no-direct-db"
|
|
410
411
|
description = "API routes must not import database layer directly"
|
|
@@ -416,12 +417,14 @@ class NoDirectDB(Rule):
|
|
|
416
417
|
if not context.file_path or "/routes/" not in context.file_path:
|
|
417
418
|
return []
|
|
418
419
|
if context.file_content and "from database" in context.file_content:
|
|
419
|
-
return [
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
420
|
+
return [
|
|
421
|
+
Violation(
|
|
422
|
+
rule_id=self.id,
|
|
423
|
+
message="Route imports database directly. Use repository pattern.",
|
|
424
|
+
severity=self.severity,
|
|
425
|
+
file_path=context.file_path,
|
|
426
|
+
)
|
|
427
|
+
]
|
|
425
428
|
return []
|
|
426
429
|
```
|
|
427
430
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# AgentLint release process
|
|
2
|
+
|
|
3
|
+
This repo publishes the `agentlint` Python package to PyPI from GitHub Actions.
|
|
4
|
+
Do not publish from a local machine.
|
|
5
|
+
|
|
6
|
+
## Release owner checklist
|
|
7
|
+
|
|
8
|
+
1. Merge all required product/API/dashboard dependencies first.
|
|
9
|
+
- If the release depends on AgentChute server behavior, merge and deploy
|
|
10
|
+
AgentChute before publishing AgentLint.
|
|
11
|
+
|
|
12
|
+
2. Prepare a release PR from a branch like `release/vX.Y.Z-description`.
|
|
13
|
+
Update these files together:
|
|
14
|
+
- `pyproject.toml`
|
|
15
|
+
- `src/agentlint/__init__.py`
|
|
16
|
+
- `uv.lock`
|
|
17
|
+
- `CHANGELOG.md`
|
|
18
|
+
|
|
19
|
+
3. Run local verification before opening or updating the PR.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
.venv/bin/pytest tests/test_cli.py tests/test_agentchute_policy_queue_sync.py -k "not test_list_rules_universal_pack"
|
|
23
|
+
uv run ruff check CHANGELOG.md pyproject.toml src/agentlint/__init__.py src/agentlint/cli.py src/agentlint/agentchute/queue.py tests/test_cli.py tests/test_agentchute_policy_queue_sync.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Adjust the test list when the release touches other areas.
|
|
27
|
+
|
|
28
|
+
4. Open the PR and wait for required GitHub checks.
|
|
29
|
+
- Python matrix must pass.
|
|
30
|
+
- Codecov patch must pass.
|
|
31
|
+
- Resolve conflicts by merging `origin/main` into the release branch.
|
|
32
|
+
|
|
33
|
+
5. Merge the PR into `main`.
|
|
34
|
+
|
|
35
|
+
6. Create the GitHub Release from the final `main` commit.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git fetch origin main --tags
|
|
39
|
+
TARGET_SHA="$(git rev-parse origin/main)"
|
|
40
|
+
gh release create vX.Y.Z \
|
|
41
|
+
--target "$TARGET_SHA" \
|
|
42
|
+
--title "AgentLint vX.Y.Z" \
|
|
43
|
+
--notes-file /path/to/release-notes.md
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`gh-personal` can be used instead of `gh` on machines configured with that
|
|
47
|
+
wrapper.
|
|
48
|
+
|
|
49
|
+
7. Let GitHub Actions publish to PyPI.
|
|
50
|
+
- The workflow is `.github/workflows/publish.yml`.
|
|
51
|
+
- It runs on `release.published`.
|
|
52
|
+
- It builds with `uv build`.
|
|
53
|
+
- It publishes with trusted publishing through `pypa/gh-action-pypi-publish`.
|
|
54
|
+
|
|
55
|
+
Check it with:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
gh run list --limit 5
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
8. Verify the package after the publish workflow succeeds.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv tool install --upgrade --reinstall agentlint
|
|
65
|
+
agentlint --version
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Expected output:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
agentlint X.Y.Z
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Important rules
|
|
75
|
+
|
|
76
|
+
- Do not run `uv publish` locally. PyPI credentials are intentionally owned by
|
|
77
|
+
GitHub trusted publishing.
|
|
78
|
+
- Do not move an already published release tag. If a release is wrong after
|
|
79
|
+
publishing, create a follow-up patch version.
|
|
80
|
+
- Keep release notes focused on user-visible behavior, fixes, and migration
|
|
81
|
+
notes.
|
|
82
|
+
- If the release changes AgentLint behavior consumed by `agentlint-plugin`,
|
|
83
|
+
release AgentLint first, verify PyPI, then release the plugin.
|
|
@@ -10,6 +10,7 @@ Create a class that inherits from `AgentAdapter`:
|
|
|
10
10
|
from agentlint.adapters.base import AgentAdapter
|
|
11
11
|
from agentlint.models import AgentEvent, HookEvent, NormalizedTool, RuleContext
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
class MyFrameworkAdapter(AgentAdapter):
|
|
14
15
|
@property
|
|
15
16
|
def platform_name(self) -> str:
|
|
@@ -18,6 +19,7 @@ class MyFrameworkAdapter(AgentAdapter):
|
|
|
18
19
|
@property
|
|
19
20
|
def formatter(self):
|
|
20
21
|
from agentlint.formats.plain_json import PlainJsonFormatter
|
|
22
|
+
|
|
21
23
|
return PlainJsonFormatter()
|
|
22
24
|
|
|
23
25
|
def resolve_project_dir(self) -> str:
|
|
@@ -83,6 +85,7 @@ You can also write custom formatters:
|
|
|
83
85
|
from agentlint.formats.base import OutputFormatter
|
|
84
86
|
from agentlint.models import AgentEvent, Severity, Violation
|
|
85
87
|
|
|
88
|
+
|
|
86
89
|
class MyFormatter(OutputFormatter):
|
|
87
90
|
def exit_code(self, violations, event=""):
|
|
88
91
|
return 1 if any(v.severity == Severity.ERROR for v in violations) else 0
|
|
@@ -47,13 +47,15 @@ class NoRawSQL(Rule):
|
|
|
47
47
|
sql_keywords = ["execute(", "raw_sql(", "cursor.execute("]
|
|
48
48
|
for keyword in sql_keywords:
|
|
49
49
|
if keyword in content:
|
|
50
|
-
return [
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
return [
|
|
51
|
+
Violation(
|
|
52
|
+
rule_id=self.id,
|
|
53
|
+
message=f"Raw SQL detected ({keyword}). Use the ORM.",
|
|
54
|
+
severity=self.severity,
|
|
55
|
+
file_path=context.file_path,
|
|
56
|
+
suggestion="Use Model.objects or the query builder instead.",
|
|
57
|
+
)
|
|
58
|
+
]
|
|
57
59
|
return []
|
|
58
60
|
```
|
|
59
61
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentlint"
|
|
3
|
-
version = "2.5.
|
|
3
|
+
version = "2.5.4"
|
|
4
4
|
description = "Real-time quality guardrails for AI coding agents"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -33,6 +33,7 @@ dev = [
|
|
|
33
33
|
"pytest-cov>=5.0",
|
|
34
34
|
"pytest-asyncio>=0.24",
|
|
35
35
|
"fastmcp>=3.0",
|
|
36
|
+
"ruff>=0.9",
|
|
36
37
|
]
|
|
37
38
|
mcp = [
|
|
38
39
|
"fastmcp>=3.0",
|
|
@@ -64,3 +65,16 @@ asyncio_mode = "auto"
|
|
|
64
65
|
[tool.coverage.run]
|
|
65
66
|
relative_files = true
|
|
66
67
|
source = ["src/agentlint"]
|
|
68
|
+
branch = true
|
|
69
|
+
|
|
70
|
+
[tool.coverage.report]
|
|
71
|
+
fail_under = 95
|
|
72
|
+
show_missing = true
|
|
73
|
+
skip_covered = true
|
|
74
|
+
|
|
75
|
+
[tool.ruff]
|
|
76
|
+
target-version = "py311"
|
|
77
|
+
line-length = 100
|
|
78
|
+
|
|
79
|
+
[tool.ruff.lint]
|
|
80
|
+
select = ["E4", "E7", "E9", "F", "I", "UP", "B", "SIM"]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Claude Code adapter for AgentLint."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import json
|
|
@@ -16,7 +17,6 @@ from agentlint.adapters.base import AgentAdapter
|
|
|
16
17
|
from agentlint.formats.claude_hooks import ClaudeHookFormatter
|
|
17
18
|
from agentlint.models import AgentEvent, HookEvent, NormalizedTool, RuleContext
|
|
18
19
|
|
|
19
|
-
|
|
20
20
|
# Mapping from Claude Code native event names to generic AgentEvent
|
|
21
21
|
_CLAUDE_EVENT_MAP: dict[str, AgentEvent] = {
|
|
22
22
|
"PreToolUse": AgentEvent.PRE_TOOL_USE,
|
|
@@ -183,8 +183,8 @@ class ClaudeAdapter(AgentAdapter):
|
|
|
183
183
|
def translate_event(self, native_event: str) -> AgentEvent:
|
|
184
184
|
try:
|
|
185
185
|
return _CLAUDE_EVENT_MAP[native_event]
|
|
186
|
-
except KeyError:
|
|
187
|
-
raise ValueError(f"Unknown Claude event: {native_event}")
|
|
186
|
+
except KeyError as exc:
|
|
187
|
+
raise ValueError(f"Unknown Claude event: {native_event}") from exc
|
|
188
188
|
|
|
189
189
|
def normalize_tool_name(self, native_tool: str) -> str:
|
|
190
190
|
return _CLAUDE_TOOL_MAP.get(native_tool, NormalizedTool.UNKNOWN).value
|
|
@@ -205,7 +205,8 @@ class ClaudeAdapter(AgentAdapter):
|
|
|
205
205
|
config={},
|
|
206
206
|
session_state=session_state,
|
|
207
207
|
prompt=raw_payload.get("prompt"),
|
|
208
|
-
subagent_output=raw_payload.get("last_assistant_message")
|
|
208
|
+
subagent_output=raw_payload.get("last_assistant_message")
|
|
209
|
+
or raw_payload.get("subagent_output"),
|
|
209
210
|
notification_type=raw_payload.get("notification_type"),
|
|
210
211
|
compact_source=raw_payload.get("compact_source"),
|
|
211
212
|
agent_transcript_path=raw_payload.get("agent_transcript_path"),
|
|
@@ -240,6 +241,7 @@ class ClaudeAdapter(AgentAdapter):
|
|
|
240
241
|
|
|
241
242
|
if dry_run:
|
|
242
243
|
import click
|
|
244
|
+
|
|
243
245
|
click.echo(f"\nDry run — would write to {path}:")
|
|
244
246
|
click.echo(json.dumps(settings, indent=2))
|
|
245
247
|
return
|