codeboarding 0.13.0__tar.gz → 0.13.2__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.
- {codeboarding-0.13.0/codeboarding.egg-info → codeboarding-0.13.2}/PKG-INFO +10 -10
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/incremental_agent.py +3 -1
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/incremental_planning_agent.py +12 -2
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/repair.py +72 -2
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/validation.py +28 -6
- {codeboarding-0.13.0 → codeboarding-0.13.2/codeboarding.egg-info}/PKG-INFO +10 -10
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding.egg-info/SOURCES.txt +0 -1
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding.egg-info/requires.txt +9 -9
- {codeboarding-0.13.0 → codeboarding-0.13.2}/pyproject.toml +10 -10
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/graph.py +1 -2
- codeboarding-0.13.0/health_main.py +0 -152
- {codeboarding-0.13.0 → codeboarding-0.13.2}/LICENSE +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/PYPI.md +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/README.md +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/abstraction_agent.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/agent.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/agent_responses.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/change_status.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/cluster_budget.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/cluster_ids.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/cluster_methods_mixin.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/constants.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/content_hash.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/dependency_discovery.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/details_agent.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/file_index_models.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/incremental_results.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/llm_config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/llm_errors.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/meta_agent.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/model_capabilities.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/planner_agent.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/abstract_prompt_factory.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/claude_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/deepseek_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/gemini_flash_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/glm_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/gpt_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/kimi_prompts.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/prompts/prompt_factory.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/relation_edges.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/retry.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/scope_ids.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/scope_operations.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/base.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/component_bridge_edges.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/get_external_deps.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/get_method_invocations.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/list_git_changes.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_cfg.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_docs.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_file.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_file_structure.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_packages.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_source.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/read_structure.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/agents/tools/toolkit.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/caching/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/caching/cache.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/caching/details_cache.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/caching/meta_cache.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding.egg-info/dependency_links.txt +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding.egg-info/entry_points.txt +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding.egg-info/top_level.txt +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/bootstrap.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/commands/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/commands/full_analysis.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/commands/incremental_analysis.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/commands/partial_analysis.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_cli/view_instructions.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/analysis.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/orchestration.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/rendering.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/sources/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/sources/local.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/codeboarding_workflows/sources/remote.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/constants.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/core/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/core/plugin_loader.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/core/protocols.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/core/registry.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/analysis_json.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/cluster_delta.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/cluster_snapshot.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/diagram_generator.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/exceptions.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/file_coverage.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/file_index.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/io_utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/run_context.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/diagram_analysis/run_mode.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/github_action.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/circular_deps.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/cohesion.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/coupling.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/function_size.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/god_class.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/inheritance.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/instability.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/checks/unused_code_diagnostics.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/models.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/health/runner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/install.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/logging_config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/main.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/callbacks.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/context.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/mixin.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/paths.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/stats.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/monitoring/writers.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/html.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/html_template.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/markdown.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/mdx.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/output_generators/sphinx.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/change_detector.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/errors.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/fingerprint_diff.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/git_ops.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/ignore.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/repo_utils/path_utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/setup.cfg +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/analysis_cache.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/analysis_result.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/cfg_skip_planner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/cluster_helpers.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/cluster_relations.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/constants.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/csharp_config_scanner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/dotnet_sdk.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/csharp_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/go_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/java_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/php_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/python_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/rust_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/adapters/typescript_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/call_graph_builder.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/edge_build_context.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/edge_builder.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/hierarchy_builder.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/language_adapter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/lsp_client.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/lsp_constants.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/models.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/progress.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/protocols.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/result_converter.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/source_inspector.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/symbol_table.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/engine/utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/incremental_orchestrator.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/internal_references.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/java_config_scanner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/java_utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/language_results.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/leiden_utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/lsp_client/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/lsp_client/diagnostics.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/method_cluster_paths.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/node.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/programming_language.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/reference_resolver.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/scanner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/static_analyzer/typescript_config_scanner.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/telemetry/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/telemetry/device_id.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/telemetry/events.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/telemetry/schemas.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/telemetry/service.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_cli_parser.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_github_action.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_install.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_logging_config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_main.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_pyproject_packages.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_registry_coverage.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_telemetry_events.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_tool_registry.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_user_config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_view_instructions.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_vscode_constants.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_windows_compatibility.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tests/test_windows_encoding.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tool_registry/__init__.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tool_registry/installers.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tool_registry/manifest.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tool_registry/paths.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/tool_registry/registry.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/user_config.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/utils.py +0 -0
- {codeboarding-0.13.0 → codeboarding-0.13.2}/vscode_constants.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -45,15 +45,15 @@ Requires-Dist: pydantic>=2.0
|
|
|
45
45
|
Requires-Dist: pyyaml>=6.0
|
|
46
46
|
Requires-Dist: regex>=2024.11
|
|
47
47
|
Requires-Dist: rich>=12.6
|
|
48
|
-
Requires-Dist: tree-sitter
|
|
49
|
-
Requires-Dist: tree-sitter-c-sharp
|
|
50
|
-
Requires-Dist: tree-sitter-go
|
|
51
|
-
Requires-Dist: tree-sitter-java
|
|
52
|
-
Requires-Dist: tree-sitter-javascript
|
|
53
|
-
Requires-Dist: tree-sitter-php
|
|
54
|
-
Requires-Dist: tree-sitter-python
|
|
55
|
-
Requires-Dist: tree-sitter-rust
|
|
56
|
-
Requires-Dist: tree-sitter-typescript
|
|
48
|
+
Requires-Dist: tree-sitter==0.25.2
|
|
49
|
+
Requires-Dist: tree-sitter-c-sharp==0.23.5
|
|
50
|
+
Requires-Dist: tree-sitter-go==0.25.0
|
|
51
|
+
Requires-Dist: tree-sitter-java==0.23.5
|
|
52
|
+
Requires-Dist: tree-sitter-javascript==0.25.0
|
|
53
|
+
Requires-Dist: tree-sitter-php==0.24.1
|
|
54
|
+
Requires-Dist: tree-sitter-python==0.25.0
|
|
55
|
+
Requires-Dist: tree-sitter-rust==0.24.2
|
|
56
|
+
Requires-Dist: tree-sitter-typescript==0.23.2
|
|
57
57
|
Requires-Dist: trustcall>=0.0.39
|
|
58
58
|
Requires-Dist: uvicorn>=0.23
|
|
59
59
|
Provides-Extra: dev
|
|
@@ -404,7 +404,9 @@ def _log_scope_relations_summary(all_rels: list[tuple[str, list[Relation]]]) ->
|
|
|
404
404
|
|
|
405
405
|
|
|
406
406
|
def _operation_source_cluster_ids(scope_id: str, operation: ScopeOperation) -> list[str]:
|
|
407
|
-
|
|
407
|
+
# Match how the validator reads refs (cluster_ref_from_scoped_ref treats a blank scope as root),
|
|
408
|
+
# so a ref the validator counted is not silently dropped here and orphaned.
|
|
409
|
+
local_ids = {ref.cluster_id for ref in operation.cluster_refs if (ref.scope_id or ROOT_SCOPE_ID) == scope_id}
|
|
408
410
|
return CodeBoardingClusterIds.qualify_local_ids(
|
|
409
411
|
CodeBoardingClusterIds.from_graph_ids(local_ids),
|
|
410
412
|
CodeBoardingClusterIds.prefix_for_scope(scope_id),
|
|
@@ -87,15 +87,25 @@ class IncrementalPlanningAgent(CodeBoardingAgent):
|
|
|
87
87
|
changed_files=_format_changed_files(self.toolkit.context.changes),
|
|
88
88
|
structural_diff=format_structural_diff(structural_diff),
|
|
89
89
|
)
|
|
90
|
+
actionable_cluster_refs = _actionable_new_cluster_refs(structural_diff)
|
|
91
|
+
component_ids_by_cluster_ref = _component_ids_by_cluster_ref(scope_id, scope.components, structural_diff)
|
|
90
92
|
repair_context = ScopeOperationRepairContext(
|
|
91
93
|
reference_resolver=self.reference_resolver,
|
|
92
94
|
allowed_key_entity_qnames=cluster_member_qnames(cluster_results),
|
|
93
|
-
component_ids_by_cluster_ref=
|
|
95
|
+
component_ids_by_cluster_ref=component_ids_by_cluster_ref,
|
|
94
96
|
component_ids_by_name=_component_ids_by_name(scope.components),
|
|
97
|
+
scope_id=scope_id,
|
|
98
|
+
actionable_cluster_refs=actionable_cluster_refs,
|
|
99
|
+
owned_cluster_ids_by_component_id={
|
|
100
|
+
component.component_id: set(component.source_cluster_ids)
|
|
101
|
+
for component in scope.components
|
|
102
|
+
if component.component_id
|
|
103
|
+
},
|
|
95
104
|
)
|
|
96
105
|
validation_context = ScopeOperationValidationContext(
|
|
97
|
-
expected_cluster_refs=
|
|
106
|
+
expected_cluster_refs=actionable_cluster_refs,
|
|
98
107
|
existing_component_ids={component.component_id for component in scope.components if component.component_id},
|
|
108
|
+
component_ids_by_cluster_ref=component_ids_by_cluster_ref,
|
|
99
109
|
)
|
|
100
110
|
decision = self._invoke_repair_validate(
|
|
101
111
|
prompt,
|
|
@@ -11,8 +11,11 @@ from agents.agent_responses import (
|
|
|
11
11
|
Component,
|
|
12
12
|
ScopeOperation,
|
|
13
13
|
ScopeOperationAction,
|
|
14
|
+
ScopedClusterRef,
|
|
14
15
|
ScopeUpdateDecision,
|
|
15
16
|
)
|
|
17
|
+
from agents.cluster_ids import CodeBoardingClusterIds
|
|
18
|
+
from agents.scope_ids import ROOT_SCOPE_ID
|
|
16
19
|
from agents.scope_operations import (
|
|
17
20
|
EXISTING_COMPONENT_ACTIONS,
|
|
18
21
|
cluster_member_qnames,
|
|
@@ -50,6 +53,9 @@ class ScopeOperationRepairContext:
|
|
|
50
53
|
allowed_key_entity_qnames: set[str]
|
|
51
54
|
component_ids_by_cluster_ref: dict[ClusterRef, str] = field(default_factory=dict)
|
|
52
55
|
component_ids_by_name: dict[str, str] = field(default_factory=dict)
|
|
56
|
+
scope_id: str = ROOT_SCOPE_ID
|
|
57
|
+
actionable_cluster_refs: set[ClusterRef] = field(default_factory=set)
|
|
58
|
+
owned_cluster_ids_by_component_id: dict[str, set[str]] = field(default_factory=dict)
|
|
53
59
|
|
|
54
60
|
|
|
55
61
|
def repair_unambiguous_routing_and_optional_key_entity_metadata(
|
|
@@ -58,21 +64,85 @@ def repair_unambiguous_routing_and_optional_key_entity_metadata(
|
|
|
58
64
|
) -> None:
|
|
59
65
|
"""Repair deterministic routing and optional key-entity metadata defects."""
|
|
60
66
|
routed_operations = _repair_unambiguous_operation_routing(decision, context)
|
|
67
|
+
trimmed_refs = _drop_redundant_owned_cluster_refs(decision, context)
|
|
61
68
|
canonicalized_qnames, dropped_qnames = _repair_optional_key_entity_metadata(
|
|
62
69
|
decision,
|
|
63
70
|
context,
|
|
64
71
|
)
|
|
65
72
|
|
|
66
|
-
if routed_operations or canonicalized_qnames:
|
|
73
|
+
if routed_operations or trimmed_refs or canonicalized_qnames:
|
|
67
74
|
logger.info(
|
|
68
|
-
"Repaired incremental plan: routed %d operation(s),
|
|
75
|
+
"Repaired incremental plan: routed %d operation(s), trimmed %d redundant owned cluster ref(s), "
|
|
76
|
+
"canonicalized %d key-entity qname(s)",
|
|
69
77
|
routed_operations,
|
|
78
|
+
trimmed_refs,
|
|
70
79
|
canonicalized_qnames,
|
|
71
80
|
)
|
|
72
81
|
if dropped_qnames:
|
|
73
82
|
logger.warning("Dropped unresolved optional key entities: %s", sorted(dropped_qnames))
|
|
74
83
|
|
|
75
84
|
|
|
85
|
+
def _drop_redundant_owned_cluster_refs(
|
|
86
|
+
decision: ScopeUpdateDecision,
|
|
87
|
+
context: ScopeOperationRepairContext,
|
|
88
|
+
) -> int:
|
|
89
|
+
"""Drop cluster_refs an operation lists that its own component already owns and that did not change.
|
|
90
|
+
|
|
91
|
+
Why: the planner copies a component's whole ``clusters=[...]`` list, but only the changed
|
|
92
|
+
(actionable) clusters need to be there. A component re-listing its own unchanged clusters changes
|
|
93
|
+
nothing, so drop those to match what the validator expects. Clusters owned by another component
|
|
94
|
+
are always kept so the validator still catches them. Only some operations are safe to trim here
|
|
95
|
+
(see ``_may_trim_owned_refs``).
|
|
96
|
+
"""
|
|
97
|
+
prefix = CodeBoardingClusterIds.prefix_for_scope(context.scope_id)
|
|
98
|
+
trimmed = 0
|
|
99
|
+
for operation in decision.operations:
|
|
100
|
+
if operation.component_id is None or not _may_trim_owned_refs(operation, context):
|
|
101
|
+
continue
|
|
102
|
+
owned = context.owned_cluster_ids_by_component_id.get(operation.component_id, set())
|
|
103
|
+
kept: list[ScopedClusterRef] = []
|
|
104
|
+
for ref in operation.cluster_refs:
|
|
105
|
+
source_cluster_id = CodeBoardingClusterIds.qualify_local_id(
|
|
106
|
+
CodeBoardingClusterIds.from_graph_id(ref.cluster_id), prefix
|
|
107
|
+
)
|
|
108
|
+
redundant = source_cluster_id in owned and cluster_ref_from_scoped_ref(ref) not in (
|
|
109
|
+
context.actionable_cluster_refs
|
|
110
|
+
)
|
|
111
|
+
if redundant:
|
|
112
|
+
trimmed += 1
|
|
113
|
+
continue
|
|
114
|
+
kept.append(ref)
|
|
115
|
+
operation.cluster_refs = kept
|
|
116
|
+
return trimmed
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _may_trim_owned_refs(operation: ScopeOperation, context: ScopeOperationRepairContext) -> bool:
|
|
120
|
+
"""Whether an operation's already-owned, unchanged cluster_refs are safe to drop.
|
|
121
|
+
|
|
122
|
+
- noop: always. It only preserves a component; the validator separately rejects a noop that
|
|
123
|
+
claims a cluster owned by another component.
|
|
124
|
+
- update_component: only a genuine self-update - it must list at least one changed (actionable)
|
|
125
|
+
cluster, and no changed ref it lists may belong to another component. Otherwise keep the refs
|
|
126
|
+
so an empty or cross-component update is rejected instead of silently applied.
|
|
127
|
+
- delete_component / create_component: never - keep the refs so a delete of a component that
|
|
128
|
+
still owns clusters is rejected.
|
|
129
|
+
"""
|
|
130
|
+
if operation.action == ScopeOperationAction.NOOP:
|
|
131
|
+
return True
|
|
132
|
+
if operation.action != ScopeOperationAction.UPDATE_COMPONENT:
|
|
133
|
+
return False
|
|
134
|
+
lists_own_change = False
|
|
135
|
+
for ref in operation.cluster_refs:
|
|
136
|
+
cluster_ref = cluster_ref_from_scoped_ref(ref)
|
|
137
|
+
if cluster_ref not in context.actionable_cluster_refs:
|
|
138
|
+
continue
|
|
139
|
+
proven_owner = context.component_ids_by_cluster_ref.get(cluster_ref)
|
|
140
|
+
if proven_owner is not None and proven_owner != operation.component_id:
|
|
141
|
+
return False
|
|
142
|
+
lists_own_change = True
|
|
143
|
+
return lists_own_change
|
|
144
|
+
|
|
145
|
+
|
|
76
146
|
def _repair_unambiguous_operation_routing(
|
|
77
147
|
decision: ScopeUpdateDecision,
|
|
78
148
|
context: ScopeOperationRepairContext,
|
|
@@ -64,6 +64,7 @@ class ValidationContext:
|
|
|
64
64
|
class ScopeOperationValidationContext:
|
|
65
65
|
expected_cluster_refs: set[ClusterRef] = field(default_factory=set)
|
|
66
66
|
existing_component_ids: set[str] = field(default_factory=set)
|
|
67
|
+
component_ids_by_cluster_ref: dict[ClusterRef, str] = field(default_factory=dict)
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
@dataclass
|
|
@@ -88,10 +89,26 @@ def validate_scope_update_decision(
|
|
|
88
89
|
context: ScopeOperationValidationContext,
|
|
89
90
|
) -> ValidationResult:
|
|
90
91
|
errors: list[str] = []
|
|
91
|
-
|
|
92
|
+
claimed_refs: list[ClusterRef] = [] # every op's refs, for the over-claim (extra) and duplicate checks
|
|
93
|
+
covered_refs: list[ClusterRef] = [] # non-delete refs only; a delete discards its clusters, so it cannot cover them
|
|
92
94
|
for operation in decision.operations:
|
|
93
95
|
refs = [cluster_ref_from_scoped_ref(ref) for ref in operation.cluster_refs]
|
|
94
|
-
|
|
96
|
+
claimed_refs.extend(refs)
|
|
97
|
+
if operation.action != ScopeOperationAction.DELETE_COMPONENT:
|
|
98
|
+
covered_refs.extend(refs)
|
|
99
|
+
if operation.action == ScopeOperationAction.NOOP:
|
|
100
|
+
# A noop unions its refs into its component without removing them from the real owner,
|
|
101
|
+
# so any changed cluster it claims from another component becomes duplicate-owned.
|
|
102
|
+
foreign = {
|
|
103
|
+
ref
|
|
104
|
+
for ref in refs
|
|
105
|
+
if context.component_ids_by_cluster_ref.get(ref) not in (None, operation.component_id)
|
|
106
|
+
}
|
|
107
|
+
if foreign:
|
|
108
|
+
errors.append(
|
|
109
|
+
f"noop for component_id={operation.component_id!r} claims clusters owned by another "
|
|
110
|
+
f"component: {_format_cluster_ref_list(foreign)}. A noop must only preserve its own clusters."
|
|
111
|
+
)
|
|
95
112
|
if operation.action in EXISTING_COMPONENT_ACTIONS:
|
|
96
113
|
if operation.component_id not in context.existing_component_ids:
|
|
97
114
|
errors.append(
|
|
@@ -111,10 +128,15 @@ def validate_scope_update_decision(
|
|
|
111
128
|
if duplicate_qnames:
|
|
112
129
|
errors.append(f"Operation {operation.action} repeats key entities: {sorted(duplicate_qnames)}.")
|
|
113
130
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
claimed_set: set[ClusterRef] = set()
|
|
132
|
+
duplicates: set[ClusterRef] = set()
|
|
133
|
+
for ref in claimed_refs:
|
|
134
|
+
if ref in claimed_set:
|
|
135
|
+
duplicates.add(ref)
|
|
136
|
+
else:
|
|
137
|
+
claimed_set.add(ref)
|
|
138
|
+
missing = context.expected_cluster_refs - set(covered_refs)
|
|
139
|
+
extra = claimed_set - context.expected_cluster_refs
|
|
118
140
|
if missing:
|
|
119
141
|
errors.append(f"Missing cluster_refs: {_format_cluster_ref_list(missing)}")
|
|
120
142
|
if extra:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeboarding
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: Interactive Diagrams for Code
|
|
5
5
|
Author: CodeBoarding Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -45,15 +45,15 @@ Requires-Dist: pydantic>=2.0
|
|
|
45
45
|
Requires-Dist: pyyaml>=6.0
|
|
46
46
|
Requires-Dist: regex>=2024.11
|
|
47
47
|
Requires-Dist: rich>=12.6
|
|
48
|
-
Requires-Dist: tree-sitter
|
|
49
|
-
Requires-Dist: tree-sitter-c-sharp
|
|
50
|
-
Requires-Dist: tree-sitter-go
|
|
51
|
-
Requires-Dist: tree-sitter-java
|
|
52
|
-
Requires-Dist: tree-sitter-javascript
|
|
53
|
-
Requires-Dist: tree-sitter-php
|
|
54
|
-
Requires-Dist: tree-sitter-python
|
|
55
|
-
Requires-Dist: tree-sitter-rust
|
|
56
|
-
Requires-Dist: tree-sitter-typescript
|
|
48
|
+
Requires-Dist: tree-sitter==0.25.2
|
|
49
|
+
Requires-Dist: tree-sitter-c-sharp==0.23.5
|
|
50
|
+
Requires-Dist: tree-sitter-go==0.25.0
|
|
51
|
+
Requires-Dist: tree-sitter-java==0.23.5
|
|
52
|
+
Requires-Dist: tree-sitter-javascript==0.25.0
|
|
53
|
+
Requires-Dist: tree-sitter-php==0.24.1
|
|
54
|
+
Requires-Dist: tree-sitter-python==0.25.0
|
|
55
|
+
Requires-Dist: tree-sitter-rust==0.24.2
|
|
56
|
+
Requires-Dist: tree-sitter-typescript==0.23.2
|
|
57
57
|
Requires-Dist: trustcall>=0.0.39
|
|
58
58
|
Requires-Dist: uvicorn>=0.23
|
|
59
59
|
Provides-Extra: dev
|
|
@@ -27,15 +27,15 @@ pydantic>=2.0
|
|
|
27
27
|
pyyaml>=6.0
|
|
28
28
|
regex>=2024.11
|
|
29
29
|
rich>=12.6
|
|
30
|
-
tree-sitter
|
|
31
|
-
tree-sitter-c-sharp
|
|
32
|
-
tree-sitter-go
|
|
33
|
-
tree-sitter-java
|
|
34
|
-
tree-sitter-javascript
|
|
35
|
-
tree-sitter-php
|
|
36
|
-
tree-sitter-python
|
|
37
|
-
tree-sitter-rust
|
|
38
|
-
tree-sitter-typescript
|
|
30
|
+
tree-sitter==0.25.2
|
|
31
|
+
tree-sitter-c-sharp==0.23.5
|
|
32
|
+
tree-sitter-go==0.25.0
|
|
33
|
+
tree-sitter-java==0.23.5
|
|
34
|
+
tree-sitter-javascript==0.25.0
|
|
35
|
+
tree-sitter-php==0.24.1
|
|
36
|
+
tree-sitter-python==0.25.0
|
|
37
|
+
tree-sitter-rust==0.24.2
|
|
38
|
+
tree-sitter-typescript==0.23.2
|
|
39
39
|
trustcall>=0.0.39
|
|
40
40
|
uvicorn>=0.23
|
|
41
41
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codeboarding"
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.2"
|
|
8
8
|
description = "Interactive Diagrams for Code"
|
|
9
9
|
readme = "PYPI.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -51,15 +51,15 @@ dependencies = [
|
|
|
51
51
|
"pyyaml>=6.0",
|
|
52
52
|
"regex>=2024.11",
|
|
53
53
|
"rich>=12.6",
|
|
54
|
-
"tree-sitter
|
|
55
|
-
"tree-sitter-c-sharp
|
|
56
|
-
"tree-sitter-go
|
|
57
|
-
"tree-sitter-java
|
|
58
|
-
"tree-sitter-javascript
|
|
59
|
-
"tree-sitter-php
|
|
60
|
-
"tree-sitter-python
|
|
61
|
-
"tree-sitter-rust
|
|
62
|
-
"tree-sitter-typescript
|
|
54
|
+
"tree-sitter==0.25.2",
|
|
55
|
+
"tree-sitter-c-sharp==0.23.5",
|
|
56
|
+
"tree-sitter-go==0.25.0",
|
|
57
|
+
"tree-sitter-java==0.23.5",
|
|
58
|
+
"tree-sitter-javascript==0.25.0",
|
|
59
|
+
"tree-sitter-php==0.24.1",
|
|
60
|
+
"tree-sitter-python==0.25.0",
|
|
61
|
+
"tree-sitter-rust==0.24.2",
|
|
62
|
+
"tree-sitter-typescript==0.23.2",
|
|
63
63
|
"trustcall>=0.0.39",
|
|
64
64
|
"uvicorn>=0.23",
|
|
65
65
|
]
|
|
@@ -8,7 +8,6 @@ import networkx as nx
|
|
|
8
8
|
import networkx.algorithms.community as nx_comm
|
|
9
9
|
|
|
10
10
|
from static_analyzer.constants import (
|
|
11
|
-
ENTITY_LABELS,
|
|
12
11
|
GRAPH_NODE_TYPES,
|
|
13
12
|
ClusteringConfig,
|
|
14
13
|
NodeType,
|
|
@@ -695,7 +694,7 @@ class CallGraph:
|
|
|
695
694
|
node_type = node_data.get("type")
|
|
696
695
|
files_in_cluster.add(file_path)
|
|
697
696
|
|
|
698
|
-
type_label =
|
|
697
|
+
type_label = node_type.label() if isinstance(node_type, NodeType) else "Function"
|
|
699
698
|
parts = node_name.split(".")
|
|
700
699
|
|
|
701
700
|
if node_type == NodeType.CLASS:
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"""Standalone entry point for running health checks on a repository.
|
|
2
|
-
|
|
3
|
-
Runs static analysis and health checks only — no LLM agents or diagram generation.
|
|
4
|
-
Useful for testing health checks in isolation and for CI/CD health gates.
|
|
5
|
-
|
|
6
|
-
Usage:
|
|
7
|
-
# Local repository (output written to <repo>/.codeboarding/health/)
|
|
8
|
-
python health_main.py --local /path/to/repo
|
|
9
|
-
|
|
10
|
-
# Remote repository (cloned to cwd/repos/, output to cwd/<repo_name>/.codeboarding/health/)
|
|
11
|
-
python health_main.py https://github.com/user/repo
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
import argparse
|
|
15
|
-
import logging
|
|
16
|
-
from pathlib import Path
|
|
17
|
-
|
|
18
|
-
from health.runner import run_health_checks
|
|
19
|
-
from health.config import initialize_health_dir, load_health_config
|
|
20
|
-
from logging_config import setup_logging
|
|
21
|
-
from repo_utils import clone_repository, get_repo_name
|
|
22
|
-
from static_analyzer import get_static_analysis
|
|
23
|
-
from utils import CODEBOARDING_DIR_NAME, get_artifact_dir
|
|
24
|
-
from vscode_constants import update_config
|
|
25
|
-
|
|
26
|
-
logger = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def run_health_check_local(
|
|
30
|
-
repo_path: Path,
|
|
31
|
-
project_name: str | None = None,
|
|
32
|
-
) -> None:
|
|
33
|
-
"""Run health checks on a local repository.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
repo_path: Path to a local repository
|
|
37
|
-
project_name: Optional project name (default: repo directory name)
|
|
38
|
-
"""
|
|
39
|
-
resolved_repo_path = repo_path.resolve()
|
|
40
|
-
if not resolved_repo_path.is_dir():
|
|
41
|
-
raise ValueError(f"Repository path does not exist: {resolved_repo_path}")
|
|
42
|
-
|
|
43
|
-
resolved_project_name = project_name or resolved_repo_path.name
|
|
44
|
-
output_dir = resolved_repo_path / CODEBOARDING_DIR_NAME
|
|
45
|
-
|
|
46
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
47
|
-
setup_logging(log_dir=output_dir)
|
|
48
|
-
|
|
49
|
-
_run_health_checks(resolved_repo_path, resolved_project_name, output_dir)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def run_health_check_remote(
|
|
53
|
-
repo_url: str,
|
|
54
|
-
project_name: str | None = None,
|
|
55
|
-
) -> None:
|
|
56
|
-
"""Run health checks on a remote repository.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
repo_url: URL of a remote Git repository
|
|
60
|
-
project_name: Optional project name (default: extracted from URL)
|
|
61
|
-
"""
|
|
62
|
-
repo_root = Path("repos")
|
|
63
|
-
repo_name = clone_repository(repo_url, repo_root)
|
|
64
|
-
resolved_repo_path = repo_root / repo_name
|
|
65
|
-
resolved_project_name = project_name or get_repo_name(repo_url)
|
|
66
|
-
output_dir = Path.cwd() / repo_name / CODEBOARDING_DIR_NAME
|
|
67
|
-
|
|
68
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
69
|
-
setup_logging(log_dir=output_dir)
|
|
70
|
-
|
|
71
|
-
_run_health_checks(resolved_repo_path, resolved_project_name, output_dir)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def _run_health_checks(repo_path: Path, project_name: str, output_dir: Path) -> None:
|
|
75
|
-
"""Core health check logic shared by local and remote paths."""
|
|
76
|
-
logger.info(f"Running health checks on '{project_name}' at {repo_path}")
|
|
77
|
-
|
|
78
|
-
static_analysis = get_static_analysis(repo_path, cache_dir=get_artifact_dir(repo_path))
|
|
79
|
-
|
|
80
|
-
# Load health check configuration and initialize health config dir
|
|
81
|
-
health_config_dir = output_dir / "health"
|
|
82
|
-
initialize_health_dir(health_config_dir)
|
|
83
|
-
health_config = load_health_config(health_config_dir)
|
|
84
|
-
|
|
85
|
-
report = run_health_checks(static_analysis, project_name, config=health_config, repo_path=repo_path)
|
|
86
|
-
|
|
87
|
-
if report is None:
|
|
88
|
-
logger.warning("Health checks skipped: no languages found in static analysis results")
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
report_path = health_config_dir / "health_report.json"
|
|
92
|
-
report_path.write_text(report.model_dump_json(indent=2, exclude_none=True))
|
|
93
|
-
|
|
94
|
-
logger.info(f"Health report written to {report_path} (overall score: {report.overall_score:.3f})")
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def main():
|
|
98
|
-
"""Main entry point that parses CLI arguments and routes to subcommands."""
|
|
99
|
-
parser = argparse.ArgumentParser(
|
|
100
|
-
description="Run static analysis health checks on a repository (local or remote)",
|
|
101
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
102
|
-
epilog="""
|
|
103
|
-
Examples:
|
|
104
|
-
# Local repository (output written to <repo>/.codeboarding/health/)
|
|
105
|
-
python health_main.py --local /path/to/repo
|
|
106
|
-
|
|
107
|
-
# Remote repository (cloned to cwd/repos/, output to cwd/<repo_name>/.codeboarding/health/)
|
|
108
|
-
python health_main.py https://github.com/user/repo
|
|
109
|
-
|
|
110
|
-
""",
|
|
111
|
-
)
|
|
112
|
-
parser.add_argument(
|
|
113
|
-
"repositories",
|
|
114
|
-
nargs="*",
|
|
115
|
-
help="One or more remote Git repository URLs to run health checks on",
|
|
116
|
-
)
|
|
117
|
-
parser.add_argument("--local", type=Path, help="Path to a local repository")
|
|
118
|
-
parser.add_argument(
|
|
119
|
-
"--project-name",
|
|
120
|
-
type=str,
|
|
121
|
-
default=None,
|
|
122
|
-
help="Name of the project (default: extracted from repo path or URL)",
|
|
123
|
-
)
|
|
124
|
-
parser.add_argument(
|
|
125
|
-
"--binary-location", type=Path, help="Path to the binary directory for language servers and tools"
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
args = parser.parse_args()
|
|
129
|
-
|
|
130
|
-
# Validate: must provide either remote repos or --local, not both
|
|
131
|
-
has_remote = bool(args.repositories)
|
|
132
|
-
has_local = args.local is not None
|
|
133
|
-
|
|
134
|
-
if has_remote == has_local:
|
|
135
|
-
parser.error("Provide either one or more remote repositories or --local, but not both.")
|
|
136
|
-
|
|
137
|
-
# Resolve binary paths for tools (tokei, LSP servers, etc.)
|
|
138
|
-
if args.binary_location:
|
|
139
|
-
update_config(args.binary_location)
|
|
140
|
-
|
|
141
|
-
try:
|
|
142
|
-
if has_local:
|
|
143
|
-
run_health_check_local(args.local, args.project_name)
|
|
144
|
-
else:
|
|
145
|
-
for repo_url in args.repositories:
|
|
146
|
-
run_health_check_remote(repo_url, args.project_name)
|
|
147
|
-
except ValueError as e:
|
|
148
|
-
parser.error(str(e))
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if __name__ == "__main__":
|
|
152
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|