desloppify 0.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.
- desloppify-0.7.0/LICENSE +21 -0
- desloppify-0.7.0/PKG-INFO +216 -0
- desloppify-0.7.0/README.md +187 -0
- desloppify-0.7.0/desloppify/__init__.py +3 -0
- desloppify-0.7.0/desloppify/__main__.py +5 -0
- desloppify-0.7.0/desloppify/app/__init__.py +1 -0
- desloppify-0.7.0/desloppify/app/cli_support/__init__.py +2 -0
- desloppify-0.7.0/desloppify/app/cli_support/parser.py +122 -0
- desloppify-0.7.0/desloppify/app/cli_support/parser_groups.py +243 -0
- desloppify-0.7.0/desloppify/app/cli_support/parser_groups_admin.py +320 -0
- desloppify-0.7.0/desloppify/app/commands/__init__.py +1 -0
- desloppify-0.7.0/desloppify/app/commands/_show_terminal.py +46 -0
- desloppify-0.7.0/desloppify/app/commands/config_cmd.py +95 -0
- desloppify-0.7.0/desloppify/app/commands/detect.py +89 -0
- desloppify-0.7.0/desloppify/app/commands/dev_cmd.py +174 -0
- desloppify-0.7.0/desloppify/app/commands/dev_scaffold_templates.py +264 -0
- desloppify-0.7.0/desloppify/app/commands/fix/__init__.py +5 -0
- desloppify-0.7.0/desloppify/app/commands/fix/apply_flow.py +323 -0
- desloppify-0.7.0/desloppify/app/commands/fix/cmd.py +70 -0
- desloppify-0.7.0/desloppify/app/commands/fix/io.py +15 -0
- desloppify-0.7.0/desloppify/app/commands/fix/options.py +33 -0
- desloppify-0.7.0/desloppify/app/commands/fix/review_flow.py +144 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/__init__.py +1 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/lang.py +133 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/query.py +16 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/rendering.py +69 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/runtime.py +39 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/runtime_options.py +49 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/score.py +40 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/state.py +31 -0
- desloppify-0.7.0/desloppify/app/commands/helpers/subjective.py +52 -0
- desloppify-0.7.0/desloppify/app/commands/issues_cmd.py +231 -0
- desloppify-0.7.0/desloppify/app/commands/langs.py +77 -0
- desloppify-0.7.0/desloppify/app/commands/move/__init__.py +0 -0
- desloppify-0.7.0/desloppify/app/commands/move/move.py +91 -0
- desloppify-0.7.0/desloppify/app/commands/move/move_apply.py +113 -0
- desloppify-0.7.0/desloppify/app/commands/move/move_directory.py +107 -0
- desloppify-0.7.0/desloppify/app/commands/move/move_language.py +101 -0
- desloppify-0.7.0/desloppify/app/commands/move/move_planning.py +179 -0
- desloppify-0.7.0/desloppify/app/commands/move/move_reporting.py +116 -0
- desloppify-0.7.0/desloppify/app/commands/next.py +166 -0
- desloppify-0.7.0/desloppify/app/commands/next_output.py +116 -0
- desloppify-0.7.0/desloppify/app/commands/next_render.py +395 -0
- desloppify-0.7.0/desloppify/app/commands/plan_cmd.py +36 -0
- desloppify-0.7.0/desloppify/app/commands/registry.py +64 -0
- desloppify-0.7.0/desloppify/app/commands/resolve/__init__.py +8 -0
- desloppify-0.7.0/desloppify/app/commands/resolve/apply.py +53 -0
- desloppify-0.7.0/desloppify/app/commands/resolve/cmd.py +183 -0
- desloppify-0.7.0/desloppify/app/commands/resolve/render.py +178 -0
- desloppify-0.7.0/desloppify/app/commands/resolve/selection.py +158 -0
- desloppify-0.7.0/desloppify/app/commands/review/__init__.py +2 -0
- desloppify-0.7.0/desloppify/app/commands/review/batch.py +195 -0
- desloppify-0.7.0/desloppify/app/commands/review/batch_core.py +669 -0
- desloppify-0.7.0/desloppify/app/commands/review/batches.py +183 -0
- desloppify-0.7.0/desloppify/app/commands/review/entrypoint.py +52 -0
- desloppify-0.7.0/desloppify/app/commands/review/import_cmd.py +137 -0
- desloppify-0.7.0/desloppify/app/commands/review/import_helpers.py +235 -0
- desloppify-0.7.0/desloppify/app/commands/review/output.py +72 -0
- desloppify-0.7.0/desloppify/app/commands/review/prepare.py +126 -0
- desloppify-0.7.0/desloppify/app/commands/review/runner_helpers.py +388 -0
- desloppify-0.7.0/desloppify/app/commands/review/runtime.py +69 -0
- desloppify-0.7.0/desloppify/app/commands/scan/__init__.py +0 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan.py +166 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_artifacts.py +131 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_helpers.py +170 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_analysis.py +383 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_dimensions.py +249 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_llm.py +331 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_presentation.py +291 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_subjective.py +477 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_reporting_summary.py +192 -0
- desloppify-0.7.0/desloppify/app/commands/scan/scan_workflow.py +530 -0
- desloppify-0.7.0/desloppify/app/commands/show/__init__.py +1 -0
- desloppify-0.7.0/desloppify/app/commands/show/cmd.py +155 -0
- desloppify-0.7.0/desloppify/app/commands/show/formatting.py +69 -0
- desloppify-0.7.0/desloppify/app/commands/show/payload.py +71 -0
- desloppify-0.7.0/desloppify/app/commands/show/render.py +266 -0
- desloppify-0.7.0/desloppify/app/commands/show/scope.py +75 -0
- desloppify-0.7.0/desloppify/app/commands/status.py +182 -0
- desloppify-0.7.0/desloppify/app/commands/status_parts/__init__.py +2 -0
- desloppify-0.7.0/desloppify/app/commands/status_parts/render.py +527 -0
- desloppify-0.7.0/desloppify/app/commands/status_parts/strict_target.py +52 -0
- desloppify-0.7.0/desloppify/app/commands/status_parts/summary.py +78 -0
- desloppify-0.7.0/desloppify/app/commands/update_skill.py +147 -0
- desloppify-0.7.0/desloppify/app/commands/viz_cmd.py +21 -0
- desloppify-0.7.0/desloppify/app/commands/zone_cmd.py +130 -0
- desloppify-0.7.0/desloppify/app/output/__init__.py +5 -0
- desloppify-0.7.0/desloppify/app/output/_viz_cmd_context.py +27 -0
- desloppify-0.7.0/desloppify/app/output/scorecard.py +199 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/__init__.py +17 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/dimension_policy.py +104 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/dimensions.py +242 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/draw.py +127 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/left_panel.py +340 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/meta.py +76 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/ornaments.py +57 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/projection.py +148 -0
- desloppify-0.7.0/desloppify/app/output/scorecard_parts/theme.py +127 -0
- desloppify-0.7.0/desloppify/app/output/tree_text.py +92 -0
- desloppify-0.7.0/desloppify/app/output/visualize.py +287 -0
- desloppify-0.7.0/desloppify/cli.py +148 -0
- desloppify-0.7.0/desloppify/conftest.py +20 -0
- desloppify-0.7.0/desloppify/core/__init__.py +7 -0
- desloppify-0.7.0/desloppify/core/_internal/__init__.py +2 -0
- desloppify-0.7.0/desloppify/core/_internal/text_utils.py +140 -0
- desloppify-0.7.0/desloppify/core/config.py +308 -0
- desloppify-0.7.0/desloppify/core/enums.py +31 -0
- desloppify-0.7.0/desloppify/core/fallbacks.py +48 -0
- desloppify-0.7.0/desloppify/core/issues_render.py +195 -0
- desloppify-0.7.0/desloppify/core/query.py +35 -0
- desloppify-0.7.0/desloppify/core/registry.py +395 -0
- desloppify-0.7.0/desloppify/core/runtime_state.py +111 -0
- desloppify-0.7.0/desloppify/core/signal_patterns.py +35 -0
- desloppify-0.7.0/desloppify/engine/__init__.py +1 -0
- desloppify-0.7.0/desloppify/engine/_scoring/__init__.py +1 -0
- desloppify-0.7.0/desloppify/engine/_scoring/detection.py +200 -0
- desloppify-0.7.0/desloppify/engine/_scoring/policy/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/_scoring/policy/core.py +266 -0
- desloppify-0.7.0/desloppify/engine/_scoring/results/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/_scoring/results/core.py +412 -0
- desloppify-0.7.0/desloppify/engine/_scoring/subjective/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/_scoring/subjective/core.py +242 -0
- desloppify-0.7.0/desloppify/engine/_state/__init__.py +1 -0
- desloppify-0.7.0/desloppify/engine/_state/filtering.py +151 -0
- desloppify-0.7.0/desloppify/engine/_state/merge.py +153 -0
- desloppify-0.7.0/desloppify/engine/_state/merge_findings.py +203 -0
- desloppify-0.7.0/desloppify/engine/_state/merge_history.py +151 -0
- desloppify-0.7.0/desloppify/engine/_state/noise.py +198 -0
- desloppify-0.7.0/desloppify/engine/_state/persistence.py +156 -0
- desloppify-0.7.0/desloppify/engine/_state/resolution.py +149 -0
- desloppify-0.7.0/desloppify/engine/_state/schema.py +336 -0
- desloppify-0.7.0/desloppify/engine/_state/scoring.py +296 -0
- desloppify-0.7.0/desloppify/engine/_work_queue/__init__.py +1 -0
- desloppify-0.7.0/desloppify/engine/_work_queue/core.py +154 -0
- desloppify-0.7.0/desloppify/engine/_work_queue/helpers.py +297 -0
- desloppify-0.7.0/desloppify/engine/_work_queue/issues.py +102 -0
- desloppify-0.7.0/desloppify/engine/_work_queue/ranking.py +210 -0
- desloppify-0.7.0/desloppify/engine/concerns.py +449 -0
- desloppify-0.7.0/desloppify/engine/detectors/__init__.py +7 -0
- desloppify-0.7.0/desloppify/engine/detectors/base.py +69 -0
- desloppify-0.7.0/desloppify/engine/detectors/complexity.py +82 -0
- desloppify-0.7.0/desloppify/engine/detectors/coupling.py +146 -0
- desloppify-0.7.0/desloppify/engine/detectors/coverage/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/detectors/coverage/mapping.py +365 -0
- desloppify-0.7.0/desloppify/engine/detectors/dupes.py +260 -0
- desloppify-0.7.0/desloppify/engine/detectors/flat_dirs.py +21 -0
- desloppify-0.7.0/desloppify/engine/detectors/gods.py +25 -0
- desloppify-0.7.0/desloppify/engine/detectors/graph.py +153 -0
- desloppify-0.7.0/desloppify/engine/detectors/jscpd_adapter.py +150 -0
- desloppify-0.7.0/desloppify/engine/detectors/large.py +34 -0
- desloppify-0.7.0/desloppify/engine/detectors/naming.py +86 -0
- desloppify-0.7.0/desloppify/engine/detectors/orphaned.py +100 -0
- desloppify-0.7.0/desloppify/engine/detectors/passthrough.py +68 -0
- desloppify-0.7.0/desloppify/engine/detectors/patterns/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/detectors/patterns/security.py +177 -0
- desloppify-0.7.0/desloppify/engine/detectors/review_coverage.py +267 -0
- desloppify-0.7.0/desloppify/engine/detectors/security/__init__.py +5 -0
- desloppify-0.7.0/desloppify/engine/detectors/security/detector.py +54 -0
- desloppify-0.7.0/desloppify/engine/detectors/security/filters.py +28 -0
- desloppify-0.7.0/desloppify/engine/detectors/security/rules.py +201 -0
- desloppify-0.7.0/desloppify/engine/detectors/security/scanner.py +30 -0
- desloppify-0.7.0/desloppify/engine/detectors/signature.py +147 -0
- desloppify-0.7.0/desloppify/engine/detectors/single_use.py +85 -0
- desloppify-0.7.0/desloppify/engine/detectors/test_coverage/__init__.py +7 -0
- desloppify-0.7.0/desloppify/engine/detectors/test_coverage/detector.py +299 -0
- desloppify-0.7.0/desloppify/engine/detectors/test_coverage/discovery.py +126 -0
- desloppify-0.7.0/desloppify/engine/detectors/test_coverage/heuristics.py +60 -0
- desloppify-0.7.0/desloppify/engine/detectors/test_coverage/metrics.py +40 -0
- desloppify-0.7.0/desloppify/engine/planning/__init__.py +7 -0
- desloppify-0.7.0/desloppify/engine/planning/common.py +23 -0
- desloppify-0.7.0/desloppify/engine/planning/core.py +15 -0
- desloppify-0.7.0/desloppify/engine/planning/dimension_rows.py +65 -0
- desloppify-0.7.0/desloppify/engine/planning/render.py +302 -0
- desloppify-0.7.0/desloppify/engine/planning/scan.py +151 -0
- desloppify-0.7.0/desloppify/engine/planning/select.py +44 -0
- desloppify-0.7.0/desloppify/engine/planning/types.py +34 -0
- desloppify-0.7.0/desloppify/engine/policy/__init__.py +2 -0
- desloppify-0.7.0/desloppify/engine/policy/zones.py +275 -0
- desloppify-0.7.0/desloppify/engine/policy/zones_data.py +55 -0
- desloppify-0.7.0/desloppify/engine/work_queue.py +83 -0
- desloppify-0.7.0/desloppify/file_discovery.py +248 -0
- desloppify-0.7.0/desloppify/hook_registry.py +67 -0
- desloppify-0.7.0/desloppify/intelligence/__init__.py +29 -0
- desloppify-0.7.0/desloppify/intelligence/integrity.py +110 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/__init__.py +25 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/_constants.py +43 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/action_engine.py +265 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/action_models.py +73 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/action_tools.py +79 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/core.py +393 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/dimensions.py +217 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/headline.py +157 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/phase.py +90 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/reminders.py +482 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/strategy_engine.py +337 -0
- desloppify-0.7.0/desloppify/intelligence/narrative/types.py +157 -0
- desloppify-0.7.0/desloppify/intelligence/review/__init__.py +103 -0
- desloppify-0.7.0/desloppify/intelligence/review/_context/__init__.py +1 -0
- desloppify-0.7.0/desloppify/intelligence/review/_context/models.py +90 -0
- desloppify-0.7.0/desloppify/intelligence/review/_context/patterns.py +70 -0
- desloppify-0.7.0/desloppify/intelligence/review/_context/structure.py +126 -0
- desloppify-0.7.0/desloppify/intelligence/review/_prepare/__init__.py +1 -0
- desloppify-0.7.0/desloppify/intelligence/review/_prepare/helpers.py +47 -0
- desloppify-0.7.0/desloppify/intelligence/review/_prepare/remediation_engine.py +210 -0
- desloppify-0.7.0/desloppify/intelligence/review/context.py +269 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/__init__.py +10 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/budget.py +220 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/orchestrator.py +103 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/readers.py +19 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/selection.py +237 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_holistic/types.py +5 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_signals/__init__.py +1 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_signals/ai.py +72 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_signals/auth.py +166 -0
- desloppify-0.7.0/desloppify/intelligence/review/context_signals/migration.py +170 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/__init__.py +50 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/data.py +202 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/holistic.py +7 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/lang.py +62 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/metadata.py +282 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/selection.py +46 -0
- desloppify-0.7.0/desloppify/intelligence/review/dimensions/validation.py +219 -0
- desloppify-0.7.0/desloppify/intelligence/review/importing/__init__.py +25 -0
- desloppify-0.7.0/desloppify/intelligence/review/importing/holistic.py +383 -0
- desloppify-0.7.0/desloppify/intelligence/review/importing/per_file.py +189 -0
- desloppify-0.7.0/desloppify/intelligence/review/importing/shared.py +98 -0
- desloppify-0.7.0/desloppify/intelligence/review/policy.py +160 -0
- desloppify-0.7.0/desloppify/intelligence/review/prepare.py +303 -0
- desloppify-0.7.0/desloppify/intelligence/review/prepare_batches.py +492 -0
- desloppify-0.7.0/desloppify/intelligence/review/remediation.py +10 -0
- desloppify-0.7.0/desloppify/intelligence/review/selection.py +253 -0
- desloppify-0.7.0/desloppify/languages/__init__.py +72 -0
- desloppify-0.7.0/desloppify/languages/_framework/__init__.py +33 -0
- desloppify-0.7.0/desloppify/languages/_framework/base/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/_framework/base/phase_builders.py +65 -0
- desloppify-0.7.0/desloppify/languages/_framework/base/shared_phases.py +470 -0
- desloppify-0.7.0/desloppify/languages/_framework/base/structural.py +82 -0
- desloppify-0.7.0/desloppify/languages/_framework/base/types.py +299 -0
- desloppify-0.7.0/desloppify/languages/_framework/commands_base.py +499 -0
- desloppify-0.7.0/desloppify/languages/_framework/contract_validation.py +132 -0
- desloppify-0.7.0/desloppify/languages/_framework/discovery.py +91 -0
- desloppify-0.7.0/desloppify/languages/_framework/facade_common.py +41 -0
- desloppify-0.7.0/desloppify/languages/_framework/finding_factories.py +290 -0
- desloppify-0.7.0/desloppify/languages/_framework/generic.py +612 -0
- desloppify-0.7.0/desloppify/languages/_framework/policy.py +32 -0
- desloppify-0.7.0/desloppify/languages/_framework/registry_state.py +93 -0
- desloppify-0.7.0/desloppify/languages/_framework/resolution.py +84 -0
- desloppify-0.7.0/desloppify/languages/_framework/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/_framework/review_data/dimensions.json +375 -0
- desloppify-0.7.0/desloppify/languages/_framework/runtime.py +182 -0
- desloppify-0.7.0/desloppify/languages/_framework/structure_validation.py +32 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/__init__.py +116 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_cache.py +69 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_cohesion.py +132 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_complexity.py +361 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_extractors.py +239 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_imports.py +748 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_normalize.py +90 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_smells.py +210 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_specs.py +801 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/_unused_imports.py +122 -0
- desloppify-0.7.0/desloppify/languages/_framework/treesitter/phases.py +160 -0
- desloppify-0.7.0/desloppify/languages/bash/__init__.py +21 -0
- desloppify-0.7.0/desloppify/languages/clojure/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/csharp/__init__.py +168 -0
- desloppify-0.7.0/desloppify/languages/csharp/_parse_helpers.py +150 -0
- desloppify-0.7.0/desloppify/languages/csharp/commands.py +134 -0
- desloppify-0.7.0/desloppify/languages/csharp/deps/__init__.py +2 -0
- desloppify-0.7.0/desloppify/languages/csharp/deps/cli.py +85 -0
- desloppify-0.7.0/desloppify/languages/csharp/detectors/__init__.py +4 -0
- desloppify-0.7.0/desloppify/languages/csharp/detectors/deps.py +606 -0
- desloppify-0.7.0/desloppify/languages/csharp/detectors/security.py +131 -0
- desloppify-0.7.0/desloppify/languages/csharp/extractors.py +166 -0
- desloppify-0.7.0/desloppify/languages/csharp/extractors_classes.py +166 -0
- desloppify-0.7.0/desloppify/languages/csharp/fixers/__init__.py +4 -0
- desloppify-0.7.0/desloppify/languages/csharp/move.py +45 -0
- desloppify-0.7.0/desloppify/languages/csharp/phases.py +200 -0
- desloppify-0.7.0/desloppify/languages/csharp/review.py +101 -0
- desloppify-0.7.0/desloppify/languages/csharp/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/csharp/review_data/dimensions.override.json +22 -0
- desloppify-0.7.0/desloppify/languages/csharp/review_data/holistic_dimensions.override.json +19 -0
- desloppify-0.7.0/desloppify/languages/csharp/test_coverage.py +169 -0
- desloppify-0.7.0/desloppify/languages/csharp/tests/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/csharp/tests/test_csharp_deps_cli.py +356 -0
- desloppify-0.7.0/desloppify/languages/csharp/tests/test_csharp_parse_helpers.py +260 -0
- desloppify-0.7.0/desloppify/languages/csharp/tests/test_smoke.py +2 -0
- desloppify-0.7.0/desloppify/languages/cxx/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/dart/__init__.py +107 -0
- desloppify-0.7.0/desloppify/languages/dart/commands.py +82 -0
- desloppify-0.7.0/desloppify/languages/dart/detectors/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/dart/detectors/deps.py +110 -0
- desloppify-0.7.0/desloppify/languages/dart/extractors.py +164 -0
- desloppify-0.7.0/desloppify/languages/dart/fixers/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/dart/move.py +25 -0
- desloppify-0.7.0/desloppify/languages/dart/phases.py +61 -0
- desloppify-0.7.0/desloppify/languages/dart/pubspec.py +24 -0
- desloppify-0.7.0/desloppify/languages/dart/review.py +76 -0
- desloppify-0.7.0/desloppify/languages/dart/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/dart/review_data/dimensions.override.json +1 -0
- desloppify-0.7.0/desloppify/languages/dart/review_data/holistic_dimensions.override.json +1 -0
- desloppify-0.7.0/desloppify/languages/dart/test_coverage.py +149 -0
- desloppify-0.7.0/desloppify/languages/dart/tests/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/dart/tests/test_init.py +49 -0
- desloppify-0.7.0/desloppify/languages/elixir/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/erlang/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/fsharp/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/gdscript/__init__.py +100 -0
- desloppify-0.7.0/desloppify/languages/gdscript/commands.py +78 -0
- desloppify-0.7.0/desloppify/languages/gdscript/detectors/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/gdscript/detectors/deps.py +83 -0
- desloppify-0.7.0/desloppify/languages/gdscript/extractors.py +102 -0
- desloppify-0.7.0/desloppify/languages/gdscript/fixers/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/gdscript/move.py +25 -0
- desloppify-0.7.0/desloppify/languages/gdscript/patterns.py +12 -0
- desloppify-0.7.0/desloppify/languages/gdscript/phases.py +56 -0
- desloppify-0.7.0/desloppify/languages/gdscript/review.py +68 -0
- desloppify-0.7.0/desloppify/languages/gdscript/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/gdscript/review_data/dimensions.override.json +1 -0
- desloppify-0.7.0/desloppify/languages/gdscript/review_data/holistic_dimensions.override.json +1 -0
- desloppify-0.7.0/desloppify/languages/gdscript/test_coverage.py +95 -0
- desloppify-0.7.0/desloppify/languages/gdscript/tests/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/gdscript/tests/test_init.py +49 -0
- desloppify-0.7.0/desloppify/languages/go/__init__.py +42 -0
- desloppify-0.7.0/desloppify/languages/go/test_coverage.py +120 -0
- desloppify-0.7.0/desloppify/languages/go/tests/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/go/tests/test_init.py +78 -0
- desloppify-0.7.0/desloppify/languages/haskell/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/java/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/javascript/__init__.py +24 -0
- desloppify-0.7.0/desloppify/languages/kotlin/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/lua/__init__.py +21 -0
- desloppify-0.7.0/desloppify/languages/nim/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/ocaml/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/perl/__init__.py +21 -0
- desloppify-0.7.0/desloppify/languages/php/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/powershell/__init__.py +24 -0
- desloppify-0.7.0/desloppify/languages/python/__init__.py +172 -0
- desloppify-0.7.0/desloppify/languages/python/commands.py +217 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/bandit_adapter.py +167 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/complexity.py +108 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/coupling_contracts.py +122 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/deps.py +306 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/dict_keys.py +336 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/dict_keys_visitor.py +470 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/facade.py +111 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/import_linter_adapter.py +114 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/mutable_state.py +341 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/private_imports.py +164 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/responsibility_cohesion.py +169 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/ruff_smells.py +148 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells.py +431 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/__init__.py +30 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_dispatch.py +202 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_node_detectors.py +177 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_shared.py +107 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_source_detectors.py +244 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_tree_context_detectors.py +148 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_tree_quality_detectors.py +263 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_tree_quality_detectors_types.py +145 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_tree_safety_detectors.py +246 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_tree_safety_detectors_runtime.py +210 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/smells_ast/_types.py +57 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/uncalled.py +120 -0
- desloppify-0.7.0/desloppify/languages/python/detectors/unused.py +200 -0
- desloppify-0.7.0/desloppify/languages/python/extractors.py +208 -0
- desloppify-0.7.0/desloppify/languages/python/extractors_classes.py +131 -0
- desloppify-0.7.0/desloppify/languages/python/extractors_shared.py +51 -0
- desloppify-0.7.0/desloppify/languages/python/fixers/__init__.py +4 -0
- desloppify-0.7.0/desloppify/languages/python/move.py +236 -0
- desloppify-0.7.0/desloppify/languages/python/phases.py +370 -0
- desloppify-0.7.0/desloppify/languages/python/phases_quality.py +179 -0
- desloppify-0.7.0/desloppify/languages/python/review.py +70 -0
- desloppify-0.7.0/desloppify/languages/python/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/python/review_data/dimensions.override.json +21 -0
- desloppify-0.7.0/desloppify/languages/python/review_data/holistic_dimensions.override.json +19 -0
- desloppify-0.7.0/desloppify/languages/python/test_coverage.py +162 -0
- desloppify-0.7.0/desloppify/languages/python/tests/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_commands.py +49 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_complexity.py +187 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_coupling_contracts.py +66 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_deps.py +339 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_dict_keys.py +347 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_extractors.py +347 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_facade.py +160 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_init.py +156 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_move.py +72 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_mutable_state.py +238 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_private_imports.py +54 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_responsibility_cohesion.py +81 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_smells.py +818 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_smells_ast_perf.py +30 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_uncalled.py +338 -0
- desloppify-0.7.0/desloppify/languages/python/tests/test_py_unused.py +238 -0
- desloppify-0.7.0/desloppify/languages/r/__init__.py +28 -0
- desloppify-0.7.0/desloppify/languages/ruby/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/rust/__init__.py +31 -0
- desloppify-0.7.0/desloppify/languages/scala/__init__.py +23 -0
- desloppify-0.7.0/desloppify/languages/swift/__init__.py +22 -0
- desloppify-0.7.0/desloppify/languages/typescript/__init__.py +297 -0
- desloppify-0.7.0/desloppify/languages/typescript/commands.py +336 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/__init__.py +0 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/_smell_detectors.py +336 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/_smell_effects.py +269 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/_smell_helpers.py +226 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/concerns.py +103 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/contracts.py +24 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/deprecated.py +220 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/deps.py +398 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/deps_runtime.py +56 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/exports.py +47 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/facade.py +60 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/knip_adapter.py +114 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/logs.py +142 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/patterns.py +327 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/props.py +112 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/react.py +485 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/security.py +373 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/smells.py +520 -0
- desloppify-0.7.0/desloppify/languages/typescript/detectors/unused.py +359 -0
- desloppify-0.7.0/desloppify/languages/typescript/extractors.py +248 -0
- desloppify-0.7.0/desloppify/languages/typescript/extractors_components.py +183 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/__init__.py +37 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/common.py +439 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/if_chain.py +69 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/imports.py +231 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/logs.py +315 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/params.py +103 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/useeffect.py +44 -0
- desloppify-0.7.0/desloppify/languages/typescript/fixers/vars.py +212 -0
- desloppify-0.7.0/desloppify/languages/typescript/move.py +156 -0
- desloppify-0.7.0/desloppify/languages/typescript/phases.py +675 -0
- desloppify-0.7.0/desloppify/languages/typescript/review.py +100 -0
- desloppify-0.7.0/desloppify/languages/typescript/review_data/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/typescript/review_data/dimensions.override.json +22 -0
- desloppify-0.7.0/desloppify/languages/typescript/review_data/holistic_dimensions.override.json +19 -0
- desloppify-0.7.0/desloppify/languages/typescript/test_coverage.py +279 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/__init__.py +1 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/smells/test_ts_smell_helpers.py +401 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_commands.py +60 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_concerns.py +207 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_deprecated.py +218 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_deps.py +566 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_detector_contracts.py +97 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_exports_detector.py +154 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_extractors.py +326 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_facade.py +99 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_fixers.py +766 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_init.py +90 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_logs.py +135 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_move.py +43 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_patterns.py +211 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_phases.py +171 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_props.py +148 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_react.py +369 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_smells.py +441 -0
- desloppify-0.7.0/desloppify/languages/typescript/tests/test_ts_unused.py +209 -0
- desloppify-0.7.0/desloppify/languages/zig/__init__.py +22 -0
- desloppify-0.7.0/desloppify/scoring.py +82 -0
- desloppify-0.7.0/desloppify/search.py +76 -0
- desloppify-0.7.0/desloppify/state.py +128 -0
- desloppify-0.7.0/desloppify/utils.py +331 -0
- desloppify-0.7.0/desloppify/versioning.py +42 -0
- desloppify-0.7.0/desloppify.egg-info/PKG-INFO +216 -0
- desloppify-0.7.0/desloppify.egg-info/SOURCES.txt +469 -0
- desloppify-0.7.0/desloppify.egg-info/dependency_links.txt +1 -0
- desloppify-0.7.0/desloppify.egg-info/entry_points.txt +2 -0
- desloppify-0.7.0/desloppify.egg-info/requires.txt +4 -0
- desloppify-0.7.0/desloppify.egg-info/top_level.txt +1 -0
- desloppify-0.7.0/pyproject.toml +92 -0
- desloppify-0.7.0/setup.cfg +4 -0
desloppify-0.7.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Peter O'Malley
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: desloppify
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Multi-language codebase health scanner and technical debt tracker
|
|
5
|
+
Author-email: Peter O'Malley <pete@banodoco.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/peteromallet/desloppify
|
|
8
|
+
Project-URL: Repository, https://github.com/peteromallet/desloppify
|
|
9
|
+
Project-URL: Issues, https://github.com/peteromallet/desloppify/issues
|
|
10
|
+
Keywords: code-quality,technical-debt,linter,static-analysis,refactoring
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
20
|
+
Classifier: Topic :: Software Development :: Testing
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: Pillow>=9.0.0
|
|
26
|
+
Provides-Extra: treesitter
|
|
27
|
+
Requires-Dist: tree-sitter-language-pack>=0.3; extra == "treesitter"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Desloppify - an agent harness to make your codebase 🤌
|
|
31
|
+
|
|
32
|
+
Desloppify gives your AI coding agent the tools to identify, understand, and systematically improve codebase quality. It finds issues in two ways:
|
|
33
|
+
|
|
34
|
+
1. **Subjective** — Examines the codebase from multiple subjective perspectives: abstraction quality, naming consistency, module boundaries, error handling patterns, convention drift, and language-specific questions. LLM evaluation scores these and tracks them as findings.
|
|
35
|
+
|
|
36
|
+
2. **Mechanical** — Detects common mechanical issues like unused imports, dead code, overly long functions, duplication, and dependency cycles. Questionable issues are also flagged to the subjective agent for review.
|
|
37
|
+
|
|
38
|
+
Your agent works through a prioritized list — auto-fixing what it can, presenting the rest for your judgment. State persists across scans so it chips away over multiple sessions, and the scoring is designed to resist gaming: attestation requirements, strict scoring that penalizes dismissed issues, and cross-checked subjective assessments.
|
|
39
|
+
|
|
40
|
+
This produces a combined health score — our goal is that a score above 98 correlates with a codebase a seasoned engineer would call beautiful. That score generates a scorecard badge for your GitHub profile or README:
|
|
41
|
+
|
|
42
|
+
<img src="assets/scorecard.png" width="100%">
|
|
43
|
+
|
|
44
|
+
Currently supports 28 languages — full plugin depth for TypeScript, Python, C#, Dart, and GDScript; generic linter + tree-sitter support for Go, Rust, Ruby, Java, Kotlin, and 18 more.
|
|
45
|
+
|
|
46
|
+
## For your agent's consideration...
|
|
47
|
+
|
|
48
|
+
Paste this prompt into your agent:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Install or update desloppify, then scan this codebase for code quality issues (dead code,
|
|
52
|
+
duplication, complexity, smells). It tracks findings persistently across sessions and reports
|
|
53
|
+
a health score — state is cumulative, so each scan builds on previous progress.
|
|
54
|
+
|
|
55
|
+
pip install --upgrade git+https://github.com/peteromallet/desloppify.git
|
|
56
|
+
desloppify update-skill claude # pick yours: claude, cursor, codex, copilot, windsurf, gemini
|
|
57
|
+
desloppify scan --path .
|
|
58
|
+
desloppify status
|
|
59
|
+
desloppify next
|
|
60
|
+
|
|
61
|
+
--path is the directory to scan (use "." for the whole project, or "src/" etc).
|
|
62
|
+
Language is auto-detected. To override: desloppify --lang python scan --path .
|
|
63
|
+
(note: --lang goes BEFORE the subcommand)
|
|
64
|
+
|
|
65
|
+
Fix what it finds, then "desloppify resolve fixed <id> --note 'what changed' --attest 'I have actually [DESCRIBE THE CONCRETE CHANGE YOU MADE] and I am not gaming the score by resolving without fixing.'" and rescan.
|
|
66
|
+
For false positives: "desloppify resolve wontfix <id> --note 'reason' --attest 'I have actually verified this is intentional/false-positive and I am not gaming the score by resolving without fixing.'" (note is required — don't skip work; attestation must include the keywords "I have actually" and "not gaming").
|
|
67
|
+
Keep going until all issues are resolved.
|
|
68
|
+
|
|
69
|
+
If subjective scores feel stale or inflated, force a clean baseline:
|
|
70
|
+
desloppify scan --path . --reset-subjective
|
|
71
|
+
|
|
72
|
+
Because state persists, desloppify works best when run regularly. Ask the user if they'd
|
|
73
|
+
like to add a desloppify scan to their workflow — for example, adding "run desloppify scan
|
|
74
|
+
before each git push" to their CLAUDE.md, AGENTS.md, or equivalent agent instructions file,
|
|
75
|
+
so code health is checked at a natural interval.
|
|
76
|
+
|
|
77
|
+
If you notice anything wrong or confusing about
|
|
78
|
+
desloppify itself, tell me and ask if I want you to log an issue. If you need to understand
|
|
79
|
+
how desloppify works or debug an issue: git clone https://github.com/peteromallet/desloppify.git /tmp/desloppify
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## From Vibe Coding to Vibe Engineering
|
|
83
|
+
|
|
84
|
+
Vibe coding gets things built fast. But the codebases it produces tend to rot in ways that are hard to see and harder to fix — not just the mechanical stuff like dead imports, but the structural kind. Abstractions that made sense at first stop making sense. Naming drifts. Error handling is done three different ways. The codebase works, but working in it gets worse over time.
|
|
85
|
+
|
|
86
|
+
LLMs are actually good at spotting this now, if you ask them the right questions. That's the core bet here — that an agent with the right framework can hold a codebase to a real standard, the kind that used to require a senior engineer paying close attention over months.
|
|
87
|
+
|
|
88
|
+
So we're trying to define what "good" looks like as a score that's actually worth optimizing. Not a lint score you game to 100 by suppressing warnings. Something where improving the number means the codebase genuinely got better. That's hard, and we're not done, but the anti-gaming stuff matters to us a lot — it's the difference between a useful signal and a vanity metric.
|
|
89
|
+
|
|
90
|
+
The hope is that anyone can use this to build something a seasoned engineer would look at and respect. That's the bar we're aiming for.
|
|
91
|
+
|
|
92
|
+
If you'd like to join a community of vibe engineers who want to build beautiful things, [come hang out](https://discord.gg/aZdzbZrHaY).
|
|
93
|
+
|
|
94
|
+
<img src="docs/engineering.png" width="100%">
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
<details>
|
|
99
|
+
<summary><strong>Stuff you probably won't need to know</strong></summary>
|
|
100
|
+
|
|
101
|
+
#### Commands
|
|
102
|
+
|
|
103
|
+
| Command | Description |
|
|
104
|
+
|---------|-------------|
|
|
105
|
+
| `scan [--reset-subjective]` | Run all detectors, update state (optional: reset subjective baseline to 0 first) |
|
|
106
|
+
| `status` | Score + per-tier progress |
|
|
107
|
+
| `show <pattern>` | Findings by file, directory, detector, or ID |
|
|
108
|
+
| `next [--tier N] [--explain]` | Highest-priority open finding (--explain: with score context) |
|
|
109
|
+
| `resolve <status> <patterns>` | Mark fixed / wontfix / false_positive / ignore |
|
|
110
|
+
| `fix <fixer> [--dry-run]` | Auto-fix mechanical issues |
|
|
111
|
+
| `review --prepare` | Generate subjective review packet (`query.json`) |
|
|
112
|
+
| `review --import <file>` | Import subjective review findings |
|
|
113
|
+
| `issues` | Review findings queue (list/show/update) |
|
|
114
|
+
| `zone` | Show/set/clear zone classifications |
|
|
115
|
+
| `config` | Show/set/unset project configuration |
|
|
116
|
+
| `move <src> <dst>` | Move file/directory, update all imports |
|
|
117
|
+
| `detect <name>` | Run a single detector raw |
|
|
118
|
+
| `plan` | Prioritized markdown plan |
|
|
119
|
+
| `tree` | Annotated codebase tree |
|
|
120
|
+
| `viz` | Interactive HTML treemap |
|
|
121
|
+
| `dev scaffold-lang` | Generate a standardized language plugin scaffold |
|
|
122
|
+
|
|
123
|
+
#### Detectors
|
|
124
|
+
|
|
125
|
+
**TypeScript/React**: logs, unused, exports, deprecated, large, complexity, gods, single_use, props, passthrough, concerns, deps, dupes, smells, coupling, patterns, naming, cycles, orphaned, react
|
|
126
|
+
|
|
127
|
+
**Python**: unused, large, complexity, gods, props, smells, dupes, deps, cycles, orphaned, single_use, naming
|
|
128
|
+
|
|
129
|
+
**C#/.NET**: deps, cycles, orphaned, dupes, large, complexity
|
|
130
|
+
|
|
131
|
+
#### Tiers & scoring
|
|
132
|
+
|
|
133
|
+
| Tier | Fix type | Examples |
|
|
134
|
+
|------|----------|----------|
|
|
135
|
+
| T1 | Auto-fixable | Unused imports, debug logs |
|
|
136
|
+
| T2 | Quick manual | Unused vars, dead exports |
|
|
137
|
+
| T3 | Needs judgment | Near-dupes, single_use abstractions |
|
|
138
|
+
| T4 | Major refactor | God components, mixed concerns |
|
|
139
|
+
|
|
140
|
+
Score is weighted (T4 = 4x T1). Strict score penalizes both open and wontfix.
|
|
141
|
+
|
|
142
|
+
#### Configuration
|
|
143
|
+
|
|
144
|
+
| Variable | Default | Description |
|
|
145
|
+
|----------|---------|-------------|
|
|
146
|
+
| `DESLOPPIFY_ROOT` | cwd | Project root |
|
|
147
|
+
| `DESLOPPIFY_SRC` | `src` | Source directory (TS alias resolution) |
|
|
148
|
+
| `--lang <name>` | auto-detected | Language selection (each has own state) |
|
|
149
|
+
| `--exclude <pattern>` | none | Path patterns to skip (repeatable: `--exclude migrations --exclude tests`) |
|
|
150
|
+
| `--no-badge` | false | Skip scorecard image generation |
|
|
151
|
+
| `--badge-path <path>` | `scorecard.png` | Output path for scorecard image |
|
|
152
|
+
| `DESLOPPIFY_NO_BADGE` | — | Set to `true` to disable badge via env |
|
|
153
|
+
| `DESLOPPIFY_BADGE_PATH` | `scorecard.png` | Badge output path via env |
|
|
154
|
+
|
|
155
|
+
Project config values (stored in `.desloppify/config.json`) are managed via:
|
|
156
|
+
- `desloppify config show`
|
|
157
|
+
- `desloppify config set target_strict_score 95` (default: `95`, valid range: `0-100`)
|
|
158
|
+
- `desloppify config set badge_path scorecard.png` (or nested path like `assets/health.png`)
|
|
159
|
+
|
|
160
|
+
#### Adding or augmenting a language
|
|
161
|
+
|
|
162
|
+
Use the scaffold workflow documented in `desloppify/languages/README.md`:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
desloppify dev scaffold-lang <name> --extension .ext --marker <root-marker>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Detect command keys are standardized to snake_case. CLI compatibility aliases
|
|
169
|
+
like `single-use` and legacy `passthrough` are still accepted.
|
|
170
|
+
Standard plugin shape: `__init__.py`, `commands.py`, `extractors.py`, `phases.py`,
|
|
171
|
+
`move.py`, `review.py`, `test_coverage.py`, plus `detectors/`, `fixers/`, and `tests/`.
|
|
172
|
+
Validated at registration. Zero shared code changes.
|
|
173
|
+
|
|
174
|
+
#### Architecture
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
engine/detectors/ ← Generic algorithms (zero language knowledge)
|
|
178
|
+
hook_registry.py ← Detector-safe access to optional language hooks
|
|
179
|
+
languages/_framework/runtime.py ← LangRun (per-run mutable scan state)
|
|
180
|
+
languages/_framework/base/ ← Shared framework contracts + phase helpers
|
|
181
|
+
languages/_framework/generic.py ← generic_lang() factory for tool-based plugins
|
|
182
|
+
languages/_framework/treesitter/ ← Tree-sitter integration (optional)
|
|
183
|
+
languages/<name>/ ← Language config + phases + extractors + detectors + fixers
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Import direction: `languages/` → `engine/detectors/`. Never the reverse.
|
|
187
|
+
`LangConfig` stays static; runtime state lives on `LangRun`.
|
|
188
|
+
|
|
189
|
+
#### Command-Layer Boundaries
|
|
190
|
+
|
|
191
|
+
Command entry modules are intentionally thin orchestrators:
|
|
192
|
+
|
|
193
|
+
- `desloppify/app/commands/review/cmd.py` delegates to
|
|
194
|
+
`desloppify/app/commands/review/prepare.py`, `desloppify/app/commands/review/batches.py`, `desloppify/app/commands/review/import_cmd.py`, and `desloppify/app/commands/review/runtime.py`
|
|
195
|
+
- `desloppify/app/commands/scan/scan_reporting_dimensions.py` delegates to
|
|
196
|
+
`desloppify/app/commands/scan/scan_reporting_presentation.py` and `desloppify/app/commands/scan/scan_reporting_subjective.py`
|
|
197
|
+
- `desloppify/app/cli_support/parser.py` delegates subcommand construction to `desloppify/app/cli_support/parser_groups.py`
|
|
198
|
+
|
|
199
|
+
Public CLI behavior should be preserved when refactoring these orchestrators.
|
|
200
|
+
|
|
201
|
+
#### Allowed Dynamic Import Zones
|
|
202
|
+
|
|
203
|
+
Dynamic/optional loading is allowed only in explicit extension points:
|
|
204
|
+
|
|
205
|
+
- `desloppify/languages/__init__.py` for plugin discovery and registration
|
|
206
|
+
- `desloppify/hook_registry.py` for detector-safe optional hooks
|
|
207
|
+
|
|
208
|
+
Outside these zones, use static imports.
|
|
209
|
+
|
|
210
|
+
#### State Ownership
|
|
211
|
+
|
|
212
|
+
- `desloppify/state.py` and `desloppify/engine/_state/` own persisted schema and merge rules
|
|
213
|
+
- `desloppify/languages/_framework/runtime.py` (`LangRun`) owns per-run mutable execution state
|
|
214
|
+
- command modules may read/write state through state APIs, but should not define ad-hoc persisted fields
|
|
215
|
+
|
|
216
|
+
</details>
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Desloppify - an agent harness to make your codebase 🤌
|
|
2
|
+
|
|
3
|
+
Desloppify gives your AI coding agent the tools to identify, understand, and systematically improve codebase quality. It finds issues in two ways:
|
|
4
|
+
|
|
5
|
+
1. **Subjective** — Examines the codebase from multiple subjective perspectives: abstraction quality, naming consistency, module boundaries, error handling patterns, convention drift, and language-specific questions. LLM evaluation scores these and tracks them as findings.
|
|
6
|
+
|
|
7
|
+
2. **Mechanical** — Detects common mechanical issues like unused imports, dead code, overly long functions, duplication, and dependency cycles. Questionable issues are also flagged to the subjective agent for review.
|
|
8
|
+
|
|
9
|
+
Your agent works through a prioritized list — auto-fixing what it can, presenting the rest for your judgment. State persists across scans so it chips away over multiple sessions, and the scoring is designed to resist gaming: attestation requirements, strict scoring that penalizes dismissed issues, and cross-checked subjective assessments.
|
|
10
|
+
|
|
11
|
+
This produces a combined health score — our goal is that a score above 98 correlates with a codebase a seasoned engineer would call beautiful. That score generates a scorecard badge for your GitHub profile or README:
|
|
12
|
+
|
|
13
|
+
<img src="assets/scorecard.png" width="100%">
|
|
14
|
+
|
|
15
|
+
Currently supports 28 languages — full plugin depth for TypeScript, Python, C#, Dart, and GDScript; generic linter + tree-sitter support for Go, Rust, Ruby, Java, Kotlin, and 18 more.
|
|
16
|
+
|
|
17
|
+
## For your agent's consideration...
|
|
18
|
+
|
|
19
|
+
Paste this prompt into your agent:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Install or update desloppify, then scan this codebase for code quality issues (dead code,
|
|
23
|
+
duplication, complexity, smells). It tracks findings persistently across sessions and reports
|
|
24
|
+
a health score — state is cumulative, so each scan builds on previous progress.
|
|
25
|
+
|
|
26
|
+
pip install --upgrade git+https://github.com/peteromallet/desloppify.git
|
|
27
|
+
desloppify update-skill claude # pick yours: claude, cursor, codex, copilot, windsurf, gemini
|
|
28
|
+
desloppify scan --path .
|
|
29
|
+
desloppify status
|
|
30
|
+
desloppify next
|
|
31
|
+
|
|
32
|
+
--path is the directory to scan (use "." for the whole project, or "src/" etc).
|
|
33
|
+
Language is auto-detected. To override: desloppify --lang python scan --path .
|
|
34
|
+
(note: --lang goes BEFORE the subcommand)
|
|
35
|
+
|
|
36
|
+
Fix what it finds, then "desloppify resolve fixed <id> --note 'what changed' --attest 'I have actually [DESCRIBE THE CONCRETE CHANGE YOU MADE] and I am not gaming the score by resolving without fixing.'" and rescan.
|
|
37
|
+
For false positives: "desloppify resolve wontfix <id> --note 'reason' --attest 'I have actually verified this is intentional/false-positive and I am not gaming the score by resolving without fixing.'" (note is required — don't skip work; attestation must include the keywords "I have actually" and "not gaming").
|
|
38
|
+
Keep going until all issues are resolved.
|
|
39
|
+
|
|
40
|
+
If subjective scores feel stale or inflated, force a clean baseline:
|
|
41
|
+
desloppify scan --path . --reset-subjective
|
|
42
|
+
|
|
43
|
+
Because state persists, desloppify works best when run regularly. Ask the user if they'd
|
|
44
|
+
like to add a desloppify scan to their workflow — for example, adding "run desloppify scan
|
|
45
|
+
before each git push" to their CLAUDE.md, AGENTS.md, or equivalent agent instructions file,
|
|
46
|
+
so code health is checked at a natural interval.
|
|
47
|
+
|
|
48
|
+
If you notice anything wrong or confusing about
|
|
49
|
+
desloppify itself, tell me and ask if I want you to log an issue. If you need to understand
|
|
50
|
+
how desloppify works or debug an issue: git clone https://github.com/peteromallet/desloppify.git /tmp/desloppify
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## From Vibe Coding to Vibe Engineering
|
|
54
|
+
|
|
55
|
+
Vibe coding gets things built fast. But the codebases it produces tend to rot in ways that are hard to see and harder to fix — not just the mechanical stuff like dead imports, but the structural kind. Abstractions that made sense at first stop making sense. Naming drifts. Error handling is done three different ways. The codebase works, but working in it gets worse over time.
|
|
56
|
+
|
|
57
|
+
LLMs are actually good at spotting this now, if you ask them the right questions. That's the core bet here — that an agent with the right framework can hold a codebase to a real standard, the kind that used to require a senior engineer paying close attention over months.
|
|
58
|
+
|
|
59
|
+
So we're trying to define what "good" looks like as a score that's actually worth optimizing. Not a lint score you game to 100 by suppressing warnings. Something where improving the number means the codebase genuinely got better. That's hard, and we're not done, but the anti-gaming stuff matters to us a lot — it's the difference between a useful signal and a vanity metric.
|
|
60
|
+
|
|
61
|
+
The hope is that anyone can use this to build something a seasoned engineer would look at and respect. That's the bar we're aiming for.
|
|
62
|
+
|
|
63
|
+
If you'd like to join a community of vibe engineers who want to build beautiful things, [come hang out](https://discord.gg/aZdzbZrHaY).
|
|
64
|
+
|
|
65
|
+
<img src="docs/engineering.png" width="100%">
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
<details>
|
|
70
|
+
<summary><strong>Stuff you probably won't need to know</strong></summary>
|
|
71
|
+
|
|
72
|
+
#### Commands
|
|
73
|
+
|
|
74
|
+
| Command | Description |
|
|
75
|
+
|---------|-------------|
|
|
76
|
+
| `scan [--reset-subjective]` | Run all detectors, update state (optional: reset subjective baseline to 0 first) |
|
|
77
|
+
| `status` | Score + per-tier progress |
|
|
78
|
+
| `show <pattern>` | Findings by file, directory, detector, or ID |
|
|
79
|
+
| `next [--tier N] [--explain]` | Highest-priority open finding (--explain: with score context) |
|
|
80
|
+
| `resolve <status> <patterns>` | Mark fixed / wontfix / false_positive / ignore |
|
|
81
|
+
| `fix <fixer> [--dry-run]` | Auto-fix mechanical issues |
|
|
82
|
+
| `review --prepare` | Generate subjective review packet (`query.json`) |
|
|
83
|
+
| `review --import <file>` | Import subjective review findings |
|
|
84
|
+
| `issues` | Review findings queue (list/show/update) |
|
|
85
|
+
| `zone` | Show/set/clear zone classifications |
|
|
86
|
+
| `config` | Show/set/unset project configuration |
|
|
87
|
+
| `move <src> <dst>` | Move file/directory, update all imports |
|
|
88
|
+
| `detect <name>` | Run a single detector raw |
|
|
89
|
+
| `plan` | Prioritized markdown plan |
|
|
90
|
+
| `tree` | Annotated codebase tree |
|
|
91
|
+
| `viz` | Interactive HTML treemap |
|
|
92
|
+
| `dev scaffold-lang` | Generate a standardized language plugin scaffold |
|
|
93
|
+
|
|
94
|
+
#### Detectors
|
|
95
|
+
|
|
96
|
+
**TypeScript/React**: logs, unused, exports, deprecated, large, complexity, gods, single_use, props, passthrough, concerns, deps, dupes, smells, coupling, patterns, naming, cycles, orphaned, react
|
|
97
|
+
|
|
98
|
+
**Python**: unused, large, complexity, gods, props, smells, dupes, deps, cycles, orphaned, single_use, naming
|
|
99
|
+
|
|
100
|
+
**C#/.NET**: deps, cycles, orphaned, dupes, large, complexity
|
|
101
|
+
|
|
102
|
+
#### Tiers & scoring
|
|
103
|
+
|
|
104
|
+
| Tier | Fix type | Examples |
|
|
105
|
+
|------|----------|----------|
|
|
106
|
+
| T1 | Auto-fixable | Unused imports, debug logs |
|
|
107
|
+
| T2 | Quick manual | Unused vars, dead exports |
|
|
108
|
+
| T3 | Needs judgment | Near-dupes, single_use abstractions |
|
|
109
|
+
| T4 | Major refactor | God components, mixed concerns |
|
|
110
|
+
|
|
111
|
+
Score is weighted (T4 = 4x T1). Strict score penalizes both open and wontfix.
|
|
112
|
+
|
|
113
|
+
#### Configuration
|
|
114
|
+
|
|
115
|
+
| Variable | Default | Description |
|
|
116
|
+
|----------|---------|-------------|
|
|
117
|
+
| `DESLOPPIFY_ROOT` | cwd | Project root |
|
|
118
|
+
| `DESLOPPIFY_SRC` | `src` | Source directory (TS alias resolution) |
|
|
119
|
+
| `--lang <name>` | auto-detected | Language selection (each has own state) |
|
|
120
|
+
| `--exclude <pattern>` | none | Path patterns to skip (repeatable: `--exclude migrations --exclude tests`) |
|
|
121
|
+
| `--no-badge` | false | Skip scorecard image generation |
|
|
122
|
+
| `--badge-path <path>` | `scorecard.png` | Output path for scorecard image |
|
|
123
|
+
| `DESLOPPIFY_NO_BADGE` | — | Set to `true` to disable badge via env |
|
|
124
|
+
| `DESLOPPIFY_BADGE_PATH` | `scorecard.png` | Badge output path via env |
|
|
125
|
+
|
|
126
|
+
Project config values (stored in `.desloppify/config.json`) are managed via:
|
|
127
|
+
- `desloppify config show`
|
|
128
|
+
- `desloppify config set target_strict_score 95` (default: `95`, valid range: `0-100`)
|
|
129
|
+
- `desloppify config set badge_path scorecard.png` (or nested path like `assets/health.png`)
|
|
130
|
+
|
|
131
|
+
#### Adding or augmenting a language
|
|
132
|
+
|
|
133
|
+
Use the scaffold workflow documented in `desloppify/languages/README.md`:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
desloppify dev scaffold-lang <name> --extension .ext --marker <root-marker>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Detect command keys are standardized to snake_case. CLI compatibility aliases
|
|
140
|
+
like `single-use` and legacy `passthrough` are still accepted.
|
|
141
|
+
Standard plugin shape: `__init__.py`, `commands.py`, `extractors.py`, `phases.py`,
|
|
142
|
+
`move.py`, `review.py`, `test_coverage.py`, plus `detectors/`, `fixers/`, and `tests/`.
|
|
143
|
+
Validated at registration. Zero shared code changes.
|
|
144
|
+
|
|
145
|
+
#### Architecture
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
engine/detectors/ ← Generic algorithms (zero language knowledge)
|
|
149
|
+
hook_registry.py ← Detector-safe access to optional language hooks
|
|
150
|
+
languages/_framework/runtime.py ← LangRun (per-run mutable scan state)
|
|
151
|
+
languages/_framework/base/ ← Shared framework contracts + phase helpers
|
|
152
|
+
languages/_framework/generic.py ← generic_lang() factory for tool-based plugins
|
|
153
|
+
languages/_framework/treesitter/ ← Tree-sitter integration (optional)
|
|
154
|
+
languages/<name>/ ← Language config + phases + extractors + detectors + fixers
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Import direction: `languages/` → `engine/detectors/`. Never the reverse.
|
|
158
|
+
`LangConfig` stays static; runtime state lives on `LangRun`.
|
|
159
|
+
|
|
160
|
+
#### Command-Layer Boundaries
|
|
161
|
+
|
|
162
|
+
Command entry modules are intentionally thin orchestrators:
|
|
163
|
+
|
|
164
|
+
- `desloppify/app/commands/review/cmd.py` delegates to
|
|
165
|
+
`desloppify/app/commands/review/prepare.py`, `desloppify/app/commands/review/batches.py`, `desloppify/app/commands/review/import_cmd.py`, and `desloppify/app/commands/review/runtime.py`
|
|
166
|
+
- `desloppify/app/commands/scan/scan_reporting_dimensions.py` delegates to
|
|
167
|
+
`desloppify/app/commands/scan/scan_reporting_presentation.py` and `desloppify/app/commands/scan/scan_reporting_subjective.py`
|
|
168
|
+
- `desloppify/app/cli_support/parser.py` delegates subcommand construction to `desloppify/app/cli_support/parser_groups.py`
|
|
169
|
+
|
|
170
|
+
Public CLI behavior should be preserved when refactoring these orchestrators.
|
|
171
|
+
|
|
172
|
+
#### Allowed Dynamic Import Zones
|
|
173
|
+
|
|
174
|
+
Dynamic/optional loading is allowed only in explicit extension points:
|
|
175
|
+
|
|
176
|
+
- `desloppify/languages/__init__.py` for plugin discovery and registration
|
|
177
|
+
- `desloppify/hook_registry.py` for detector-safe optional hooks
|
|
178
|
+
|
|
179
|
+
Outside these zones, use static imports.
|
|
180
|
+
|
|
181
|
+
#### State Ownership
|
|
182
|
+
|
|
183
|
+
- `desloppify/state.py` and `desloppify/engine/_state/` own persisted schema and merge rules
|
|
184
|
+
- `desloppify/languages/_framework/runtime.py` (`LangRun`) owns per-run mutable execution state
|
|
185
|
+
- command modules may read/write state through state APIs, but should not define ad-hoc persisted fields
|
|
186
|
+
|
|
187
|
+
</details>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Application-layer packages: CLI, commands, and output surfaces."""
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""CLI parser construction helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
from desloppify.app.cli_support.parser_groups import (
|
|
8
|
+
_add_config_parser,
|
|
9
|
+
_add_detect_parser,
|
|
10
|
+
_add_dev_parser,
|
|
11
|
+
_add_fix_parser,
|
|
12
|
+
_add_ignore_parser,
|
|
13
|
+
_add_issues_parser,
|
|
14
|
+
_add_langs_parser,
|
|
15
|
+
_add_move_parser,
|
|
16
|
+
_add_next_parser,
|
|
17
|
+
_add_plan_parser,
|
|
18
|
+
_add_resolve_parser,
|
|
19
|
+
_add_review_parser,
|
|
20
|
+
_add_scan_parser,
|
|
21
|
+
_add_show_parser,
|
|
22
|
+
_add_status_parser,
|
|
23
|
+
_add_tree_parser,
|
|
24
|
+
_add_update_skill_parser,
|
|
25
|
+
_add_viz_parser,
|
|
26
|
+
_add_zone_parser,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
USAGE_EXAMPLES = """
|
|
30
|
+
workflow:
|
|
31
|
+
scan Run all detectors, update state, show diff
|
|
32
|
+
status Score dashboard with per-tier progress
|
|
33
|
+
tree Annotated codebase tree (zoom with --focus)
|
|
34
|
+
show <pattern> Dig into findings by file/dir/detector/ID
|
|
35
|
+
resolve <pattern> <status> Mark findings as fixed/wontfix/false_positive
|
|
36
|
+
ignore <pattern> Suppress findings matching a pattern
|
|
37
|
+
zone show Show zone classifications for all files
|
|
38
|
+
zone set <file> <zone> Override zone for a file
|
|
39
|
+
review --prepare Prepare holistic codebase review data
|
|
40
|
+
review --import FILE Import review findings from JSON
|
|
41
|
+
issues Review findings work queue
|
|
42
|
+
plan Generate prioritized markdown plan
|
|
43
|
+
|
|
44
|
+
examples:
|
|
45
|
+
desloppify scan --skip-slow
|
|
46
|
+
desloppify --lang python scan --path scripts/desloppify
|
|
47
|
+
desloppify tree --focus shared/components --sort findings --depth 3
|
|
48
|
+
desloppify tree --detail --focus shared/components/MediaLightbox --min-loc 300
|
|
49
|
+
desloppify show src/shared/components/PromptEditorModal.tsx
|
|
50
|
+
desloppify show gods
|
|
51
|
+
desloppify show "src/shared/components/MediaLightbox"
|
|
52
|
+
desloppify resolve fixed "unused::src/foo.tsx::React" --note "removed unused React import" --attest "I have actually removed the unused React import from foo.tsx and I am not gaming the score by resolving without fixing."
|
|
53
|
+
desloppify resolve fixed "logs::src/foo.tsx::*" --note "removed debug logs" --attest "I have actually removed all console.log calls from foo.tsx and I am not gaming the score by resolving without fixing."
|
|
54
|
+
desloppify resolve wontfix deprecated --note "migration in progress" --attest "I have actually verified these are tracked in the migration plan and I am not gaming the score by resolving without fixing."
|
|
55
|
+
desloppify ignore "smells::*::async_no_await" --attest "I have actually verified these are intentional fire-and-forget patterns and I am not gaming the score by resolving without fixing."
|
|
56
|
+
desloppify detect logs --top 10
|
|
57
|
+
desloppify detect dupes --threshold 0.9
|
|
58
|
+
desloppify dev scaffold-lang go --extension .go --marker go.mod --default-src .
|
|
59
|
+
desloppify move src/shared/hooks/useFoo.ts src/shared/hooks/video/useFoo.ts --dry-run
|
|
60
|
+
desloppify move scripts/foo/bar.py scripts/foo/baz/bar.py
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class _NoAbbrevArgumentParser(argparse.ArgumentParser):
|
|
65
|
+
"""Argparse parser variant that disables long-option abbreviation."""
|
|
66
|
+
|
|
67
|
+
def __init__(self, *args, **kwargs):
|
|
68
|
+
kwargs.setdefault("allow_abbrev", False)
|
|
69
|
+
super().__init__(*args, **kwargs)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def create_parser(*, langs: list[str], detector_names: list[str]) -> argparse.ArgumentParser:
|
|
73
|
+
"""Build top-level CLI parser with all subcommands."""
|
|
74
|
+
lang_help = ", ".join(langs) if langs else "registered languages"
|
|
75
|
+
|
|
76
|
+
parser = _NoAbbrevArgumentParser(
|
|
77
|
+
prog="desloppify",
|
|
78
|
+
description="Desloppify — codebase health tracker",
|
|
79
|
+
epilog=USAGE_EXAMPLES,
|
|
80
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
81
|
+
)
|
|
82
|
+
parser.add_argument(
|
|
83
|
+
"--lang",
|
|
84
|
+
type=str,
|
|
85
|
+
default=None,
|
|
86
|
+
help=f"Language to scan ({lang_help}). Auto-detected if omitted.",
|
|
87
|
+
)
|
|
88
|
+
parser.add_argument(
|
|
89
|
+
"--exclude",
|
|
90
|
+
action="append",
|
|
91
|
+
default=None,
|
|
92
|
+
metavar="PATTERN",
|
|
93
|
+
help="Path pattern to exclude (component/prefix match; repeatable)",
|
|
94
|
+
)
|
|
95
|
+
sub = parser.add_subparsers(
|
|
96
|
+
dest="command",
|
|
97
|
+
required=True,
|
|
98
|
+
parser_class=_NoAbbrevArgumentParser,
|
|
99
|
+
)
|
|
100
|
+
_add_scan_parser(sub)
|
|
101
|
+
_add_status_parser(sub)
|
|
102
|
+
_add_tree_parser(sub)
|
|
103
|
+
_add_show_parser(sub)
|
|
104
|
+
_add_next_parser(sub)
|
|
105
|
+
_add_resolve_parser(sub)
|
|
106
|
+
_add_ignore_parser(sub)
|
|
107
|
+
_add_fix_parser(sub, langs)
|
|
108
|
+
_add_plan_parser(sub)
|
|
109
|
+
_add_viz_parser(sub)
|
|
110
|
+
_add_detect_parser(sub, detector_names)
|
|
111
|
+
_add_move_parser(sub)
|
|
112
|
+
_add_review_parser(sub)
|
|
113
|
+
_add_issues_parser(sub)
|
|
114
|
+
_add_zone_parser(sub)
|
|
115
|
+
_add_config_parser(sub)
|
|
116
|
+
_add_dev_parser(sub)
|
|
117
|
+
_add_langs_parser(sub)
|
|
118
|
+
_add_update_skill_parser(sub)
|
|
119
|
+
return parser
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
__all__ = ["USAGE_EXAMPLES", "create_parser"]
|