maintainability-agent 2.6.0__tar.gz → 2.7.0__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.
- {maintainability_agent-2.6.0/src/maintainability_agent.egg-info → maintainability_agent-2.7.0}/PKG-INFO +44 -44
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/README.md +43 -43
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/pyproject.toml +1 -1
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0/src/maintainability_agent.egg-info}/PKG-INFO +44 -44
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_cognitive.py +57 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_config_defaults.py +1 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_discovery.py +1 -1
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_metrics_types.py +35 -0
- maintainability_agent-2.7.0/src/maintainability_audit/_ranges_cobol.py +274 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/config.py +1 -1
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/declarations.py +13 -1
- maintainability_agent-2.7.0/tests/test_cobol_declarations.py +385 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_language_coverage.py +52 -2
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/LICENSE +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/setup.cfg +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_analysis.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_bands.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cli.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declared_authorship.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_promises.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_roles_recorded.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_runner.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_trends.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -44,7 +44,7 @@ Dynamic: license-file
|
|
|
44
44
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
45
45
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
46
46
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
47
|
-
Version **2.
|
|
47
|
+
Version **2.7.0**.
|
|
48
48
|
|
|
49
49
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
50
50
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -78,9 +78,11 @@ What 1.0 guarantees:
|
|
|
78
78
|
- **Deterministic and local.** Same tree, config, pinned analyzer versions and
|
|
79
79
|
history in → same evidence, findings and score out. The analysis performs no
|
|
80
80
|
network access and invokes no LLM, and **this agent does not transmit your
|
|
81
|
-
source.**
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
source.** Every report states what it examined and produced — files,
|
|
82
|
+
declarations, findings, bounded work items — **all computed with no model
|
|
83
|
+
call**: work a metered agent never has to do. Third-party analyzers it may
|
|
84
|
+
spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
|
|
85
|
+
not police whether *they* phone home; install them for an air-gapped run.
|
|
84
86
|
- **One uniform rubric**, readable in source, applied to every repository —
|
|
85
87
|
so "better" and "worse" are not an argument. Calibrated against a
|
|
86
88
|
query-selected corpus of mature open-source projects; the corpus median
|
|
@@ -183,9 +185,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
|
|
|
183
185
|
no report. A configured repository returns `choice_needed` (`run` or
|
|
184
186
|
`reconfigure`), also without a report. Answering setup does not start an audit.
|
|
185
187
|
`action="run"` returns the report and its bounded remediation prompt to the
|
|
186
|
-
conversation. `record_history=None` follows the persisted first-run
|
|
187
|
-
|
|
188
|
-
or `false` wins.
|
|
188
|
+
conversation. `record_history=None` follows the persisted first-run consent and
|
|
189
|
+
always appends to an existing history; an explicit `true` or `false` wins.
|
|
189
190
|
|
|
190
191
|
```bash
|
|
191
192
|
python3 -m pip install "maintainability-agent[mcp]"
|
|
@@ -193,10 +194,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
|
|
|
193
194
|
```
|
|
194
195
|
|
|
195
196
|
Presentation is exactly three choices — **chat**, a **Markdown** file, or a
|
|
196
|
-
single-file **HTML** report
|
|
197
|
-
|
|
198
|
-
[chat workflow help](docs/help/README.md) and
|
|
199
|
-
|
|
197
|
+
single-file **HTML** report. Where to save is asked only after a file format is
|
|
198
|
+
chosen, and no report file is written without that choice. See
|
|
199
|
+
[chat workflow help](docs/help/README.md) and [IDE and agent
|
|
200
|
+
integration](docs/ide-agent-integration.md).
|
|
200
201
|
|
|
201
202
|
## Automation / CI: CLI
|
|
202
203
|
|
|
@@ -290,14 +291,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
|
|
|
290
291
|
|
|
291
292
|
## Language support
|
|
292
293
|
|
|
293
|
-
**Be clear-eyed
|
|
294
|
-
|
|
295
|
-
Coverage comes from two layers.
|
|
294
|
+
**Be clear-eyed: the tool does not support every language equally, and on an
|
|
295
|
+
unrecognized language it under-reports rather than fails.** Coverage has two layers.
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
299
|
-
JS/TS family, and HTML. Each has a scanner written for it and a
|
|
300
|
-
misses — a language is claimed
|
|
297
|
+
Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
|
|
298
|
+
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
299
|
+
COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
|
|
300
|
+
documented list of what it misses — a language is claimed only when both exist.
|
|
301
301
|
|
|
302
302
|
**Built-in scanner (always on, no dependencies)** — reads function/class
|
|
303
303
|
declarations, sizes and complexity for a fixed set of languages, and **only**
|
|
@@ -311,18 +311,19 @@ these:
|
|
|
311
311
|
| C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
|
|
312
312
|
| C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
|
|
313
313
|
| Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
|
|
314
|
+
| COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
|
|
314
315
|
| Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
|
|
315
316
|
| Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
|
|
316
317
|
| JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
|
|
317
318
|
| HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
|
|
318
319
|
| TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
|
|
319
320
|
|
|
320
|
-
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
|
|
322
|
+
is **not parsed for declarations by the built-in scanner.** Its files still count
|
|
323
|
+
toward repo size, but the built-ins produce no function-size, complexity,
|
|
324
|
+
duplication or dead-code findings for them, and the estimate leans on whatever
|
|
325
|
+
evidence *is* available (which is why the report discloses its evidence tier and
|
|
326
|
+
can withhold the grade).
|
|
326
327
|
|
|
327
328
|
**Which analyzer covers which language** (the opt-in pool, when installed):
|
|
328
329
|
|
|
@@ -332,13 +333,14 @@ discloses its evidence tier and can withhold the grade).
|
|
|
332
333
|
| Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
|
|
333
334
|
| C / C++ / C# | dedicated scanners | lizard, multimetric |
|
|
334
335
|
| **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
|
|
336
|
+
| **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
|
|
335
337
|
| JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
|
|
336
338
|
|
|
337
|
-
Fortran reached parity in 1.6.0
|
|
338
|
-
catalog row
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
339
|
+
Fortran reached parity in 1.6.0: lizard had read it for years behind a
|
|
340
|
+
stale catalog row, so it came out `not-applicable` and never ran. A lint fails
|
|
341
|
+
the build if a parsed language has no analyzer measuring complexity — **COBOL is
|
|
342
|
+
the one disclosed exemption**, because the tooling that reads it is licensed and
|
|
343
|
+
host-resident, so its external tier is empty and the report says so.
|
|
342
344
|
|
|
343
345
|
**External analyzer adapters (opt-in pool)** — this is how coverage extends
|
|
344
346
|
beyond the built-in set. When you enable the analyzer pool, the tool shells out
|
|
@@ -350,12 +352,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
|
|
|
350
352
|
they measured a full concept set they become the *primary* evidence, with the
|
|
351
353
|
built-ins as the fallback.
|
|
352
354
|
|
|
353
|
-
So: **first-class today is Python** (and TypeScript for semantics);
|
|
354
|
-
|
|
355
|
-
the
|
|
356
|
-
|
|
357
|
-
the
|
|
358
|
-
[docs/language-support.md](docs/language-support.md); the adapter catalog is in
|
|
355
|
+
So: **first-class today is Python** (and TypeScript for semantics); every other
|
|
356
|
+
parsed language is bounded-but-real; anything outside the table is only as
|
|
357
|
+
covered as the analyzer you point at it, and with none it is under-reported by
|
|
358
|
+
design. Per-language accuracy and limits:
|
|
359
|
+
[docs/language-support.md](docs/language-support.md); the adapter catalog:
|
|
359
360
|
[docs/adapters.md](docs/adapters.md).
|
|
360
361
|
|
|
361
362
|
## What it produces
|
|
@@ -423,10 +424,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
|
|
|
423
424
|
repo with production code and zero test files cannot earn an A-grade) and banded
|
|
424
425
|
from the evidence floor, so withholding evidence never buys a better letter.
|
|
425
426
|
Every threshold gate — file, function, duplication — is opted **on** for this
|
|
426
|
-
repo's own CI,
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
roughly a grade — use `fetch-depth: 0`.)
|
|
427
|
+
repo's own CI, so drifting below the bar fails the build rather than the README.
|
|
428
|
+
(CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
|
|
429
|
+
and costs roughly a grade — use `fetch-depth: 0`.)
|
|
430
430
|
|
|
431
431
|
## Platform support
|
|
432
432
|
|
|
@@ -517,14 +517,14 @@ gate, and the self-audit — is in
|
|
|
517
517
|
|
|
518
518
|
## Support this work
|
|
519
519
|
|
|
520
|
-
This is a single-maintainer, MIT-licensed project — free to use, and built on
|
|
521
|
-
|
|
520
|
+
This is a single-maintainer, MIT-licensed project — free to use, and built on a
|
|
521
|
+
lot of unpaid hours. If it saves you or your team time, please consider
|
|
522
522
|
sponsoring its continued development:
|
|
523
523
|
|
|
524
524
|
**❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
|
|
525
525
|
|
|
526
|
-
Sponsorship is
|
|
527
|
-
|
|
526
|
+
Sponsorship is optional and never gates a feature, a fix, or support — the whole
|
|
527
|
+
tool stays free and open. It just helps keep the work going.
|
|
528
528
|
|
|
529
529
|
## Acknowledgements
|
|
530
530
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
6
6
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
7
7
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
8
|
-
Version **2.
|
|
8
|
+
Version **2.7.0**.
|
|
9
9
|
|
|
10
10
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
11
11
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -39,9 +39,11 @@ What 1.0 guarantees:
|
|
|
39
39
|
- **Deterministic and local.** Same tree, config, pinned analyzer versions and
|
|
40
40
|
history in → same evidence, findings and score out. The analysis performs no
|
|
41
41
|
network access and invokes no LLM, and **this agent does not transmit your
|
|
42
|
-
source.**
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
source.** Every report states what it examined and produced — files,
|
|
43
|
+
declarations, findings, bounded work items — **all computed with no model
|
|
44
|
+
call**: work a metered agent never has to do. Third-party analyzers it may
|
|
45
|
+
spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
|
|
46
|
+
not police whether *they* phone home; install them for an air-gapped run.
|
|
45
47
|
- **One uniform rubric**, readable in source, applied to every repository —
|
|
46
48
|
so "better" and "worse" are not an argument. Calibrated against a
|
|
47
49
|
query-selected corpus of mature open-source projects; the corpus median
|
|
@@ -144,9 +146,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
|
|
|
144
146
|
no report. A configured repository returns `choice_needed` (`run` or
|
|
145
147
|
`reconfigure`), also without a report. Answering setup does not start an audit.
|
|
146
148
|
`action="run"` returns the report and its bounded remediation prompt to the
|
|
147
|
-
conversation. `record_history=None` follows the persisted first-run
|
|
148
|
-
|
|
149
|
-
or `false` wins.
|
|
149
|
+
conversation. `record_history=None` follows the persisted first-run consent and
|
|
150
|
+
always appends to an existing history; an explicit `true` or `false` wins.
|
|
150
151
|
|
|
151
152
|
```bash
|
|
152
153
|
python3 -m pip install "maintainability-agent[mcp]"
|
|
@@ -154,10 +155,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
|
|
|
154
155
|
```
|
|
155
156
|
|
|
156
157
|
Presentation is exactly three choices — **chat**, a **Markdown** file, or a
|
|
157
|
-
single-file **HTML** report
|
|
158
|
-
|
|
159
|
-
[chat workflow help](docs/help/README.md) and
|
|
160
|
-
|
|
158
|
+
single-file **HTML** report. Where to save is asked only after a file format is
|
|
159
|
+
chosen, and no report file is written without that choice. See
|
|
160
|
+
[chat workflow help](docs/help/README.md) and [IDE and agent
|
|
161
|
+
integration](docs/ide-agent-integration.md).
|
|
161
162
|
|
|
162
163
|
## Automation / CI: CLI
|
|
163
164
|
|
|
@@ -251,14 +252,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
|
|
|
251
252
|
|
|
252
253
|
## Language support
|
|
253
254
|
|
|
254
|
-
**Be clear-eyed
|
|
255
|
-
|
|
256
|
-
Coverage comes from two layers.
|
|
255
|
+
**Be clear-eyed: the tool does not support every language equally, and on an
|
|
256
|
+
unrecognized language it under-reports rather than fails.** Coverage has two layers.
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
260
|
-
JS/TS family, and HTML. Each has a scanner written for it and a
|
|
261
|
-
misses — a language is claimed
|
|
258
|
+
Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
|
|
259
|
+
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
260
|
+
COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
|
|
261
|
+
documented list of what it misses — a language is claimed only when both exist.
|
|
262
262
|
|
|
263
263
|
**Built-in scanner (always on, no dependencies)** — reads function/class
|
|
264
264
|
declarations, sizes and complexity for a fixed set of languages, and **only**
|
|
@@ -272,18 +272,19 @@ these:
|
|
|
272
272
|
| C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
|
|
273
273
|
| C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
|
|
274
274
|
| Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
|
|
275
|
+
| COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
|
|
275
276
|
| Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
|
|
276
277
|
| Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
|
|
277
278
|
| JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
|
|
278
279
|
| HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
|
|
279
280
|
| TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
|
|
280
281
|
|
|
281
|
-
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
282
|
+
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
|
|
283
|
+
is **not parsed for declarations by the built-in scanner.** Its files still count
|
|
284
|
+
toward repo size, but the built-ins produce no function-size, complexity,
|
|
285
|
+
duplication or dead-code findings for them, and the estimate leans on whatever
|
|
286
|
+
evidence *is* available (which is why the report discloses its evidence tier and
|
|
287
|
+
can withhold the grade).
|
|
287
288
|
|
|
288
289
|
**Which analyzer covers which language** (the opt-in pool, when installed):
|
|
289
290
|
|
|
@@ -293,13 +294,14 @@ discloses its evidence tier and can withhold the grade).
|
|
|
293
294
|
| Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
|
|
294
295
|
| C / C++ / C# | dedicated scanners | lizard, multimetric |
|
|
295
296
|
| **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
|
|
297
|
+
| **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
|
|
296
298
|
| JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
|
|
297
299
|
|
|
298
|
-
Fortran reached parity in 1.6.0
|
|
299
|
-
catalog row
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
300
|
+
Fortran reached parity in 1.6.0: lizard had read it for years behind a
|
|
301
|
+
stale catalog row, so it came out `not-applicable` and never ran. A lint fails
|
|
302
|
+
the build if a parsed language has no analyzer measuring complexity — **COBOL is
|
|
303
|
+
the one disclosed exemption**, because the tooling that reads it is licensed and
|
|
304
|
+
host-resident, so its external tier is empty and the report says so.
|
|
303
305
|
|
|
304
306
|
**External analyzer adapters (opt-in pool)** — this is how coverage extends
|
|
305
307
|
beyond the built-in set. When you enable the analyzer pool, the tool shells out
|
|
@@ -311,12 +313,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
|
|
|
311
313
|
they measured a full concept set they become the *primary* evidence, with the
|
|
312
314
|
built-ins as the fallback.
|
|
313
315
|
|
|
314
|
-
So: **first-class today is Python** (and TypeScript for semantics);
|
|
315
|
-
|
|
316
|
-
the
|
|
317
|
-
|
|
318
|
-
the
|
|
319
|
-
[docs/language-support.md](docs/language-support.md); the adapter catalog is in
|
|
316
|
+
So: **first-class today is Python** (and TypeScript for semantics); every other
|
|
317
|
+
parsed language is bounded-but-real; anything outside the table is only as
|
|
318
|
+
covered as the analyzer you point at it, and with none it is under-reported by
|
|
319
|
+
design. Per-language accuracy and limits:
|
|
320
|
+
[docs/language-support.md](docs/language-support.md); the adapter catalog:
|
|
320
321
|
[docs/adapters.md](docs/adapters.md).
|
|
321
322
|
|
|
322
323
|
## What it produces
|
|
@@ -384,10 +385,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
|
|
|
384
385
|
repo with production code and zero test files cannot earn an A-grade) and banded
|
|
385
386
|
from the evidence floor, so withholding evidence never buys a better letter.
|
|
386
387
|
Every threshold gate — file, function, duplication — is opted **on** for this
|
|
387
|
-
repo's own CI,
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
roughly a grade — use `fetch-depth: 0`.)
|
|
388
|
+
repo's own CI, so drifting below the bar fails the build rather than the README.
|
|
389
|
+
(CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
|
|
390
|
+
and costs roughly a grade — use `fetch-depth: 0`.)
|
|
391
391
|
|
|
392
392
|
## Platform support
|
|
393
393
|
|
|
@@ -478,14 +478,14 @@ gate, and the self-audit — is in
|
|
|
478
478
|
|
|
479
479
|
## Support this work
|
|
480
480
|
|
|
481
|
-
This is a single-maintainer, MIT-licensed project — free to use, and built on
|
|
482
|
-
|
|
481
|
+
This is a single-maintainer, MIT-licensed project — free to use, and built on a
|
|
482
|
+
lot of unpaid hours. If it saves you or your team time, please consider
|
|
483
483
|
sponsoring its continued development:
|
|
484
484
|
|
|
485
485
|
**❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
|
|
486
486
|
|
|
487
|
-
Sponsorship is
|
|
488
|
-
|
|
487
|
+
Sponsorship is optional and never gates a feature, a fix, or support — the whole
|
|
488
|
+
tool stays free and open. It just helps keep the work going.
|
|
489
489
|
|
|
490
490
|
## Acknowledgements
|
|
491
491
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maintainability-agent"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.7.0"
|
|
8
8
|
description = "Maintainability gate and AI remediation prompt generator for CI."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# 3.11, not 3.10. `_discovery`, `_pillars` and `_runner` all import
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -44,7 +44,7 @@ Dynamic: license-file
|
|
|
44
44
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
45
45
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
46
46
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
47
|
-
Version **2.
|
|
47
|
+
Version **2.7.0**.
|
|
48
48
|
|
|
49
49
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
50
50
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -78,9 +78,11 @@ What 1.0 guarantees:
|
|
|
78
78
|
- **Deterministic and local.** Same tree, config, pinned analyzer versions and
|
|
79
79
|
history in → same evidence, findings and score out. The analysis performs no
|
|
80
80
|
network access and invokes no LLM, and **this agent does not transmit your
|
|
81
|
-
source.**
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
source.** Every report states what it examined and produced — files,
|
|
82
|
+
declarations, findings, bounded work items — **all computed with no model
|
|
83
|
+
call**: work a metered agent never has to do. Third-party analyzers it may
|
|
84
|
+
spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
|
|
85
|
+
not police whether *they* phone home; install them for an air-gapped run.
|
|
84
86
|
- **One uniform rubric**, readable in source, applied to every repository —
|
|
85
87
|
so "better" and "worse" are not an argument. Calibrated against a
|
|
86
88
|
query-selected corpus of mature open-source projects; the corpus median
|
|
@@ -183,9 +185,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
|
|
|
183
185
|
no report. A configured repository returns `choice_needed` (`run` or
|
|
184
186
|
`reconfigure`), also without a report. Answering setup does not start an audit.
|
|
185
187
|
`action="run"` returns the report and its bounded remediation prompt to the
|
|
186
|
-
conversation. `record_history=None` follows the persisted first-run
|
|
187
|
-
|
|
188
|
-
or `false` wins.
|
|
188
|
+
conversation. `record_history=None` follows the persisted first-run consent and
|
|
189
|
+
always appends to an existing history; an explicit `true` or `false` wins.
|
|
189
190
|
|
|
190
191
|
```bash
|
|
191
192
|
python3 -m pip install "maintainability-agent[mcp]"
|
|
@@ -193,10 +194,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
|
|
|
193
194
|
```
|
|
194
195
|
|
|
195
196
|
Presentation is exactly three choices — **chat**, a **Markdown** file, or a
|
|
196
|
-
single-file **HTML** report
|
|
197
|
-
|
|
198
|
-
[chat workflow help](docs/help/README.md) and
|
|
199
|
-
|
|
197
|
+
single-file **HTML** report. Where to save is asked only after a file format is
|
|
198
|
+
chosen, and no report file is written without that choice. See
|
|
199
|
+
[chat workflow help](docs/help/README.md) and [IDE and agent
|
|
200
|
+
integration](docs/ide-agent-integration.md).
|
|
200
201
|
|
|
201
202
|
## Automation / CI: CLI
|
|
202
203
|
|
|
@@ -290,14 +291,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
|
|
|
290
291
|
|
|
291
292
|
## Language support
|
|
292
293
|
|
|
293
|
-
**Be clear-eyed
|
|
294
|
-
|
|
295
|
-
Coverage comes from two layers.
|
|
294
|
+
**Be clear-eyed: the tool does not support every language equally, and on an
|
|
295
|
+
unrecognized language it under-reports rather than fails.** Coverage has two layers.
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
299
|
-
JS/TS family, and HTML. Each has a scanner written for it and a
|
|
300
|
-
misses — a language is claimed
|
|
297
|
+
Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
|
|
298
|
+
C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
|
|
299
|
+
COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
|
|
300
|
+
documented list of what it misses — a language is claimed only when both exist.
|
|
301
301
|
|
|
302
302
|
**Built-in scanner (always on, no dependencies)** — reads function/class
|
|
303
303
|
declarations, sizes and complexity for a fixed set of languages, and **only**
|
|
@@ -311,18 +311,19 @@ these:
|
|
|
311
311
|
| C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
|
|
312
312
|
| C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
|
|
313
313
|
| Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
|
|
314
|
+
| COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
|
|
314
315
|
| Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
|
|
315
316
|
| Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
|
|
316
317
|
| JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
|
|
317
318
|
| HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
|
|
318
319
|
| TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
|
|
319
320
|
|
|
320
|
-
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
321
|
+
Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
|
|
322
|
+
is **not parsed for declarations by the built-in scanner.** Its files still count
|
|
323
|
+
toward repo size, but the built-ins produce no function-size, complexity,
|
|
324
|
+
duplication or dead-code findings for them, and the estimate leans on whatever
|
|
325
|
+
evidence *is* available (which is why the report discloses its evidence tier and
|
|
326
|
+
can withhold the grade).
|
|
326
327
|
|
|
327
328
|
**Which analyzer covers which language** (the opt-in pool, when installed):
|
|
328
329
|
|
|
@@ -332,13 +333,14 @@ discloses its evidence tier and can withhold the grade).
|
|
|
332
333
|
| Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
|
|
333
334
|
| C / C++ / C# | dedicated scanners | lizard, multimetric |
|
|
334
335
|
| **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
|
|
336
|
+
| **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
|
|
335
337
|
| JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
|
|
336
338
|
|
|
337
|
-
Fortran reached parity in 1.6.0
|
|
338
|
-
catalog row
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
339
|
+
Fortran reached parity in 1.6.0: lizard had read it for years behind a
|
|
340
|
+
stale catalog row, so it came out `not-applicable` and never ran. A lint fails
|
|
341
|
+
the build if a parsed language has no analyzer measuring complexity — **COBOL is
|
|
342
|
+
the one disclosed exemption**, because the tooling that reads it is licensed and
|
|
343
|
+
host-resident, so its external tier is empty and the report says so.
|
|
342
344
|
|
|
343
345
|
**External analyzer adapters (opt-in pool)** — this is how coverage extends
|
|
344
346
|
beyond the built-in set. When you enable the analyzer pool, the tool shells out
|
|
@@ -350,12 +352,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
|
|
|
350
352
|
they measured a full concept set they become the *primary* evidence, with the
|
|
351
353
|
built-ins as the fallback.
|
|
352
354
|
|
|
353
|
-
So: **first-class today is Python** (and TypeScript for semantics);
|
|
354
|
-
|
|
355
|
-
the
|
|
356
|
-
|
|
357
|
-
the
|
|
358
|
-
[docs/language-support.md](docs/language-support.md); the adapter catalog is in
|
|
355
|
+
So: **first-class today is Python** (and TypeScript for semantics); every other
|
|
356
|
+
parsed language is bounded-but-real; anything outside the table is only as
|
|
357
|
+
covered as the analyzer you point at it, and with none it is under-reported by
|
|
358
|
+
design. Per-language accuracy and limits:
|
|
359
|
+
[docs/language-support.md](docs/language-support.md); the adapter catalog:
|
|
359
360
|
[docs/adapters.md](docs/adapters.md).
|
|
360
361
|
|
|
361
362
|
## What it produces
|
|
@@ -423,10 +424,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
|
|
|
423
424
|
repo with production code and zero test files cannot earn an A-grade) and banded
|
|
424
425
|
from the evidence floor, so withholding evidence never buys a better letter.
|
|
425
426
|
Every threshold gate — file, function, duplication — is opted **on** for this
|
|
426
|
-
repo's own CI,
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
roughly a grade — use `fetch-depth: 0`.)
|
|
427
|
+
repo's own CI, so drifting below the bar fails the build rather than the README.
|
|
428
|
+
(CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
|
|
429
|
+
and costs roughly a grade — use `fetch-depth: 0`.)
|
|
430
430
|
|
|
431
431
|
## Platform support
|
|
432
432
|
|
|
@@ -517,14 +517,14 @@ gate, and the self-audit — is in
|
|
|
517
517
|
|
|
518
518
|
## Support this work
|
|
519
519
|
|
|
520
|
-
This is a single-maintainer, MIT-licensed project — free to use, and built on
|
|
521
|
-
|
|
520
|
+
This is a single-maintainer, MIT-licensed project — free to use, and built on a
|
|
521
|
+
lot of unpaid hours. If it saves you or your team time, please consider
|
|
522
522
|
sponsoring its continued development:
|
|
523
523
|
|
|
524
524
|
**❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
|
|
525
525
|
|
|
526
|
-
Sponsorship is
|
|
527
|
-
|
|
526
|
+
Sponsorship is optional and never gates a feature, a fix, or support — the whole
|
|
527
|
+
tool stays free and open. It just helps keep the work going.
|
|
528
528
|
|
|
529
529
|
## Acknowledgements
|
|
530
530
|
|
|
@@ -59,6 +59,7 @@ src/maintainability_audit/_pillars.py
|
|
|
59
59
|
src/maintainability_audit/_practice.py
|
|
60
60
|
src/maintainability_audit/_pressures.py
|
|
61
61
|
src/maintainability_audit/_ranges_c.py
|
|
62
|
+
src/maintainability_audit/_ranges_cobol.py
|
|
62
63
|
src/maintainability_audit/_ranges_core.py
|
|
63
64
|
src/maintainability_audit/_ranges_cpp.py
|
|
64
65
|
src/maintainability_audit/_ranges_csharp.py
|
|
@@ -173,6 +174,7 @@ tests/test_ci_installs_the_analyzer_pool.py
|
|
|
173
174
|
tests/test_claimed_languages.py
|
|
174
175
|
tests/test_cli.py
|
|
175
176
|
tests/test_clone_group_class.py
|
|
177
|
+
tests/test_cobol_declarations.py
|
|
176
178
|
tests/test_cognitive_complexity.py
|
|
177
179
|
tests/test_cohort_statistics.py
|
|
178
180
|
tests/test_concealment_properties.py
|
{maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_cognitive.py
RENAMED
|
@@ -35,6 +35,12 @@ import re
|
|
|
35
35
|
|
|
36
36
|
from ._masking import mask_fortran_lines, mask_lines
|
|
37
37
|
|
|
38
|
+
# Both live in `parsing`, and `_ranges_core` reaches nothing here, so this
|
|
39
|
+
# is a sibling import rather than a cycle. COBOL's mask is not in
|
|
40
|
+
# `_masking` with the others because it needs the whole file to know which
|
|
41
|
+
# division a line is in — see `_ranges_cobol.mask_cobol_lines`.
|
|
42
|
+
from ._ranges_cobol import mask_cobol_lines
|
|
43
|
+
|
|
38
44
|
# Constructs that both cost a point and deepen the nesting for whatever
|
|
39
45
|
# they contain.
|
|
40
46
|
_NESTING_NODES = (ast.If, ast.For, ast.AsyncFor, ast.While, ast.ExceptHandler, ast.IfExp)
|
|
@@ -175,6 +181,57 @@ def fortran_cognitive(lines: list[str]) -> int:
|
|
|
175
181
|
return score
|
|
176
182
|
|
|
177
183
|
|
|
184
|
+
_CB_CLOSES_RE = re.compile(r"\bEND-(?:IF|EVALUATE|PERFORM|SEARCH|READ|STRING)\b", re.I)
|
|
185
|
+
_CB_OPENS_RE = re.compile(
|
|
186
|
+
r"\bIF\b|\bEVALUATE\b|\bPERFORM\b(?=[^.]*\b(?:UNTIL|VARYING|TIMES)\b)|\bSEARCH\b",
|
|
187
|
+
re.I,
|
|
188
|
+
)
|
|
189
|
+
_CB_ELSE_RE = re.compile(r"^\s*ELSE\b|\bWHEN\b", re.I) # noqa: S5850 - alternation is intended
|
|
190
|
+
_CB_BOOLEAN_RE = re.compile(r"\b(?:AND|OR)\b", re.I)
|
|
191
|
+
_CB_CONTROL_RE = re.compile(r"\b(?:IF|EVALUATE|UNTIL|VARYING|TIMES|SEARCH)\b", re.I)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def cobol_cognitive(lines: list[str]) -> int:
|
|
195
|
+
"""Cognitive complexity for a COBOL paragraph.
|
|
196
|
+
|
|
197
|
+
Nesting is read from the constructs themselves, as in Fortran, since
|
|
198
|
+
COBOL has no braces either. What COBOL adds is a second way to close
|
|
199
|
+
every open scope at once: **a period ends the sentence and with it
|
|
200
|
+
every construct the sentence opened.** Classic COBOL leans on that
|
|
201
|
+
entirely — `IF X DISPLAY Y.` opens and closes an `IF` with no
|
|
202
|
+
`END-IF` anywhere — and a reader that only counted `END-` terminators
|
|
203
|
+
would let depth climb monotonically through a paragraph and charge
|
|
204
|
+
the last statement for every branch above it.
|
|
205
|
+
|
|
206
|
+
The `PERFORM` lookahead is the other judgment. `PERFORM SOME-PARA` is
|
|
207
|
+
a call and opens nothing; `PERFORM UNTIL DONE` is a loop and does.
|
|
208
|
+
Counting every `PERFORM` as nesting would make an ordinary
|
|
209
|
+
call-per-line paragraph read as deeply nested.
|
|
210
|
+
"""
|
|
211
|
+
masked = mask_cobol_lines(lines)
|
|
212
|
+
score = 0
|
|
213
|
+
depth = 0
|
|
214
|
+
for line in masked:
|
|
215
|
+
statement = line.rstrip()
|
|
216
|
+
if not statement.strip():
|
|
217
|
+
continue
|
|
218
|
+
if _CB_CLOSES_RE.search(statement):
|
|
219
|
+
depth = max(0, depth - len(_CB_CLOSES_RE.findall(statement)))
|
|
220
|
+
body = _CB_CLOSES_RE.sub(" ", statement)
|
|
221
|
+
if _CB_ELSE_RE.search(body):
|
|
222
|
+
score += 1
|
|
223
|
+
score += len(_CB_BOOLEAN_RE.findall(body))
|
|
224
|
+
else:
|
|
225
|
+
for _ in _CB_CONTROL_RE.finditer(body):
|
|
226
|
+
score += 1 + depth
|
|
227
|
+
score += len(_CB_BOOLEAN_RE.findall(body))
|
|
228
|
+
depth += len(_CB_OPENS_RE.findall(body))
|
|
229
|
+
if statement.rstrip().endswith("."):
|
|
230
|
+
# The sentence ended, and with it every scope it opened.
|
|
231
|
+
depth = 0
|
|
232
|
+
return score
|
|
233
|
+
|
|
234
|
+
|
|
178
235
|
def brace_cognitive(lines: list[str], control: re.Pattern[str] | None = None) -> int:
|
|
179
236
|
"""Approximate cognitive complexity for a C-family declaration body.
|
|
180
237
|
|