@ngocsangairvds/vsaf 3.2.14 → 3.2.16
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.
- package/bin/vsaf.js +18 -4
- package/package.json +1 -1
- package/src/config.js +167 -0
- package/src/global.js +1 -48
- package/src/project.js +1 -0
- package/src/utils.js +44 -1
- package/tools/vds-scripts/Makefile +9 -31
- package/tools/vds-scripts/docker/docker-compose.cli.yml +1 -117
- package/tools/vds-scripts/docker/docker-compose.services.yml +1 -40
- package/tools/vds-scripts/docker/infrastructure/init-schemas.sql +0 -34
- package/tools/vds-scripts/docker/infrastructure/pgbouncer/pgbouncer.ini +2 -6
- package/tools/vds-scripts/pyproject.toml +1 -33
- package/tools/vds-scripts/uv.lock +80 -1651
- package/tools/vds-scripts/vds_cli/pyproject.toml +3 -0
- package/tools/vds-scripts/vds_cli/src/vds_cli/cli.py +1 -127
- package/tools/vds-scripts/vds_cli/src/vds_cli/commands/lint_cli.py +1 -20
- package/tools/vds-scripts/vds_cli/src/vds_cli/router.py +0 -100
- package/tools/vds-scripts/vds_cli/tests/conftest.py +0 -2
- package/tools/vds-scripts/vds_cli/tests/unit/test_cli.py +0 -25
- package/tools/vds-scripts/vds_cli/tests/unit/test_lint_cli.py +2 -2
- package/tools/vds-scripts/vds_cli/tests/unit/test_router.py +0 -2
- package/tools/vds-scripts/CLOSURE.md +0 -340
- package/tools/vds-scripts/ECOSYSTEM-CHANGELOG.md +0 -52
- package/tools/vds-scripts/ECOSYSTEM-DOCS.md +0 -602
- package/tools/vds-scripts/ECOSYSTEM_ALIGNMENT.md +0 -133
- package/tools/vds-scripts/ENV-HYGIENE-OPS-NOTE.md +0 -65
- package/tools/vds-scripts/INVESTIGATION-cloud-401.md +0 -103
- package/tools/vds-scripts/MEM0_2.0_API_REFERENCE.md +0 -238
- package/tools/vds-scripts/PACKAGE_P125B_IMPLEMENTATION_SUMMARY.md +0 -131
- package/tools/vds-scripts/PHASE-MERGE-SUMMARY.md +0 -121
- package/tools/vds-scripts/PHASES-3-ARCHIVE.md +0 -59
- package/tools/vds-scripts/PROJECT_COMPLETION_SUMMARY.md +0 -45
- package/tools/vds-scripts/SEARCH-CRASH-REPRO.md +0 -51
- package/tools/vds-scripts/analyze_hexagonal.py +0 -217
- package/tools/vds-scripts/analyze_profiles.py +0 -60
- package/tools/vds-scripts/audit-checklist.xlsx +0 -0
- package/tools/vds-scripts/audit_orchestrator/.audit_approvals/approvals_index.json +0 -1
- package/tools/vds-scripts/audit_orchestrator/.env.example +0 -85
- package/tools/vds-scripts/audit_orchestrator/.github/workflows/audit.yml +0 -47
- package/tools/vds-scripts/audit_orchestrator/Dockerfile +0 -92
- package/tools/vds-scripts/audit_orchestrator/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +0 -218
- package/tools/vds-scripts/audit_orchestrator/PHASE3_INTEGRATION_SUMMARY.md +0 -268
- package/tools/vds-scripts/audit_orchestrator/PHASE7-MERGE-SUMMARY.md +0 -174
- package/tools/vds-scripts/audit_orchestrator/README.md +0 -1573
- package/tools/vds-scripts/audit_orchestrator/TSK-168-IMPLEMENTATION-SUMMARY.md +0 -191
- package/tools/vds-scripts/audit_orchestrator/TSK-196-IMPLEMENTATION-SUMMARY.md +0 -201
- package/tools/vds-scripts/audit_orchestrator/alembic/env.py +0 -37
- package/tools/vds-scripts/audit_orchestrator/alembic/script.py.mako +0 -28
- package/tools/vds-scripts/audit_orchestrator/alembic/versions/0001_initial_audit_state_schema.py +0 -1260
- package/tools/vds-scripts/audit_orchestrator/alembic.ini +0 -68
- package/tools/vds-scripts/audit_orchestrator/config/category-mapping.json +0 -81
- package/tools/vds-scripts/audit_orchestrator/config/profile-timeouts.yaml +0 -17
- package/tools/vds-scripts/audit_orchestrator/create_sample.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/data/corpus_accuracy_report.json +0 -17
- package/tools/vds-scripts/audit_orchestrator/data/exemplar_quality_report.json +0 -1606
- package/tools/vds-scripts/audit_orchestrator/data/instruction_plan_fixtures.json +0 -163
- package/tools/vds-scripts/audit_orchestrator/data/requirement_exemplars.json +0 -3443
- package/tools/vds-scripts/audit_orchestrator/data/requirement_scope_fixtures.json +0 -172
- package/tools/vds-scripts/audit_orchestrator/debug_rg.py +0 -46
- package/tools/vds-scripts/audit_orchestrator/demo_code_pack.py +0 -127
- package/tools/vds-scripts/audit_orchestrator/docs/AGENT_SDK_SELECTION_SPEC.md +0 -720
- package/tools/vds-scripts/audit_orchestrator/docs/API.md +0 -804
- package/tools/vds-scripts/audit_orchestrator/docs/CONTENT_ANALYSIS_APPROACH.md +0 -1041
- package/tools/vds-scripts/audit_orchestrator/docs/CONTENT_SCORING_EVOLUTION_SPEC.md +0 -868
- package/tools/vds-scripts/audit_orchestrator/docs/DEPLOYMENT.md +0 -778
- package/tools/vds-scripts/audit_orchestrator/docs/LLM_AGENT_AUDIT_SPEC.md +0 -721
- package/tools/vds-scripts/audit_orchestrator/docs/LLM_CONTENT_ANALYSIS_SPEC.md +0 -1143
- package/tools/vds-scripts/audit_orchestrator/docs/LSP_SETUP_GUIDE.md +0 -221
- package/tools/vds-scripts/audit_orchestrator/docs/MULTI_REPO_AUDIT_SPEC.md +0 -951
- package/tools/vds-scripts/audit_orchestrator/docs/OLLAMA_EMBEDDINGS_SETUP.md +0 -119
- package/tools/vds-scripts/audit_orchestrator/docs/PHASE32_REAL_BENCHMARK_2026-02-08.md +0 -66
- package/tools/vds-scripts/audit_orchestrator/docs/PHASE_64_TO_92_HISTORICAL_SPEC.md +0 -1772
- package/tools/vds-scripts/audit_orchestrator/docs/TSK-193-flow-trace.md +0 -201
- package/tools/vds-scripts/audit_orchestrator/docs/TSK-193-verification.md +0 -124
- package/tools/vds-scripts/audit_orchestrator/docs/phase152-hierarchical-query-surface.md +0 -46
- package/tools/vds-scripts/audit_orchestrator/examples/bitbucket_metadata_example.json +0 -50
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/README.md +0 -68
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase117_phase118_shared_state.sql +0 -64
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase154_published_pages.sql +0 -28
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase157_dispatch_tables.sql +0 -94
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase157_events.sql +0 -91
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase157_scope_snapshots.sql +0 -24
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase157_status_view.sql +0 -22
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/phase169_dispatch_observability.sql +0 -55
- package/tools/vds-scripts/audit_orchestrator/legacy/migrations/state_repair_hardening.sql +0 -24
- package/tools/vds-scripts/audit_orchestrator/pyproject.toml +0 -211
- package/tools/vds-scripts/audit_orchestrator/pyrightconfig.json +0 -51
- package/tools/vds-scripts/audit_orchestrator/pytest.ini +0 -37
- package/tools/vds-scripts/audit_orchestrator/reproduce_scanner.py +0 -40
- package/tools/vds-scripts/audit_orchestrator/scripts/README.md +0 -116
- package/tools/vds-scripts/audit_orchestrator/scripts/benchmark_crawl_modes.py +0 -455
- package/tools/vds-scripts/audit_orchestrator/scripts/benchmark_dspy.py +0 -513
- package/tools/vds-scripts/audit_orchestrator/scripts/benchmark_nlp_accuracy.py +0 -138
- package/tools/vds-scripts/audit_orchestrator/scripts/benchmark_retrieval_modes.py +0 -176
- package/tools/vds-scripts/audit_orchestrator/scripts/benchmark_upload_update_mode.py +0 -167
- package/tools/vds-scripts/audit_orchestrator/scripts/build_check.py +0 -76
- package/tools/vds-scripts/audit_orchestrator/scripts/check_live_progress.py +0 -61
- package/tools/vds-scripts/audit_orchestrator/scripts/cli_integration_test.py +0 -400
- package/tools/vds-scripts/audit_orchestrator/scripts/index_workspace.py +0 -178
- package/tools/vds-scripts/audit_orchestrator/scripts/inspect_route_conformance.py +0 -196
- package/tools/vds-scripts/audit_orchestrator/scripts/monitor_postgres.py +0 -145
- package/tools/vds-scripts/audit_orchestrator/scripts/optimize_audit.py +0 -462
- package/tools/vds-scripts/audit_orchestrator/scripts/verify.py +0 -673
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase111_requirement_analysis.py +0 -375
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase117_cross_repo_evidence.py +0 -77
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase121_short_circuit.py +0 -680
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase122_instruction_handling.py +0 -478
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase125_skill_integration.py +0 -832
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase_36.py +0 -394
- package/tools/vds-scripts/audit_orchestrator/scripts/verify_phase_37.py +0 -58
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/__init__.py +0 -17
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/__init__.py +0 -29
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/_langchain_warnings.py +0 -17
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/agentic_investigator.py +0 -4130
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/approval.py +0 -490
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/audit_loop_hooks.py +0 -107
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/audit_state.py +0 -50
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/base.py +0 -4035
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/code_agent.py +0 -667
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/code_analysis_helpers.py +0 -236
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/code_analysis_prompts.py +0 -146
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/docs_agent.py +0 -1234
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/langgraph_workflow.py +0 -2002
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/pydantic_base.py +0 -1227
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/requirement_analysis_agent.py +0 -593
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/security_agent.py +0 -1829
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/security_scanner.py +0 -686
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/skill_tools.py +0 -204
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/synthesis_agent.py +0 -1463
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/tool_efficiency_guard.py +0 -609
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/tool_registry.py +0 -3822
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/__init__.py +0 -52
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/evidence_corpus.py +0 -385
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/filesystem.py +0 -1134
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/lsp.py +0 -458
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/mcp_toolset.py +0 -491
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/skills_toolset.py +0 -997
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/toolsets/vector_evidence.py +0 -842
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/usage_tracker.py +0 -682
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/agents/visualization.py +0 -303
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/analyze_cmds.py +0 -892
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checklist_query/__init__.py +0 -15
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checklist_query/service.py +0 -171
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/__init__.py +0 -20
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/base.py +0 -60
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/bitbucket/__init__.py +0 -6
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/bitbucket/checks.py +0 -257
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/confluence/__init__.py +0 -10
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/confluence/checks.py +0 -78
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/git/__init__.py +0 -6
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/git/file_checks.py +0 -133
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/llm_checks/__init__.py +0 -17
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/llm_checks/api_docs_check.py +0 -80
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/llm_checks/readme_check.py +0 -76
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/llm_checks/security_docs_check.py +0 -78
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/registry.py +0 -402
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/sonarqube/__init__.py +0 -10
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/checks/sonarqube/checks.py +0 -276
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/cli.py +0 -12
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/cli_common.py +0 -128
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/cli_impl.py +0 -9826
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/clients/bitbucket_cli_client.py +0 -187
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/clients/confluence_cli_client.py +0 -977
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/clients/sonarqube_cli_client.py +0 -28
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/__init__.py +0 -21
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/base.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/bitbucket_downloader.py +0 -644
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/bitbucket_metadata.py +0 -133
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/checklist_parser.py +0 -180
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/completeness/__init__.py +0 -31
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/completeness/bitbucket_probe.py +0 -443
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/completeness/confluence_probe.py +0 -365
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/completeness/freshness_evaluator.py +0 -330
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/completeness/material_completeness_service.py +0 -1079
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/confluence_collector.py +0 -259
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/diagram_extractor.py +0 -280
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/enrichment_extractor.py +0 -200
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/evidence_cache.py +0 -35
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/git_collector.py +0 -148
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/graphify_collector.py +0 -171
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/image_extractor.py +0 -359
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/linked_page_tracker.py +0 -120
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/markdown_converter.py +0 -344
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/material_cache.py +0 -1252
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/material_downloader.py +0 -1165
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/orchestrator.py +0 -168
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/registry_parser.py +0 -3063
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/requirements.py +0 -70
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/runner.py +0 -119
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/collectors/sonarqube_collector.py +0 -113
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config.py +0 -1943
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/__init__.py +0 -23
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/discovery.py +0 -90
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/environment_resolver.py +0 -56
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/evidence.py +0 -78
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/models.py +0 -73
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/precedence.py +0 -10
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/config_resolution/redaction.py +0 -20
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/confluence_connectivity.py +0 -140
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/corpus_cmds.py +0 -278
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/db/__init__.py +0 -7
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/db/alembic_filters.py +0 -57
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/docs/__init__.py +0 -29
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/docs/diataxis_validator.py +0 -687
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/doctor_cmds.py +0 -3295
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/dspy_modules/__init__.py +0 -5
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/dspy_modules/evaluation.py +0 -301
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/dspy_modules/modules.py +0 -172
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/dspy_modules/runtime.py +0 -836
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/dspy_modules/signatures.py +0 -406
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/__init__.py +0 -192
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/ad_hoc_analyzer.py +0 -399
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/aggregator.py +0 -220
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/auditor.py +0 -504
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/batch_evidence_cache.py +0 -111
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/batch_processor.py +0 -4776
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/calibration.py +0 -217
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/checklist_generator.py +0 -1201
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/checklist_projection.py +0 -192
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/checklist_scoping.py +0 -221
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/checkpoint.py +0 -159
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/cl003_shared_lib_guard.py +0 -194
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/companion_context_service.py +0 -445
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/confluence_checklist_contract.py +0 -7425
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/cross_check_rules.py +0 -213
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/deterministic_evaluator.py +0 -237
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/drift_detector.py +0 -157
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/dspy_requirement_classifier.py +0 -640
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/evidence_assembler.py +0 -407
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/evidence_collector.py +0 -119
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/evidence_diversity.py +0 -101
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/gap_analyzer.py +0 -549
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/graduated.py +0 -185
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/grounding_validator.py +0 -287
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/instruction_analyzer.py +0 -882
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/instruction_compliance.py +0 -172
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/llm_row_evaluator.py +0 -9270
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/loader.py +0 -1070
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/manual_check_config.py +0 -136
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/mapping.py +0 -269
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/multi_judge.py +0 -65
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/phase120_checklist_update.py +0 -416
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/profile_scorer.py +0 -427
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/project_evidence_context.py +0 -449
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/project_knowledge_query_service.py +0 -155
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/project_knowledge_store.py +0 -383
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/project_topology.py +0 -1920
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/provider_failure_classifier.py +0 -778
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/readiness_cli_helpers.py +0 -341
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/readiness_extractor.py +0 -303
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/readiness_synthesizer.py +0 -730
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/regression_guard.py +0 -138
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/repo_type_classifier.py +0 -297
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/requirement_analysis.py +0 -1433
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/requirement_classification.py +0 -1725
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/result_merger.py +0 -814
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/route_matrix.py +0 -267
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/row_evaluator.py +0 -9437
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/row_evaluator_runtime.py +0 -1270
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/row_evaluator_types.py +0 -2102
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/rubric.py +0 -592
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/scorer.py +0 -1239
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/section_packs.py +0 -645
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/skill_recommendation.py +0 -1183
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/stability_harness.py +0 -207
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/target_selector.py +0 -841
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/telemetry.py +0 -347
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/template_analyzer.py +0 -469
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/token_tracker.py +0 -111
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/tool_first_planner.py +0 -7905
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/topology_query_service.py +0 -80
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/validator.py +0 -449
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/engine/weight_policy.py +0 -464
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/errors.py +0 -430
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/extract_cmds.py +0 -4887
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/identity.py +0 -146
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/incremental/__init__.py +0 -52
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/incremental/baseline.py +0 -378
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/incremental/change_analyzer.py +0 -407
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/incremental/delta_report.py +0 -189
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/incremental/diff_detector.py +0 -301
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/integrations/__init__.py +0 -3
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/__init__.py +0 -50
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/audit_schemas.py +0 -459
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/codex_oauth.py +0 -340
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/cost_tracker.py +0 -288
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/engine.py +0 -751
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/evaluator.py +0 -245
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/__init__.py +0 -32
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/api_docs_evaluation.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/gap_analysis.py +0 -31
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/instruction_templates.py +0 -634
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/readme_evaluation.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/row_evaluation.py +0 -247
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/security_docs_evaluation.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts/template_analysis.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/prompts.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/llm/provider.py +0 -626
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/logging_config.py +0 -577
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/mappings/__init__.py +0 -58
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/mappings/default_checklist_mapping.json +0 -18
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/mappings/vietnamese_checklist_mapping.json +0 -38
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/misc_cmds.py +0 -4689
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/__init__.py +0 -153
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/calibration.py +0 -98
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/checklist.py +0 -921
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/completeness.py +0 -309
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/enrichment.py +0 -58
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/enums.py +0 -97
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/evidence.py +0 -351
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/findings.py +0 -381
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/gaps.py +0 -299
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/graph.py +0 -42
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/multi_judge.py +0 -50
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/readiness.py +0 -309
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/registry.py +0 -386
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/reporting.py +0 -32
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/task.py +0 -549
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/models/template.py +0 -477
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/observability/__init__.py +0 -31
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/observability/metrics.py +0 -404
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/parse_cmds.py +0 -608
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/pdf_cmds.py +0 -208
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/performance_gates.py +0 -224
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/phase151_projection.py +0 -84
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/profiles/__init__.py +0 -65
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/profiles/detection.py +0 -842
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/profiles/models.py +0 -474
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/__init__.py +0 -1
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/_confluence_macros.py +0 -145
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/_field_sanitizer.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/_table_builder.py +0 -63
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/_vietnamese_templates.py +0 -103
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/bitbucket_link_resolver.py +0 -34
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/checklist_renderer.py +0 -483
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/confluence_publisher.py +0 -3048
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/hierarchy_publisher.py +0 -213
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/live_data_injector.py +0 -152
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/macro_builder.py +0 -101
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/markdown_converter.py +0 -154
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/priority_renderer.py +0 -133
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/project_aggregate_renderer.py +0 -423
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/readiness_renderer.py +0 -186
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/system_doc_hierarchy_renderer.py +0 -382
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/publishers/system_doc_renderer.py +0 -683
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/report_cmds.py +0 -788
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/__init__.py +0 -13
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/aggregation_report.py +0 -86
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/checklist_generator.py +0 -425
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/excel_generator.py +0 -599
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/gap_report.py +0 -131
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/json_generator.py +0 -188
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/markdown_generator.py +0 -595
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/__init__.py +0 -154
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/collector.py +0 -61
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/department_builder.py +0 -77
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/errors.py +0 -9
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/md_renderer.py +0 -386
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/pdf_models.py +0 -95
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/pdf_writer.py +0 -27
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/pdf/repo_project_builders.py +0 -274
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/readiness_report.py +0 -447
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/reporting.py +0 -94
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/reports/sarif_generator.py +0 -519
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/runtime_profiles.py +0 -98
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/seed/__init__.py +0 -29
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/seed/seed_loader.py +0 -561
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/skills/__init__.py +0 -5
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/skills/skill_routing.py +0 -312
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/base.py +0 -110
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/bitbucket.py +0 -129
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/git_url.py +0 -60
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/github.py +0 -75
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sources/local.py +0 -58
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/spec_sync_validator.py +0 -15
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/state/__init__.py +0 -6285
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/state/readiness_helpers.py +0 -74
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/state/skill_readiness.py +0 -487
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/state/store.py +0 -12927
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/state_cmds.py +0 -1868
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sync/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sync/repo_sync.py +0 -409
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/sync_cmds.py +0 -1247
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/utils/__init__.py +0 -3
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/utils/debug_bundle.py +0 -214
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/validators/checklist_validator.py +0 -342
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflow_cmds.py +0 -19147
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/__init__.py +0 -9
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/_test_audit_daily_batch.py +0 -192
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/audit_daily_batch.py +0 -308
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/audit_deep_monthly.py +0 -193
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/audit_drift_scan.py +0 -178
- package/tools/vds-scripts/audit_orchestrator/src/vds_audit_orchestrator/workflows/audit_security_daily.py +0 -183
- package/tools/vds-scripts/audit_orchestrator/templates/sample_audit_template.xlsx +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/_helpers.py +0 -32
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/completeness/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/completeness/test_bitbucket_probe.py +0 -403
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/completeness/test_confluence_probe.py +0 -423
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_bitbucket_downloader.py +0 -289
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_image_extractor.py +0 -260
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_markdown_converter.py +0 -57
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_material_cache.py +0 -197
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_material_downloader.py +0 -550
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_registry_parser.py +0 -3514
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_registry_parser_department_entry.py +0 -214
- package/tools/vds-scripts/audit_orchestrator/tests/collectors/test_registry_parser_flow.py +0 -200
- package/tools/vds-scripts/audit_orchestrator/tests/conftest.py +0 -988
- package/tools/vds-scripts/audit_orchestrator/tests/engine/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/engine/test_calibration.py +0 -48
- package/tools/vds-scripts/audit_orchestrator/tests/engine/test_confluence_checklist_phase22_helpers.py +0 -6065
- package/tools/vds-scripts/audit_orchestrator/tests/engine/test_multi_judge.py +0 -62
- package/tools/vds-scripts/audit_orchestrator/tests/engine/test_stability_harness.py +0 -61
- package/tools/vds-scripts/audit_orchestrator/tests/engine/test_structured_metadata.py +0 -419
- package/tools/vds-scripts/audit_orchestrator/tests/factories/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/factories/models.py +0 -534
- package/tools/vds-scripts/audit_orchestrator/tests/factories/templates.py +0 -241
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/diagrams/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/diagrams/compressed.drawio +0 -2
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/diagrams/mockup.bmpr +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/diagrams/simple.drawio +0 -26
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/bitbucket/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/bitbucket/branch_permissions_cli.json +0 -26
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/bitbucket/branch_permissions_direct.json +0 -24
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/bitbucket/repo_conditions_cli.json +0 -14
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/bitbucket/repo_conditions_direct.json +0 -12
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/confluence/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/confluence/page_cli.json +0 -7
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/confluence/page_direct.json +0 -7
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/confluence/search_cli.json +0 -11
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/confluence/search_direct.json +0 -7
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/sonarqube/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/sonarqube/quality_gate_cli.json +0 -12
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/golden/sonarqube/quality_gate_direct.json +0 -12
- package/tools/vds-scripts/audit_orchestrator/tests/fixtures/requirement_strategy_phase115.json +0 -118
- package/tools/vds-scripts/audit_orchestrator/tests/integration/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/conftest.py +0 -107
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/expected_outcomes.md +0 -50
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/auth.py +0 -27
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/config.py +0 -16
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/db.py +0 -24
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/main.py +0 -18
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/src/__init__.py +0 -1
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_audit_repo/src/utils.py +0 -22
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_checklist_template.json +0 -110
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/code_evidence_pack.json +0 -40
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/manifest.json +0 -49
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/brd.md +0 -19
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/design.md +0 -32
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/security.md +0 -23
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/srs.md +0 -25
- package/tools/vds-scripts/audit_orchestrator/tests/integration/fixtures/mock_evidence/projects/mock-audit-project/test.md +0 -30
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_checkpoint_merge.py +0 -1371
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_decoupling_route_p149.py +0 -176
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_gap_analyzer_batch_p149.py +0 -151
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_hybrid_search.py +0 -799
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_mcp_integration.py +0 -741
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_merge_ranking_p149.py +0 -98
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_modality_mismatch_p149.py +0 -171
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_phase117_118_storage.py +0 -350
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_phase121_short_circuit.py +0 -732
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_phase18_workflow.py +0 -223
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_phase48_e2e_verification.py +0 -763
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_phase81_doc_anchor_regression.py +0 -252
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_provider_failure_finding_p149.py +0 -339
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_readiness_e2e.py +0 -430
- package/tools/vds-scripts/audit_orchestrator/tests/integration/test_refined_workflow.py +0 -1180
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/snapshots/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/snapshots/department_renderer.md +0 -24
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/snapshots/project_renderer.md +0 -8
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/snapshots/repo_renderer.md +0 -10
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_department_pdf.py +0 -112
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_e2e_pdf.py +0 -135
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_idempotency.py +0 -45
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_md_renderer.py +0 -46
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_pdf_cmds.py +0 -97
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_pdf_snapshot.py +0 -77
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_pdf_writer.py +0 -65
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_project_builder.py +0 -199
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_public_api.py +0 -135
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_repo_builder.py +0 -246
- package/tools/vds-scripts/audit_orchestrator/tests/pdf/test_workflow_pdf_flags.py +0 -36
- package/tools/vds-scripts/audit_orchestrator/tests/property/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/property/test_properties.py +0 -807
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_agent_error_compat.py +0 -38
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_agentic_skill_policy_skip.py +0 -234
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_base_event_stream_logging.py +0 -785
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_base_timeout_policy.py +0 -277
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_base_trace_payload_sanitization.py +0 -92
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_code_agent.py +0 -2311
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_code_agent_re_exports.py +0 -25
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_code_analysis_helpers.py +0 -94
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_create_audit_agent_reasoning_effort.py +0 -69
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_docs_agent.py +0 -2044
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_langgraph_workflow_efficiency_metrics.py +0 -71
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_output_validators.py +0 -317
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_phase41_toolsets.py +0 -6427
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_pydantic_ai_models.py +0 -1219
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_pydantic_base_url_resolution.py +0 -84
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_security_agent.py +0 -2069
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_skill_manager_focus.py +0 -439
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_synthesis_agent.py +0 -1195
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_tool_efficiency_guard_fr120.py +0 -683
- package/tools/vds-scripts/audit_orchestrator/tests/test_agents/test_toolsets.py +0 -716
- package/tools/vds-scripts/audit_orchestrator/tests/test_aggregator_p149.py +0 -171
- package/tools/vds-scripts/audit_orchestrator/tests/test_alembic_migrations.py +0 -287
- package/tools/vds-scripts/audit_orchestrator/tests/test_anchor_allowlist_p149.py +0 -273
- package/tools/vds-scripts/audit_orchestrator/tests/test_audit_otel.py +0 -283
- package/tools/vds-scripts/audit_orchestrator/tests/test_checklist_models.py +0 -583
- package/tools/vds-scripts/audit_orchestrator/tests/test_checks/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_checks/test_base_check.py +0 -211
- package/tools/vds-scripts/audit_orchestrator/tests/test_checks/test_llm_checks.py +0 -126
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_analyze_command.py +0 -400
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_archive_stale_page_cli.py +0 -217
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_bitbucket_metadata_cli.py +0 -354
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_cli_impl_profile_availability.py +0 -114
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_codex_profile.py +0 -174
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_compare_backends_cli.py +0 -449
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_confluence_parent_auto_resolve.py +0 -451
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_corpus_purge_cli.py +0 -290
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_credentials_preflight.py +0 -106
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_debug_bundle.py +0 -37
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_deprecation_phase157.py +0 -484
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_dispatch_concurrency_diagnostics.py +0 -758
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_check_confluence_cli.py +0 -320
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_codex.py +0 -187
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_corpus_status_cli.py +0 -236
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_correlation_cli.py +0 -128
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_crawl_status_cli.py +0 -192
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_credentials_cli.py +0 -86
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_dispatch_status_cli.py +0 -421
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_heartbeat_phase169.py +0 -173
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_hierarchy_status_cli.py +0 -199
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_locks_cli.py +0 -134
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_logs_follow_cli.py +0 -305
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_migration.py +0 -333
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_profile_availability_cli.py +0 -151
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_doctor_skills_policy_cli.py +0 -153
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_evidence_quality_cli.py +0 -307
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_export_debug_bundle_phase36.py +0 -60
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_export_git_manifest_cli.py +0 -172
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_file_removal_phase157e.py +0 -770
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_grounding_classifier.py +0 -226
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_logging.py +0 -49
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_materials_cli.py +0 -9127
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_metadata_completeness_phase92.py +0 -364
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_parent_dispatch_finalization_phase168f.py +0 -111
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_parse_cli.py +0 -590
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_phase117_118_feature_flags.py +0 -219
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_phase164_control_plane.py +0 -718
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_phase165_runner_scripts.py +0 -230
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_preparation_classifications.py +0 -146
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_prepare_cli.py +0 -398
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_publication_quality_gate.py +0 -126
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_publish_system_doc_cli.py +0 -158
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_query_checklist_cli.py +0 -219
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_readiness_cli.py +0 -673
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_readiness_cli_integration.py +0 -689
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_removed_flags_phase92.py +0 -36
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_report_cmds.py +0 -1317
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_run_history_index.py +0 -57
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_run_management.py +0 -1194
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_runtime_profiles_cli.py +0 -1658
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_smart_run_selection.py +0 -1562
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_state_cli.py +0 -2467
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_state_migration.py +0 -339
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_sync_repos_debug_artifacts.py +0 -1109
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_upload_results_cli.py +0 -809
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_validate_checklist.py +0 -178
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_validate_checklist_cli.py +0 -110
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_validate_spec_sync_cli.py +0 -519
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_default_parameters_baseline.py +0 -101
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_options.py +0 -7896
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_project_db_modes.py +0 -6516
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_project_project_scope.py +0 -831
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_project_target.py +0 -611
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_projects_phase131_lifecycle.py +0 -2488
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_projects_phase131_scaffolding.py +0 -96
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_row_key_guard.py +0 -78
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli/test_workflow_summary_artifacts.py +0 -1872
- package/tools/vds-scripts/audit_orchestrator/tests/test_cli_paths_phase2.py +0 -45
- package/tools/vds-scripts/audit_orchestrator/tests/test_clients/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_clients/test_bitbucket_cli_client.py +0 -124
- package/tools/vds-scripts/audit_orchestrator/tests/test_clients/test_cli_parity.py +0 -110
- package/tools/vds-scripts/audit_orchestrator/tests/test_clients/test_confluence_cli_client.py +0 -1149
- package/tools/vds-scripts/audit_orchestrator/tests/test_clients/test_sonarqube_cli_client.py +0 -19
- package/tools/vds-scripts/audit_orchestrator/tests/test_collectors/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_collectors/test_linked_page_tracker.py +0 -118
- package/tools/vds-scripts/audit_orchestrator/tests/test_companion_context_service.py +0 -230
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/conftest.py +0 -11
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_compile_artifact.py +0 -465
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_cross_provider_critique.py +0 -120
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_cross_provider_critique_e2e.py +0 -75
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_evaluation.py +0 -515
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_runtime_loader.py +0 -537
- package/tools/vds-scripts/audit_orchestrator/tests/test_dspy_modules/test_signatures_normalization.py +0 -172
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_auditor_applicability.py +0 -68
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_checklist_generator.py +0 -1252
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_checklist_projection.py +0 -54
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_confluence_checklist_projection_consistency.py +0 -1696
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_critique_merger_matrix.py +0 -120
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_cross_check_rules.py +0 -459
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_cross_provider_critique.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_doc_loader.py +0 -73
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_drift_detector.py +0 -34
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_evidence_collectors.py +0 -93
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_lease_timeout.py +0 -114
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_loader.py +0 -350
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_loader_parity.py +0 -179
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_low_confidence_reeval.py +0 -691
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_phase145a_completion.py +0 -209
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_phase31_row_consistency_retry_benchmark.py +0 -150
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_profile_detector.py +0 -286
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_regression_guard.py +0 -53
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_result_merger.py +0 -619
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_row_evaluator.py +0 -15783
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_row_failover.py +0 -215
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_scorer.py +0 -597
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_skill_breakdown_telemetry_fr137.py +0 -421
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_targeted_auto_merge.py +0 -229
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_timeout_failover.py +0 -488
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_timeout_telemetry.py +0 -73
- package/tools/vds-scripts/audit_orchestrator/tests/test_engine/test_validator.py +0 -419
- package/tools/vds-scripts/audit_orchestrator/tests/test_incremental/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_incremental/test_diff_detector.py +0 -111
- package/tools/vds-scripts/audit_orchestrator/tests/test_infra_persistence.py +0 -291
- package/tools/vds-scripts/audit_orchestrator/tests/test_integration/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_integration/test_phase3_integration.py +0 -516
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_cache.py +0 -670
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_codex_model_builder.py +0 -281
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_codex_oauth.py +0 -330
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_codex_streaming.py +0 -433
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_cost_tracker.py +0 -27
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_engine.py +0 -876
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_evaluator.py +0 -212
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_instruction_templates.py +0 -639
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_prompt_metadata.py +0 -97
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_prompts.py +0 -660
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_provider.py +0 -330
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_provider_contract_sync.py +0 -18
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_reasoning_effort_validation.py +0 -565
- package/tools/vds-scripts/audit_orchestrator/tests/test_llm/test_schemas.py +0 -827
- package/tools/vds-scripts/audit_orchestrator/tests/test_logging_config.py +0 -297
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/test_enums.py +0 -185
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/test_findings.py +0 -1159
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/test_project_profile.py +0 -307
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/test_registry.py +0 -532
- package/tools/vds-scripts/audit_orchestrator/tests/test_models/test_template.py +0 -708
- package/tools/vds-scripts/audit_orchestrator/tests/test_observability/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_observability/test_metrics.py +0 -60
- package/tools/vds-scripts/audit_orchestrator/tests/test_paths_config_phase2.py +0 -21
- package/tools/vds-scripts/audit_orchestrator/tests/test_performance/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_performance/test_fr79_performance_guardrails.py +0 -199
- package/tools/vds-scripts/audit_orchestrator/tests/test_phase156_hardening.py +0 -498
- package/tools/vds-scripts/audit_orchestrator/tests/test_phase93_regression_guards.py +0 -123
- package/tools/vds-scripts/audit_orchestrator/tests/test_pipeline_integration.py +0 -517
- package/tools/vds-scripts/audit_orchestrator/tests/test_profiles/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_profiles/test_detection.py +0 -146
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_bitbucket_link_resolver.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_checklist_renderer.py +0 -84
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_checklist_renderer_projection.py +0 -97
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_confluence_macros.py +0 -58
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_confluence_publisher.py +0 -2171
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_evidence_links.py +0 -129
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_field_sanitizer.py +0 -108
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_hierarchy_publisher.py +0 -134
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_incremental_plan_parser.py +0 -62
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_live_data_injector.py +0 -48
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_macro_builder.py +0 -22
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_p161_confluence_optimization.py +0 -168
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_priority_renderer.py +0 -96
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_project_aggregate_renderer.py +0 -364
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_storage_validation.py +0 -273
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_summary_refactor.py +0 -118
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_system_doc_hierarchy.py +0 -50
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_table_builder.py +0 -23
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_vietnamese_templates.py +0 -37
- package/tools/vds-scripts/audit_orchestrator/tests/test_publishers/test_wiring_integration.py +0 -290
- package/tools/vds-scripts/audit_orchestrator/tests/test_reports/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_reports/test_aggregation_report.py +0 -181
- package/tools/vds-scripts/audit_orchestrator/tests/test_reports/test_checklist_generator.py +0 -258
- package/tools/vds-scripts/audit_orchestrator/tests/test_reports/test_gap_report.py +0 -73
- package/tools/vds-scripts/audit_orchestrator/tests/test_reports/test_json_generator.py +0 -317
- package/tools/vds-scripts/audit_orchestrator/tests/test_result_merger_p149.py +0 -347
- package/tools/vds-scripts/audit_orchestrator/tests/test_route_mode_p149.py +0 -178
- package/tools/vds-scripts/audit_orchestrator/tests/test_rubric_parser.py +0 -179
- package/tools/vds-scripts/audit_orchestrator/tests/test_scorer.py +0 -110
- package/tools/vds-scripts/audit_orchestrator/tests/test_state/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_state/test_sparse_coverage.py +0 -117
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow/test_langgraph_workflow.py +0 -2072
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow/test_p161_runtime_hardening.py +0 -341
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow_cmds_p149.py +0 -112
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow_cmds_p172.py +0 -126
- package/tools/vds-scripts/audit_orchestrator/tests/test_workflow_guidance_p150.py +0 -95
- package/tools/vds-scripts/audit_orchestrator/tests/unit/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_agentic_investigator_phase115.py +0 -42
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_requirement_analysis_agent.py +0 -412
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_security_agent_updates.py +0 -131
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_security_scanner.py +0 -397
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_skill_executor.py +0 -316
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_skill_fallback.py +0 -299
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_skill_policy.py +0 -520
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_skill_telemetry.py +0 -306
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_synthesis_fixes.py +0 -761
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_argument_robustness.py +0 -272
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_registry.py +0 -2548
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_registry_ast_grep.py +0 -87
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_registry_phase123_scoping.py +0 -353
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_registry_phase94_ff.py +0 -445
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_tool_registry_vector_search_phase115.py +0 -35
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_utils.py +0 -1007
- package/tools/vds-scripts/audit_orchestrator/tests/unit/agents/test_vector_evidence_toolset.py +0 -622
- package/tools/vds-scripts/audit_orchestrator/tests/unit/cli/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/cli/test_workflow_cli.py +0 -123
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/test_cache_guard.py +0 -479
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/test_checklist_parser_phase120.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/test_diagram_extractor.py +0 -467
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/test_enrichment_extractor.py +0 -59
- package/tools/vds-scripts/audit_orchestrator/tests/unit/collectors/test_graphify_collector.py +0 -158
- package/tools/vds-scripts/audit_orchestrator/tests/unit/completeness/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/completeness/test_completeness.py +0 -563
- package/tools/vds-scripts/audit_orchestrator/tests/unit/completeness/test_freshness_evaluator.py +0 -493
- package/tools/vds-scripts/audit_orchestrator/tests/unit/completeness/test_material_cache_metrics.py +0 -365
- package/tools/vds-scripts/audit_orchestrator/tests/unit/completeness/test_material_completeness_service.py +0 -2736
- package/tools/vds-scripts/audit_orchestrator/tests/unit/config_resolution/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/config_resolution/test_discovery.py +0 -47
- package/tools/vds-scripts/audit_orchestrator/tests/unit/config_resolution/test_redaction.py +0 -15
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_ad_hoc_analyzer.py +0 -576
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_agent_loop.py +0 -1896
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_anchor_filter_cl003.py +0 -181
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_batch_evidence_cache.py +0 -155
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_batch_processor.py +0 -3608
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_checklist_contract.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_checklist_scoping.py +0 -371
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_config_companion_phase123.py +0 -142
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_config_evidence_phase123.py +0 -249
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_confluence_checklist_contract_export_parity.py +0 -813
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_cross_repo_config_phase122.py +0 -613
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_dspy_requirement_classifier.py +0 -517
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_evidence_diversity.py +0 -144
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_evidence_truncation.py +0 -108
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_grounding_validator.py +0 -127
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_guidance_injection_phase120.py +0 -105
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_instruction_analysis_phase122.py +0 -761
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_instruction_pre_filter_phase167.py +0 -334
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_llm_row_evaluator_retries.py +0 -3684
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_loader_phase123.py +0 -345
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_manual_check_gating_phase122.py +0 -474
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_parallel_eval.py +0 -263
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_phase122_verifier_phase122.py +0 -169
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_phase166_route_failover.py +0 -437
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_post_eval_cl003_shared_lib.py +0 -267
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_postproc_streaming.py +0 -194
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_pre_eval_gating_phase122.py +0 -362
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_prepare_topology_coverage.py +0 -247
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_private_dns_sanitization_phase104.py +0 -397
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_project_evidence_context.py +0 -450
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_project_knowledge_store.py +0 -487
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_project_topology.py +0 -1142
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_provider_failure_classifier.py +0 -195
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_readiness_extractor.py +0 -496
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_readiness_synthesizer.py +0 -653
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_repo_type_classifier.py +0 -303
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_analysis.py +0 -508
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_analysis_execution_scope.py +0 -239
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_analysis_phase114.py +0 -919
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_analysis_phase115.py +0 -97
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_analysis_shared_lib.py +0 -340
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_classification_drift.py +0 -729
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_classification_nlp.py +0 -670
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_requirement_scope_phase122.py +0 -615
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_route_matrix.py +0 -258
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_route_override.py +0 -141
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_routing_precision.py +0 -650
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_row_evaluator_dual_evidence.py +0 -2987
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_row_evaluator_instruction_runtime_phase122.py +0 -365
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_row_evaluator_runtime.py +0 -830
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_runtime_hardening_phase122.py +0 -225
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_scoped_na_skip.py +0 -107
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_scoring_enhancements.py +0 -404
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_shared_library_retrieval_phase123.py +0 -441
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_shared_library_routing_phase123.py +0 -279
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_shared_resource_indexing_phase122.py +0 -188
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_skill_recommendation.py +0 -225
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_skill_routing_cl003_shared_lib.py +0 -338
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_skills_toolset.py +0 -319
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_stability_metric.py +0 -60
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_target_selector.py +0 -958
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_token_tracker.py +0 -121
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_token_wiring.py +0 -119
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_tool_first_planner.py +0 -7103
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_topology_knowledge_persistence.py +0 -332
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_topology_query_service.py +0 -55
- package/tools/vds-scripts/audit_orchestrator/tests/unit/engine/test_unverified_ref_retry.py +0 -909
- package/tools/vds-scripts/audit_orchestrator/tests/unit/models/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/models/test_evidence.py +0 -515
- package/tools/vds-scripts/audit_orchestrator/tests/unit/models/test_gaps.py +0 -422
- package/tools/vds-scripts/audit_orchestrator/tests/unit/models/test_readiness.py +0 -428
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_confluence_hierarchy.py +0 -227
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_project_title_generation.py +0 -335
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_publisher_registry_helpers.py +0 -290
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_publisher_registry_integration.py +0 -557
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_readiness_renderer.py +0 -381
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_repo_title_consistency.py +0 -266
- package/tools/vds-scripts/audit_orchestrator/tests/unit/publishers/test_upload_hierarchy_integration.py +0 -470
- package/tools/vds-scripts/audit_orchestrator/tests/unit/scripts/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/scripts/test_benchmark_dspy.py +0 -177
- package/tools/vds-scripts/audit_orchestrator/tests/unit/scripts/test_benchmark_nlp_accuracy.py +0 -72
- package/tools/vds-scripts/audit_orchestrator/tests/unit/scripts/test_benchmark_retrieval_modes.py +0 -123
- package/tools/vds-scripts/audit_orchestrator/tests/unit/scripts/test_verify_phase111_requirement_analysis.py +0 -409
- package/tools/vds-scripts/audit_orchestrator/tests/unit/seed/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/seed/test_seed_chain_cli.py +0 -277
- package/tools/vds-scripts/audit_orchestrator/tests/unit/seed/test_seed_loader.py +0 -502
- package/tools/vds-scripts/audit_orchestrator/tests/unit/skills/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/skills/test_skill_routing.py +0 -209
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sources/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sources/test_bitbucket_source.py +0 -66
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sources/test_non_retryable_markers.py +0 -88
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sources/test_repo_info.py +0 -212
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_completeness.py +0 -598
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_dispatch_events_contract_phase169.py +0 -100
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_dispatch_hardening_phase158.py +0 -392
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_dispatch_persistence_phase157.py +0 -914
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_embedding_client.py +0 -64
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_get_latest_completed_run.py +0 -313
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_heartbeat_phase169.py +0 -109
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_hybrid_search.py +0 -398
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_normalize_url.py +0 -262
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_phase152_query_surface.py +0 -59
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_phase98_confluence_document_model.py +0 -202
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_published_pages.py +0 -754
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_readiness_helpers.py +0 -193
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_run_ledger.py +0 -522
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_run_management.py +0 -378
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_schema_contract_phase170.py +0 -755
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_state_cmds.py +0 -231
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_state_loaders.py +0 -2151
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_state_run_api.py +0 -2226
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_store.py +0 -1435
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_store_dispatch.py +0 -646
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_store_dispatch_status_view.py +0 -181
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_store_scope.py +0 -213
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_utilization_persist_phase169.py +0 -77
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_vds_search.py +0 -263
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_vector_index_api.py +0 -319
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_vector_index_runtime.py +0 -175
- package/tools/vds-scripts/audit_orchestrator/tests/unit/state/test_vector_index_store.py +0 -1756
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sync/__init__.py +0 -0
- package/tools/vds-scripts/audit_orchestrator/tests/unit/sync/test_repo_sync.py +0 -257
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_artifact_exclusion.py +0 -119
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_auto_promote_phase158.py +0 -337
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_carry_forward_artifact_filtering.py +0 -317
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_checklist_precache_p160a.py +0 -416
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_cli_decomposition_fr219.py +0 -269
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_code_chunk_carry_forward.py +0 -203
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_config_coherence.py +0 -180
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_config_secret_policy.py +0 -522
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_corpus_project_id_migration.py +0 -318
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_corpus_status_diagnostics.py +0 -239
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_department_priority_ordering.py +0 -131
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_dispatch_coordinator_phase158.py +0 -402
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_dispatch_job_identity_p167a.py +0 -238
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_dispatch_ramp_up_phase171.py +0 -434
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_dispatcher.py +0 -911
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_doc_type_en_inference.py +0 -246
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_early_exit_unchunked_repos.py +0 -111
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_errors.py +0 -237
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_errors_taxonomy.py +0 -83
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_extract_chunking_config_phase98.py +0 -73
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_extract_cmds_state_helpers.py +0 -33
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_extract_docs_code_chunking.py +0 -260
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_finalize_dispatch_run_phase168.py +0 -341
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_identity.py +0 -221
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_infrastructure_detection.py +0 -441
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_junction_table_phase95.py +0 -259
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_late_binding_assignment_p167c.py +0 -286
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_misc_cmds_fr224_225_hardening.py +0 -194
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_p172_integration.py +0 -306
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_parent_provider_preflight.py +0 -118
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_performance_gates_phase92.py +0 -141
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_performance_gates_phase93.py +0 -50
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase115_search_strategy.py +0 -106
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase154_title_consistency.py +0 -117
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase155_param_forwarding.py +0 -304
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase158_concurrency_defaults.py +0 -207
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase170_doctor_schema.py +0 -319
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase170_regression.py +0 -334
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase94_corpus_lifecycle.py +0 -307
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_phase96_repo_key_migration.py +0 -305
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_pipelined_scheduling.py +0 -130
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_profile_availability_probe.py +0 -616
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_profile_aware_row_timeout.py +0 -102
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_profile_timeout_stagger_p160cd.py +0 -205
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_progress_summary_phase169.py +0 -96
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_registry_checklist_diagnostics.py +0 -124
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_resume_manifest_p167b.py +0 -268
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_risk_mitigations_p160e1.py +0 -348
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_single_row_shards_p160b.py +0 -357
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_state_repo_discovery.py +0 -504
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_sync_metadata_entries.py +0 -57
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_task_models.py +0 -1796
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_utilization_telemetry_p167e.py +0 -259
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_vietnamese_fts_hardening.py +0 -160
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_workflow_phase98_enrichment.py +0 -92
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_workflow_project_merge_materialization.py +0 -322
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_workflow_row_key_migration_guard.py +0 -88
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_workflow_short_circuit_phase121.py +0 -564
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_workflow_single_target_row_context.py +0 -49
- package/tools/vds-scripts/audit_orchestrator/tests/unit/test_zero_result_messaging.py +0 -76
- package/tools/vds-scripts/bandit-report.json +0 -2974
- package/tools/vds-scripts/brd_orchestrator/README.md +0 -29
- package/tools/vds-scripts/brd_orchestrator/pyproject.toml +0 -63
- package/tools/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/__init__.py +0 -17
- package/tools/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/cli.py +0 -187
- package/tools/vds-scripts/brd_orchestrator/src/vds_brd_orchestrator/validator.py +0 -121
- package/tools/vds-scripts/brd_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/brd_orchestrator/tests/test_cli.py +0 -62
- package/tools/vds-scripts/brd_orchestrator/tests/test_validator.py +0 -33
- package/tools/vds-scripts/circular_dependency_orchestrator/README.md +0 -30
- package/tools/vds-scripts/circular_dependency_orchestrator/pyproject.toml +0 -43
- package/tools/vds-scripts/circular_dependency_orchestrator/src/vds_circular_dependency_orchestrator/__init__.py +0 -16
- package/tools/vds-scripts/circular_dependency_orchestrator/src/vds_circular_dependency_orchestrator/cli.py +0 -904
- package/tools/vds-scripts/circular_dependency_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/circular_dependency_orchestrator/tests/unit/__init__.py +0 -0
- package/tools/vds-scripts/circular_dependency_orchestrator/tests/unit/test_cli.py +0 -354
- package/tools/vds-scripts/coverage.json +0 -1
- package/tools/vds-scripts/create_pr.py +0 -57
- package/tools/vds-scripts/diagram_generator/README.md +0 -663
- package/tools/vds-scripts/diagram_generator/ci_validate.sh +0 -16
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.png +0 -0
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-component.puml +0 -23
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.png +0 -0
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-sequence.puml +0 -21
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.png +0 -0
- package/tools/vds-scripts/diagram_generator/docs-nttc/projects/INSURANCE/analysis/current-state/insurance-claim-business/insurance-claim-business-usecase.puml +0 -14
- package/tools/vds-scripts/diagram_generator/examples/github-actions-validate.yml +0 -39
- package/tools/vds-scripts/diagram_generator/generate_all_diagrams.py +0 -827
- package/tools/vds-scripts/diagram_generator/generate_insurance_c4_diagrams.py +0 -261
- package/tools/vds-scripts/diagram_generator/generate_insurance_c4_quick.py +0 -486
- package/tools/vds-scripts/diagram_generator/pyproject.toml +0 -28
- package/tools/vds-scripts/diagram_generator/render_png.py +0 -59
- package/tools/vds-scripts/diagram_generator/src/vds_diagram_generator/__init__.py +0 -3
- package/tools/vds-scripts/diagram_generator/src/vds_diagram_generator/cli.py +0 -50
- package/tools/vds-scripts/diagram_generator/test_c4_hierarchical.py +0 -142
- package/tools/vds-scripts/diagram_generator/test_c4_quick.py +0 -131
- package/tools/vds-scripts/diagram_generator/tests/__init__.py +0 -0
- package/tools/vds-scripts/diagram_generator/tests/test_analyzer_completeness.py +0 -260
- package/tools/vds-scripts/diagram_generator/tests/test_c4_syntax_correctness.py +0 -138
- package/tools/vds-scripts/diagram_generator/tests/test_component_coverage.py +0 -182
- package/tools/vds-scripts/diagram_generator/tests/test_mermaid_output.py +0 -80
- package/tools/vds-scripts/diagram_generator/tests/test_png_generation.py +0 -112
- package/tools/vds-scripts/diagram_generator/tests/test_scenario_templates.py +0 -15
- package/tools/vds-scripts/diagram_generator/tests/test_sequence_accuracy.py +0 -93
- package/tools/vds-scripts/diagram_generator/tests/test_structurizr_export.py +0 -177
- package/tools/vds-scripts/diagram_generator/tests/test_style_consistency.py +0 -174
- package/tools/vds-scripts/diagram_generator/tests/test_usecase_generator.py +0 -201
- package/tools/vds-scripts/diagram_generator/tests/test_usecase_integration.py +0 -124
- package/tools/vds-scripts/docker/compose.phase2-verification.yml +0 -31
- package/tools/vds-scripts/docker-compose.openapi-validator.yml +0 -14
- package/tools/vds-scripts/excel_orchestrator/README.md +0 -288
- package/tools/vds-scripts/excel_orchestrator/RESEARCH_BASED_UPDATES_REPORT.md +0 -261
- package/tools/vds-scripts/excel_orchestrator/add_essential_missing_effort.py +0 -255
- package/tools/vds-scripts/excel_orchestrator/adjust_effort_complexity.py +0 -184
- package/tools/vds-scripts/excel_orchestrator/brd_analysis_and_task_breakdown.py +0 -632
- package/tools/vds-scripts/excel_orchestrator/brd_analysis_comprehensive.py +0 -1029
- package/tools/vds-scripts/excel_orchestrator/check_overlaps_and_brd_coverage.py +0 -570
- package/tools/vds-scripts/excel_orchestrator/clean_remarks_column.py +0 -127
- package/tools/vds-scripts/excel_orchestrator/comprehensive_brd_check.py +0 -322
- package/tools/vds-scripts/excel_orchestrator/create_buffered_summary.py +0 -119
- package/tools/vds-scripts/excel_orchestrator/create_service_totals_sheet.py +0 -118
- package/tools/vds-scripts/excel_orchestrator/examples/basic_operations.py +0 -85
- package/tools/vds-scripts/excel_orchestrator/expand_all_tasks.py +0 -341
- package/tools/vds-scripts/excel_orchestrator/expand_tasks.py +0 -304
- package/tools/vds-scripts/excel_orchestrator/fill_brd_references.py +0 -347
- package/tools/vds-scripts/excel_orchestrator/fill_remarks_and_colors.py +0 -132
- package/tools/vds-scripts/excel_orchestrator/finalize_brd_and_cleanup.py +0 -295
- package/tools/vds-scripts/excel_orchestrator/finalize_brd_coverage.py +0 -327
- package/tools/vds-scripts/excel_orchestrator/fix_all_formulas.py +0 -99
- package/tools/vds-scripts/excel_orchestrator/fix_detail_presentation.py +0 -113
- package/tools/vds-scripts/excel_orchestrator/fix_presentation_and_effort.py +0 -116
- package/tools/vds-scripts/excel_orchestrator/fix_presentation_consistency.py +0 -231
- package/tools/vds-scripts/excel_orchestrator/fix_remarks_matching.py +0 -179
- package/tools/vds-scripts/excel_orchestrator/group_tasks_by_service_id.py +0 -210
- package/tools/vds-scripts/excel_orchestrator/increase_brd_coverage.py +0 -497
- package/tools/vds-scripts/excel_orchestrator/increase_effort_complexity.py +0 -155
- package/tools/vds-scripts/excel_orchestrator/organize_and_deduplicate.py +0 -273
- package/tools/vds-scripts/excel_orchestrator/pyproject.toml +0 -64
- package/tools/vds-scripts/excel_orchestrator/rebuild_all_formulas.py +0 -146
- package/tools/vds-scripts/excel_orchestrator/remove_base_multiplier_and_check_duplicates.py +0 -310
- package/tools/vds-scripts/excel_orchestrator/remove_duplicate_brd_tasks.py +0 -137
- package/tools/vds-scripts/excel_orchestrator/research_based_updates.py +0 -457
- package/tools/vds-scripts/excel_orchestrator/restore_e_values.py +0 -172
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/__init__.py +0 -5
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/cli.py +0 -746
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/config.py +0 -74
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/converters.py +0 -226
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/errors.py +0 -88
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/excel_client.py +0 -443
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/formatters.py +0 -211
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/logging.py +0 -57
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/source_contract.py +0 -29
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/target_state_status.py +0 -837
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/ulnc_alignment.py +0 -1291
- package/tools/vds-scripts/excel_orchestrator/src/vds_excel_orchestrator/validators.py +0 -164
- package/tools/vds-scripts/excel_orchestrator/sync_detail_and_total_sheets.py +0 -211
- package/tools/vds-scripts/excel_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/excel_orchestrator/tests/conftest.py +0 -36
- package/tools/vds-scripts/excel_orchestrator/tests/test_cli.py +0 -383
- package/tools/vds-scripts/excel_orchestrator/tests/test_excel_client.py +0 -129
- package/tools/vds-scripts/excel_orchestrator/tests/test_ulnc_alignment.py +0 -373
- package/tools/vds-scripts/excel_orchestrator/tests/test_validators.py +0 -64
- package/tools/vds-scripts/excel_orchestrator/update_api_database_effort.py +0 -261
- package/tools/vds-scripts/excel_orchestrator/update_buffers_inline.py +0 -115
- package/tools/vds-scripts/excel_orchestrator/update_complex_services_and_add_new.py +0 -336
- package/tools/vds-scripts/excel_orchestrator/update_responsibility_and_fix_rows.py +0 -208
- package/tools/vds-scripts/excel_orchestrator/update_task_breakdown_vietnamese.py +0 -309
- package/tools/vds-scripts/excel_orchestrator/update_vietnamese_and_responsibility.py +0 -415
- package/tools/vds-scripts/excel_orchestrator/verify_brd_coverage_comprehensive.py +0 -401
- package/tools/vds-scripts/hexagonal_orchestrator/README.md +0 -530
- package/tools/vds-scripts/hexagonal_orchestrator/pyproject.toml +0 -48
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/__init__.py +0 -39
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/analyzers/__init__.py +0 -19
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/analyzers/base.py +0 -95
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/analyzers/fallback.py +0 -614
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/analyzers/java.py +0 -372
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/analyzers/python.py +0 -437
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/cache.py +0 -331
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/classifier.py +0 -263
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/cli.py +0 -554
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/config.py +0 -577
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/models.py +0 -159
- package/tools/vds-scripts/hexagonal_orchestrator/src/vds_hexagonal_orchestrator/profiler.py +0 -451
- package/tools/vds-scripts/hexagonal_orchestrator/test-config.yaml +0 -38
- package/tools/vds-scripts/hexagonal_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/adapter/driven/persistence/InMemoryUserRepository.java +0 -62
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/adapter/driving/api/UserController.java +0 -101
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/application/port/EmailService.java +0 -33
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/application/port/UserRepository.java +0 -45
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/application/usecase/CreateUser.java +0 -58
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/domain/entity/Email.java +0 -80
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-compliant/domain/entity/User.java +0 -98
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-noncompliant/domain/User.java +0 -64
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-with-frameworks/domain/Menu.java +0 -13
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/java-with-frameworks/domain/Product.java +0 -16
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/application/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/application/ports/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/application/ports/email_service.py +0 -60
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/application/ports/user_repository.py +0 -78
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/domain/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/domain/entities/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/domain/entities/user.py +0 -56
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/domain/value_objects/__init__.py +0 -1
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-compliant/domain/value_objects/email.py +0 -63
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-noncompliant/application/user_service.py +0 -1837
- package/tools/vds-scripts/hexagonal_orchestrator/tests/fixtures/python-noncompliant/domain/user.py +0 -43
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_cache.py +0 -458
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_cli_integration.py +0 -942
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_cli_unit.py +0 -557
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_cross_repo_pollution.py +0 -275
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_foundation.py +0 -129
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_integration.py +0 -1524
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_java_analyzer.py +0 -642
- package/tools/vds-scripts/hexagonal_orchestrator/tests/test_timing_unit.py +0 -60
- package/tools/vds-scripts/intellij_orchestrator/README.md +0 -55
- package/tools/vds-scripts/intellij_orchestrator/pyproject.toml +0 -64
- package/tools/vds-scripts/intellij_orchestrator/src/vds_intellij_orchestrator/__init__.py +0 -17
- package/tools/vds-scripts/intellij_orchestrator/src/vds_intellij_orchestrator/cli.py +0 -210
- package/tools/vds-scripts/intellij_orchestrator/src/vds_intellij_orchestrator/core.py +0 -260
- package/tools/vds-scripts/intellij_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/intellij_orchestrator/tests/test_cli.py +0 -112
- package/tools/vds-scripts/intellij_orchestrator/tests/test_core.py +0 -83
- package/tools/vds-scripts/links_orchestrator/README.md +0 -63
- package/tools/vds-scripts/links_orchestrator/pyproject.toml +0 -64
- package/tools/vds-scripts/links_orchestrator/src/vds_links_orchestrator/__init__.py +0 -10
- package/tools/vds-scripts/links_orchestrator/src/vds_links_orchestrator/cli.py +0 -254
- package/tools/vds-scripts/links_orchestrator/src/vds_links_orchestrator/validator.py +0 -244
- package/tools/vds-scripts/links_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/links_orchestrator/tests/test_cli.py +0 -128
- package/tools/vds-scripts/links_orchestrator/tests/test_validator.py +0 -76
- package/tools/vds-scripts/lsp_orchestrator/.dockerignore +0 -69
- package/tools/vds-scripts/lsp_orchestrator/ARCHITECTURE.md +0 -383
- package/tools/vds-scripts/lsp_orchestrator/CODE_QUALITY_IMPROVEMENTS.md +0 -196
- package/tools/vds-scripts/lsp_orchestrator/COMMANDS.md +0 -870
- package/tools/vds-scripts/lsp_orchestrator/Dockerfile +0 -59
- package/tools/vds-scripts/lsp_orchestrator/IMPLEMENTATION_SUMMARY.md +0 -490
- package/tools/vds-scripts/lsp_orchestrator/LSP_ISSUES_AND_FINDINGS.md +0 -380
- package/tools/vds-scripts/lsp_orchestrator/README.md +0 -616
- package/tools/vds-scripts/lsp_orchestrator/SETUP.md +0 -143
- package/tools/vds-scripts/lsp_orchestrator/TEST_COVERAGE_SUMMARY.md +0 -255
- package/tools/vds-scripts/lsp_orchestrator/VERIFICATION_CHECKLIST.md +0 -814
- package/tools/vds-scripts/lsp_orchestrator/docker-compose.yml +0 -102
- package/tools/vds-scripts/lsp_orchestrator/docs/FOR_LLMS.md +0 -401
- package/tools/vds-scripts/lsp_orchestrator/docs/explanation/lsp-response-matching.md +0 -79
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/automate-with-json.md +0 -159
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/docker-mode.md +0 -256
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/navigate-code.md +0 -116
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/parallel-processing.md +0 -179
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/project-tool-detection.md +0 -320
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/type-check-code.md +0 -46
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/use-daemon-mode.md +0 -78
- package/tools/vds-scripts/lsp_orchestrator/docs/how-to-guides/wsl2-optimization.md +0 -227
- package/tools/vds-scripts/lsp_orchestrator/docs/index.md +0 -88
- package/tools/vds-scripts/lsp_orchestrator/docs/operator-hover-definition.md +0 -143
- package/tools/vds-scripts/lsp_orchestrator/docs/reference/commands.md +0 -581
- package/tools/vds-scripts/lsp_orchestrator/docs/reference/configuration.md +0 -422
- package/tools/vds-scripts/lsp_orchestrator/docs/tutorials/00-quick-start.md +0 -169
- package/tools/vds-scripts/lsp_orchestrator/pyproject.toml +0 -63
- package/tools/vds-scripts/lsp_orchestrator/src/test_file.py +0 -5
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/__init__.py +0 -3
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/aggregator.py +0 -340
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/basedpyright_runner.py +0 -167
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/cli.py +0 -3370
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/code_actions.py +0 -79
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/core.py +0 -3295
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/daemon_client.py +0 -672
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/daemon_manager.py +0 -577
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/daemon_server.py +0 -1040
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/detectors/__init__.py +0 -9
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/detectors/project_detector.py +0 -537
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/formatters.py +0 -141
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/ipc_protocol.py +0 -225
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/lsp_client.py +0 -957
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/lsp_router.py +0 -335
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/mcp_server.py +0 -181
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/models/__init__.py +0 -201
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/models/project_detector.py +0 -646
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/models/project_tools.py +0 -114
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/models.py +0 -399
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/mypy_runner.py +0 -209
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/protocols.py +0 -52
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/ruff_lsp_client.py +0 -109
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/ruff_runner.py +0 -44
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/utils.py +0 -959
- package/tools/vds-scripts/lsp_orchestrator/src/vds_lsp_orchestrator/workspace_indexer.py +0 -1037
- package/tools/vds-scripts/lsp_orchestrator/test_workspace_lsp.py +0 -6
- package/tools/vds-scripts/lsp_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/lsp_orchestrator/tests/conftest.py +0 -6
- package/tools/vds-scripts/lsp_orchestrator/tests/test_aggregator.py +0 -59
- package/tools/vds-scripts/lsp_orchestrator/tests/test_cli.py +0 -111
- package/tools/vds-scripts/lsp_orchestrator/tests/test_detect_tools_command.py +0 -186
- package/tools/vds-scripts/lsp_orchestrator/tests/test_formatter_linter_detection.py +0 -519
- package/tools/vds-scripts/lsp_orchestrator/tests/test_integration_phase9_10_11.py +0 -367
- package/tools/vds-scripts/lsp_orchestrator/tests/test_mypy_runner.py +0 -482
- package/tools/vds-scripts/lsp_orchestrator/tests/test_package_manager_detection.py +0 -399
- package/tools/vds-scripts/lsp_orchestrator/tests/test_phase10.py +0 -389
- package/tools/vds-scripts/lsp_orchestrator/tests/test_phase11.py +0 -327
- package/tools/vds-scripts/lsp_orchestrator/tests/test_phase12_integration.py +0 -634
- package/tools/vds-scripts/lsp_orchestrator/tests/test_phase9.py +0 -196
- package/tools/vds-scripts/lsp_orchestrator/tests/test_project_detector.py +0 -377
- package/tools/vds-scripts/lsp_orchestrator/tests/test_test_runner_detection.py +0 -549
- package/tools/vds-scripts/lsp_orchestrator/tests/test_type_checker_routing.py +0 -362
- package/tools/vds-scripts/lsp_orchestrator/tests/test_workspace_indexer.py +0 -144
- package/tools/vds-scripts/markdown_orchestrator/README.md +0 -72
- package/tools/vds-scripts/markdown_orchestrator/pyproject.toml +0 -39
- package/tools/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/__init__.py +0 -5
- package/tools/vds-scripts/markdown_orchestrator/src/vds_markdown_orchestrator/cli.py +0 -102
- package/tools/vds-scripts/multi_agent_orchestrator/Dockerfile +0 -65
- package/tools/vds-scripts/multi_agent_orchestrator/README.md +0 -306
- package/tools/vds-scripts/multi_agent_orchestrator/postman/README.md +0 -264
- package/tools/vds-scripts/multi_agent_orchestrator/postman/TEST_RESULTS_SUMMARY.md +0 -197
- package/tools/vds-scripts/multi_agent_orchestrator/postman/VDS-Multi-Agent-Orchestrator-API.postman_collection.json +0 -1010
- package/tools/vds-scripts/multi_agent_orchestrator/postman/environments/local-development.postman_environment.json +0 -55
- package/tools/vds-scripts/multi_agent_orchestrator/postman/test-results.json +0 -24146
- package/tools/vds-scripts/multi_agent_orchestrator/pyproject.toml +0 -63
- package/tools/vds-scripts/multi_agent_orchestrator/run_api.py +0 -9
- package/tools/vds-scripts/multi_agent_orchestrator/run_mock_api.py +0 -9
- package/tools/vds-scripts/multi_agent_orchestrator/simple_test.py +0 -53
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/__init__.py +0 -25
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/agent_pool.py +0 -433
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/api/__init__.py +0 -5
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/api/main.py +0 -722
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/api/mock_main.py +0 -812
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/change_log.py +0 -515
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/cli.py +0 -424
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/config.py +0 -220
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/conflict_resolver.py +0 -462
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/coordinator.py +0 -627
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/models.py +0 -389
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/progress_dashboard.py +0 -380
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/redis_client.py +0 -245
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/scheduler_subscriber.py +0 -272
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/task_manager.py +0 -536
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/task_tracking.py +0 -550
- package/tools/vds-scripts/multi_agent_orchestrator/src/vds_multi_agent_orchestrator/vds_ai_memory_client.py +0 -352
- package/tools/vds-scripts/multi_agent_orchestrator/test_complete_system.py +0 -149
- package/tools/vds-scripts/multi_agent_orchestrator/test_infrastructure_only.py +0 -194
- package/tools/vds-scripts/multi_agent_orchestrator/test_integration.py +0 -108
- package/tools/vds-scripts/multi_agent_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/multi_agent_orchestrator/tests/test_agent_registration_credential_validator.py +0 -223
- package/tools/vds-scripts/multi_agent_orchestrator/tests/test_config.py +0 -210
- package/tools/vds-scripts/multi_agent_orchestrator/tests/test_models.py +0 -195
- package/tools/vds-scripts/multi_agent_orchestrator/tests/test_w9_agent_routes.py +0 -321
- package/tools/vds-scripts/openapi_orchestrator/README.md +0 -197
- package/tools/vds-scripts/openapi_orchestrator/pyproject.toml +0 -106
- package/tools/vds-scripts/openapi_orchestrator/src/vds_openapi_orchestrator/__init__.py +0 -29
- package/tools/vds-scripts/openapi_orchestrator/src/vds_openapi_orchestrator/cli.py +0 -345
- package/tools/vds-scripts/openapi_orchestrator/src/vds_openapi_orchestrator/full_validator.py +0 -183
- package/tools/vds-scripts/openapi_orchestrator/src/vds_openapi_orchestrator/spec_validator.py +0 -197
- package/tools/vds-scripts/openapi_orchestrator/tests/__init__.py +0 -1
- package/tools/vds-scripts/openapi_orchestrator/tests/test_cli.py +0 -234
- package/tools/vds-scripts/openapi_orchestrator/tests/test_full_validator.py +0 -203
- package/tools/vds-scripts/openapi_orchestrator/tests/test_spec_validator.py +0 -295
- package/tools/vds-scripts/pdf_orchestrator/.dockerignore +0 -93
- package/tools/vds-scripts/pdf_orchestrator/.env.example +0 -40
- package/tools/vds-scripts/pdf_orchestrator/.ruff_rules.py +0 -350
- package/tools/vds-scripts/pdf_orchestrator/.yamllint.yml +0 -43
- package/tools/vds-scripts/pdf_orchestrator/DEVELOPMENT_PLAN.md +0 -80
- package/tools/vds-scripts/pdf_orchestrator/Dockerfile +0 -87
- package/tools/vds-scripts/pdf_orchestrator/README.md +0 -608
- package/tools/vds-scripts/pdf_orchestrator/cli_verification_test/test.md +0 -6
- package/tools/vds-scripts/pdf_orchestrator/cli_verification_test/test.pdf +0 -0
- package/tools/vds-scripts/pdf_orchestrator/config/alertmanager.yml +0 -83
- package/tools/vds-scripts/pdf_orchestrator/config/prometheus.prod.yml +0 -98
- package/tools/vds-scripts/pdf_orchestrator/config/prometheus.yml +0 -40
- package/tools/vds-scripts/pdf_orchestrator/config/redis.conf +0 -78
- package/tools/vds-scripts/pdf_orchestrator/docs/COMPETITIVE_ANALYSIS_REPORT.md +0 -309
- package/tools/vds-scripts/pdf_orchestrator/docs/FEATURES_GUIDE.md +0 -518
- package/tools/vds-scripts/pdf_orchestrator/docs/MULTI_USER_DEPLOYMENT_GUIDE.md +0 -615
- package/tools/vds-scripts/pdf_orchestrator/docs/USER_GUIDE.md +0 -829
- package/tools/vds-scripts/pdf_orchestrator/pyproject.toml +0 -87
- package/tools/vds-scripts/pdf_orchestrator/pytest.ini +0 -71
- package/tools/vds-scripts/pdf_orchestrator/ruff.toml +0 -6
- package/tools/vds-scripts/pdf_orchestrator/scripts/debug_security_report.py +0 -59
- package/tools/vds-scripts/pdf_orchestrator/scripts/demo_library_selector.py +0 -109
- package/tools/vds-scripts/pdf_orchestrator/scripts/generate_project_stats.py +0 -52
- package/tools/vds-scripts/pdf_orchestrator/scripts/generate_styled_pdf.py +0 -95
- package/tools/vds-scripts/pdf_orchestrator/scripts/migrate_render_pdfs.py +0 -285
- package/tools/vds-scripts/pdf_orchestrator/scripts/setup_team.bat +0 -283
- package/tools/vds-scripts/pdf_orchestrator/scripts/setup_team.sh +0 -324
- package/tools/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/__init__.py +0 -5
- package/tools/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/cli.py +0 -542
- package/tools/vds-scripts/pdf_orchestrator/src/vds_pdf_orchestrator/config.py +0 -33
- package/tools/vds-scripts/pdf_orchestrator/tests/README.md +0 -650
- package/tools/vds-scripts/pdf_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/pdf_orchestrator/tests/conftest.py +0 -520
- package/tools/vds-scripts/pdf_orchestrator/tests/requirements.txt +0 -51
- package/tools/vds-scripts/pdf_orchestrator/tests/run_tests.py +0 -659
- package/tools/vds-scripts/pdf_orchestrator/tests/test_config.py +0 -36
- package/tools/vds-scripts/progress_report_orchestrator/Dockerfile +0 -77
- package/tools/vds-scripts/progress_report_orchestrator/README.md +0 -39
- package/tools/vds-scripts/progress_report_orchestrator/alembic/env.py +0 -42
- package/tools/vds-scripts/progress_report_orchestrator/alembic/script.py.mako +0 -28
- package/tools/vds-scripts/progress_report_orchestrator/alembic/versions/0001_initial_progress_schema.py +0 -180
- package/tools/vds-scripts/progress_report_orchestrator/alembic.ini +0 -67
- package/tools/vds-scripts/progress_report_orchestrator/pyproject.toml +0 -67
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/__init__.py +0 -3
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/analyzers/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/analyzers/endpoint_scanner.py +0 -238
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/analyzers/git_activity.py +0 -159
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/analyzers/hexagonal.py +0 -100
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/analyzers/test_scanner.py +0 -136
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/cli.py +0 -743
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/config.py +0 -50
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/db/__init__.py +0 -12
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/db/alembic_filters.py +0 -64
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/memory.py +0 -82
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/models/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/models/analysis.py +0 -84
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/models/report.py +0 -117
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/models/topology.py +0 -101
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/parsers/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/parsers/kg_parser.py +0 -252
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/parsers/uc_reader.py +0 -159
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/concurrency.py +0 -39
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/llm_eval.py +0 -570
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/report.py +0 -1256
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/structural.py +0 -384
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/pipeline/sync.py +0 -143
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/recommendations/__init__.py +0 -5
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/recommendations/engine.py +0 -105
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/recommendations/templates.py +0 -236
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/scheduler_subscriber.py +0 -238
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/skills/README.md +0 -56
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/skills/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/skills/srs-architecture-reviewer/SKILL.md +0 -67
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/skills/srs-endpoint-matcher/SKILL.md +0 -67
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/state/__init__.py +0 -1
- package/tools/vds-scripts/progress_report_orchestrator/src/progress_report_orchestrator/state/schema.py +0 -625
- package/tools/vds-scripts/progress_report_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/__init__.py +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/.gitkeep +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/__init__.py +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/doc-dependencies.yaml +0 -79
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/fr-to-docs.yaml +0 -478
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/fr-to-services.yaml +0 -18
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/kg/registry.yaml +0 -346
- package/tools/vds-scripts/progress_report_orchestrator/tests/fixtures/phase3_baseline_standard.md +0 -564
- package/tools/vds-scripts/progress_report_orchestrator/tests/integration/__init__.py +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/integration/test_checkpoint.py +0 -276
- package/tools/vds-scripts/progress_report_orchestrator/tests/test_alembic_migrations.py +0 -265
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/__init__.py +0 -0
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_analyzers.py +0 -267
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_bounded_gather.py +0 -176
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_cli_phase_report.py +0 -119
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_delta.py +0 -169
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_error_handling.py +0 -150
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_gate_exit_codes.py +0 -230
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_git_activity.py +0 -215
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_kg_parser.py +0 -267
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_llm_autodetect.py +0 -183
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_llm_eval.py +0 -529
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_memory_integration.py +0 -151
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_migration_contract.py +0 -254
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_mode_rendering.py +0 -576
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_models.py +0 -251
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_progress_llm_config.py +0 -67
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_recommendations.py +0 -480
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_report_enhancements.py +0 -415
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_resume_reload.py +0 -343
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_trend_regression.py +0 -294
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_uc_reader.py +0 -169
- package/tools/vds-scripts/progress_report_orchestrator/tests/unit/test_valence_gap.py +0 -293
- package/tools/vds-scripts/project-cycle-report.json +0 -14
- package/tools/vds-scripts/project-dependency-graph.json +0 -11361
- package/tools/vds-scripts/project-topology.json +0 -99
- package/tools/vds-scripts/public_interface_boundary_orchestrator/pyproject.toml +0 -18
- package/tools/vds-scripts/public_interface_boundary_orchestrator/src/vds_public_interface_boundary_orchestrator/__init__.py +0 -0
- package/tools/vds-scripts/public_interface_boundary_orchestrator/src/vds_public_interface_boundary_orchestrator/cli.py +0 -232
- package/tools/vds-scripts/public_interface_boundary_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/public_interface_boundary_orchestrator/tests/test_cli.py +0 -108
- package/tools/vds-scripts/research_orchestrator/README.md +0 -68
- package/tools/vds-scripts/research_orchestrator/py.typed +0 -0
- package/tools/vds-scripts/research_orchestrator/pyproject.toml +0 -95
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/__init__.py +0 -3
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/_env.py +0 -11
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/cli.py +0 -335
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/config.py +0 -43
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/evidence/__init__.py +0 -0
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/evidence/models.py +0 -89
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/evidence/scoring.py +0 -102
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/exceptions.py +0 -78
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/http_client.py +0 -160
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/logging.py +0 -49
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/output/__init__.py +0 -0
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/output/formatters.py +0 -93
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/py.typed +0 -1
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/report/__init__.py +0 -0
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/report/build.py +0 -156
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/report/format.py +0 -147
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/tools/__init__.py +0 -0
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/tools/health.py +0 -66
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/tools/health_graph.py +0 -52
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/tools/registry.py +0 -127
- package/tools/vds-scripts/research_orchestrator/src/vds_research_orchestrator/tools/search.py +0 -230
- package/tools/vds-scripts/research_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/research_orchestrator/tests/conftest.py +0 -53
- package/tools/vds-scripts/research_orchestrator/tests/test_cli.py +0 -222
- package/tools/vds-scripts/research_orchestrator/tests/test_config.py +0 -23
- package/tools/vds-scripts/research_orchestrator/tests/test_exceptions.py +0 -62
- package/tools/vds-scripts/research_orchestrator/tests/test_formatters.py +0 -89
- package/tools/vds-scripts/research_orchestrator/tests/test_graph_integration.py +0 -149
- package/tools/vds-scripts/research_orchestrator/tests/test_http_client.py +0 -134
- package/tools/vds-scripts/research_orchestrator/tests/test_report_build.py +0 -128
- package/tools/vds-scripts/research_orchestrator/tests/test_report_format.py +0 -91
- package/tools/vds-scripts/research_orchestrator/tests/test_scoring.py +0 -95
- package/tools/vds-scripts/research_orchestrator/tests/vds_research_orchestrator/test_tools/__init__.py +0 -1
- package/tools/vds-scripts/research_orchestrator/tests/vds_research_orchestrator/test_tools/test_health.py +0 -139
- package/tools/vds-scripts/research_orchestrator/tests/vds_research_orchestrator/test_tools/test_registry.py +0 -135
- package/tools/vds-scripts/research_orchestrator/tests/vds_research_orchestrator/test_tools/test_search.py +0 -238
- package/tools/vds-scripts/run-history.json +0 -26
- package/tools/vds-scripts/schema_converter/README.md +0 -109
- package/tools/vds-scripts/schema_converter/pyproject.toml +0 -37
- package/tools/vds-scripts/schema_converter/src/vds_schema_converter/__init__.py +0 -3
- package/tools/vds-scripts/schema_converter/src/vds_schema_converter/cli.py +0 -50
- package/tools/vds-scripts/schema_converter/tests/__init__.py +0 -0
- package/tools/vds-scripts/schema_converter/tests/test_json_schema_generator.py +0 -115
- package/tools/vds-scripts/schema_converter/tests/test_mermaid_generator.py +0 -112
- package/tools/vds-scripts/schema_converter/tests/test_parser.py +0 -111
- package/tools/vds-scripts/schema_converter/tests/test_plantuml_generator.py +0 -112
- package/tools/vds-scripts/schema_converter/tests/test_plantuml_validator.py +0 -69
- package/tools/vds-scripts/schema_converter/tests/test_prisma_generator.py +0 -113
- package/tools/vds-scripts/schema_converter/tests/test_sql_generator.py +0 -138
- package/tools/vds-scripts/schema_converter/tests/test_typeorm_generator.py +0 -110
- package/tools/vds-scripts/schema_converter/tests/test_validators.py +0 -96
- package/tools/vds-scripts/spec_orchestrator/README.md +0 -13
- package/tools/vds-scripts/spec_orchestrator/pyproject.toml +0 -40
- package/tools/vds-scripts/spec_orchestrator/src/vds_spec_orchestrator/__init__.py +0 -5
- package/tools/vds-scripts/spec_orchestrator/src/vds_spec_orchestrator/cli.py +0 -162
- package/tools/vds-scripts/spec_orchestrator/src/vds_spec_orchestrator/core.py +0 -575
- package/tools/vds-scripts/spec_orchestrator/src/vds_spec_orchestrator/sync.py +0 -306
- package/tools/vds-scripts/spec_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/spec_orchestrator/tests/test_frontmatter_drift.py +0 -243
- package/tools/vds-scripts/spec_orchestrator/tests/test_sync.py +0 -342
- package/tools/vds-scripts/structure_orchestrator/README.md +0 -60
- package/tools/vds-scripts/structure_orchestrator/pyproject.toml +0 -103
- package/tools/vds-scripts/structure_orchestrator/src/vds_structure_orchestrator/__init__.py +0 -13
- package/tools/vds-scripts/structure_orchestrator/src/vds_structure_orchestrator/cli.py +0 -308
- package/tools/vds-scripts/structure_orchestrator/src/vds_structure_orchestrator/validator.py +0 -257
- package/tools/vds-scripts/structure_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/structure_orchestrator/tests/test_cli.py +0 -161
- package/tools/vds-scripts/structure_orchestrator/tests/test_helpers.py +0 -115
- package/tools/vds-scripts/structure_orchestrator/tests/test_validator.py +0 -104
- package/tools/vds-scripts/task_orchestrator/README.md +0 -50
- package/tools/vds-scripts/task_orchestrator/__init__.py +0 -18
- package/tools/vds-scripts/task_orchestrator/pyproject.toml +0 -43
- package/tools/vds-scripts/task_orchestrator/scripts/run_excel_sync.py +0 -36
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/__init__.py +0 -13
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/audit.py +0 -134
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/cli.py +0 -127
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/debug.py +0 -133
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/normalize.py +0 -113
- package/tools/vds-scripts/task_orchestrator/src/vds_task_orchestrator/refine.py +0 -201
- package/tools/vds-scripts/task_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/task_orchestrator/tests/test_task_orchestrator.py +0 -84
- package/tools/vds-scripts/temp_query_projects.py +0 -2
- package/tools/vds-scripts/test_small.md +0 -1
- package/tools/vds-scripts/text_utils_orchestrator/pyproject.toml +0 -20
- package/tools/vds-scripts/text_utils_orchestrator/src/vds_text_utils/__init__.py +0 -7
- package/tools/vds-scripts/text_utils_orchestrator/src/vds_text_utils/i18n.py +0 -143
- package/tools/vds-scripts/text_utils_orchestrator/tests/__init__.py +0 -0
- package/tools/vds-scripts/text_utils_orchestrator/tests/test_i18n.py +0 -53
- package/tools/vds-scripts/upgrade_major.py +0 -61
- package/tools/vds-scripts/upgrade_major_v2.py +0 -64
- package/tools/vds-scripts/verify_violations.py +0 -57
- package/tools/vds-scripts/workflow-summary.json +0 -325
- package/tools/vds-scripts/workflow-summary.md +0 -8
|
@@ -1,3295 +0,0 @@
|
|
|
1
|
-
"""Core LSP routing and coordination."""
|
|
2
|
-
|
|
3
|
-
import contextlib
|
|
4
|
-
import logging
|
|
5
|
-
import shutil
|
|
6
|
-
import subprocess
|
|
7
|
-
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
from typing import Any, cast
|
|
11
|
-
|
|
12
|
-
from .aggregator import DiagnosticAggregator
|
|
13
|
-
from .basedpyright_runner import BasedPyrightRunner
|
|
14
|
-
from .code_actions import CodeActionExtractor
|
|
15
|
-
from .lsp_client import LspClient
|
|
16
|
-
from .mypy_runner import MypyRunner
|
|
17
|
-
from .protocols import LspClientProtocol
|
|
18
|
-
from .ruff_lsp_client import RuffLSPClient
|
|
19
|
-
from .ruff_runner import RuffRunner
|
|
20
|
-
from .utils import (
|
|
21
|
-
_uri_to_path,
|
|
22
|
-
apply_text_edits,
|
|
23
|
-
apply_workspace_edit,
|
|
24
|
-
build_unified_diff,
|
|
25
|
-
extract_context,
|
|
26
|
-
load_config,
|
|
27
|
-
preview_workspace_edit,
|
|
28
|
-
restore_backup,
|
|
29
|
-
workspace_edit_needs_confirmation,
|
|
30
|
-
)
|
|
31
|
-
from .workspace_indexer import WorkspaceIndexer
|
|
32
|
-
|
|
33
|
-
logger = logging.getLogger(__name__)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class LSPRouter:
|
|
37
|
-
"""Routes LSP commands to appropriate backends."""
|
|
38
|
-
|
|
39
|
-
def __init__(
|
|
40
|
-
self,
|
|
41
|
-
root_path: Path | None = None,
|
|
42
|
-
*,
|
|
43
|
-
config_file: Path | None = None,
|
|
44
|
-
lsp_server: str | None = None,
|
|
45
|
-
force_direct: bool = False,
|
|
46
|
-
):
|
|
47
|
-
self.root = root_path or Path.cwd()
|
|
48
|
-
self.config = load_config(self.root, config_file=config_file, lsp_server=lsp_server)
|
|
49
|
-
|
|
50
|
-
# WorkspaceIndexer expects IndexerConfig - LspConfig is compatible via Protocol
|
|
51
|
-
self.indexer = WorkspaceIndexer(
|
|
52
|
-
self.root,
|
|
53
|
-
self.config, # pyright: ignore[reportArgumentType]
|
|
54
|
-
)
|
|
55
|
-
self.pyright = BasedPyrightRunner(self.root, self.config)
|
|
56
|
-
self.lsp: LspClientProtocol | None = None
|
|
57
|
-
self.code_actions: CodeActionExtractor | None = None
|
|
58
|
-
self.lsp_error: str | None = None
|
|
59
|
-
self.using_daemon = False
|
|
60
|
-
|
|
61
|
-
# Check if daemon mode is enabled (skip if force_direct is True, e.g., inside daemon)
|
|
62
|
-
daemon_check = use_daemon(self.root, config_file=config_file)
|
|
63
|
-
logger.info("Daemon mode check: force_direct=%s, use_daemon=%s", force_direct, daemon_check)
|
|
64
|
-
if not force_direct and daemon_check:
|
|
65
|
-
try:
|
|
66
|
-
daemon_client = get_daemon_client(self.root, config_file=config_file)
|
|
67
|
-
daemon_lsp = DaemonLspClient(self.root, self.config, daemon_client)
|
|
68
|
-
self.lsp = daemon_lsp # pyright: ignore[reportAttributeAccessIssue]
|
|
69
|
-
self.code_actions = CodeActionExtractor(
|
|
70
|
-
self.lsp # pyright: ignore[reportArgumentType]
|
|
71
|
-
)
|
|
72
|
-
self.using_daemon = True
|
|
73
|
-
logger.info("Using daemon mode for LSP operations")
|
|
74
|
-
except (ConnectionError, Exception) as exc:
|
|
75
|
-
logger.warning("Daemon mode enabled but not available: %s", exc)
|
|
76
|
-
# Fall back to direct LSP client
|
|
77
|
-
self.using_daemon = False
|
|
78
|
-
elif force_direct:
|
|
79
|
-
logger.info("Daemon mode bypassed (force_direct=True)")
|
|
80
|
-
else:
|
|
81
|
-
logger.info("Daemon mode not enabled or daemon not running")
|
|
82
|
-
|
|
83
|
-
# If not using daemon, initialize direct LSP client
|
|
84
|
-
if self.lsp is None:
|
|
85
|
-
try:
|
|
86
|
-
self.lsp = LspClient(
|
|
87
|
-
self.root,
|
|
88
|
-
self.config,
|
|
89
|
-
docker_mode=getattr(self.config, "docker_mode", False),
|
|
90
|
-
)
|
|
91
|
-
self.code_actions = CodeActionExtractor(self.lsp)
|
|
92
|
-
except FileNotFoundError as exc:
|
|
93
|
-
self.lsp_error = str(exc)
|
|
94
|
-
logger.warning("LSP server unavailable: %s", exc)
|
|
95
|
-
except Exception as exc:
|
|
96
|
-
self.lsp_error = str(exc)
|
|
97
|
-
logger.warning("LSP client init failed: %s", exc)
|
|
98
|
-
|
|
99
|
-
self.ruff = RuffRunner(self.root)
|
|
100
|
-
self.aggregator = DiagnosticAggregator()
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
class MultiLSPRouter(LSPRouter):
|
|
104
|
-
"""Routes features between BasedPyright and Ruff LSP servers."""
|
|
105
|
-
|
|
106
|
-
def __init__(
|
|
107
|
-
self,
|
|
108
|
-
root_path: Path | None = None,
|
|
109
|
-
*,
|
|
110
|
-
config_file: Path | None = None,
|
|
111
|
-
lsp_server: str | None = None,
|
|
112
|
-
):
|
|
113
|
-
super().__init__(root_path, config_file=config_file, lsp_server=lsp_server)
|
|
114
|
-
self.ruff_lsp: RuffLSPClient | None = None
|
|
115
|
-
self.feature_map: dict[str, str] = {}
|
|
116
|
-
self._init_ruff()
|
|
117
|
-
self._init_feature_map()
|
|
118
|
-
|
|
119
|
-
def _init_ruff(self) -> None:
|
|
120
|
-
# Auto-detect Ruff LSP if not explicitly configured
|
|
121
|
-
enable_ruff = getattr(self.config, "enable_ruff_lsp", None)
|
|
122
|
-
|
|
123
|
-
# Check if explicitly disabled via config file
|
|
124
|
-
# (default False without config file should trigger auto-detection)
|
|
125
|
-
config_file = getattr(self.config, "config_file", None)
|
|
126
|
-
basedpyright_config_path = getattr(self.config, "basedpyright_config_path", None)
|
|
127
|
-
has_config = config_file is not None or basedpyright_config_path is not None
|
|
128
|
-
|
|
129
|
-
if enable_ruff is False and has_config:
|
|
130
|
-
# Explicitly disabled in config file
|
|
131
|
-
return
|
|
132
|
-
if enable_ruff is None or (enable_ruff is False and not has_config):
|
|
133
|
-
# Not explicitly configured OR using default False without config - auto-detect
|
|
134
|
-
from .ruff_lsp_client import _check_ruff_version
|
|
135
|
-
|
|
136
|
-
if not _check_ruff_version():
|
|
137
|
-
logger.debug("Ruff LSP auto-detection: ruff >= 0.5.3 not found")
|
|
138
|
-
return
|
|
139
|
-
logger.info("Ruff LSP auto-detected and enabled")
|
|
140
|
-
|
|
141
|
-
try:
|
|
142
|
-
self.ruff_lsp = RuffLSPClient(self.root, self.config)
|
|
143
|
-
except FileNotFoundError as exc:
|
|
144
|
-
logger.warning("Ruff LSP unavailable: %s", exc)
|
|
145
|
-
self.ruff_lsp = None
|
|
146
|
-
|
|
147
|
-
if self.ruff_lsp:
|
|
148
|
-
self.code_actions = CodeActionExtractor(self.ruff_lsp.lsp)
|
|
149
|
-
|
|
150
|
-
def _init_feature_map(self) -> None:
|
|
151
|
-
self.feature_map = {
|
|
152
|
-
"diagnostics": "ruff" if self.ruff_lsp else "ruff-cli",
|
|
153
|
-
"formatting": "ruff" if self.ruff_lsp else "none",
|
|
154
|
-
"code_actions": "ruff" if self.ruff_lsp else "basedpyright",
|
|
155
|
-
"organize_imports": "ruff" if self.ruff_lsp else "none",
|
|
156
|
-
"fix_all": "ruff" if self.ruff_lsp else "none",
|
|
157
|
-
"hover": "basedpyright",
|
|
158
|
-
"completion": "basedpyright",
|
|
159
|
-
"rename": "basedpyright",
|
|
160
|
-
"signature_help": "basedpyright",
|
|
161
|
-
"inlay_hints": "basedpyright",
|
|
162
|
-
"semantic_tokens": "basedpyright",
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
def health_check(self) -> dict[str, bool]:
|
|
166
|
-
status = {"basedpyright": self.lsp is not None, "ruff": self.ruff_lsp is not None}
|
|
167
|
-
return status
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def _build_router(
|
|
171
|
-
root: Path | None,
|
|
172
|
-
*,
|
|
173
|
-
config_file: Path | None = None,
|
|
174
|
-
lsp_server: str | None = None,
|
|
175
|
-
) -> LSPRouter:
|
|
176
|
-
return MultiLSPRouter(root, config_file=config_file, lsp_server=lsp_server)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def _normalize_call_hierarchy(
|
|
180
|
-
result: list[dict[str, Any]],
|
|
181
|
-
*,
|
|
182
|
-
direction: str,
|
|
183
|
-
root: Path,
|
|
184
|
-
root_symbol: str,
|
|
185
|
-
) -> list[dict[str, Any]]:
|
|
186
|
-
calls: list[dict[str, Any]] = []
|
|
187
|
-
|
|
188
|
-
for entry in result:
|
|
189
|
-
if direction == "incoming":
|
|
190
|
-
item = entry.get("from") or {}
|
|
191
|
-
from_symbol = item.get("name")
|
|
192
|
-
to_symbol = root_symbol
|
|
193
|
-
else:
|
|
194
|
-
item = entry.get("to") or {}
|
|
195
|
-
from_symbol = root_symbol
|
|
196
|
-
to_symbol = item.get("name")
|
|
197
|
-
|
|
198
|
-
if not from_symbol or not to_symbol:
|
|
199
|
-
continue
|
|
200
|
-
|
|
201
|
-
uri = item.get("uri")
|
|
202
|
-
if not uri:
|
|
203
|
-
continue
|
|
204
|
-
|
|
205
|
-
file_path = _uri_to_path(uri)
|
|
206
|
-
external = False
|
|
207
|
-
if file_path.is_absolute():
|
|
208
|
-
try:
|
|
209
|
-
file_path = file_path.relative_to(root)
|
|
210
|
-
except ValueError:
|
|
211
|
-
external = True
|
|
212
|
-
|
|
213
|
-
ranges = entry.get("fromRanges") or []
|
|
214
|
-
range_info = ranges[0] if ranges else item.get("range") or item.get("selectionRange") or {}
|
|
215
|
-
start = range_info.get("start", {})
|
|
216
|
-
end = range_info.get("end", {})
|
|
217
|
-
start_line = start.get("line", 0) + 1
|
|
218
|
-
start_col = start.get("character", 0) + 1
|
|
219
|
-
end_line = end.get("line", start.get("line", 0)) + 1
|
|
220
|
-
end_col = end.get("character", start.get("character", 0)) + 1
|
|
221
|
-
|
|
222
|
-
calls.append(
|
|
223
|
-
{
|
|
224
|
-
"from_symbol": from_symbol,
|
|
225
|
-
"to_symbol": to_symbol,
|
|
226
|
-
"location": {
|
|
227
|
-
"file": file_path.as_posix(),
|
|
228
|
-
"line": start_line,
|
|
229
|
-
"column": start_col,
|
|
230
|
-
"end_line": end_line,
|
|
231
|
-
"end_column": end_col,
|
|
232
|
-
},
|
|
233
|
-
"depth": 1,
|
|
234
|
-
"relation": "direct",
|
|
235
|
-
"path": [from_symbol, to_symbol],
|
|
236
|
-
"external": external,
|
|
237
|
-
},
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
return calls
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
def _call_hierarchy(
|
|
244
|
-
router: LSPRouter,
|
|
245
|
-
symbol: str,
|
|
246
|
-
*,
|
|
247
|
-
direction: str,
|
|
248
|
-
) -> list[dict[str, Any]] | None:
|
|
249
|
-
if not router.lsp:
|
|
250
|
-
return None
|
|
251
|
-
|
|
252
|
-
# Type narrowing: after the check, lsp is guaranteed to be not None
|
|
253
|
-
lsp = router.lsp
|
|
254
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
255
|
-
|
|
256
|
-
matches = router.indexer.find_symbols(symbol)
|
|
257
|
-
if not matches:
|
|
258
|
-
return None
|
|
259
|
-
|
|
260
|
-
location = matches[0]["location"]
|
|
261
|
-
# Ensure location is a dict-like object with required keys
|
|
262
|
-
if not isinstance(location, dict):
|
|
263
|
-
return None
|
|
264
|
-
# Cast to proper dict type for indexing - location values are union types from indexer
|
|
265
|
-
loc = cast(dict[str, Any], location)
|
|
266
|
-
file_path = router.root / loc["file"]
|
|
267
|
-
uri: str | None = None
|
|
268
|
-
|
|
269
|
-
try:
|
|
270
|
-
uri = lsp.open_document(file_path)
|
|
271
|
-
params = {
|
|
272
|
-
"textDocument": {"uri": uri},
|
|
273
|
-
"position": {
|
|
274
|
-
"line": loc["line"] - 1,
|
|
275
|
-
"character": loc["column"] - 1,
|
|
276
|
-
},
|
|
277
|
-
}
|
|
278
|
-
items = lsp.request("textDocument/prepareCallHierarchy", params)
|
|
279
|
-
if not items:
|
|
280
|
-
return None
|
|
281
|
-
item = items[0]
|
|
282
|
-
method = (
|
|
283
|
-
"callHierarchy/incomingCalls"
|
|
284
|
-
if direction == "incoming"
|
|
285
|
-
else "callHierarchy/outgoingCalls"
|
|
286
|
-
)
|
|
287
|
-
result = lsp.request(method, {"item": item})
|
|
288
|
-
if not result:
|
|
289
|
-
return []
|
|
290
|
-
return _normalize_call_hierarchy(
|
|
291
|
-
result, direction=direction, root=router.root, root_symbol=symbol
|
|
292
|
-
)
|
|
293
|
-
except Exception as exc:
|
|
294
|
-
logger.debug("Call hierarchy via LSP failed: %s", exc)
|
|
295
|
-
return None
|
|
296
|
-
finally:
|
|
297
|
-
if uri and lsp:
|
|
298
|
-
lsp.close_document(uri)
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
def find_symbols(
|
|
302
|
-
path: Path,
|
|
303
|
-
query: str,
|
|
304
|
-
kind: str | None,
|
|
305
|
-
match: str = "contains",
|
|
306
|
-
limit: int | None = 50,
|
|
307
|
-
*,
|
|
308
|
-
config_file: Path | None = None,
|
|
309
|
-
lsp_server: str | None = None,
|
|
310
|
-
) -> list[dict[str, Any]]:
|
|
311
|
-
"""Find symbols in workspace using LSP-first approach with AST fallback."""
|
|
312
|
-
router = _build_router(path, config_file=config_file, lsp_server=lsp_server)
|
|
313
|
-
|
|
314
|
-
# Try LSP first
|
|
315
|
-
if router.lsp:
|
|
316
|
-
try:
|
|
317
|
-
result = router.lsp.request("workspace/symbol", {"query": query})
|
|
318
|
-
if result:
|
|
319
|
-
symbols: list[dict[str, Any]] = []
|
|
320
|
-
for item in result:
|
|
321
|
-
# Convert LSP SymbolInformation to our format
|
|
322
|
-
uri = item.get("uri")
|
|
323
|
-
if not uri:
|
|
324
|
-
continue
|
|
325
|
-
|
|
326
|
-
file_path = _uri_to_path(uri)
|
|
327
|
-
if not file_path.is_absolute():
|
|
328
|
-
file_path = router.root / file_path
|
|
329
|
-
|
|
330
|
-
# Convert to relative path if within workspace
|
|
331
|
-
with contextlib.suppress(ValueError):
|
|
332
|
-
file_path = file_path.relative_to(router.root)
|
|
333
|
-
|
|
334
|
-
# Convert LSP kind to our SymbolKind
|
|
335
|
-
lsp_kind = item.get("kind", 0)
|
|
336
|
-
kind_name = _lsp_symbol_kind_to_name(lsp_kind)
|
|
337
|
-
|
|
338
|
-
# Apply kind filter if specified
|
|
339
|
-
if kind and kind_name.lower() != kind.lower():
|
|
340
|
-
continue
|
|
341
|
-
|
|
342
|
-
# Get location info
|
|
343
|
-
location = item.get("location") or {}
|
|
344
|
-
range_info = location.get("range") or {}
|
|
345
|
-
start = range_info.get("start", {})
|
|
346
|
-
end = range_info.get("end", {})
|
|
347
|
-
|
|
348
|
-
symbol = {
|
|
349
|
-
"name": item.get("name", ""),
|
|
350
|
-
"kind": kind_name,
|
|
351
|
-
"location": {
|
|
352
|
-
"file": str(file_path),
|
|
353
|
-
"line": start.get("line", 0) + 1,
|
|
354
|
-
"column": start.get("character", 0) + 1,
|
|
355
|
-
"end_line": end.get("line", start.get("line", 0)) + 1,
|
|
356
|
-
"end_column": end.get("character", start.get("character", 0)) + 1,
|
|
357
|
-
},
|
|
358
|
-
"container_name": item.get("containerName"),
|
|
359
|
-
"source": "lsp",
|
|
360
|
-
}
|
|
361
|
-
symbols.append(symbol)
|
|
362
|
-
|
|
363
|
-
if symbols and limit is not None and limit > 0:
|
|
364
|
-
symbols = symbols[:limit]
|
|
365
|
-
|
|
366
|
-
if symbols:
|
|
367
|
-
logger.debug("Found %d symbols via LSP", len(symbols))
|
|
368
|
-
return symbols
|
|
369
|
-
except Exception as exc:
|
|
370
|
-
logger.debug("LSP workspace/symbol failed: %s", exc)
|
|
371
|
-
|
|
372
|
-
# Fallback to AST
|
|
373
|
-
logger.debug("Falling back to AST-based symbol search")
|
|
374
|
-
ast_symbols = router.indexer.find_symbols(query, kind, match=match, limit=limit)
|
|
375
|
-
|
|
376
|
-
# Mark with source
|
|
377
|
-
for symbol in ast_symbols:
|
|
378
|
-
symbol["source"] = "ast"
|
|
379
|
-
|
|
380
|
-
return ast_symbols
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
def check_types(
|
|
384
|
-
paths: list[Path],
|
|
385
|
-
mode: str,
|
|
386
|
-
fix: bool,
|
|
387
|
-
*,
|
|
388
|
-
config_file: Path | None = None,
|
|
389
|
-
lsp_server: str | None = None,
|
|
390
|
-
type_checker: str | None = None,
|
|
391
|
-
) -> dict[str, Any]:
|
|
392
|
-
"""Run type checking using detected or specified type checker.
|
|
393
|
-
|
|
394
|
-
Args:
|
|
395
|
-
paths: List of paths to type check
|
|
396
|
-
mode: Type checking mode (basic, standard, strict)
|
|
397
|
-
fix: Whether to apply auto-fixes
|
|
398
|
-
config_file: Optional config file path
|
|
399
|
-
lsp_server: Optional LSP server path
|
|
400
|
-
type_checker: Optional explicit type checker ("mypy", "basedpyright", etc.)
|
|
401
|
-
|
|
402
|
-
Returns:
|
|
403
|
-
Dictionary with type check results
|
|
404
|
-
"""
|
|
405
|
-
# Determine which type checker to use
|
|
406
|
-
if type_checker and type_checker != "auto":
|
|
407
|
-
checker = type_checker
|
|
408
|
-
else:
|
|
409
|
-
# Auto-detect using ProjectDetector
|
|
410
|
-
root = paths[0] if paths else Path.cwd()
|
|
411
|
-
from .models.project_detector import ProjectDetector
|
|
412
|
-
|
|
413
|
-
detector = ProjectDetector(root)
|
|
414
|
-
tools = detector.detect_all()
|
|
415
|
-
checker = tools.type_checker
|
|
416
|
-
|
|
417
|
-
logger.debug("Using type checker: %s", checker)
|
|
418
|
-
|
|
419
|
-
# Route to appropriate runner
|
|
420
|
-
if checker == "mypy":
|
|
421
|
-
runner = MypyRunner()
|
|
422
|
-
diagnostics = runner.check_types(paths, mode=mode)
|
|
423
|
-
return {
|
|
424
|
-
"type_checker": "mypy",
|
|
425
|
-
"diagnostics": diagnostics,
|
|
426
|
-
"summary": f"Checked {len(paths)} path(s) with mypy",
|
|
427
|
-
}
|
|
428
|
-
else: # basedpyright, pyright, pylsp - all use BasedPyrightRunner
|
|
429
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
430
|
-
result = router.pyright.check_types([str(p) for p in paths], mode, fix)
|
|
431
|
-
result["type_checker"] = checker
|
|
432
|
-
return result
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
def go_to_definition(
|
|
436
|
-
symbol: str,
|
|
437
|
-
file: str | None,
|
|
438
|
-
*,
|
|
439
|
-
config_file: Path | None = None,
|
|
440
|
-
lsp_server: str | None = None,
|
|
441
|
-
) -> dict[str, Any]:
|
|
442
|
-
"""Go to symbol definition.
|
|
443
|
-
|
|
444
|
-
If 'file' is provided (format "path/to/file:line:col"), we try to use LSP.
|
|
445
|
-
Otherwise, or if LSP fails, we fall back to AST symbol search by name.
|
|
446
|
-
"""
|
|
447
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
448
|
-
|
|
449
|
-
# If location is provided, try LSP first
|
|
450
|
-
if file and ":" in file and router.lsp:
|
|
451
|
-
uri: str | None = None
|
|
452
|
-
try:
|
|
453
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
454
|
-
line = int(line_str)
|
|
455
|
-
col = int(col_str)
|
|
456
|
-
file_path = Path(file_path_str)
|
|
457
|
-
if not file_path.is_absolute():
|
|
458
|
-
file_path = router.root / file_path
|
|
459
|
-
|
|
460
|
-
uri = router.lsp.open_document(file_path)
|
|
461
|
-
params = {
|
|
462
|
-
"textDocument": {"uri": uri},
|
|
463
|
-
"position": {"line": line - 1, "character": col - 1},
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
result = router.lsp.request("textDocument/definition", params)
|
|
467
|
-
if result:
|
|
468
|
-
locations = result if isinstance(result, list) else [result]
|
|
469
|
-
return {"source": "lsp", "locations": locations}
|
|
470
|
-
except Exception as exc:
|
|
471
|
-
logger.debug("LSP definition lookup failed: %s", exc)
|
|
472
|
-
finally:
|
|
473
|
-
if uri and router.lsp:
|
|
474
|
-
router.lsp.close_document(uri)
|
|
475
|
-
|
|
476
|
-
# Fallback: AST Symbol Search
|
|
477
|
-
# If we have a file/line/col but LSP failed, find the symbol name at that position first
|
|
478
|
-
if file and ":" in file:
|
|
479
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
480
|
-
file_path = Path(file_path_str)
|
|
481
|
-
if not file_path.is_absolute():
|
|
482
|
-
file_path = router.root / file_path
|
|
483
|
-
symbol_at_pos = router.indexer.get_symbol_at_position(
|
|
484
|
-
file_path, int(line_str), int(col_str)
|
|
485
|
-
)
|
|
486
|
-
if symbol_at_pos:
|
|
487
|
-
symbol = symbol_at_pos
|
|
488
|
-
|
|
489
|
-
# Search by name
|
|
490
|
-
symbols = router.indexer.find_symbols(symbol)
|
|
491
|
-
return {"source": "ast", "locations": symbols}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
def go_to_implementation(
|
|
495
|
-
file: str,
|
|
496
|
-
*,
|
|
497
|
-
config_file: Path | None = None,
|
|
498
|
-
lsp_server: str | None = None,
|
|
499
|
-
) -> dict[str, Any]:
|
|
500
|
-
"""Go to implementation(s) of a symbol at a location.
|
|
501
|
-
|
|
502
|
-
Takes file path with line and column (format "path/to/file:line:col").
|
|
503
|
-
Uses BasedPyright LSP client to call textDocument/implementation.
|
|
504
|
-
Falls back to AST-based search if LSP unavailable.
|
|
505
|
-
"""
|
|
506
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
507
|
-
|
|
508
|
-
# Validate location format
|
|
509
|
-
if ":" not in file:
|
|
510
|
-
return {
|
|
511
|
-
"source": "error",
|
|
512
|
-
"locations": [],
|
|
513
|
-
"message": "Location must be in format file:line:col",
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
# If location is provided, try LSP first
|
|
517
|
-
if file and ":" in file and router.lsp:
|
|
518
|
-
uri: str | None = None
|
|
519
|
-
try:
|
|
520
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
521
|
-
line = int(line_str)
|
|
522
|
-
col = int(col_str)
|
|
523
|
-
file_path = Path(file_path_str)
|
|
524
|
-
if not file_path.is_absolute():
|
|
525
|
-
file_path = router.root / file_path
|
|
526
|
-
|
|
527
|
-
uri = router.lsp.open_document(file_path)
|
|
528
|
-
params = {
|
|
529
|
-
"textDocument": {"uri": uri},
|
|
530
|
-
"position": {"line": line - 1, "character": col - 1},
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
result = router.lsp.request("textDocument/implementation", params)
|
|
534
|
-
if result:
|
|
535
|
-
locations = result if isinstance(result, list) else [result]
|
|
536
|
-
return {"source": "lsp", "locations": locations}
|
|
537
|
-
except Exception as exc:
|
|
538
|
-
logger.debug("LSP implementation lookup failed: %s", exc)
|
|
539
|
-
finally:
|
|
540
|
-
if uri and router.lsp:
|
|
541
|
-
router.lsp.close_document(uri)
|
|
542
|
-
|
|
543
|
-
# Fallback: AST-based search
|
|
544
|
-
# Find the symbol name at the position and search for implementations
|
|
545
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
546
|
-
file_path = Path(file_path_str)
|
|
547
|
-
if not file_path.is_absolute():
|
|
548
|
-
file_path = router.root / file_path
|
|
549
|
-
|
|
550
|
-
symbol_at_pos = router.indexer.get_symbol_at_position(file_path, int(line_str), int(col_str))
|
|
551
|
-
if symbol_at_pos:
|
|
552
|
-
# Search for the symbol to find its implementations
|
|
553
|
-
symbols = router.indexer.find_symbols(symbol_at_pos)
|
|
554
|
-
return {
|
|
555
|
-
"source": "ast",
|
|
556
|
-
"locations": symbols,
|
|
557
|
-
"message": "LSP unavailable, showing symbol definitions",
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
return {"source": "ast", "locations": [], "message": "No symbol found at location"}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
def get_callers(
|
|
564
|
-
symbol: str,
|
|
565
|
-
*,
|
|
566
|
-
config_file: Path | None = None,
|
|
567
|
-
lsp_server: str | None = None,
|
|
568
|
-
max_depth: int | None = None,
|
|
569
|
-
) -> dict[str, Any]:
|
|
570
|
-
"""Get callers of a symbol."""
|
|
571
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
572
|
-
depth_limit = 1 if max_depth is None else max(max_depth, 1)
|
|
573
|
-
stats = {"count": 0, "max_depth": 0}
|
|
574
|
-
if depth_limit == 1:
|
|
575
|
-
lsp_result = _call_hierarchy(router, symbol, direction="incoming")
|
|
576
|
-
if lsp_result is not None:
|
|
577
|
-
if lsp_result:
|
|
578
|
-
stats["count"] = len(lsp_result) # type: ignore[assignment]
|
|
579
|
-
stats["max_depth"] = max(call.get("depth", 1) for call in lsp_result) # type: ignore[assignment]
|
|
580
|
-
return {"source": "lsp", "callers": lsp_result, "stats": stats}
|
|
581
|
-
else:
|
|
582
|
-
logger.debug("Using AST call hierarchy for max_depth=%s", depth_limit)
|
|
583
|
-
callers = router.indexer.get_callers(symbol, max_depth=depth_limit)
|
|
584
|
-
if callers:
|
|
585
|
-
stats["count"] = len(callers)
|
|
586
|
-
stats["max_depth"] = cast(int, max((call.get("depth", 1) or 1) for call in callers))
|
|
587
|
-
return {"source": "ast", "callers": callers, "stats": stats}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
def get_callees(
|
|
591
|
-
symbol: str,
|
|
592
|
-
*,
|
|
593
|
-
config_file: Path | None = None,
|
|
594
|
-
lsp_server: str | None = None,
|
|
595
|
-
max_depth: int | None = None,
|
|
596
|
-
) -> dict[str, Any]:
|
|
597
|
-
"""Get callees of a symbol."""
|
|
598
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
599
|
-
depth_limit = 1 if max_depth is None else max(max_depth, 1)
|
|
600
|
-
stats = {"count": 0, "max_depth": 0}
|
|
601
|
-
if depth_limit == 1:
|
|
602
|
-
lsp_result = _call_hierarchy(router, symbol, direction="outgoing")
|
|
603
|
-
if lsp_result is not None:
|
|
604
|
-
if lsp_result:
|
|
605
|
-
stats["count"] = len(lsp_result) # type: ignore[assignment]
|
|
606
|
-
stats["max_depth"] = max(call.get("depth", 1) for call in lsp_result) # type: ignore[assignment]
|
|
607
|
-
return {"source": "lsp", "callees": lsp_result, "stats": stats}
|
|
608
|
-
else:
|
|
609
|
-
logger.debug("Using AST call hierarchy for max_depth=%s", depth_limit)
|
|
610
|
-
callees = router.indexer.get_callees(symbol, max_depth=depth_limit)
|
|
611
|
-
if callees:
|
|
612
|
-
stats["count"] = len(callees)
|
|
613
|
-
stats["max_depth"] = cast(int, max((call.get("depth", 1) or 1) for call in callees))
|
|
614
|
-
return {"source": "ast", "callees": callees, "stats": stats}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
def find_references(
|
|
618
|
-
symbol: str,
|
|
619
|
-
file: str | None,
|
|
620
|
-
*,
|
|
621
|
-
context_lines: int = 0,
|
|
622
|
-
config_file: Path | None = None,
|
|
623
|
-
lsp_server: str | None = None,
|
|
624
|
-
) -> dict[str, Any]:
|
|
625
|
-
"""Find references to a symbol.
|
|
626
|
-
|
|
627
|
-
If 'file' is provided (format "path/to/file:line:col"), we try to use LSP.
|
|
628
|
-
Otherwise, we fall back to AST text search.
|
|
629
|
-
"""
|
|
630
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
631
|
-
|
|
632
|
-
# Try LSP first if location provided
|
|
633
|
-
if file and ":" in file and router.lsp:
|
|
634
|
-
uri: str | None = None
|
|
635
|
-
try:
|
|
636
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
637
|
-
line = int(line_str)
|
|
638
|
-
col = int(col_str)
|
|
639
|
-
file_path = Path(file_path_str)
|
|
640
|
-
if not file_path.is_absolute():
|
|
641
|
-
file_path = router.root / file_path
|
|
642
|
-
|
|
643
|
-
uri = router.lsp.open_document(file_path)
|
|
644
|
-
params = {
|
|
645
|
-
"textDocument": {"uri": uri},
|
|
646
|
-
"position": {"line": line - 1, "character": col - 1},
|
|
647
|
-
"context": {"includeDeclaration": True},
|
|
648
|
-
}
|
|
649
|
-
result = router.lsp.request("textDocument/references", params)
|
|
650
|
-
if result:
|
|
651
|
-
refs: list[dict[str, Any]] = []
|
|
652
|
-
for ref in result:
|
|
653
|
-
ref_item = dict(ref)
|
|
654
|
-
uri_val = ref_item.get("uri")
|
|
655
|
-
if uri_val:
|
|
656
|
-
file_path = _uri_to_path(uri_val)
|
|
657
|
-
if not file_path.is_absolute():
|
|
658
|
-
file_path = router.root / file_path
|
|
659
|
-
start = ref_item.get("range", {}).get("start", {})
|
|
660
|
-
line = start.get("line", 0) + 1
|
|
661
|
-
context = extract_context(file_path, line=line, context_lines=context_lines)
|
|
662
|
-
if context:
|
|
663
|
-
ref_item["context"] = context
|
|
664
|
-
ref_item.setdefault("category", "reference")
|
|
665
|
-
refs.append(ref_item)
|
|
666
|
-
return {"source": "lsp", "references": refs}
|
|
667
|
-
except Exception as exc:
|
|
668
|
-
logger.debug("LSP references lookup failed: %s", exc)
|
|
669
|
-
finally:
|
|
670
|
-
if uri and router.lsp:
|
|
671
|
-
router.lsp.close_document(uri)
|
|
672
|
-
|
|
673
|
-
# Fallback to AST
|
|
674
|
-
# If file provided, try to resolve symbol name at position first
|
|
675
|
-
if file and ":" in file:
|
|
676
|
-
file_path_str, line_str, col_str = file.split(":")
|
|
677
|
-
file_path = Path(file_path_str)
|
|
678
|
-
if not file_path.is_absolute():
|
|
679
|
-
file_path = router.root / file_path
|
|
680
|
-
symbol_at_pos = router.indexer.get_symbol_at_position(
|
|
681
|
-
file_path, int(line_str), int(col_str)
|
|
682
|
-
)
|
|
683
|
-
if symbol_at_pos:
|
|
684
|
-
symbol = symbol_at_pos
|
|
685
|
-
|
|
686
|
-
refs = router.indexer.find_references(symbol, context_lines=context_lines)
|
|
687
|
-
return {"source": "ast", "references": refs}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
def get_document_symbols(
|
|
691
|
-
file: Path,
|
|
692
|
-
*,
|
|
693
|
-
config_file: Path | None = None,
|
|
694
|
-
lsp_server: str | None = None,
|
|
695
|
-
) -> dict[str, Any]:
|
|
696
|
-
"""Get document symbols.
|
|
697
|
-
|
|
698
|
-
Try LSP first, fallback to AST.
|
|
699
|
-
"""
|
|
700
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
701
|
-
|
|
702
|
-
# Try LSP first
|
|
703
|
-
if router.lsp:
|
|
704
|
-
uri: str | None = None
|
|
705
|
-
try:
|
|
706
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
707
|
-
uri = router.lsp.open_document(file_path)
|
|
708
|
-
params = {"textDocument": {"uri": uri}}
|
|
709
|
-
result = router.lsp.request("textDocument/documentSymbol", params)
|
|
710
|
-
if result:
|
|
711
|
-
return {"source": "lsp", "symbols": result}
|
|
712
|
-
except Exception as exc:
|
|
713
|
-
logger.debug("LSP document symbols failed: %s", exc)
|
|
714
|
-
finally:
|
|
715
|
-
if uri and router.lsp:
|
|
716
|
-
router.lsp.close_document(uri)
|
|
717
|
-
|
|
718
|
-
# Fallback to AST
|
|
719
|
-
symbols = router.indexer.get_document_symbols_tree(router.root / file)
|
|
720
|
-
return {"source": "ast", "symbols": symbols}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
def get_diagnostics(
|
|
724
|
-
paths: list[Path],
|
|
725
|
-
include_warnings: bool = True,
|
|
726
|
-
include_fixable: bool = False,
|
|
727
|
-
max_fixable: int | None = None,
|
|
728
|
-
*,
|
|
729
|
-
config_file: Path | None = None,
|
|
730
|
-
lsp_server: str | None = None,
|
|
731
|
-
) -> dict[str, Any]:
|
|
732
|
-
"""Get diagnostics for paths (basedpyright + ruff)."""
|
|
733
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
734
|
-
basedpyright = router.pyright.check_types([str(p) for p in paths])
|
|
735
|
-
ruff_lsp = None
|
|
736
|
-
ruff_cli = None
|
|
737
|
-
notebook_paths = [p for p in paths if p.suffix == ".ipynb"]
|
|
738
|
-
non_notebook_paths = [p for p in paths if p.suffix != ".ipynb"]
|
|
739
|
-
if isinstance(router, MultiLSPRouter) and router.ruff_lsp:
|
|
740
|
-
if non_notebook_paths:
|
|
741
|
-
ruff_lsp = router.ruff_lsp.get_diagnostics(non_notebook_paths)
|
|
742
|
-
if notebook_paths:
|
|
743
|
-
ruff_cli = router.ruff.check([str(p) for p in notebook_paths])
|
|
744
|
-
else:
|
|
745
|
-
ruff_cli = router.ruff.check([str(p) for p in paths])
|
|
746
|
-
payload = router.aggregator.aggregate(
|
|
747
|
-
basedpyright,
|
|
748
|
-
ruff_cli,
|
|
749
|
-
ruff_lsp=ruff_lsp,
|
|
750
|
-
include_warnings=include_warnings,
|
|
751
|
-
)
|
|
752
|
-
|
|
753
|
-
fixable_count = 0 # Initialize to avoid "possibly unbound" error
|
|
754
|
-
# Convert read-only TypedDict to mutable dict for modification
|
|
755
|
-
result: dict[str, Any] = dict(payload) # pyright: ignore[reportAssignmentType]
|
|
756
|
-
diagnostics = [dict(d) for d in result.get("diagnostics", [])]
|
|
757
|
-
if include_fixable:
|
|
758
|
-
if router.code_actions and router.lsp:
|
|
759
|
-
for diag in diagnostics:
|
|
760
|
-
if max_fixable is not None and fixable_count >= max_fixable:
|
|
761
|
-
diag["fixable"] = None
|
|
762
|
-
continue
|
|
763
|
-
file_path = diag.get("file")
|
|
764
|
-
if not file_path:
|
|
765
|
-
diag["fixable"] = False
|
|
766
|
-
continue
|
|
767
|
-
path = Path(file_path)
|
|
768
|
-
if not path.is_absolute():
|
|
769
|
-
path = router.root / path
|
|
770
|
-
range_start = diag.get("range", {}).get("start", {})
|
|
771
|
-
line = range_start.get("line", 0) + 1
|
|
772
|
-
col = range_start.get("character", 0) + 1
|
|
773
|
-
actions = router.code_actions.get_code_actions(path, line, col, diagnostics=[diag])
|
|
774
|
-
is_fixable = bool(actions)
|
|
775
|
-
diag["fixable"] = is_fixable
|
|
776
|
-
diag["actions_available"] = len(actions)
|
|
777
|
-
if is_fixable:
|
|
778
|
-
fixable_count += 1
|
|
779
|
-
else:
|
|
780
|
-
for diag in diagnostics:
|
|
781
|
-
diag["fixable"] = None
|
|
782
|
-
result["diagnostics"] = diagnostics
|
|
783
|
-
result["fixable_count"] = fixable_count
|
|
784
|
-
|
|
785
|
-
return result
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
def fix_errors(
|
|
789
|
-
paths: list[Path],
|
|
790
|
-
*,
|
|
791
|
-
apply: bool = False,
|
|
792
|
-
max_actions: int | None = None,
|
|
793
|
-
allow_kinds: list[str] | None = None,
|
|
794
|
-
confirm_annotations: bool = False,
|
|
795
|
-
config_file: Path | None = None,
|
|
796
|
-
lsp_server: str | None = None,
|
|
797
|
-
) -> dict[str, Any]:
|
|
798
|
-
"""Attempt to fix errors in specified paths.
|
|
799
|
-
|
|
800
|
-
This is a complex operation:
|
|
801
|
-
1. Get diagnostics
|
|
802
|
-
2. Request code actions for errors
|
|
803
|
-
3. Apply available quickfixes
|
|
804
|
-
|
|
805
|
-
For now, we implement a simplified version that can be expanded.
|
|
806
|
-
"""
|
|
807
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
808
|
-
if not router.code_actions or not router.lsp:
|
|
809
|
-
return {
|
|
810
|
-
"fixed_count": 0,
|
|
811
|
-
"actions_available": 0,
|
|
812
|
-
"message": "No LSP server available for code actions.",
|
|
813
|
-
"error": router.lsp_error,
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
diagnostics_data = router.pyright.check_types([str(p) for p in paths])
|
|
817
|
-
diagnostics = diagnostics_data.get("diagnostics") or []
|
|
818
|
-
|
|
819
|
-
if not diagnostics:
|
|
820
|
-
return {"fixed_count": 0, "actions_available": 0, "message": "No diagnostics found."}
|
|
821
|
-
|
|
822
|
-
actions_available = 0
|
|
823
|
-
actions_applied = 0
|
|
824
|
-
actions_considered = 0
|
|
825
|
-
skipped_needs_confirmation = 0
|
|
826
|
-
previews: list[dict[str, Any]] = []
|
|
827
|
-
patch_chunks: list[str] = []
|
|
828
|
-
backup_dir: Path | None = None
|
|
829
|
-
|
|
830
|
-
if apply:
|
|
831
|
-
stamp = datetime.utcnow().strftime("%Y%m%d-%H%M%S")
|
|
832
|
-
backup_dir = router.root / ".vds-lsp" / "backups" / stamp
|
|
833
|
-
|
|
834
|
-
for diag in diagnostics:
|
|
835
|
-
file_path = diag.get("file")
|
|
836
|
-
if not file_path:
|
|
837
|
-
continue
|
|
838
|
-
file_path = Path(file_path)
|
|
839
|
-
if not file_path.is_absolute():
|
|
840
|
-
file_path = router.root / file_path
|
|
841
|
-
|
|
842
|
-
range_start = diag.get("range", {}).get("start", {})
|
|
843
|
-
line = range_start.get("line", 0) + 1
|
|
844
|
-
col = range_start.get("character", 0) + 1
|
|
845
|
-
|
|
846
|
-
actions = router.code_actions.get_code_actions(file_path, line, col, diagnostics=[diag])
|
|
847
|
-
actions_available += len(actions)
|
|
848
|
-
|
|
849
|
-
for action in actions:
|
|
850
|
-
if max_actions is not None and actions_applied >= max_actions:
|
|
851
|
-
break
|
|
852
|
-
if action.get("disabled"):
|
|
853
|
-
continue
|
|
854
|
-
|
|
855
|
-
kind = (action.get("kind") or "").lower()
|
|
856
|
-
category = (action.get("category") or "").lower()
|
|
857
|
-
if allow_kinds:
|
|
858
|
-
if not any(
|
|
859
|
-
kind.startswith(k.lower()) or category == k.lower() for k in allow_kinds
|
|
860
|
-
):
|
|
861
|
-
continue
|
|
862
|
-
elif not (category == "quickfix" or kind.startswith("quickfix")):
|
|
863
|
-
continue
|
|
864
|
-
actions_considered += 1
|
|
865
|
-
|
|
866
|
-
resolved = action
|
|
867
|
-
if "edit" not in action and "data" in action:
|
|
868
|
-
try:
|
|
869
|
-
resolved = router.lsp.request("codeAction/resolve", action)
|
|
870
|
-
except Exception as exc:
|
|
871
|
-
logger.debug("Failed to resolve code action: %s", exc)
|
|
872
|
-
|
|
873
|
-
edit = resolved.get("edit") or action.get("edit")
|
|
874
|
-
command = resolved.get("command") or action.get("command")
|
|
875
|
-
|
|
876
|
-
if edit:
|
|
877
|
-
needs_confirmation = workspace_edit_needs_confirmation(edit)
|
|
878
|
-
if apply and needs_confirmation and not confirm_annotations:
|
|
879
|
-
skipped_needs_confirmation += 1
|
|
880
|
-
previews.append(
|
|
881
|
-
{
|
|
882
|
-
"file": str(file_path),
|
|
883
|
-
"title": action.get("title", "Unnamed action"),
|
|
884
|
-
"needs_confirmation": True,
|
|
885
|
-
},
|
|
886
|
-
)
|
|
887
|
-
continue
|
|
888
|
-
if not apply:
|
|
889
|
-
preview_map = preview_workspace_edit(edit, root=router.root)
|
|
890
|
-
for path, (before, after) in preview_map.items():
|
|
891
|
-
patch_chunks.append(build_unified_diff(path, before, after))
|
|
892
|
-
previews.append(
|
|
893
|
-
{
|
|
894
|
-
"file": str(path),
|
|
895
|
-
"before": before,
|
|
896
|
-
"after": after,
|
|
897
|
-
"title": action.get("title", "Unnamed action"),
|
|
898
|
-
"needs_confirmation": needs_confirmation,
|
|
899
|
-
},
|
|
900
|
-
)
|
|
901
|
-
else:
|
|
902
|
-
changed = apply_workspace_edit(
|
|
903
|
-
edit,
|
|
904
|
-
root=router.root,
|
|
905
|
-
backup_dir=backup_dir,
|
|
906
|
-
dry_run=False,
|
|
907
|
-
)
|
|
908
|
-
if changed:
|
|
909
|
-
actions_applied += 1
|
|
910
|
-
continue
|
|
911
|
-
|
|
912
|
-
if command:
|
|
913
|
-
if not apply:
|
|
914
|
-
previews.append(
|
|
915
|
-
{
|
|
916
|
-
"file": str(file_path),
|
|
917
|
-
"command": command,
|
|
918
|
-
"title": action.get("title", "Unnamed action"),
|
|
919
|
-
},
|
|
920
|
-
)
|
|
921
|
-
continue
|
|
922
|
-
|
|
923
|
-
try:
|
|
924
|
-
payload = command if isinstance(command, dict) else {"command": command}
|
|
925
|
-
router.lsp.request("workspace/executeCommand", payload)
|
|
926
|
-
actions_applied += 1
|
|
927
|
-
except Exception as exc:
|
|
928
|
-
logger.debug("Failed to execute code action command: %s", exc)
|
|
929
|
-
|
|
930
|
-
if apply:
|
|
931
|
-
return {
|
|
932
|
-
"fixed_count": actions_applied,
|
|
933
|
-
"actions_available": actions_available,
|
|
934
|
-
"actions_considered": actions_considered,
|
|
935
|
-
"skipped_needs_confirmation": skipped_needs_confirmation,
|
|
936
|
-
"backup_dir": str(backup_dir) if backup_dir else None,
|
|
937
|
-
"message": "Applied code actions.",
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
return {
|
|
941
|
-
"fixed_count": 0,
|
|
942
|
-
"actions_available": actions_available,
|
|
943
|
-
"actions_considered": actions_considered,
|
|
944
|
-
"skipped_needs_confirmation": skipped_needs_confirmation,
|
|
945
|
-
"previews": previews,
|
|
946
|
-
"patch": "".join(patch_chunks),
|
|
947
|
-
"message": "Use --apply to apply available code actions.",
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
def rollback_fixes(
|
|
952
|
-
backup_dir: Path,
|
|
953
|
-
*,
|
|
954
|
-
root: Path | None = None,
|
|
955
|
-
) -> dict[str, Any]:
|
|
956
|
-
"""Restore files from a backup directory created by fix-errors."""
|
|
957
|
-
resolved_root = root or Path.cwd()
|
|
958
|
-
|
|
959
|
-
if not backup_dir.exists():
|
|
960
|
-
return {"restored": 0, "message": "Backup directory does not exist."}
|
|
961
|
-
|
|
962
|
-
restored = restore_backup(backup_dir, root=resolved_root)
|
|
963
|
-
return {
|
|
964
|
-
"restored": len(restored),
|
|
965
|
-
"files": [str(path) for path in restored],
|
|
966
|
-
"message": "Restored files from backup.",
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
def get_code_actions(
|
|
971
|
-
file: str,
|
|
972
|
-
line: int,
|
|
973
|
-
col: int,
|
|
974
|
-
*,
|
|
975
|
-
config_file: Path | None = None,
|
|
976
|
-
lsp_server: str | None = None,
|
|
977
|
-
) -> list[dict[str, Any]]:
|
|
978
|
-
"""Get code actions for location."""
|
|
979
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
980
|
-
if not router.code_actions:
|
|
981
|
-
return []
|
|
982
|
-
file_path = Path(file)
|
|
983
|
-
if not file_path.is_absolute():
|
|
984
|
-
file_path = router.root / file_path
|
|
985
|
-
return router.code_actions.get_code_actions(file_path, line, col)
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
def _require_language_services(router: LSPRouter) -> dict[str, Any] | None:
|
|
989
|
-
if not getattr(router.config, "enable_language_services", True):
|
|
990
|
-
return {"message": "Language services are disabled by configuration.", "result": None}
|
|
991
|
-
if not router.lsp:
|
|
992
|
-
return {"message": "BasedPyright LSP is unavailable.", "result": None}
|
|
993
|
-
return None
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
def _format_operator_hover(hover_result: dict[str, Any] | None) -> dict[str, Any]:
|
|
997
|
-
"""Format operator hover result to highlight dunder methods.
|
|
998
|
-
|
|
999
|
-
BasedPyright provides hover information for operators that includes
|
|
1000
|
-
the corresponding dunder method (e.g., `+` -> `__add__`).
|
|
1001
|
-
This function enhances the output to make this clearer.
|
|
1002
|
-
|
|
1003
|
-
Args:
|
|
1004
|
-
hover_result: The raw LSP hover result
|
|
1005
|
-
|
|
1006
|
-
Returns:
|
|
1007
|
-
Enhanced hover result with operator metadata
|
|
1008
|
-
"""
|
|
1009
|
-
if not hover_result:
|
|
1010
|
-
return {"is_operator": False, "result": None}
|
|
1011
|
-
|
|
1012
|
-
contents = hover_result.get("contents")
|
|
1013
|
-
if not contents:
|
|
1014
|
-
return {"is_operator": False, "result": hover_result}
|
|
1015
|
-
|
|
1016
|
-
# Extract the hover text
|
|
1017
|
-
hover_text = ""
|
|
1018
|
-
if isinstance(contents, str):
|
|
1019
|
-
hover_text = contents
|
|
1020
|
-
elif isinstance(contents, list):
|
|
1021
|
-
# Handle MarkedString format
|
|
1022
|
-
for item in contents:
|
|
1023
|
-
if isinstance(item, str):
|
|
1024
|
-
hover_text += item
|
|
1025
|
-
elif isinstance(item, dict):
|
|
1026
|
-
hover_text += item.get("value", "")
|
|
1027
|
-
|
|
1028
|
-
# Check if this looks like an operator hover (contains dunder method references)
|
|
1029
|
-
operator_dunder_methods = [
|
|
1030
|
-
"__add__",
|
|
1031
|
-
"__sub__",
|
|
1032
|
-
"__mul__",
|
|
1033
|
-
"__truediv__",
|
|
1034
|
-
"__floordiv__",
|
|
1035
|
-
"__mod__",
|
|
1036
|
-
"__pow__",
|
|
1037
|
-
"__eq__",
|
|
1038
|
-
"__ne__",
|
|
1039
|
-
"__lt__",
|
|
1040
|
-
"__le__",
|
|
1041
|
-
"__gt__",
|
|
1042
|
-
"__ge__",
|
|
1043
|
-
"__contains__",
|
|
1044
|
-
"__getitem__",
|
|
1045
|
-
"__setitem__",
|
|
1046
|
-
"__and__",
|
|
1047
|
-
"__or__",
|
|
1048
|
-
"__xor__",
|
|
1049
|
-
"__lshift__",
|
|
1050
|
-
"__rshift__",
|
|
1051
|
-
"__iadd__",
|
|
1052
|
-
"__isub__",
|
|
1053
|
-
"__imul__",
|
|
1054
|
-
"__itruediv__",
|
|
1055
|
-
"__ifloordiv__",
|
|
1056
|
-
]
|
|
1057
|
-
|
|
1058
|
-
is_operator = any(
|
|
1059
|
-
f"__{method}" in hover_text or method in hover_text for method in operator_dunder_methods
|
|
1060
|
-
)
|
|
1061
|
-
|
|
1062
|
-
if is_operator:
|
|
1063
|
-
# Enhance the result with operator metadata
|
|
1064
|
-
return {
|
|
1065
|
-
"is_operator": True,
|
|
1066
|
-
"result": hover_result,
|
|
1067
|
-
"operator_info": {
|
|
1068
|
-
"description": "Operator hover - shows dunder method implementation",
|
|
1069
|
-
"note": "Use 'goto' command to jump to the dunder method definition",
|
|
1070
|
-
},
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
return {"is_operator": False, "result": hover_result}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
def hover(
|
|
1077
|
-
file: Path,
|
|
1078
|
-
line: int,
|
|
1079
|
-
col: int,
|
|
1080
|
-
*,
|
|
1081
|
-
config_file: Path | None = None,
|
|
1082
|
-
lsp_server: str | None = None,
|
|
1083
|
-
) -> dict[str, Any]:
|
|
1084
|
-
"""Get hover information at a location.
|
|
1085
|
-
|
|
1086
|
-
Supports:
|
|
1087
|
-
- Symbol documentation (functions, classes, variables)
|
|
1088
|
-
- Operator hover (shows dunder method implementation like __add__, __mul__)
|
|
1089
|
-
|
|
1090
|
-
BasedPyright provides hover for operators like +, *, //, etc., showing
|
|
1091
|
-
the corresponding dunder method and its documentation.
|
|
1092
|
-
|
|
1093
|
-
Args:
|
|
1094
|
-
file: Path to the file
|
|
1095
|
-
line: Line number (1-indexed)
|
|
1096
|
-
col: Column number (1-indexed)
|
|
1097
|
-
config_file: Optional path to pyright config
|
|
1098
|
-
lsp_server: Optional LSP server override
|
|
1099
|
-
|
|
1100
|
-
Returns:
|
|
1101
|
-
Dict with hover result. Includes 'is_operator' key for operator hovers.
|
|
1102
|
-
"""
|
|
1103
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1104
|
-
guard = _require_language_services(router)
|
|
1105
|
-
if guard:
|
|
1106
|
-
return guard
|
|
1107
|
-
|
|
1108
|
-
# Type narrowing: after the guard, lsp is guaranteed to be not None
|
|
1109
|
-
lsp = router.lsp
|
|
1110
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1111
|
-
|
|
1112
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1113
|
-
uri = lsp.open_document(file_path)
|
|
1114
|
-
# Use longer timeout for first-time requests (30 seconds)
|
|
1115
|
-
# BasedPyright needs significant time to process newly opened files
|
|
1116
|
-
result = lsp.request_with_timeout(
|
|
1117
|
-
"textDocument/hover",
|
|
1118
|
-
{"textDocument": {"uri": uri}, "position": {"line": line - 1, "character": col - 1}},
|
|
1119
|
-
timeout=30.0,
|
|
1120
|
-
)
|
|
1121
|
-
# In daemon mode, keep documents open to avoid re-processing overhead
|
|
1122
|
-
# Subsequent requests will be fast since the file is already loaded
|
|
1123
|
-
if not router.using_daemon:
|
|
1124
|
-
lsp.close_document(uri)
|
|
1125
|
-
|
|
1126
|
-
# Enhance operator hover results
|
|
1127
|
-
formatted = _format_operator_hover(result)
|
|
1128
|
-
response = {"message": "OK", "result": formatted["result"]}
|
|
1129
|
-
if formatted["is_operator"]:
|
|
1130
|
-
response["is_operator"] = True
|
|
1131
|
-
response["operator_info"] = formatted.get("operator_info")
|
|
1132
|
-
return response
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
def completion(
|
|
1136
|
-
file: Path,
|
|
1137
|
-
line: int,
|
|
1138
|
-
col: int,
|
|
1139
|
-
*,
|
|
1140
|
-
config_file: Path | None = None,
|
|
1141
|
-
lsp_server: str | None = None,
|
|
1142
|
-
) -> dict[str, Any]:
|
|
1143
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1144
|
-
guard = _require_language_services(router)
|
|
1145
|
-
if guard:
|
|
1146
|
-
return guard
|
|
1147
|
-
|
|
1148
|
-
# Type narrowing: after the guard check, lsp is guaranteed to be not None
|
|
1149
|
-
lsp = router.lsp
|
|
1150
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1151
|
-
|
|
1152
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1153
|
-
uri = lsp.open_document(file_path)
|
|
1154
|
-
# Use shorter timeout for language service (5 seconds)
|
|
1155
|
-
result = lsp.request_with_timeout(
|
|
1156
|
-
"textDocument/completion",
|
|
1157
|
-
{"textDocument": {"uri": uri}, "position": {"line": line - 1, "character": col - 1}},
|
|
1158
|
-
timeout=5.0,
|
|
1159
|
-
)
|
|
1160
|
-
lsp.close_document(uri)
|
|
1161
|
-
return {"message": "OK", "result": result}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
def rename_symbol(
|
|
1165
|
-
file: Path,
|
|
1166
|
-
line: int,
|
|
1167
|
-
col: int,
|
|
1168
|
-
new_name: str,
|
|
1169
|
-
*,
|
|
1170
|
-
apply: bool = False,
|
|
1171
|
-
config_file: Path | None = None,
|
|
1172
|
-
lsp_server: str | None = None,
|
|
1173
|
-
) -> dict[str, Any]:
|
|
1174
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1175
|
-
guard = _require_language_services(router)
|
|
1176
|
-
if guard:
|
|
1177
|
-
return guard
|
|
1178
|
-
|
|
1179
|
-
# Type narrowing: after the guard check, lsp is guaranteed to be not None
|
|
1180
|
-
lsp = router.lsp
|
|
1181
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1182
|
-
|
|
1183
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1184
|
-
uri = lsp.open_document(file_path)
|
|
1185
|
-
edit = lsp.request(
|
|
1186
|
-
"textDocument/rename",
|
|
1187
|
-
{
|
|
1188
|
-
"textDocument": {"uri": uri},
|
|
1189
|
-
"position": {"line": line - 1, "character": col - 1},
|
|
1190
|
-
"newName": new_name,
|
|
1191
|
-
},
|
|
1192
|
-
)
|
|
1193
|
-
lsp.close_document(uri)
|
|
1194
|
-
if not edit:
|
|
1195
|
-
return {"message": "No rename edits available.", "applied": False}
|
|
1196
|
-
if not apply:
|
|
1197
|
-
preview_map = preview_workspace_edit(edit, root=router.root)
|
|
1198
|
-
return {
|
|
1199
|
-
"message": "Use --apply to apply rename.",
|
|
1200
|
-
"applied": False,
|
|
1201
|
-
"previews": [
|
|
1202
|
-
{"file": str(path), "before": before, "after": after}
|
|
1203
|
-
for path, (before, after) in preview_map.items()
|
|
1204
|
-
],
|
|
1205
|
-
}
|
|
1206
|
-
changed = apply_workspace_edit(edit, root=router.root, dry_run=False)
|
|
1207
|
-
return {"message": "Rename applied.", "applied": True, "files": [str(p) for p in changed]}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
def signature_help(
|
|
1211
|
-
file: Path,
|
|
1212
|
-
line: int,
|
|
1213
|
-
col: int,
|
|
1214
|
-
*,
|
|
1215
|
-
config_file: Path | None = None,
|
|
1216
|
-
lsp_server: str | None = None,
|
|
1217
|
-
) -> dict[str, Any]:
|
|
1218
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1219
|
-
guard = _require_language_services(router)
|
|
1220
|
-
if guard:
|
|
1221
|
-
return guard
|
|
1222
|
-
|
|
1223
|
-
# Type narrowing: after the guard check, lsp is guaranteed to be not None
|
|
1224
|
-
lsp = router.lsp
|
|
1225
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1226
|
-
|
|
1227
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1228
|
-
uri = lsp.open_document(file_path)
|
|
1229
|
-
# Use shorter timeout for language service (5 seconds)
|
|
1230
|
-
result = lsp.request_with_timeout(
|
|
1231
|
-
"textDocument/signatureHelp",
|
|
1232
|
-
{"textDocument": {"uri": uri}, "position": {"line": line - 1, "character": col - 1}},
|
|
1233
|
-
timeout=5.0,
|
|
1234
|
-
)
|
|
1235
|
-
lsp.close_document(uri)
|
|
1236
|
-
return {"message": "OK", "result": result}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
def inlay_hints(
|
|
1240
|
-
file: Path,
|
|
1241
|
-
*,
|
|
1242
|
-
config_file: Path | None = None,
|
|
1243
|
-
lsp_server: str | None = None,
|
|
1244
|
-
inlay_return_types: bool = True,
|
|
1245
|
-
inlay_variable_types: bool = True,
|
|
1246
|
-
inlay_function_parameters: bool = True,
|
|
1247
|
-
inlay_generic_types: bool = True,
|
|
1248
|
-
inlay_parameter_names_matching: bool = False,
|
|
1249
|
-
) -> dict[str, Any]:
|
|
1250
|
-
"""Get inlay hints from BasedPyright LSP.
|
|
1251
|
-
|
|
1252
|
-
Args:
|
|
1253
|
-
file: Path to the file to analyze
|
|
1254
|
-
config_file: Optional path to pyright config file
|
|
1255
|
-
lsp_server: Optional LSP server command override
|
|
1256
|
-
inlay_return_types: Enable function return type hints
|
|
1257
|
-
inlay_variable_types: Enable variable type hints
|
|
1258
|
-
inlay_function_parameters: Enable function parameter name hints
|
|
1259
|
-
inlay_generic_types: Enable generic type hints
|
|
1260
|
-
inlay_parameter_names_matching: Enable hints when param name matches arg name
|
|
1261
|
-
|
|
1262
|
-
Returns:
|
|
1263
|
-
Dictionary with inlay hints results
|
|
1264
|
-
"""
|
|
1265
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1266
|
-
guard = _require_language_services(router)
|
|
1267
|
-
if guard:
|
|
1268
|
-
return guard
|
|
1269
|
-
|
|
1270
|
-
# Type narrowing: after the guard check, lsp is guaranteed to be not None
|
|
1271
|
-
lsp = router.lsp
|
|
1272
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1273
|
-
|
|
1274
|
-
lsp.configure_inlay_hints(
|
|
1275
|
-
variable_types=inlay_variable_types,
|
|
1276
|
-
function_return_types=inlay_return_types,
|
|
1277
|
-
call_argument_names=inlay_function_parameters,
|
|
1278
|
-
generic_types=inlay_generic_types,
|
|
1279
|
-
call_argument_names_matching=inlay_parameter_names_matching,
|
|
1280
|
-
)
|
|
1281
|
-
|
|
1282
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1283
|
-
uri = lsp.open_document(file_path)
|
|
1284
|
-
content = file_path.read_text()
|
|
1285
|
-
lines = content.splitlines()
|
|
1286
|
-
end_line = max(len(lines) - 1, 0)
|
|
1287
|
-
end_col = len(lines[end_line]) if lines else 0
|
|
1288
|
-
result = lsp.request(
|
|
1289
|
-
"textDocument/inlayHint",
|
|
1290
|
-
{
|
|
1291
|
-
"textDocument": {"uri": uri},
|
|
1292
|
-
"range": {
|
|
1293
|
-
"start": {"line": 0, "character": 0},
|
|
1294
|
-
"end": {"line": end_line, "character": end_col},
|
|
1295
|
-
},
|
|
1296
|
-
},
|
|
1297
|
-
)
|
|
1298
|
-
lsp.close_document(uri)
|
|
1299
|
-
return {"message": "OK", "result": result}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
def semantic_tokens(
|
|
1303
|
-
file: Path,
|
|
1304
|
-
*,
|
|
1305
|
-
config_file: Path | None = None,
|
|
1306
|
-
lsp_server: str | None = None,
|
|
1307
|
-
) -> dict[str, Any]:
|
|
1308
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1309
|
-
guard = _require_language_services(router)
|
|
1310
|
-
if guard:
|
|
1311
|
-
return guard
|
|
1312
|
-
|
|
1313
|
-
# Type narrowing: after the guard check, lsp is guaranteed to be not None
|
|
1314
|
-
lsp = router.lsp
|
|
1315
|
-
assert lsp is not None # Type narrowing for mypy/pyright
|
|
1316
|
-
|
|
1317
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1318
|
-
uri = lsp.open_document(file_path)
|
|
1319
|
-
result = lsp.request("textDocument/semanticTokens/full", {"textDocument": {"uri": uri}})
|
|
1320
|
-
lsp.close_document(uri)
|
|
1321
|
-
return {"message": "OK", "result": result}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
def lsp_health(
|
|
1325
|
-
*,
|
|
1326
|
-
config_file: Path | None = None,
|
|
1327
|
-
lsp_server: str | None = None,
|
|
1328
|
-
) -> dict[str, Any]:
|
|
1329
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1330
|
-
if isinstance(router, MultiLSPRouter):
|
|
1331
|
-
return {"status": router.health_check()}
|
|
1332
|
-
return {"status": {"basedpyright": router.lsp is not None}}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
def apply_code_action(
|
|
1336
|
-
file: str,
|
|
1337
|
-
line: int,
|
|
1338
|
-
col: int,
|
|
1339
|
-
index: int,
|
|
1340
|
-
*,
|
|
1341
|
-
apply: bool = False,
|
|
1342
|
-
confirm_annotations: bool = False,
|
|
1343
|
-
config_file: Path | None = None,
|
|
1344
|
-
lsp_server: str | None = None,
|
|
1345
|
-
) -> dict[str, Any]:
|
|
1346
|
-
"""Preview or apply a single code action at a location."""
|
|
1347
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1348
|
-
if not router.code_actions or not router.lsp:
|
|
1349
|
-
return {
|
|
1350
|
-
"applied": False,
|
|
1351
|
-
"message": "No LSP server available for code actions.",
|
|
1352
|
-
"error": router.lsp_error,
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
file_path = Path(file)
|
|
1356
|
-
if not file_path.is_absolute():
|
|
1357
|
-
file_path = router.root / file_path
|
|
1358
|
-
|
|
1359
|
-
actions = router.code_actions.get_code_actions(file_path, line, col)
|
|
1360
|
-
if not actions:
|
|
1361
|
-
return {"applied": False, "message": "No code actions available."}
|
|
1362
|
-
|
|
1363
|
-
if index < 1 or index > len(actions):
|
|
1364
|
-
return {
|
|
1365
|
-
"applied": False,
|
|
1366
|
-
"message": f"Invalid index {index}. Available actions: 1..{len(actions)}.",
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1369
|
-
action = actions[index - 1]
|
|
1370
|
-
if action.get("disabled"):
|
|
1371
|
-
return {"applied": False, "message": "Selected action is disabled by the server."}
|
|
1372
|
-
|
|
1373
|
-
resolved = action
|
|
1374
|
-
if "edit" not in action and "data" in action:
|
|
1375
|
-
try:
|
|
1376
|
-
resolved = router.lsp.request("codeAction/resolve", action)
|
|
1377
|
-
except Exception as exc:
|
|
1378
|
-
logger.debug("Failed to resolve code action: %s", exc)
|
|
1379
|
-
|
|
1380
|
-
edit = resolved.get("edit") or action.get("edit")
|
|
1381
|
-
command = resolved.get("command") or action.get("command")
|
|
1382
|
-
|
|
1383
|
-
if edit:
|
|
1384
|
-
needs_confirmation = workspace_edit_needs_confirmation(edit)
|
|
1385
|
-
if apply and needs_confirmation and not confirm_annotations:
|
|
1386
|
-
return {
|
|
1387
|
-
"applied": False,
|
|
1388
|
-
"needs_confirmation": True,
|
|
1389
|
-
"message": "Action requires confirmation via change annotations.",
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
if not apply:
|
|
1393
|
-
preview_map = preview_workspace_edit(edit, root=router.root)
|
|
1394
|
-
previews: list[dict[str, Any]] = []
|
|
1395
|
-
patch_chunks: list[str] = []
|
|
1396
|
-
for path, (before, after) in preview_map.items():
|
|
1397
|
-
patch_chunks.append(build_unified_diff(path, before, after))
|
|
1398
|
-
previews.append(
|
|
1399
|
-
{
|
|
1400
|
-
"file": str(path),
|
|
1401
|
-
"before": before,
|
|
1402
|
-
"after": after,
|
|
1403
|
-
"title": action.get("title", "Unnamed action"),
|
|
1404
|
-
"needs_confirmation": needs_confirmation,
|
|
1405
|
-
},
|
|
1406
|
-
)
|
|
1407
|
-
return {
|
|
1408
|
-
"applied": False,
|
|
1409
|
-
"previews": previews,
|
|
1410
|
-
"patch": "".join(patch_chunks),
|
|
1411
|
-
"message": "Use --apply to apply the selected action.",
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
stamp = datetime.utcnow().strftime("%Y%m%d-%H%M%S")
|
|
1415
|
-
backup_dir = router.root / ".vds-lsp" / "backups" / stamp
|
|
1416
|
-
changed = apply_workspace_edit(edit, root=router.root, backup_dir=backup_dir, dry_run=False)
|
|
1417
|
-
return {
|
|
1418
|
-
"applied": bool(changed),
|
|
1419
|
-
"backup_dir": str(backup_dir),
|
|
1420
|
-
"message": "Applied code action." if changed else "No changes applied.",
|
|
1421
|
-
}
|
|
1422
|
-
|
|
1423
|
-
if command:
|
|
1424
|
-
if not apply:
|
|
1425
|
-
return {
|
|
1426
|
-
"applied": False,
|
|
1427
|
-
"command": command,
|
|
1428
|
-
"message": "Use --apply to execute the selected action.",
|
|
1429
|
-
}
|
|
1430
|
-
try:
|
|
1431
|
-
payload = command if isinstance(command, dict) else {"command": command}
|
|
1432
|
-
router.lsp.request("workspace/executeCommand", payload)
|
|
1433
|
-
return {"applied": True, "message": "Executed code action command."}
|
|
1434
|
-
except Exception as exc:
|
|
1435
|
-
logger.debug("Failed to execute code action command: %s", exc)
|
|
1436
|
-
return {"applied": False, "message": "Failed to execute code action command."}
|
|
1437
|
-
|
|
1438
|
-
return {"applied": False, "message": "Selected action has no edit or command."}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
def _action_is_unsafe(action: dict[str, Any]) -> bool:
|
|
1442
|
-
data = action.get("data")
|
|
1443
|
-
if isinstance(data, dict) and data.get("isUnsafe"):
|
|
1444
|
-
return True
|
|
1445
|
-
title = str(action.get("title", "")).lower()
|
|
1446
|
-
return "unsafe" in title
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
def _apply_code_action_by_kind(
|
|
1450
|
-
router: LSPRouter,
|
|
1451
|
-
file_path: Path,
|
|
1452
|
-
kind_prefix: str,
|
|
1453
|
-
*,
|
|
1454
|
-
apply: bool,
|
|
1455
|
-
allow_unsafe: bool,
|
|
1456
|
-
) -> dict[str, Any]:
|
|
1457
|
-
if not router.code_actions or not router.lsp:
|
|
1458
|
-
return {"applied": False, "message": "No LSP server available for code actions."}
|
|
1459
|
-
only = [kind_prefix]
|
|
1460
|
-
if kind_prefix == "source.fixAll":
|
|
1461
|
-
only.append("source.fixAll.ruff")
|
|
1462
|
-
actions = router.code_actions.get_code_actions(file_path, 1, 1, only=only)
|
|
1463
|
-
selected = None
|
|
1464
|
-
for action in actions:
|
|
1465
|
-
kind = (action.get("kind") or "").lower()
|
|
1466
|
-
if kind.startswith(kind_prefix.lower()):
|
|
1467
|
-
if not allow_unsafe and _action_is_unsafe(action):
|
|
1468
|
-
continue
|
|
1469
|
-
selected = action
|
|
1470
|
-
break
|
|
1471
|
-
if not selected:
|
|
1472
|
-
return {"applied": False, "message": f"No code action found for kind {kind_prefix}."}
|
|
1473
|
-
|
|
1474
|
-
resolved = selected
|
|
1475
|
-
if "edit" not in selected and "data" in selected:
|
|
1476
|
-
try:
|
|
1477
|
-
resolved = router.lsp.request("codeAction/resolve", selected)
|
|
1478
|
-
except Exception as exc:
|
|
1479
|
-
logger.debug("Failed to resolve code action: %s", exc)
|
|
1480
|
-
|
|
1481
|
-
edit = resolved.get("edit") or selected.get("edit")
|
|
1482
|
-
command = resolved.get("command") or selected.get("command")
|
|
1483
|
-
|
|
1484
|
-
if not apply:
|
|
1485
|
-
if edit:
|
|
1486
|
-
preview_map = preview_workspace_edit(edit, root=router.root)
|
|
1487
|
-
return {
|
|
1488
|
-
"applied": False,
|
|
1489
|
-
"previews": [
|
|
1490
|
-
{"file": str(path), "before": before, "after": after}
|
|
1491
|
-
for path, (before, after) in preview_map.items()
|
|
1492
|
-
],
|
|
1493
|
-
"message": "Use --apply to apply the selected action.",
|
|
1494
|
-
}
|
|
1495
|
-
if command:
|
|
1496
|
-
return {
|
|
1497
|
-
"applied": False,
|
|
1498
|
-
"command": command,
|
|
1499
|
-
"message": "Use --apply to execute the selected action.",
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
if edit:
|
|
1503
|
-
changed = apply_workspace_edit(edit, root=router.root, dry_run=False)
|
|
1504
|
-
return {
|
|
1505
|
-
"applied": bool(changed),
|
|
1506
|
-
"files": [str(path) for path in changed],
|
|
1507
|
-
"message": "Applied code action." if changed else "No changes applied.",
|
|
1508
|
-
}
|
|
1509
|
-
if command:
|
|
1510
|
-
payload = command if isinstance(command, dict) else {"command": command}
|
|
1511
|
-
router.lsp.request("workspace/executeCommand", payload)
|
|
1512
|
-
return {"applied": True, "message": "Executed code action command."}
|
|
1513
|
-
|
|
1514
|
-
return {"applied": False, "message": "Selected action has no edit or command."}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
def format_document(
|
|
1518
|
-
file: Path,
|
|
1519
|
-
*,
|
|
1520
|
-
apply: bool = False,
|
|
1521
|
-
config_file: Path | None = None,
|
|
1522
|
-
lsp_server: str | None = None,
|
|
1523
|
-
) -> dict[str, Any]:
|
|
1524
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1525
|
-
if not isinstance(router, MultiLSPRouter) or not router.ruff_lsp:
|
|
1526
|
-
return {"applied": False, "message": "Ruff LSP is not enabled or available."}
|
|
1527
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1528
|
-
uri = router.ruff_lsp.open_document(file_path)
|
|
1529
|
-
edits = router.ruff_lsp.request(
|
|
1530
|
-
"textDocument/formatting",
|
|
1531
|
-
{"textDocument": {"uri": uri}, "options": {"tabSize": 4, "insertSpaces": True}},
|
|
1532
|
-
)
|
|
1533
|
-
router.ruff_lsp.close_document(uri)
|
|
1534
|
-
if not edits:
|
|
1535
|
-
return {"applied": False, "message": "No formatting changes available."}
|
|
1536
|
-
before = file_path.read_text()
|
|
1537
|
-
after = apply_text_edits(before, edits)
|
|
1538
|
-
if not apply:
|
|
1539
|
-
return {
|
|
1540
|
-
"applied": False,
|
|
1541
|
-
"previews": [{"file": str(file_path), "before": before, "after": after}],
|
|
1542
|
-
"message": "Use --apply to apply formatting.",
|
|
1543
|
-
}
|
|
1544
|
-
_ = file_path.write_text(after)
|
|
1545
|
-
return {"applied": True, "message": "Formatted document.", "files": [str(file_path)]}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
def format_range(
|
|
1549
|
-
file: Path,
|
|
1550
|
-
start_line: int,
|
|
1551
|
-
start_col: int,
|
|
1552
|
-
end_line: int,
|
|
1553
|
-
end_col: int,
|
|
1554
|
-
*,
|
|
1555
|
-
apply: bool = False,
|
|
1556
|
-
config_file: Path | None = None,
|
|
1557
|
-
lsp_server: str | None = None,
|
|
1558
|
-
) -> dict[str, Any]:
|
|
1559
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1560
|
-
if not isinstance(router, MultiLSPRouter) or not router.ruff_lsp:
|
|
1561
|
-
return {"applied": False, "message": "Ruff LSP is not enabled or available."}
|
|
1562
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1563
|
-
uri = router.ruff_lsp.open_document(file_path)
|
|
1564
|
-
params = {
|
|
1565
|
-
"textDocument": {"uri": uri},
|
|
1566
|
-
"range": {
|
|
1567
|
-
"start": {"line": start_line - 1, "character": start_col - 1},
|
|
1568
|
-
"end": {"line": end_line - 1, "character": end_col - 1},
|
|
1569
|
-
},
|
|
1570
|
-
"options": {"tabSize": 4, "insertSpaces": True},
|
|
1571
|
-
}
|
|
1572
|
-
edits = router.ruff_lsp.request("textDocument/rangeFormatting", params)
|
|
1573
|
-
router.ruff_lsp.close_document(uri)
|
|
1574
|
-
if not edits:
|
|
1575
|
-
return {"applied": False, "message": "No formatting changes available."}
|
|
1576
|
-
before = file_path.read_text()
|
|
1577
|
-
after = apply_text_edits(before, edits)
|
|
1578
|
-
if not apply:
|
|
1579
|
-
return {
|
|
1580
|
-
"applied": False,
|
|
1581
|
-
"previews": [{"file": str(file_path), "before": before, "after": after}],
|
|
1582
|
-
"message": "Use --apply to apply formatting.",
|
|
1583
|
-
}
|
|
1584
|
-
_ = file_path.write_text(after)
|
|
1585
|
-
return {"applied": True, "message": "Formatted range.", "files": [str(file_path)]}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
def organize_imports(
|
|
1589
|
-
file: Path,
|
|
1590
|
-
*,
|
|
1591
|
-
apply: bool = False,
|
|
1592
|
-
config_file: Path | None = None,
|
|
1593
|
-
lsp_server: str | None = None,
|
|
1594
|
-
) -> dict[str, Any]:
|
|
1595
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1596
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1597
|
-
return _apply_code_action_by_kind(
|
|
1598
|
-
router,
|
|
1599
|
-
file_path,
|
|
1600
|
-
"source.organizeImports",
|
|
1601
|
-
apply=apply,
|
|
1602
|
-
allow_unsafe=getattr(router.config, "fixes_allow_unsafe", False),
|
|
1603
|
-
)
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
def fix_all(
|
|
1607
|
-
file: Path,
|
|
1608
|
-
*,
|
|
1609
|
-
apply: bool = False,
|
|
1610
|
-
config_file: Path | None = None,
|
|
1611
|
-
lsp_server: str | None = None,
|
|
1612
|
-
) -> dict[str, Any]:
|
|
1613
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1614
|
-
file_path = file if file.is_absolute() else router.root / file
|
|
1615
|
-
return _apply_code_action_by_kind(
|
|
1616
|
-
router,
|
|
1617
|
-
file_path,
|
|
1618
|
-
"source.fixAll",
|
|
1619
|
-
apply=apply,
|
|
1620
|
-
allow_unsafe=getattr(router.config, "fixes_allow_unsafe", False),
|
|
1621
|
-
)
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
def add_type_ignore_comment(
|
|
1625
|
-
file: str,
|
|
1626
|
-
line: int,
|
|
1627
|
-
col: int,
|
|
1628
|
-
*,
|
|
1629
|
-
error_code: str | None = None,
|
|
1630
|
-
apply: bool = False,
|
|
1631
|
-
confirm_annotations: bool = False,
|
|
1632
|
-
config_file: Path | None = None,
|
|
1633
|
-
lsp_server: str | None = None,
|
|
1634
|
-
) -> dict[str, Any]:
|
|
1635
|
-
"""Add a type ignore comment to suppress a diagnostic.
|
|
1636
|
-
|
|
1637
|
-
This function searches for code actions that add '# type: ignore' comments
|
|
1638
|
-
at the specified location. If an error_code is provided, it will prefer
|
|
1639
|
-
'# type: ignore[error-code]' format.
|
|
1640
|
-
|
|
1641
|
-
Args:
|
|
1642
|
-
file: Path to the file
|
|
1643
|
-
line: 1-based line number
|
|
1644
|
-
col: 1-based column number
|
|
1645
|
-
error_code: Optional specific error code to ignore (e.g., 'reportOptionalMemberAccess')
|
|
1646
|
-
apply: If True, apply the change; if False, preview only
|
|
1647
|
-
confirm_annotations: Allow edits that require change annotations
|
|
1648
|
-
config_file: Optional path to config file
|
|
1649
|
-
lsp_server: Override LSP server selection
|
|
1650
|
-
|
|
1651
|
-
Returns:
|
|
1652
|
-
Dictionary with preview/apply result
|
|
1653
|
-
"""
|
|
1654
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1655
|
-
if not router.code_actions or not router.lsp:
|
|
1656
|
-
return {
|
|
1657
|
-
"applied": False,
|
|
1658
|
-
"message": "No LSP server available for code actions.",
|
|
1659
|
-
"error": router.lsp_error,
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
file_path = Path(file)
|
|
1663
|
-
if not file_path.is_absolute():
|
|
1664
|
-
file_path = router.root / file_path
|
|
1665
|
-
|
|
1666
|
-
# Get diagnostics at the location to find available ignore actions
|
|
1667
|
-
try:
|
|
1668
|
-
if router.lsp:
|
|
1669
|
-
uri = router.lsp.open_document(file_path)
|
|
1670
|
-
diagnostics_result = router.lsp.request(
|
|
1671
|
-
"textDocument/diagnostic", {"textDocument": {"uri": uri}}
|
|
1672
|
-
)
|
|
1673
|
-
diagnostics = diagnostics_result.get("items", []) if diagnostics_result else []
|
|
1674
|
-
else:
|
|
1675
|
-
diagnostics = []
|
|
1676
|
-
except Exception as exc:
|
|
1677
|
-
logger.debug("Failed to get diagnostics: %s", exc)
|
|
1678
|
-
diagnostics = []
|
|
1679
|
-
|
|
1680
|
-
# Request code actions with diagnostics context
|
|
1681
|
-
actions = router.code_actions.get_code_actions(file_path, line, col, diagnostics=diagnostics)
|
|
1682
|
-
|
|
1683
|
-
# Filter for ignore comment actions
|
|
1684
|
-
ignore_actions = []
|
|
1685
|
-
for action in actions:
|
|
1686
|
-
title = action.get("title", "").lower()
|
|
1687
|
-
# Look for actions related to type ignore comments
|
|
1688
|
-
if (
|
|
1689
|
-
"ignore" in title
|
|
1690
|
-
or "suppress" in title
|
|
1691
|
-
or "pyright: ignore" in title
|
|
1692
|
-
or "type: ignore" in title
|
|
1693
|
-
):
|
|
1694
|
-
# If error_code specified, prefer actions that include it
|
|
1695
|
-
if error_code:
|
|
1696
|
-
if error_code in title or f"[{error_code}]" in title:
|
|
1697
|
-
ignore_actions.insert(0, action) # Prioritize exact match
|
|
1698
|
-
else:
|
|
1699
|
-
ignore_actions.append(action)
|
|
1700
|
-
else:
|
|
1701
|
-
ignore_actions.append(action)
|
|
1702
|
-
|
|
1703
|
-
if not ignore_actions:
|
|
1704
|
-
return {
|
|
1705
|
-
"applied": False,
|
|
1706
|
-
"message": "No ignore comment actions available at this location.",
|
|
1707
|
-
"actions_available": len(actions),
|
|
1708
|
-
"hint": "Make sure there is a diagnostic at this location that can be suppressed.",
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1711
|
-
# Use the first matching ignore action
|
|
1712
|
-
action = ignore_actions[0]
|
|
1713
|
-
|
|
1714
|
-
if action.get("disabled"):
|
|
1715
|
-
return {
|
|
1716
|
-
"applied": False,
|
|
1717
|
-
"message": "Selected ignore action is disabled by the server.",
|
|
1718
|
-
}
|
|
1719
|
-
|
|
1720
|
-
# Resolve the action if needed
|
|
1721
|
-
resolved = action
|
|
1722
|
-
if "edit" not in action and "data" in action:
|
|
1723
|
-
try:
|
|
1724
|
-
resolved = router.lsp.request("codeAction/resolve", action)
|
|
1725
|
-
except Exception as exc:
|
|
1726
|
-
logger.debug("Failed to resolve code action: %s", exc)
|
|
1727
|
-
|
|
1728
|
-
edit = resolved.get("edit") or action.get("edit")
|
|
1729
|
-
command = resolved.get("command") or action.get("command")
|
|
1730
|
-
|
|
1731
|
-
if edit:
|
|
1732
|
-
needs_confirmation = workspace_edit_needs_confirmation(edit)
|
|
1733
|
-
if apply and needs_confirmation and not confirm_annotations:
|
|
1734
|
-
return {
|
|
1735
|
-
"applied": False,
|
|
1736
|
-
"needs_confirmation": True,
|
|
1737
|
-
"message": "Action requires confirmation via change annotations.",
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
if not apply:
|
|
1741
|
-
preview_map = preview_workspace_edit(edit, root=router.root)
|
|
1742
|
-
previews: list[dict[str, Any]] = []
|
|
1743
|
-
patch_chunks: list[str] = []
|
|
1744
|
-
for path, (before, after) in preview_map.items():
|
|
1745
|
-
patch_chunks.append(build_unified_diff(path, before, after))
|
|
1746
|
-
previews.append(
|
|
1747
|
-
{
|
|
1748
|
-
"file": str(path),
|
|
1749
|
-
"before": before,
|
|
1750
|
-
"after": after,
|
|
1751
|
-
"title": action.get("title", "Unnamed action"),
|
|
1752
|
-
"needs_confirmation": needs_confirmation,
|
|
1753
|
-
},
|
|
1754
|
-
)
|
|
1755
|
-
return {
|
|
1756
|
-
"applied": False,
|
|
1757
|
-
"previews": previews,
|
|
1758
|
-
"patch": "".join(patch_chunks),
|
|
1759
|
-
"message": "Use --apply to add the ignore comment.",
|
|
1760
|
-
"action_title": action.get("title"),
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
# Apply the edit
|
|
1764
|
-
stamp = datetime.utcnow().strftime("%Y%m%d-%H%M%S")
|
|
1765
|
-
backup_dir = router.root / ".vds-lsp" / "backups" / stamp
|
|
1766
|
-
changed = apply_workspace_edit(edit, root=router.root, backup_dir=backup_dir, dry_run=False)
|
|
1767
|
-
return {
|
|
1768
|
-
"applied": bool(changed),
|
|
1769
|
-
"backup_dir": str(backup_dir),
|
|
1770
|
-
"message": "Added type ignore comment." if changed else "No changes applied.",
|
|
1771
|
-
"action_title": action.get("title"),
|
|
1772
|
-
}
|
|
1773
|
-
|
|
1774
|
-
if command:
|
|
1775
|
-
if not apply:
|
|
1776
|
-
return {
|
|
1777
|
-
"applied": False,
|
|
1778
|
-
"command": command,
|
|
1779
|
-
"message": "Use --apply to execute the ignore comment command.",
|
|
1780
|
-
"action_title": action.get("title"),
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
try:
|
|
1784
|
-
payload = command if isinstance(command, dict) else {"command": command}
|
|
1785
|
-
router.lsp.request("workspace/executeCommand", payload)
|
|
1786
|
-
return {
|
|
1787
|
-
"applied": True,
|
|
1788
|
-
"message": "Executed ignore comment command.",
|
|
1789
|
-
"action_title": action.get("title"),
|
|
1790
|
-
}
|
|
1791
|
-
except Exception as exc:
|
|
1792
|
-
logger.debug("Failed to execute ignore comment command: %s", exc)
|
|
1793
|
-
return {
|
|
1794
|
-
"applied": False,
|
|
1795
|
-
"message": f"Failed to execute command: {exc}",
|
|
1796
|
-
}
|
|
1797
|
-
|
|
1798
|
-
return {
|
|
1799
|
-
"applied": False,
|
|
1800
|
-
"message": "No edit or command found in the ignore action.",
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
def index_workspace(
|
|
1805
|
-
path: Path,
|
|
1806
|
-
force: bool = False,
|
|
1807
|
-
*,
|
|
1808
|
-
config_file: Path | None = None,
|
|
1809
|
-
lsp_server: str | None = None,
|
|
1810
|
-
progress: Any | None = None,
|
|
1811
|
-
parallel: bool = False,
|
|
1812
|
-
**kwargs: Any,
|
|
1813
|
-
):
|
|
1814
|
-
router = _build_router(path, config_file=config_file, lsp_server=lsp_server)
|
|
1815
|
-
return router.indexer.index_directory(force=force, progress=progress, parallel=parallel)
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
def document_highlight(
|
|
1819
|
-
file: str,
|
|
1820
|
-
line: int,
|
|
1821
|
-
col: int,
|
|
1822
|
-
*,
|
|
1823
|
-
config_file: Path | None = None,
|
|
1824
|
-
lsp_server: str | None = None,
|
|
1825
|
-
) -> dict[str, Any]:
|
|
1826
|
-
"""Get document highlights for a symbol at a location.
|
|
1827
|
-
|
|
1828
|
-
Returns all references to the symbol in the current document.
|
|
1829
|
-
Distinguishes between read and write references.
|
|
1830
|
-
Falls back to AST-based search if LSP unavailable.
|
|
1831
|
-
"""
|
|
1832
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1833
|
-
file_path = Path(file)
|
|
1834
|
-
if not file_path.is_absolute():
|
|
1835
|
-
file_path = router.root / file_path
|
|
1836
|
-
|
|
1837
|
-
# Try LSP first
|
|
1838
|
-
if router.lsp:
|
|
1839
|
-
uri: str | None = None
|
|
1840
|
-
try:
|
|
1841
|
-
uri = router.lsp.open_document(file_path)
|
|
1842
|
-
params = {
|
|
1843
|
-
"textDocument": {"uri": uri},
|
|
1844
|
-
"position": {"line": line - 1, "character": col - 1},
|
|
1845
|
-
}
|
|
1846
|
-
result = router.lsp.request("textDocument/documentHighlight", params)
|
|
1847
|
-
if result:
|
|
1848
|
-
highlights: list[dict[str, Any]] = []
|
|
1849
|
-
for hl in result:
|
|
1850
|
-
range_info = hl.get("range", {})
|
|
1851
|
-
start = range_info.get("start", {})
|
|
1852
|
-
end = range_info.get("end", {})
|
|
1853
|
-
kind = hl.get("kind", 0) # 1=Text, 2=Read, 3=Write
|
|
1854
|
-
|
|
1855
|
-
highlights.append(
|
|
1856
|
-
{
|
|
1857
|
-
"range": {
|
|
1858
|
-
"start": {
|
|
1859
|
-
"line": start.get("line", 0) + 1,
|
|
1860
|
-
"character": start.get("character", 0) + 1,
|
|
1861
|
-
},
|
|
1862
|
-
"end": {
|
|
1863
|
-
"line": end.get("line", 0) + 1,
|
|
1864
|
-
"character": end.get("character", 0) + 1,
|
|
1865
|
-
},
|
|
1866
|
-
},
|
|
1867
|
-
"kind": kind,
|
|
1868
|
-
"kind_name": _highlight_kind_name(kind),
|
|
1869
|
-
},
|
|
1870
|
-
)
|
|
1871
|
-
return {"source": "lsp", "file": str(file_path), "highlights": highlights}
|
|
1872
|
-
except Exception as exc:
|
|
1873
|
-
logger.debug("LSP document highlight failed: %s", exc)
|
|
1874
|
-
finally:
|
|
1875
|
-
if uri and router.lsp:
|
|
1876
|
-
router.lsp.close_document(uri)
|
|
1877
|
-
|
|
1878
|
-
# Fallback to AST - get symbol at position and search in same file
|
|
1879
|
-
symbol_name = router.indexer.get_symbol_at_position(file_path, line, col)
|
|
1880
|
-
if not symbol_name:
|
|
1881
|
-
return {
|
|
1882
|
-
"source": "ast",
|
|
1883
|
-
"file": str(file_path),
|
|
1884
|
-
"highlights": [],
|
|
1885
|
-
"message": "No symbol found at location",
|
|
1886
|
-
}
|
|
1887
|
-
|
|
1888
|
-
# Get all document symbols and filter for matches
|
|
1889
|
-
# Note: get_document_symbols returns SymbolInformation objects
|
|
1890
|
-
doc_symbols = router.indexer.get_document_symbols(file_path)
|
|
1891
|
-
highlights: list[dict[str, Any]] = []
|
|
1892
|
-
|
|
1893
|
-
for sym in doc_symbols:
|
|
1894
|
-
# SymbolInformation has a location attribute with line/column info
|
|
1895
|
-
if sym.name == symbol_name:
|
|
1896
|
-
loc = sym.location
|
|
1897
|
-
sym_range = {
|
|
1898
|
-
"start": {"line": loc.line, "character": loc.column},
|
|
1899
|
-
"end": {"line": loc.end_line, "character": loc.end_column},
|
|
1900
|
-
}
|
|
1901
|
-
highlights.append(
|
|
1902
|
-
{
|
|
1903
|
-
"range": sym_range,
|
|
1904
|
-
"kind": 1, # Default to Text for AST
|
|
1905
|
-
"kind_name": "Text",
|
|
1906
|
-
},
|
|
1907
|
-
)
|
|
1908
|
-
|
|
1909
|
-
return {"source": "ast", "file": str(file_path), "highlights": highlights}
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
def _highlight_kind_name(kind: int) -> str:
|
|
1913
|
-
"""Convert LSP DocumentHighlightKind to name."""
|
|
1914
|
-
kind_map = {
|
|
1915
|
-
0: "Unknown",
|
|
1916
|
-
1: "Text",
|
|
1917
|
-
2: "Read",
|
|
1918
|
-
3: "Write",
|
|
1919
|
-
}
|
|
1920
|
-
return kind_map.get(kind, "Unknown")
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
def _lsp_symbol_kind_to_name(kind: int) -> str:
|
|
1924
|
-
"""Convert LSP SymbolKind number to our SymbolKind string.
|
|
1925
|
-
|
|
1926
|
-
LSP SymbolKind values (from LSP spec):
|
|
1927
|
-
1: File, 2: Module, 3: Namespace, 4: Package, 5: Class,
|
|
1928
|
-
6: Method, 7: Property, 8: Field, 9: Constructor, 10: Enum,
|
|
1929
|
-
11: Interface, 12: Function, 13: Variable, 14: Constant,
|
|
1930
|
-
15: String, 16: Number, 17: Boolean, 18: Array, 19: Object,
|
|
1931
|
-
20: Key, 21: Null, 22: EnumMember, 23: Struct, 24: Event,
|
|
1932
|
-
25: Operator, 26: TypeParameter
|
|
1933
|
-
"""
|
|
1934
|
-
kind_map = {
|
|
1935
|
-
1: "File",
|
|
1936
|
-
2: "Module",
|
|
1937
|
-
3: "Namespace",
|
|
1938
|
-
4: "Package",
|
|
1939
|
-
5: "Class",
|
|
1940
|
-
6: "Method",
|
|
1941
|
-
7: "Property",
|
|
1942
|
-
8: "Field",
|
|
1943
|
-
9: "Constructor",
|
|
1944
|
-
10: "Enum",
|
|
1945
|
-
11: "Interface",
|
|
1946
|
-
12: "Function",
|
|
1947
|
-
13: "Variable",
|
|
1948
|
-
14: "Constant",
|
|
1949
|
-
15: "String",
|
|
1950
|
-
16: "Number",
|
|
1951
|
-
17: "Boolean",
|
|
1952
|
-
18: "Array",
|
|
1953
|
-
19: "Object",
|
|
1954
|
-
20: "Key",
|
|
1955
|
-
21: "Null",
|
|
1956
|
-
22: "EnumMember",
|
|
1957
|
-
23: "Struct",
|
|
1958
|
-
24: "Event",
|
|
1959
|
-
25: "Operator",
|
|
1960
|
-
26: "TypeParameter",
|
|
1961
|
-
}
|
|
1962
|
-
return kind_map.get(kind, "Unknown")
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
def document_links(
|
|
1966
|
-
file: str,
|
|
1967
|
-
*,
|
|
1968
|
-
config_file: Path | None = None,
|
|
1969
|
-
lsp_server: str | None = None,
|
|
1970
|
-
) -> dict[str, Any]:
|
|
1971
|
-
"""Get document links for a file.
|
|
1972
|
-
|
|
1973
|
-
Returns clickable links found in the document including:
|
|
1974
|
-
- URLs (http/https)
|
|
1975
|
-
- Import statements that resolve to workspace files
|
|
1976
|
-
- Relative file paths in strings
|
|
1977
|
-
|
|
1978
|
-
Falls back to AST-based link detection if LSP unavailable.
|
|
1979
|
-
"""
|
|
1980
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
1981
|
-
file_path = Path(file)
|
|
1982
|
-
if not file_path.is_absolute():
|
|
1983
|
-
file_path = router.root / file_path
|
|
1984
|
-
|
|
1985
|
-
if not file_path.exists():
|
|
1986
|
-
return {"source": "error", "file": str(file_path), "links": [], "message": "File not found"}
|
|
1987
|
-
|
|
1988
|
-
# Try LSP first
|
|
1989
|
-
if router.lsp:
|
|
1990
|
-
uri: str | None = None
|
|
1991
|
-
try:
|
|
1992
|
-
uri = router.lsp.open_document(file_path)
|
|
1993
|
-
params = {"textDocument": {"uri": uri}}
|
|
1994
|
-
result = router.lsp.request("textDocument/documentLink", params)
|
|
1995
|
-
if result:
|
|
1996
|
-
links: list[dict[str, Any]] = []
|
|
1997
|
-
for link in result:
|
|
1998
|
-
range_info = link.get("range", {})
|
|
1999
|
-
start = range_info.get("start", {})
|
|
2000
|
-
end = range_info.get("end", {})
|
|
2001
|
-
target = link.get("target")
|
|
2002
|
-
tooltip = link.get("tooltip", "")
|
|
2003
|
-
|
|
2004
|
-
link_info = {
|
|
2005
|
-
"range": {
|
|
2006
|
-
"start": {
|
|
2007
|
-
"line": start.get("line", 0) + 1,
|
|
2008
|
-
"character": start.get("character", 0) + 1,
|
|
2009
|
-
},
|
|
2010
|
-
"end": {
|
|
2011
|
-
"line": end.get("line", 0) + 1,
|
|
2012
|
-
"character": end.get("character", 0) + 1,
|
|
2013
|
-
},
|
|
2014
|
-
},
|
|
2015
|
-
}
|
|
2016
|
-
if target:
|
|
2017
|
-
link_info["target"] = target
|
|
2018
|
-
if tooltip:
|
|
2019
|
-
link_info["tooltip"] = tooltip
|
|
2020
|
-
links.append(link_info)
|
|
2021
|
-
return {"source": "lsp", "file": str(file_path), "links": links}
|
|
2022
|
-
except Exception as exc:
|
|
2023
|
-
logger.debug("LSP document link failed: %s", exc)
|
|
2024
|
-
finally:
|
|
2025
|
-
if uri and router.lsp:
|
|
2026
|
-
router.lsp.close_document(uri)
|
|
2027
|
-
|
|
2028
|
-
# Fallback to AST-based link detection
|
|
2029
|
-
links: list[dict[str, Any]] = []
|
|
2030
|
-
try:
|
|
2031
|
-
content = file_path.read_text()
|
|
2032
|
-
lines = content.splitlines()
|
|
2033
|
-
|
|
2034
|
-
import re
|
|
2035
|
-
|
|
2036
|
-
# Pattern 1: URLs (http/https)
|
|
2037
|
-
url_pattern = re.compile(r"https?://[^\s\"'<>]+")
|
|
2038
|
-
|
|
2039
|
-
# Pattern 2: Relative file paths in strings (basic detection)
|
|
2040
|
-
# Matches strings that look like relative paths: "./foo", "../bar", "path/to/file"
|
|
2041
|
-
rel_path_pattern = re.compile(
|
|
2042
|
-
r'["\']([\.A-Za-z_][\w\.\/\-\\\ ]+\.(?:py|txt|md|json|yaml|yml|toml|cfg|ini))["\']'
|
|
2043
|
-
)
|
|
2044
|
-
|
|
2045
|
-
# Pattern 3: Import statements
|
|
2046
|
-
import_pattern = re.compile(r"^\s*(?:from|import)\s+([\w\.]+)")
|
|
2047
|
-
|
|
2048
|
-
for line_idx, line in enumerate(lines, start=1):
|
|
2049
|
-
# Find URLs
|
|
2050
|
-
for match in url_pattern.finditer(line):
|
|
2051
|
-
links.append(
|
|
2052
|
-
{
|
|
2053
|
-
"range": {
|
|
2054
|
-
"start": {"line": line_idx, "character": match.start() + 1},
|
|
2055
|
-
"end": {"line": line_idx, "character": match.end() + 1},
|
|
2056
|
-
},
|
|
2057
|
-
"target": match.group(0),
|
|
2058
|
-
"kind": "url",
|
|
2059
|
-
}
|
|
2060
|
-
)
|
|
2061
|
-
|
|
2062
|
-
# Find relative paths in strings
|
|
2063
|
-
for match in rel_path_pattern.finditer(line):
|
|
2064
|
-
path_str = match.group(1)
|
|
2065
|
-
# Try to resolve relative to current file
|
|
2066
|
-
try:
|
|
2067
|
-
resolved = (file_path.parent / path_str).resolve()
|
|
2068
|
-
if resolved.exists():
|
|
2069
|
-
links.append(
|
|
2070
|
-
{
|
|
2071
|
-
"range": {
|
|
2072
|
-
"start": {"line": line_idx, "character": match.start(1) + 1},
|
|
2073
|
-
"end": {"line": line_idx, "character": match.end(1) + 1},
|
|
2074
|
-
},
|
|
2075
|
-
"target": str(resolved),
|
|
2076
|
-
"kind": "file",
|
|
2077
|
-
}
|
|
2078
|
-
)
|
|
2079
|
-
except Exception:
|
|
2080
|
-
pass
|
|
2081
|
-
|
|
2082
|
-
# Find import statements
|
|
2083
|
-
for match in import_pattern.finditer(line):
|
|
2084
|
-
module_name = match.group(1)
|
|
2085
|
-
links.append(
|
|
2086
|
-
{
|
|
2087
|
-
"range": {
|
|
2088
|
-
"start": {"line": line_idx, "character": match.start(1) + 1},
|
|
2089
|
-
"end": {"line": line_idx, "character": match.end(1) + 1},
|
|
2090
|
-
},
|
|
2091
|
-
"target": module_name,
|
|
2092
|
-
"kind": "import",
|
|
2093
|
-
}
|
|
2094
|
-
)
|
|
2095
|
-
|
|
2096
|
-
except Exception as exc:
|
|
2097
|
-
logger.debug("AST link detection failed: %s", exc)
|
|
2098
|
-
|
|
2099
|
-
return {"source": "ast", "file": str(file_path), "links": links}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
# ============================================================================
|
|
2103
|
-
# Batch Operations
|
|
2104
|
-
# ============================================================================
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
def _collect_python_files(
|
|
2108
|
-
paths: list[Path],
|
|
2109
|
-
root: Path,
|
|
2110
|
-
*,
|
|
2111
|
-
include_paths: list[Path] | None = None,
|
|
2112
|
-
exclude_paths: list[Path] | None = None,
|
|
2113
|
-
git_tracked_only: bool = False,
|
|
2114
|
-
) -> list[Path]:
|
|
2115
|
-
"""Collect Python files from given paths for batch operations.
|
|
2116
|
-
|
|
2117
|
-
Args:
|
|
2118
|
-
paths: List of file/directory paths to process
|
|
2119
|
-
root: Root path for resolving relative paths
|
|
2120
|
-
include_paths: Optional list of paths to include (filters)
|
|
2121
|
-
exclude_paths: Optional list of paths to exclude
|
|
2122
|
-
git_tracked_only: If True, only include git-tracked files
|
|
2123
|
-
|
|
2124
|
-
Returns:
|
|
2125
|
-
List of Python file paths to process
|
|
2126
|
-
"""
|
|
2127
|
-
|
|
2128
|
-
# Ensure root is absolute for path comparisons
|
|
2129
|
-
root = root.resolve()
|
|
2130
|
-
files: list[Path] = []
|
|
2131
|
-
seen: set[Path] = set()
|
|
2132
|
-
|
|
2133
|
-
# Convert filters to Path objects
|
|
2134
|
-
include_set = {p.resolve() for p in include_paths} if include_paths else None
|
|
2135
|
-
exclude_set = {p.resolve() for p in exclude_paths} if exclude_paths else None
|
|
2136
|
-
|
|
2137
|
-
# Get git tracked files if requested
|
|
2138
|
-
git_files: set[Path] | None = None
|
|
2139
|
-
if git_tracked_only:
|
|
2140
|
-
try:
|
|
2141
|
-
result = subprocess.run(
|
|
2142
|
-
["git", "ls-files", "*.py"],
|
|
2143
|
-
cwd=root,
|
|
2144
|
-
capture_output=True,
|
|
2145
|
-
text=True,
|
|
2146
|
-
check=False,
|
|
2147
|
-
)
|
|
2148
|
-
git_files = {root / f for f in result.stdout.splitlines() if f}
|
|
2149
|
-
except FileNotFoundError:
|
|
2150
|
-
logger.warning("git not found, skipping git-tracked filter")
|
|
2151
|
-
|
|
2152
|
-
for path in paths:
|
|
2153
|
-
resolved = path if path.is_absolute() else root / path
|
|
2154
|
-
if not resolved.exists():
|
|
2155
|
-
continue
|
|
2156
|
-
|
|
2157
|
-
if resolved.is_file():
|
|
2158
|
-
if resolved.suffix == ".py":
|
|
2159
|
-
files.append(resolved)
|
|
2160
|
-
continue
|
|
2161
|
-
|
|
2162
|
-
# Directory: walk recursively
|
|
2163
|
-
for item in resolved.rglob("*.py"):
|
|
2164
|
-
if item in seen:
|
|
2165
|
-
continue
|
|
2166
|
-
seen.add(item)
|
|
2167
|
-
|
|
2168
|
-
# Apply include filter
|
|
2169
|
-
if include_set:
|
|
2170
|
-
rel_path = item.relative_to(root)
|
|
2171
|
-
included = False
|
|
2172
|
-
for inc in include_set:
|
|
2173
|
-
if not inc.is_relative_to(root):
|
|
2174
|
-
continue
|
|
2175
|
-
inc_rel = inc.relative_to(root)
|
|
2176
|
-
# Check if include path is a file (exact match)
|
|
2177
|
-
if inc_rel == rel_path:
|
|
2178
|
-
included = True
|
|
2179
|
-
break
|
|
2180
|
-
# Check if include path is a directory (relative to)
|
|
2181
|
-
if rel_path.is_relative_to(inc_rel):
|
|
2182
|
-
included = True
|
|
2183
|
-
break
|
|
2184
|
-
if not included:
|
|
2185
|
-
continue
|
|
2186
|
-
|
|
2187
|
-
# Apply exclude filter
|
|
2188
|
-
if exclude_set:
|
|
2189
|
-
rel_path = item.relative_to(root)
|
|
2190
|
-
excluded = False
|
|
2191
|
-
for exc in exclude_set:
|
|
2192
|
-
if not exc.is_relative_to(root):
|
|
2193
|
-
continue
|
|
2194
|
-
exc_rel = exc.relative_to(root)
|
|
2195
|
-
# Check if exclude path is a file (exact match)
|
|
2196
|
-
if exc_rel == rel_path:
|
|
2197
|
-
excluded = True
|
|
2198
|
-
break
|
|
2199
|
-
# Check if exclude path is a directory (relative to)
|
|
2200
|
-
if rel_path.is_relative_to(exc_rel):
|
|
2201
|
-
excluded = True
|
|
2202
|
-
break
|
|
2203
|
-
if excluded:
|
|
2204
|
-
continue
|
|
2205
|
-
|
|
2206
|
-
# Apply git filter
|
|
2207
|
-
if git_files is not None and item not in git_files:
|
|
2208
|
-
continue
|
|
2209
|
-
|
|
2210
|
-
files.append(item)
|
|
2211
|
-
|
|
2212
|
-
return sorted(files)
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
def _create_backup_dir(root: Path) -> Path:
|
|
2216
|
-
"""Create a backup directory for atomic batch operations."""
|
|
2217
|
-
|
|
2218
|
-
backup_root = root / ".vds-lsp" / "backups"
|
|
2219
|
-
backup_root.mkdir(parents=True, exist_ok=True)
|
|
2220
|
-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
2221
|
-
backup_dir = backup_root / timestamp
|
|
2222
|
-
backup_dir.mkdir(exist_ok=True)
|
|
2223
|
-
return backup_dir
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
def _backup_files(files: list[Path], backup_dir: Path) -> dict[Path, Path]:
|
|
2227
|
-
"""Backup files to backup directory, maintaining directory structure.
|
|
2228
|
-
|
|
2229
|
-
Returns:
|
|
2230
|
-
Dictionary mapping original file to backup file path
|
|
2231
|
-
"""
|
|
2232
|
-
backups: dict[Path, Path] = {}
|
|
2233
|
-
for file_path in files:
|
|
2234
|
-
rel_path = file_path.relative_to(file_path.anchor)
|
|
2235
|
-
backup_file = backup_dir / rel_path
|
|
2236
|
-
backup_file.parent.mkdir(parents=True, exist_ok=True)
|
|
2237
|
-
_ = shutil.copy2(file_path, backup_file)
|
|
2238
|
-
backups[file_path] = backup_file
|
|
2239
|
-
return backups
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
def _process_file_parallel(
|
|
2243
|
-
file_path: Path,
|
|
2244
|
-
operation: str,
|
|
2245
|
-
apply: bool,
|
|
2246
|
-
config_file: Path | None,
|
|
2247
|
-
lsp_server: str | None,
|
|
2248
|
-
) -> dict[str, Any]:
|
|
2249
|
-
"""Process a single file operation in parallel.
|
|
2250
|
-
|
|
2251
|
-
Args:
|
|
2252
|
-
file_path: Path to file to process
|
|
2253
|
-
operation: Operation to perform ('format', 'organize_imports', 'fix_all')
|
|
2254
|
-
apply: Whether to apply changes
|
|
2255
|
-
config_file: Optional config file path
|
|
2256
|
-
lsp_server: Optional LSP server override
|
|
2257
|
-
|
|
2258
|
-
Returns:
|
|
2259
|
-
Dictionary with operation result
|
|
2260
|
-
"""
|
|
2261
|
-
try:
|
|
2262
|
-
if operation == "format":
|
|
2263
|
-
result = format_document(
|
|
2264
|
-
file_path, apply=apply, config_file=config_file, lsp_server=lsp_server
|
|
2265
|
-
)
|
|
2266
|
-
elif operation == "organize_imports":
|
|
2267
|
-
result = organize_imports(
|
|
2268
|
-
file_path, apply=apply, config_file=config_file, lsp_server=lsp_server
|
|
2269
|
-
)
|
|
2270
|
-
elif operation == "fix_all":
|
|
2271
|
-
result = fix_all(file_path, apply=apply, config_file=config_file, lsp_server=lsp_server)
|
|
2272
|
-
else:
|
|
2273
|
-
return {"file": file_path, "error": f"Unknown operation: {operation}"}
|
|
2274
|
-
|
|
2275
|
-
return {"file": file_path, "result": result, "success": True}
|
|
2276
|
-
except Exception as exc:
|
|
2277
|
-
logger.exception("Failed to %s %s: %s", operation, file_path, exc)
|
|
2278
|
-
return {"file": file_path, "error": str(exc), "success": False}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
def batch_format(
|
|
2282
|
-
paths: list[Path],
|
|
2283
|
-
*,
|
|
2284
|
-
apply: bool = False,
|
|
2285
|
-
atomic: bool = True,
|
|
2286
|
-
include_paths: list[Path] | None = None,
|
|
2287
|
-
exclude_paths: list[Path] | None = None,
|
|
2288
|
-
git_tracked_only: bool = False,
|
|
2289
|
-
parallel: bool = True,
|
|
2290
|
-
jobs: int | None = None,
|
|
2291
|
-
progress: Any | None = None,
|
|
2292
|
-
config_file: Path | None = None,
|
|
2293
|
-
lsp_server: str | None = None,
|
|
2294
|
-
**kwargs: Any,
|
|
2295
|
-
) -> dict[str, Any]:
|
|
2296
|
-
"""Format multiple Python files using Ruff LSP.
|
|
2297
|
-
|
|
2298
|
-
Args:
|
|
2299
|
-
paths: List of file/directory paths to format
|
|
2300
|
-
apply: If True, apply formatting changes; otherwise preview only
|
|
2301
|
-
atomic: If True, backup all files and rollback on error
|
|
2302
|
-
include_paths: Optional list of paths to include (filters)
|
|
2303
|
-
exclude_paths: Optional list of paths to exclude
|
|
2304
|
-
git_tracked_only: If True, only process git-tracked files
|
|
2305
|
-
parallel: If True, process files in parallel using ThreadPoolExecutor
|
|
2306
|
-
jobs: Number of parallel jobs (None = auto-detect based on CPU count)
|
|
2307
|
-
progress: Optional Rich Progress object for UI updates
|
|
2308
|
-
config_file: Optional path to pyright config file
|
|
2309
|
-
lsp_server: Optional LSP server command override
|
|
2310
|
-
|
|
2311
|
-
Returns:
|
|
2312
|
-
Dictionary with results including files modified, previews, and summary
|
|
2313
|
-
"""
|
|
2314
|
-
|
|
2315
|
-
router = _build_router(
|
|
2316
|
-
paths[0] if paths else Path.cwd(), config_file=config_file, lsp_server=lsp_server
|
|
2317
|
-
)
|
|
2318
|
-
if not isinstance(router, MultiLSPRouter) or not router.ruff_lsp:
|
|
2319
|
-
return {"success": False, "message": "Ruff LSP is not enabled or available."}
|
|
2320
|
-
|
|
2321
|
-
files = _collect_python_files(
|
|
2322
|
-
paths,
|
|
2323
|
-
router.root,
|
|
2324
|
-
include_paths=include_paths,
|
|
2325
|
-
exclude_paths=exclude_paths,
|
|
2326
|
-
git_tracked_only=git_tracked_only,
|
|
2327
|
-
)
|
|
2328
|
-
|
|
2329
|
-
if not files:
|
|
2330
|
-
return {"success": True, "processed": 0, "message": "No Python files found to process."}
|
|
2331
|
-
|
|
2332
|
-
backup_dir: Path | None = None
|
|
2333
|
-
backups: dict[Path, Path] | None = None
|
|
2334
|
-
|
|
2335
|
-
if atomic and apply:
|
|
2336
|
-
backup_dir = _create_backup_dir(router.root)
|
|
2337
|
-
backups = _backup_files(files, backup_dir)
|
|
2338
|
-
|
|
2339
|
-
results: list[dict[str, Any]] = []
|
|
2340
|
-
errors: list[dict[str, Any]] = []
|
|
2341
|
-
modified: list[Path] = []
|
|
2342
|
-
|
|
2343
|
-
task_id = None
|
|
2344
|
-
if progress:
|
|
2345
|
-
task_id = progress.add_task("Formatting files...", total=len(files))
|
|
2346
|
-
|
|
2347
|
-
# Process files (parallel or sequential)
|
|
2348
|
-
if parallel and len(files) > 1:
|
|
2349
|
-
import os
|
|
2350
|
-
|
|
2351
|
-
# Default to CPU count or 4, whichever is smaller
|
|
2352
|
-
max_workers = jobs or min(os.cpu_count() or 4, 8)
|
|
2353
|
-
if max_workers > len(files):
|
|
2354
|
-
max_workers = len(files)
|
|
2355
|
-
|
|
2356
|
-
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
2357
|
-
futures = {
|
|
2358
|
-
executor.submit(
|
|
2359
|
-
_process_file_parallel,
|
|
2360
|
-
file_path,
|
|
2361
|
-
"format",
|
|
2362
|
-
apply and not atomic,
|
|
2363
|
-
config_file,
|
|
2364
|
-
lsp_server,
|
|
2365
|
-
): file_path
|
|
2366
|
-
for file_path in files
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
for future in as_completed(futures):
|
|
2370
|
-
file_path = futures[future]
|
|
2371
|
-
try:
|
|
2372
|
-
result = future.result()
|
|
2373
|
-
if result.get("success"):
|
|
2374
|
-
op_result = result.get("result", {})
|
|
2375
|
-
if atomic and apply and op_result.get("previews"):
|
|
2376
|
-
results.append({"file": file_path, "result": op_result})
|
|
2377
|
-
elif apply and op_result.get("applied"):
|
|
2378
|
-
modified.append(file_path)
|
|
2379
|
-
elif not apply and op_result.get("previews"):
|
|
2380
|
-
results.append({"file": file_path, "result": op_result})
|
|
2381
|
-
else:
|
|
2382
|
-
errors.append(
|
|
2383
|
-
{"file": str(file_path), "error": result.get("error", "Unknown error")}
|
|
2384
|
-
)
|
|
2385
|
-
logger.error("Failed to format %s: %s", file_path, result.get("error"))
|
|
2386
|
-
if atomic and apply and backups:
|
|
2387
|
-
# Rollback on error
|
|
2388
|
-
for orig, backup in backups.items():
|
|
2389
|
-
_ = shutil.copy2(backup, orig)
|
|
2390
|
-
return {
|
|
2391
|
-
"success": False,
|
|
2392
|
-
"processed": len(results),
|
|
2393
|
-
"errors": errors,
|
|
2394
|
-
"backup_dir": str(backup_dir),
|
|
2395
|
-
"message": f"Rolled back due to error formatting {file_path}",
|
|
2396
|
-
}
|
|
2397
|
-
except Exception as exc:
|
|
2398
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2399
|
-
logger.exception("Failed to format %s: %s", file_path, exc)
|
|
2400
|
-
if atomic and apply and backups:
|
|
2401
|
-
# Rollback on error
|
|
2402
|
-
for orig, backup in backups.items():
|
|
2403
|
-
_ = shutil.copy2(backup, orig)
|
|
2404
|
-
return {
|
|
2405
|
-
"success": False,
|
|
2406
|
-
"processed": len(results),
|
|
2407
|
-
"errors": errors,
|
|
2408
|
-
"backup_dir": str(backup_dir),
|
|
2409
|
-
"message": f"Rolled back due to error formatting {file_path}",
|
|
2410
|
-
}
|
|
2411
|
-
finally:
|
|
2412
|
-
if progress and task_id is not None:
|
|
2413
|
-
progress.update(task_id, advance=1)
|
|
2414
|
-
else:
|
|
2415
|
-
# Sequential processing (original behavior)
|
|
2416
|
-
for file_path in files:
|
|
2417
|
-
try:
|
|
2418
|
-
result = format_document(
|
|
2419
|
-
file_path,
|
|
2420
|
-
apply=apply and not atomic,
|
|
2421
|
-
config_file=config_file,
|
|
2422
|
-
lsp_server=lsp_server,
|
|
2423
|
-
)
|
|
2424
|
-
if atomic and apply and result.get("previews"):
|
|
2425
|
-
# Store preview for atomic application
|
|
2426
|
-
results.append({"file": file_path, "result": result})
|
|
2427
|
-
elif apply and result.get("applied"):
|
|
2428
|
-
modified.append(file_path)
|
|
2429
|
-
elif not apply and result.get("previews"):
|
|
2430
|
-
results.append({"file": file_path, "result": result})
|
|
2431
|
-
except Exception as exc:
|
|
2432
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2433
|
-
logger.exception("Failed to format %s: %s", file_path, exc)
|
|
2434
|
-
if atomic and apply and backups:
|
|
2435
|
-
# Rollback on error
|
|
2436
|
-
for orig, backup in backups.items():
|
|
2437
|
-
_ = shutil.copy2(backup, orig)
|
|
2438
|
-
return {
|
|
2439
|
-
"success": False,
|
|
2440
|
-
"processed": len(results),
|
|
2441
|
-
"errors": errors,
|
|
2442
|
-
"backup_dir": str(backup_dir),
|
|
2443
|
-
"message": f"Rolled back due to error formatting {file_path}",
|
|
2444
|
-
}
|
|
2445
|
-
finally:
|
|
2446
|
-
if progress and task_id is not None:
|
|
2447
|
-
progress.update(task_id, advance=1)
|
|
2448
|
-
|
|
2449
|
-
# Apply all changes atomically if needed
|
|
2450
|
-
if atomic and apply and backups:
|
|
2451
|
-
for item in results:
|
|
2452
|
-
file_path = item["file"]
|
|
2453
|
-
result = item["result"]
|
|
2454
|
-
if result.get("previews"):
|
|
2455
|
-
preview = result["previews"][0]
|
|
2456
|
-
file_path.write_text(preview["after"])
|
|
2457
|
-
modified.append(file_path)
|
|
2458
|
-
|
|
2459
|
-
previews: list[dict[str, Any]] = []
|
|
2460
|
-
for item in results:
|
|
2461
|
-
result = item["result"]
|
|
2462
|
-
if result.get("previews"):
|
|
2463
|
-
previews.extend(result["previews"])
|
|
2464
|
-
|
|
2465
|
-
return {
|
|
2466
|
-
"success": len(errors) == 0,
|
|
2467
|
-
"processed": len(files),
|
|
2468
|
-
"modified": len(modified),
|
|
2469
|
-
"errors": len(errors),
|
|
2470
|
-
"files": [str(f) for f in modified],
|
|
2471
|
-
"previews": previews if not apply else [],
|
|
2472
|
-
"error_details": errors,
|
|
2473
|
-
"backup_dir": str(backup_dir) if backup_dir else None,
|
|
2474
|
-
"parallel": parallel,
|
|
2475
|
-
"max_workers": jobs if jobs else ("auto" if parallel else 1),
|
|
2476
|
-
"message": f"Processed {len(files)} files, modified {len(modified)} files with {len(errors)} errors.",
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
def batch_organize_imports(
|
|
2481
|
-
paths: list[Path],
|
|
2482
|
-
*,
|
|
2483
|
-
apply: bool = False,
|
|
2484
|
-
atomic: bool = True,
|
|
2485
|
-
include_paths: list[Path] | None = None,
|
|
2486
|
-
exclude_paths: list[Path] | None = None,
|
|
2487
|
-
git_tracked_only: bool = False,
|
|
2488
|
-
parallel: bool = True,
|
|
2489
|
-
jobs: int | None = None,
|
|
2490
|
-
progress: Any | None = None,
|
|
2491
|
-
config_file: Path | None = None,
|
|
2492
|
-
lsp_server: str | None = None,
|
|
2493
|
-
**kwargs: Any,
|
|
2494
|
-
) -> dict[str, Any]:
|
|
2495
|
-
"""Organize imports across multiple Python files.
|
|
2496
|
-
|
|
2497
|
-
Args:
|
|
2498
|
-
paths: List of file/directory paths to process
|
|
2499
|
-
apply: If True, apply import organization; otherwise preview only
|
|
2500
|
-
atomic: If True, backup all files and rollback on error
|
|
2501
|
-
include_paths: Optional list of paths to include (filters)
|
|
2502
|
-
exclude_paths: Optional list of paths to exclude
|
|
2503
|
-
git_tracked_only: If True, only process git-tracked files
|
|
2504
|
-
parallel: If True, process files in parallel using ThreadPoolExecutor
|
|
2505
|
-
jobs: Number of parallel jobs (None = auto-detect based on CPU count)
|
|
2506
|
-
progress: Optional Rich Progress object for UI updates
|
|
2507
|
-
config_file: Optional path to pyright config file
|
|
2508
|
-
lsp_server: Optional LSP server command override
|
|
2509
|
-
|
|
2510
|
-
Returns:
|
|
2511
|
-
Dictionary with results including files modified, previews, and summary
|
|
2512
|
-
"""
|
|
2513
|
-
router = _build_router(
|
|
2514
|
-
paths[0] if paths else Path.cwd(), config_file=config_file, lsp_server=lsp_server
|
|
2515
|
-
)
|
|
2516
|
-
|
|
2517
|
-
files = _collect_python_files(
|
|
2518
|
-
paths,
|
|
2519
|
-
router.root,
|
|
2520
|
-
include_paths=include_paths,
|
|
2521
|
-
exclude_paths=exclude_paths,
|
|
2522
|
-
git_tracked_only=git_tracked_only,
|
|
2523
|
-
)
|
|
2524
|
-
|
|
2525
|
-
if not files:
|
|
2526
|
-
return {"success": True, "processed": 0, "message": "No Python files found to process."}
|
|
2527
|
-
|
|
2528
|
-
backup_dir: Path | None = None
|
|
2529
|
-
backups: dict[Path, Path] | None = None
|
|
2530
|
-
|
|
2531
|
-
if atomic and apply:
|
|
2532
|
-
backup_dir = _create_backup_dir(router.root)
|
|
2533
|
-
backups = _backup_files(files, backup_dir)
|
|
2534
|
-
|
|
2535
|
-
results: list[dict[str, Any]] = []
|
|
2536
|
-
errors: list[dict[str, Any]] = []
|
|
2537
|
-
modified: list[Path] = []
|
|
2538
|
-
|
|
2539
|
-
task_id = None
|
|
2540
|
-
if progress:
|
|
2541
|
-
task_id = progress.add_task("Organizing imports...", total=len(files))
|
|
2542
|
-
|
|
2543
|
-
# Process files (parallel or sequential)
|
|
2544
|
-
if parallel and len(files) > 1:
|
|
2545
|
-
import os
|
|
2546
|
-
|
|
2547
|
-
# Default to CPU count or 4, whichever is smaller
|
|
2548
|
-
max_workers = jobs or min(os.cpu_count() or 4, 8)
|
|
2549
|
-
if max_workers > len(files):
|
|
2550
|
-
max_workers = len(files)
|
|
2551
|
-
|
|
2552
|
-
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
2553
|
-
futures = {
|
|
2554
|
-
executor.submit(
|
|
2555
|
-
_process_file_parallel,
|
|
2556
|
-
file_path,
|
|
2557
|
-
"organize_imports",
|
|
2558
|
-
apply and not atomic,
|
|
2559
|
-
config_file,
|
|
2560
|
-
lsp_server,
|
|
2561
|
-
): file_path
|
|
2562
|
-
for file_path in files
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
for future in as_completed(futures):
|
|
2566
|
-
file_path = futures[future]
|
|
2567
|
-
try:
|
|
2568
|
-
result = future.result()
|
|
2569
|
-
if result.get("success"):
|
|
2570
|
-
op_result = result.get("result", {})
|
|
2571
|
-
if atomic and apply and op_result.get("previews"):
|
|
2572
|
-
results.append({"file": file_path, "result": op_result})
|
|
2573
|
-
elif apply and op_result.get("applied"):
|
|
2574
|
-
modified.append(file_path)
|
|
2575
|
-
elif not apply and op_result.get("previews"):
|
|
2576
|
-
results.append({"file": file_path, "result": op_result})
|
|
2577
|
-
else:
|
|
2578
|
-
errors.append(
|
|
2579
|
-
{"file": str(file_path), "error": result.get("error", "Unknown error")}
|
|
2580
|
-
)
|
|
2581
|
-
logger.error(
|
|
2582
|
-
"Failed to organize imports in %s: %s", file_path, result.get("error")
|
|
2583
|
-
)
|
|
2584
|
-
if atomic and apply and backups:
|
|
2585
|
-
# Rollback on error
|
|
2586
|
-
for orig, backup in backups.items():
|
|
2587
|
-
_ = shutil.copy2(backup, orig)
|
|
2588
|
-
return {
|
|
2589
|
-
"success": False,
|
|
2590
|
-
"processed": len(results),
|
|
2591
|
-
"errors": errors,
|
|
2592
|
-
"backup_dir": str(backup_dir),
|
|
2593
|
-
"message": f"Rolled back due to error organizing imports in {file_path}",
|
|
2594
|
-
}
|
|
2595
|
-
except Exception as exc:
|
|
2596
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2597
|
-
logger.exception("Failed to organize imports in %s: %s", file_path, exc)
|
|
2598
|
-
if atomic and apply and backups:
|
|
2599
|
-
# Rollback on error
|
|
2600
|
-
for orig, backup in backups.items():
|
|
2601
|
-
_ = shutil.copy2(backup, orig)
|
|
2602
|
-
return {
|
|
2603
|
-
"success": False,
|
|
2604
|
-
"processed": len(results),
|
|
2605
|
-
"errors": errors,
|
|
2606
|
-
"backup_dir": str(backup_dir),
|
|
2607
|
-
"message": f"Rolled back due to error organizing imports in {file_path}",
|
|
2608
|
-
}
|
|
2609
|
-
finally:
|
|
2610
|
-
if progress and task_id is not None:
|
|
2611
|
-
progress.update(task_id, advance=1)
|
|
2612
|
-
else:
|
|
2613
|
-
# Sequential processing (original behavior)
|
|
2614
|
-
for file_path in files:
|
|
2615
|
-
try:
|
|
2616
|
-
result = organize_imports(
|
|
2617
|
-
file_path,
|
|
2618
|
-
apply=apply and not atomic,
|
|
2619
|
-
config_file=config_file,
|
|
2620
|
-
lsp_server=lsp_server,
|
|
2621
|
-
)
|
|
2622
|
-
if atomic and apply and result.get("previews"):
|
|
2623
|
-
results.append({"file": file_path, "result": result})
|
|
2624
|
-
elif apply and result.get("applied"):
|
|
2625
|
-
modified.append(file_path)
|
|
2626
|
-
elif not apply and result.get("previews"):
|
|
2627
|
-
results.append({"file": file_path, "result": result})
|
|
2628
|
-
except Exception as exc:
|
|
2629
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2630
|
-
logger.exception("Failed to organize imports in %s: %s", file_path, exc)
|
|
2631
|
-
if atomic and apply and backups:
|
|
2632
|
-
for orig, backup in backups.items():
|
|
2633
|
-
_ = shutil.copy2(backup, orig)
|
|
2634
|
-
return {
|
|
2635
|
-
"success": False,
|
|
2636
|
-
"processed": len(results),
|
|
2637
|
-
"errors": errors,
|
|
2638
|
-
"backup_dir": str(backup_dir),
|
|
2639
|
-
"message": f"Rolled back due to error organizing imports in {file_path}",
|
|
2640
|
-
}
|
|
2641
|
-
finally:
|
|
2642
|
-
if progress and task_id is not None:
|
|
2643
|
-
progress.update(task_id, advance=1)
|
|
2644
|
-
|
|
2645
|
-
if atomic and apply and backups:
|
|
2646
|
-
for item in results:
|
|
2647
|
-
file_path = item["file"]
|
|
2648
|
-
result = item["result"]
|
|
2649
|
-
if result.get("previews"):
|
|
2650
|
-
preview = result["previews"][0]
|
|
2651
|
-
file_path.write_text(preview["after"])
|
|
2652
|
-
modified.append(file_path)
|
|
2653
|
-
|
|
2654
|
-
previews: list[dict[str, Any]] = []
|
|
2655
|
-
for item in results:
|
|
2656
|
-
result = item["result"]
|
|
2657
|
-
if result.get("previews"):
|
|
2658
|
-
previews.extend(result["previews"])
|
|
2659
|
-
|
|
2660
|
-
return {
|
|
2661
|
-
"success": len(errors) == 0,
|
|
2662
|
-
"processed": len(files),
|
|
2663
|
-
"modified": len(modified),
|
|
2664
|
-
"errors": len(errors),
|
|
2665
|
-
"files": [str(f) for f in modified],
|
|
2666
|
-
"previews": previews if not apply else [],
|
|
2667
|
-
"error_details": errors,
|
|
2668
|
-
"backup_dir": str(backup_dir) if backup_dir else None,
|
|
2669
|
-
"parallel": parallel,
|
|
2670
|
-
"max_workers": jobs if jobs else ("auto" if parallel else 1),
|
|
2671
|
-
"message": f"Processed {len(files)} files, modified {len(modified)} files with {len(errors)} errors.",
|
|
2672
|
-
}
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
def batch_fix_all(
|
|
2676
|
-
paths: list[Path],
|
|
2677
|
-
*,
|
|
2678
|
-
apply: bool = False,
|
|
2679
|
-
atomic: bool = True,
|
|
2680
|
-
include_paths: list[Path] | None = None,
|
|
2681
|
-
exclude_paths: list[Path] | None = None,
|
|
2682
|
-
git_tracked_only: bool = False,
|
|
2683
|
-
parallel: bool = True,
|
|
2684
|
-
jobs: int | None = None,
|
|
2685
|
-
progress: Any | None = None,
|
|
2686
|
-
config_file: Path | None = None,
|
|
2687
|
-
lsp_server: str | None = None,
|
|
2688
|
-
**kwargs: Any,
|
|
2689
|
-
) -> dict[str, Any]:
|
|
2690
|
-
"""Apply fix-all code actions across multiple Python files.
|
|
2691
|
-
|
|
2692
|
-
Args:
|
|
2693
|
-
paths: List of file/directory paths to process
|
|
2694
|
-
apply: If True, apply fixes; otherwise preview only
|
|
2695
|
-
atomic: If True, backup all files and rollback on error
|
|
2696
|
-
include_paths: Optional list of paths to include (filters)
|
|
2697
|
-
exclude_paths: Optional list of paths to exclude
|
|
2698
|
-
git_tracked_only: If True, only process git-tracked files
|
|
2699
|
-
parallel: If True, process files in parallel using ThreadPoolExecutor
|
|
2700
|
-
jobs: Number of parallel jobs (None = auto-detect based on CPU count)
|
|
2701
|
-
progress: Optional Rich Progress object for UI updates
|
|
2702
|
-
config_file: Optional path to pyright config file
|
|
2703
|
-
lsp_server: Optional LSP server command override
|
|
2704
|
-
|
|
2705
|
-
Returns:
|
|
2706
|
-
Dictionary with results including files modified, previews, and summary
|
|
2707
|
-
"""
|
|
2708
|
-
router = _build_router(
|
|
2709
|
-
paths[0] if paths else Path.cwd(), config_file=config_file, lsp_server=lsp_server
|
|
2710
|
-
)
|
|
2711
|
-
|
|
2712
|
-
files = _collect_python_files(
|
|
2713
|
-
paths,
|
|
2714
|
-
router.root,
|
|
2715
|
-
include_paths=include_paths,
|
|
2716
|
-
exclude_paths=exclude_paths,
|
|
2717
|
-
git_tracked_only=git_tracked_only,
|
|
2718
|
-
)
|
|
2719
|
-
|
|
2720
|
-
if not files:
|
|
2721
|
-
return {"success": True, "processed": 0, "message": "No Python files found to process."}
|
|
2722
|
-
|
|
2723
|
-
backup_dir: Path | None = None
|
|
2724
|
-
backups: dict[Path, Path] | None = None
|
|
2725
|
-
|
|
2726
|
-
if atomic and apply:
|
|
2727
|
-
backup_dir = _create_backup_dir(router.root)
|
|
2728
|
-
backups = _backup_files(files, backup_dir)
|
|
2729
|
-
|
|
2730
|
-
results: list[dict[str, Any]] = []
|
|
2731
|
-
errors: list[dict[str, Any]] = []
|
|
2732
|
-
modified: list[Path] = []
|
|
2733
|
-
|
|
2734
|
-
task_id = None
|
|
2735
|
-
if progress:
|
|
2736
|
-
task_id = progress.add_task("Applying fixes...", total=len(files))
|
|
2737
|
-
|
|
2738
|
-
# Process files (parallel or sequential)
|
|
2739
|
-
if parallel and len(files) > 1:
|
|
2740
|
-
import os
|
|
2741
|
-
|
|
2742
|
-
# Default to CPU count or 4, whichever is smaller
|
|
2743
|
-
max_workers = jobs or min(os.cpu_count() or 4, 8)
|
|
2744
|
-
if max_workers > len(files):
|
|
2745
|
-
max_workers = len(files)
|
|
2746
|
-
|
|
2747
|
-
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
2748
|
-
futures = {
|
|
2749
|
-
executor.submit(
|
|
2750
|
-
_process_file_parallel,
|
|
2751
|
-
file_path,
|
|
2752
|
-
"fix_all",
|
|
2753
|
-
apply and not atomic,
|
|
2754
|
-
config_file,
|
|
2755
|
-
lsp_server,
|
|
2756
|
-
): file_path
|
|
2757
|
-
for file_path in files
|
|
2758
|
-
}
|
|
2759
|
-
|
|
2760
|
-
for future in as_completed(futures):
|
|
2761
|
-
file_path = futures[future]
|
|
2762
|
-
try:
|
|
2763
|
-
result = future.result()
|
|
2764
|
-
if result.get("success"):
|
|
2765
|
-
op_result = result.get("result", {})
|
|
2766
|
-
if atomic and apply and op_result.get("previews"):
|
|
2767
|
-
results.append({"file": file_path, "result": op_result})
|
|
2768
|
-
elif apply and op_result.get("applied"):
|
|
2769
|
-
modified.append(file_path)
|
|
2770
|
-
elif not apply and op_result.get("previews"):
|
|
2771
|
-
results.append({"file": file_path, "result": op_result})
|
|
2772
|
-
else:
|
|
2773
|
-
errors.append(
|
|
2774
|
-
{"file": str(file_path), "error": result.get("error", "Unknown error")}
|
|
2775
|
-
)
|
|
2776
|
-
logger.error(
|
|
2777
|
-
"Failed to apply fixes to %s: %s", file_path, result.get("error")
|
|
2778
|
-
)
|
|
2779
|
-
if atomic and apply and backups:
|
|
2780
|
-
# Rollback on error
|
|
2781
|
-
for orig, backup in backups.items():
|
|
2782
|
-
_ = shutil.copy2(backup, orig)
|
|
2783
|
-
return {
|
|
2784
|
-
"success": False,
|
|
2785
|
-
"processed": len(results),
|
|
2786
|
-
"errors": errors,
|
|
2787
|
-
"backup_dir": str(backup_dir),
|
|
2788
|
-
"message": f"Rolled back due to error applying fixes to {file_path}",
|
|
2789
|
-
}
|
|
2790
|
-
except Exception as exc:
|
|
2791
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2792
|
-
logger.exception("Failed to apply fixes to %s: %s", file_path, exc)
|
|
2793
|
-
if atomic and apply and backups:
|
|
2794
|
-
# Rollback on error
|
|
2795
|
-
for orig, backup in backups.items():
|
|
2796
|
-
_ = shutil.copy2(backup, orig)
|
|
2797
|
-
return {
|
|
2798
|
-
"success": False,
|
|
2799
|
-
"processed": len(results),
|
|
2800
|
-
"errors": errors,
|
|
2801
|
-
"backup_dir": str(backup_dir),
|
|
2802
|
-
"message": f"Rolled back due to error applying fixes to {file_path}",
|
|
2803
|
-
}
|
|
2804
|
-
finally:
|
|
2805
|
-
if progress and task_id is not None:
|
|
2806
|
-
progress.update(task_id, advance=1)
|
|
2807
|
-
else:
|
|
2808
|
-
# Sequential processing (original behavior)
|
|
2809
|
-
for file_path in files:
|
|
2810
|
-
try:
|
|
2811
|
-
result = fix_all(
|
|
2812
|
-
file_path,
|
|
2813
|
-
apply=apply and not atomic,
|
|
2814
|
-
config_file=config_file,
|
|
2815
|
-
lsp_server=lsp_server,
|
|
2816
|
-
)
|
|
2817
|
-
if atomic and apply and result.get("previews"):
|
|
2818
|
-
results.append({"file": file_path, "result": result})
|
|
2819
|
-
elif apply and result.get("applied"):
|
|
2820
|
-
modified.append(file_path)
|
|
2821
|
-
elif not apply and result.get("previews"):
|
|
2822
|
-
results.append({"file": file_path, "result": result})
|
|
2823
|
-
except Exception as exc:
|
|
2824
|
-
errors.append({"file": str(file_path), "error": str(exc)})
|
|
2825
|
-
logger.exception("Failed to apply fixes to %s: %s", file_path, exc)
|
|
2826
|
-
if atomic and apply and backups:
|
|
2827
|
-
for orig, backup in backups.items():
|
|
2828
|
-
_ = shutil.copy2(backup, orig)
|
|
2829
|
-
return {
|
|
2830
|
-
"success": False,
|
|
2831
|
-
"processed": len(results),
|
|
2832
|
-
"errors": errors,
|
|
2833
|
-
"backup_dir": str(backup_dir),
|
|
2834
|
-
"message": f"Rolled back due to error applying fixes to {file_path}",
|
|
2835
|
-
}
|
|
2836
|
-
finally:
|
|
2837
|
-
if progress and task_id is not None:
|
|
2838
|
-
progress.update(task_id, advance=1)
|
|
2839
|
-
|
|
2840
|
-
if atomic and apply and backups:
|
|
2841
|
-
for item in results:
|
|
2842
|
-
file_path = item["file"]
|
|
2843
|
-
result = item["result"]
|
|
2844
|
-
if result.get("previews"):
|
|
2845
|
-
preview = result["previews"][0]
|
|
2846
|
-
file_path.write_text(preview["after"])
|
|
2847
|
-
modified.append(file_path)
|
|
2848
|
-
|
|
2849
|
-
previews: list[dict[str, Any]] = []
|
|
2850
|
-
for item in results:
|
|
2851
|
-
result = item["result"]
|
|
2852
|
-
if result.get("previews"):
|
|
2853
|
-
previews.extend(result["previews"])
|
|
2854
|
-
|
|
2855
|
-
return {
|
|
2856
|
-
"success": len(errors) == 0,
|
|
2857
|
-
"processed": len(files),
|
|
2858
|
-
"modified": len(modified),
|
|
2859
|
-
"errors": len(errors),
|
|
2860
|
-
"files": [str(f) for f in modified],
|
|
2861
|
-
"previews": previews if not apply else [],
|
|
2862
|
-
"error_details": errors,
|
|
2863
|
-
"backup_dir": str(backup_dir) if backup_dir else None,
|
|
2864
|
-
"parallel": parallel,
|
|
2865
|
-
"max_workers": jobs if jobs else ("auto" if parallel else 1),
|
|
2866
|
-
"message": f"Processed {len(files)} files, modified {len(modified)} files with {len(errors)} errors.",
|
|
2867
|
-
}
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
# ============================================================================
|
|
2871
|
-
# Import Suggestions
|
|
2872
|
-
# ============================================================================
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
def suggest_imports(
|
|
2876
|
-
file: str,
|
|
2877
|
-
line: int,
|
|
2878
|
-
col: int,
|
|
2879
|
-
*,
|
|
2880
|
-
apply: bool = False,
|
|
2881
|
-
config_file: Path | None = None,
|
|
2882
|
-
lsp_server: str | None = None,
|
|
2883
|
-
) -> dict[str, Any]:
|
|
2884
|
-
"""Get import suggestions for a location in a file.
|
|
2885
|
-
|
|
2886
|
-
This is a convenience wrapper around code actions that filters for
|
|
2887
|
-
import-related actions (BasedPyright's auto-import feature).
|
|
2888
|
-
|
|
2889
|
-
Args:
|
|
2890
|
-
file: Path to the file
|
|
2891
|
-
line: 1-based line number
|
|
2892
|
-
col: 1-based column number
|
|
2893
|
-
apply: If True, apply the first import suggestion
|
|
2894
|
-
config_file: Optional config file path
|
|
2895
|
-
lsp_server: Optional LSP server override
|
|
2896
|
-
|
|
2897
|
-
Returns:
|
|
2898
|
-
Dict with keys:
|
|
2899
|
-
- suggestions: List of import suggestion dicts with title, kind, edit
|
|
2900
|
-
- applied: True if a suggestion was applied
|
|
2901
|
-
- message: Status message
|
|
2902
|
-
"""
|
|
2903
|
-
router = _build_router(None, config_file=config_file, lsp_server=lsp_server)
|
|
2904
|
-
if not router.code_actions or not router.lsp:
|
|
2905
|
-
return {
|
|
2906
|
-
"suggestions": [],
|
|
2907
|
-
"applied": False,
|
|
2908
|
-
"message": "No LSP server available for import suggestions.",
|
|
2909
|
-
"error": router.lsp_error,
|
|
2910
|
-
}
|
|
2911
|
-
|
|
2912
|
-
file_path = Path(file)
|
|
2913
|
-
if not file_path.is_absolute():
|
|
2914
|
-
file_path = router.root / file_path
|
|
2915
|
-
|
|
2916
|
-
# Get all code actions at the location
|
|
2917
|
-
all_actions = router.code_actions.get_code_actions(file_path, line, col)
|
|
2918
|
-
|
|
2919
|
-
# Filter for import-related actions
|
|
2920
|
-
# BasedPyright's auto-import actions typically have titles like:
|
|
2921
|
-
# "Import {name} from {module}" or "from {module} import {name}"
|
|
2922
|
-
import_actions = []
|
|
2923
|
-
for action in all_actions:
|
|
2924
|
-
title = action.get("title", "")
|
|
2925
|
-
kind = action.get("kind", "")
|
|
2926
|
-
|
|
2927
|
-
# Filter by import-related keywords in title or kind
|
|
2928
|
-
if (
|
|
2929
|
-
any(keyword in title.lower() for keyword in ("import ", "from "))
|
|
2930
|
-
or kind
|
|
2931
|
-
and ("import" in kind.lower())
|
|
2932
|
-
):
|
|
2933
|
-
import_actions.append(action)
|
|
2934
|
-
|
|
2935
|
-
if not import_actions:
|
|
2936
|
-
return {
|
|
2937
|
-
"suggestions": [],
|
|
2938
|
-
"applied": False,
|
|
2939
|
-
"message": "No import suggestions available at this location.",
|
|
2940
|
-
}
|
|
2941
|
-
|
|
2942
|
-
# Build response with import suggestions
|
|
2943
|
-
suggestions = []
|
|
2944
|
-
for action in import_actions:
|
|
2945
|
-
suggestion = {
|
|
2946
|
-
"title": action.get("title", "Unnamed suggestion"),
|
|
2947
|
-
"kind": action.get("kind", "unknown"),
|
|
2948
|
-
"category": action.get("category", "source"),
|
|
2949
|
-
}
|
|
2950
|
-
|
|
2951
|
-
# Include edit if available
|
|
2952
|
-
if "edit" in action:
|
|
2953
|
-
suggestion["has_edit"] = True
|
|
2954
|
-
# Try to extract import details from the edit
|
|
2955
|
-
edit = action.get("edit")
|
|
2956
|
-
if edit and edit.get("documentChanges"):
|
|
2957
|
-
changes = edit["documentChanges"][0].get("edits", [])
|
|
2958
|
-
if changes:
|
|
2959
|
-
# Extract the new import text
|
|
2960
|
-
new_text = changes[0].get("newText", "")
|
|
2961
|
-
suggestion["preview"] = new_text.strip()
|
|
2962
|
-
else:
|
|
2963
|
-
suggestion["has_edit"] = False
|
|
2964
|
-
|
|
2965
|
-
suggestions.append(suggestion)
|
|
2966
|
-
|
|
2967
|
-
# Apply first suggestion if requested
|
|
2968
|
-
if apply and suggestions:
|
|
2969
|
-
action = import_actions[0]
|
|
2970
|
-
edit = action.get("edit")
|
|
2971
|
-
|
|
2972
|
-
if edit:
|
|
2973
|
-
# Create backup
|
|
2974
|
-
stamp = datetime.utcnow().strftime("%Y%m%d-%H%M%S")
|
|
2975
|
-
backup_dir = router.root / ".vds-lsp" / "backups" / stamp
|
|
2976
|
-
|
|
2977
|
-
# Apply the edit
|
|
2978
|
-
changed = apply_workspace_edit(
|
|
2979
|
-
edit, root=router.root, backup_dir=backup_dir, dry_run=False
|
|
2980
|
-
)
|
|
2981
|
-
|
|
2982
|
-
return {
|
|
2983
|
-
"suggestions": suggestions,
|
|
2984
|
-
"applied": bool(changed),
|
|
2985
|
-
"backup_dir": str(backup_dir),
|
|
2986
|
-
"applied_suggestion": action.get("title"),
|
|
2987
|
-
"message": f"Applied import suggestion: {action.get('title')}"
|
|
2988
|
-
if changed
|
|
2989
|
-
else "Failed to apply import suggestion.",
|
|
2990
|
-
}
|
|
2991
|
-
|
|
2992
|
-
return {
|
|
2993
|
-
"suggestions": suggestions,
|
|
2994
|
-
"applied": False,
|
|
2995
|
-
"message": f"Found {len(suggestions)} import suggestion(s). Use --apply to add the import.",
|
|
2996
|
-
}
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
# ============================================================================
|
|
3000
|
-
# Daemon Operations
|
|
3001
|
-
# ============================================================================
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
def daemon_start(
|
|
3005
|
-
root: Path,
|
|
3006
|
-
*,
|
|
3007
|
-
timeout: int = 30,
|
|
3008
|
-
idle_timeout: int = 300,
|
|
3009
|
-
max_clients: int = 10,
|
|
3010
|
-
config_file: Path | None = None,
|
|
3011
|
-
lsp_server: str | None = None,
|
|
3012
|
-
hot_reload: bool = True,
|
|
3013
|
-
) -> dict[str, Any]:
|
|
3014
|
-
"""Start the LSP daemon for a workspace.
|
|
3015
|
-
|
|
3016
|
-
Args:
|
|
3017
|
-
root: Workspace root directory
|
|
3018
|
-
timeout: Maximum time to wait for daemon to start (seconds)
|
|
3019
|
-
idle_timeout: Daemon idle timeout before auto-shutdown (seconds)
|
|
3020
|
-
max_clients: Maximum concurrent clients allowed
|
|
3021
|
-
config_file: Optional config file path
|
|
3022
|
-
lsp_server: Optional LSP server override
|
|
3023
|
-
hot_reload: Enable configuration hot reload (default: True)
|
|
3024
|
-
|
|
3025
|
-
Returns:
|
|
3026
|
-
Status dict with keys: status, socket, pid, message
|
|
3027
|
-
"""
|
|
3028
|
-
from .daemon_manager import get_daemon_manager
|
|
3029
|
-
|
|
3030
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3031
|
-
manager = get_daemon_manager(root_path, config_file=config_file)
|
|
3032
|
-
|
|
3033
|
-
# Override idle timeout if specified
|
|
3034
|
-
if idle_timeout != 300:
|
|
3035
|
-
manager.config.daemon_idle_timeout = idle_timeout
|
|
3036
|
-
|
|
3037
|
-
# Override max_clients if specified
|
|
3038
|
-
if max_clients != 10:
|
|
3039
|
-
manager.config.daemon_max_clients = max_clients
|
|
3040
|
-
|
|
3041
|
-
# Override LSP server if specified
|
|
3042
|
-
if lsp_server is not None:
|
|
3043
|
-
manager.config.server_path = lsp_server
|
|
3044
|
-
|
|
3045
|
-
# Override hot_reload if specified
|
|
3046
|
-
manager.config.hot_reload = hot_reload
|
|
3047
|
-
|
|
3048
|
-
return manager.start(
|
|
3049
|
-
timeout=timeout, idle_timeout=idle_timeout, max_clients=max_clients, hot_reload=hot_reload
|
|
3050
|
-
)
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
def daemon_stop(
|
|
3054
|
-
root: Path,
|
|
3055
|
-
*,
|
|
3056
|
-
force: bool = False,
|
|
3057
|
-
config_file: Path | None = None,
|
|
3058
|
-
) -> dict[str, Any]:
|
|
3059
|
-
"""Stop the LSP daemon for a workspace.
|
|
3060
|
-
|
|
3061
|
-
Args:
|
|
3062
|
-
root: Workspace root directory
|
|
3063
|
-
force: If True, send SIGKILL instead of SIGTERM
|
|
3064
|
-
config_file: Optional config file path
|
|
3065
|
-
|
|
3066
|
-
Returns:
|
|
3067
|
-
Status dict with keys: status, message
|
|
3068
|
-
"""
|
|
3069
|
-
from .daemon_manager import get_daemon_manager
|
|
3070
|
-
|
|
3071
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3072
|
-
manager = get_daemon_manager(root_path, config_file=config_file)
|
|
3073
|
-
return manager.stop(force=force)
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
def daemon_status(
|
|
3077
|
-
root: Path,
|
|
3078
|
-
*,
|
|
3079
|
-
config_file: Path | None = None,
|
|
3080
|
-
) -> dict[str, Any]:
|
|
3081
|
-
"""Get the status of the LSP daemon for a workspace.
|
|
3082
|
-
|
|
3083
|
-
Args:
|
|
3084
|
-
root: Workspace root directory
|
|
3085
|
-
config_file: Optional config file path
|
|
3086
|
-
|
|
3087
|
-
Returns:
|
|
3088
|
-
DaemonStatus dict with keys: running, pid, socket_path, uptime_seconds, etc.
|
|
3089
|
-
"""
|
|
3090
|
-
from .daemon_manager import get_daemon_manager
|
|
3091
|
-
|
|
3092
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3093
|
-
manager = get_daemon_manager(root_path, config_file=config_file)
|
|
3094
|
-
return manager.status()
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
def daemon_restart(
|
|
3098
|
-
root: Path,
|
|
3099
|
-
*,
|
|
3100
|
-
timeout: int = 30,
|
|
3101
|
-
idle_timeout: int = 300,
|
|
3102
|
-
max_clients: int = 10,
|
|
3103
|
-
config_file: Path | None = None,
|
|
3104
|
-
lsp_server: str | None = None,
|
|
3105
|
-
hot_reload: bool = True,
|
|
3106
|
-
) -> dict[str, Any]:
|
|
3107
|
-
"""Restart the LSP daemon for a workspace.
|
|
3108
|
-
|
|
3109
|
-
Args:
|
|
3110
|
-
root: Workspace root directory
|
|
3111
|
-
timeout: Maximum time to wait for daemon to start (seconds)
|
|
3112
|
-
idle_timeout: Daemon idle timeout before auto-shutdown (seconds)
|
|
3113
|
-
max_clients: Maximum concurrent clients allowed
|
|
3114
|
-
config_file: Optional config file path
|
|
3115
|
-
lsp_server: Optional LSP server override
|
|
3116
|
-
hot_reload: Enable configuration hot reload (default: True)
|
|
3117
|
-
|
|
3118
|
-
Returns:
|
|
3119
|
-
Status dict
|
|
3120
|
-
"""
|
|
3121
|
-
from .daemon_manager import get_daemon_manager
|
|
3122
|
-
|
|
3123
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3124
|
-
manager = get_daemon_manager(root_path, config_file=config_file)
|
|
3125
|
-
|
|
3126
|
-
# Override idle timeout if specified
|
|
3127
|
-
if idle_timeout != 300:
|
|
3128
|
-
manager.config.daemon_idle_timeout = idle_timeout
|
|
3129
|
-
|
|
3130
|
-
# Override max_clients if specified
|
|
3131
|
-
if max_clients != 10:
|
|
3132
|
-
manager.config.daemon_max_clients = max_clients
|
|
3133
|
-
|
|
3134
|
-
# Override LSP server if specified
|
|
3135
|
-
if lsp_server is not None:
|
|
3136
|
-
manager.config.server_path = lsp_server
|
|
3137
|
-
|
|
3138
|
-
# Override hot_reload if specified
|
|
3139
|
-
manager.config.hot_reload = hot_reload
|
|
3140
|
-
|
|
3141
|
-
return manager.restart(
|
|
3142
|
-
timeout=timeout, idle_timeout=idle_timeout, max_clients=max_clients, hot_reload=hot_reload
|
|
3143
|
-
)
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
def use_daemon(
|
|
3147
|
-
root: Path,
|
|
3148
|
-
*,
|
|
3149
|
-
config_file: Path | None = None,
|
|
3150
|
-
) -> bool:
|
|
3151
|
-
"""Check if daemon mode is enabled for a workspace.
|
|
3152
|
-
|
|
3153
|
-
Args:
|
|
3154
|
-
root: Workspace root directory
|
|
3155
|
-
config_file: Optional config file path
|
|
3156
|
-
|
|
3157
|
-
Returns:
|
|
3158
|
-
True if daemon mode is enabled and daemon is running
|
|
3159
|
-
"""
|
|
3160
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3161
|
-
config = load_config(root_path, config_file=config_file)
|
|
3162
|
-
|
|
3163
|
-
logger.info("use_daemon() check: root=%s", root_path)
|
|
3164
|
-
logger.info(" config.daemon_enabled=%s", getattr(config, "daemon_enabled", False))
|
|
3165
|
-
|
|
3166
|
-
if not getattr(config, "daemon_enabled", False):
|
|
3167
|
-
logger.info(" -> Returning False (daemon not enabled in config)")
|
|
3168
|
-
return False
|
|
3169
|
-
|
|
3170
|
-
# Check if daemon is actually running
|
|
3171
|
-
from .daemon_manager import get_daemon_manager
|
|
3172
|
-
|
|
3173
|
-
manager = get_daemon_manager(root_path, config_file=config_file)
|
|
3174
|
-
logger.info(" daemon socket_path=%s", manager.socket_path)
|
|
3175
|
-
logger.info(" daemon pid_file=%s", manager._get_pid_file())
|
|
3176
|
-
is_running = manager.is_running()
|
|
3177
|
-
logger.info(" manager.is_running()=%s", is_running)
|
|
3178
|
-
logger.info(" -> Returning %s", is_running)
|
|
3179
|
-
return is_running
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
def get_daemon_client(
|
|
3183
|
-
root: Path,
|
|
3184
|
-
*,
|
|
3185
|
-
config_file: Path | None = None,
|
|
3186
|
-
):
|
|
3187
|
-
"""Get a daemon client for the workspace.
|
|
3188
|
-
|
|
3189
|
-
Args:
|
|
3190
|
-
root: Workspace root directory
|
|
3191
|
-
config_file: Optional config file path
|
|
3192
|
-
|
|
3193
|
-
Returns:
|
|
3194
|
-
DaemonClient instance if available, None otherwise
|
|
3195
|
-
|
|
3196
|
-
Raises:
|
|
3197
|
-
ConnectionError: If daemon is enabled but not running
|
|
3198
|
-
"""
|
|
3199
|
-
from .daemon_client import (
|
|
3200
|
-
get_daemon_client as _get_daemon_client,
|
|
3201
|
-
)
|
|
3202
|
-
|
|
3203
|
-
root_path = root if root.is_absolute() else Path.cwd() / root
|
|
3204
|
-
|
|
3205
|
-
client = _get_daemon_client(root_path, config_file=config_file)
|
|
3206
|
-
|
|
3207
|
-
if not client.is_available():
|
|
3208
|
-
raise ConnectionError(
|
|
3209
|
-
f"Daemon is not running for workspace: {root_path}. "
|
|
3210
|
-
f"Start it with: vds-lsp-orchestrator daemon start",
|
|
3211
|
-
)
|
|
3212
|
-
|
|
3213
|
-
return client
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
class DaemonLspClient:
|
|
3217
|
-
"""Daemon-based LSP client that provides the same interface as LspClient.
|
|
3218
|
-
|
|
3219
|
-
This wraps DaemonClient to provide compatibility with LSPRouter and existing
|
|
3220
|
-
LSP operations. When daemon mode is enabled, this client is used instead of
|
|
3221
|
-
the direct stdio-based LspClient.
|
|
3222
|
-
"""
|
|
3223
|
-
|
|
3224
|
-
def __init__(self, root: Path, config: Any, daemon_client: Any):
|
|
3225
|
-
"""Initialize daemon LSP client.
|
|
3226
|
-
|
|
3227
|
-
Args:
|
|
3228
|
-
root: Workspace root directory
|
|
3229
|
-
config: LSP configuration
|
|
3230
|
-
daemon_client: DaemonClient instance
|
|
3231
|
-
"""
|
|
3232
|
-
self.root = root
|
|
3233
|
-
self.config = config
|
|
3234
|
-
self.daemon = daemon_client
|
|
3235
|
-
|
|
3236
|
-
def start(self):
|
|
3237
|
-
"""Start the client (no-op for daemon mode)."""
|
|
3238
|
-
|
|
3239
|
-
def stop(self):
|
|
3240
|
-
"""Stop the client (no-op for daemon mode - daemon manages its own lifecycle)."""
|
|
3241
|
-
|
|
3242
|
-
def open_document(self, file_path: Path, wait_for_diagnostics: bool = False) -> str:
|
|
3243
|
-
"""Open a document in the LSP server and return its URI.
|
|
3244
|
-
|
|
3245
|
-
Note: Daemon mode doesn't require explicit document open/close,
|
|
3246
|
-
but we track this for compatibility.
|
|
3247
|
-
|
|
3248
|
-
Args:
|
|
3249
|
-
file_path: Path to the file to open
|
|
3250
|
-
wait_for_diagnostics: Unused in daemon mode (kept for interface compatibility)
|
|
3251
|
-
"""
|
|
3252
|
-
# In daemon mode, documents are automatically loaded on demand
|
|
3253
|
-
_ = wait_for_diagnostics # Unused in daemon mode
|
|
3254
|
-
return file_path.absolute().as_uri()
|
|
3255
|
-
|
|
3256
|
-
def close_document(self, uri: str) -> None:
|
|
3257
|
-
"""Close a document in the LSP server.
|
|
3258
|
-
|
|
3259
|
-
Note: Daemon mode doesn't require explicit document open/close.
|
|
3260
|
-
"""
|
|
3261
|
-
# No-op for daemon mode
|
|
3262
|
-
|
|
3263
|
-
def request(self, method: str, params: Any = None, retry_on_timeout: bool = True) -> Any:
|
|
3264
|
-
"""Send a request and wait for response.
|
|
3265
|
-
|
|
3266
|
-
Args:
|
|
3267
|
-
method: LSP method name
|
|
3268
|
-
params: LSP method parameters
|
|
3269
|
-
retry_on_timeout: Unused in daemon mode (daemon handles its own retries)
|
|
3270
|
-
|
|
3271
|
-
Returns:
|
|
3272
|
-
LSP response result
|
|
3273
|
-
"""
|
|
3274
|
-
_ = retry_on_timeout # Daemon handles retries internally
|
|
3275
|
-
try:
|
|
3276
|
-
return self.daemon.lsp_request(method, params or {})
|
|
3277
|
-
except Exception as exc:
|
|
3278
|
-
if "ConnectionError" in str(exc) or "not running" in str(exc):
|
|
3279
|
-
raise RuntimeError(f"Daemon not available: {exc}") from exc
|
|
3280
|
-
raise
|
|
3281
|
-
|
|
3282
|
-
def request_with_timeout(self, method: str, params: Any = None, timeout: float = 5.0) -> Any:
|
|
3283
|
-
"""Send a request with a custom timeout.
|
|
3284
|
-
|
|
3285
|
-
Args:
|
|
3286
|
-
method: LSP method name
|
|
3287
|
-
params: LSP method parameters
|
|
3288
|
-
timeout: Unused in daemon mode (daemon handles its own timeouts)
|
|
3289
|
-
|
|
3290
|
-
Returns:
|
|
3291
|
-
LSP response result
|
|
3292
|
-
"""
|
|
3293
|
-
_ = timeout # Daemon handles its own timeouts
|
|
3294
|
-
# Daemon client handles its own timeouts, so we just call the normal request
|
|
3295
|
-
return self.request(method, params)
|