sourcecode 1.10.0__tar.gz → 1.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sourcecode-1.10.0 → sourcecode-1.11.0}/PKG-INFO +1 -3
- {sourcecode-1.10.0 → sourcecode-1.11.0}/README.md +0 -2
- {sourcecode-1.10.0 → sourcecode-1.11.0}/pyproject.toml +1 -1
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/cli.py +4 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/prepare_context.py +19 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/serializer.py +302 -32
- sourcecode-1.11.0/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +17 -0
- sourcecode-1.11.0/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +16 -0
- sourcecode-1.11.0/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +8 -0
- sourcecode-1.11.0/tests/test_v1_10_regressions.py +560 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.continue-here.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.gitignore +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/.ruff.toml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/CONTRIBUTING.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/LICENSE +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/SECURITY.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/docs/privacy.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/docs/schema.md +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/raw +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/run_cli.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/__init__.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/conftest.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_classifier.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_cli.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_python.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_packaging.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_real_projects.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_redactor.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_scanner.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_schema.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_summarizer.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_telemetry.py +0 -0
- {sourcecode-1.10.0 → sourcecode-1.11.0}/tests/test_workspace_analyzer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.11.0
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -357,5 +357,3 @@ Generates task-specific context for AI agents.
|
|
|
357
357
|
| `refactor` | Structural problems, improvement opportunities | 🧪 EXP |
|
|
358
358
|
| `generate-tests` | Files without tests, coverage gap analysis | 🧪 EXP |
|
|
359
359
|
| `review-pr` | Changed files + architectural impact | 🧪 EXP |
|
|
360
|
-
|
|
361
|
-
...
|
|
@@ -138,5 +138,3 @@ Generates task-specific context for AI agents.
|
|
|
138
138
|
| `refactor` | Structural problems, improvement opportunities | 🧪 EXP |
|
|
139
139
|
| `generate-tests` | Files without tests, coverage gap analysis | 🧪 EXP |
|
|
140
140
|
| `review-pr` | Changed files + architectural impact | 🧪 EXP |
|
|
141
|
-
|
|
142
|
-
...
|
|
@@ -629,6 +629,10 @@ def main(
|
|
|
629
629
|
)
|
|
630
630
|
raise typer.Exit(code=1)
|
|
631
631
|
|
|
632
|
+
if symbol is not None and not symbol.strip():
|
|
633
|
+
typer.echo("symbol query cannot be empty", err=True)
|
|
634
|
+
raise typer.Exit(code=2)
|
|
635
|
+
|
|
632
636
|
if symbol and mode not in ("contract", "standard"):
|
|
633
637
|
typer.echo(
|
|
634
638
|
f"Error: --symbol requires --mode contract or standard (got '{mode}'). "
|
|
@@ -563,6 +563,25 @@ class TaskContextBuilder:
|
|
|
563
563
|
except Exception:
|
|
564
564
|
pass
|
|
565
565
|
|
|
566
|
+
# ── 5c. review-pr suspected_areas (needs git uncommitted_files) ──────
|
|
567
|
+
if task_name == "review-pr" and spec.enable_code_notes:
|
|
568
|
+
pr_areas: dict[str, int] = {}
|
|
569
|
+
for path in uncommitted_files:
|
|
570
|
+
pr_areas[path] = pr_areas.get(path, 0) + 10
|
|
571
|
+
review_kinds = {"FIXME", "TODO", "BUG", "HACK"}
|
|
572
|
+
for note in cn_notes_for_ranking:
|
|
573
|
+
if note.kind in review_kinds:
|
|
574
|
+
pr_areas[note.path] = pr_areas.get(note.path, 0) + 1
|
|
575
|
+
_BOOST_STEMS = ("Controller", "Service", "Repository", "Mapper", "Filter", "Security")
|
|
576
|
+
for path in all_paths:
|
|
577
|
+
stem = Path(path).stem
|
|
578
|
+
if any(k in stem for k in _BOOST_STEMS):
|
|
579
|
+
pr_areas[path] = pr_areas.get(path, 0) + 2
|
|
580
|
+
suspected_areas = [
|
|
581
|
+
p for p, _ in sorted(pr_areas.items(), key=lambda x: -x[1])[:8]
|
|
582
|
+
if not self._is_test(p)
|
|
583
|
+
]
|
|
584
|
+
|
|
566
585
|
# ── 6. Rank files ──────────────────────────────────────────────────
|
|
567
586
|
entry_set = {ep.path for ep in entry_points}
|
|
568
587
|
test_set = {p for p in all_paths if self._is_test(p)}
|
|
@@ -204,6 +204,178 @@ def _dep_import_key(name: str) -> str:
|
|
|
204
204
|
return lowered.split("/")[0].replace("_", "-")
|
|
205
205
|
|
|
206
206
|
|
|
207
|
+
# ---------------------------------------------------------------------------
|
|
208
|
+
# Java/Spring compact-mode helpers (v1.10.0)
|
|
209
|
+
# ---------------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
def _compact_git_context(sm: "SourceMap") -> "Optional[dict[str, Any]]":
|
|
212
|
+
"""Lightweight git_context for compact/agent output. Top-5 hotspots only."""
|
|
213
|
+
gc = sm.git_context
|
|
214
|
+
if gc is None or not gc.requested:
|
|
215
|
+
return None
|
|
216
|
+
_bad = {"no_git_repo", "git_not_found", "git_timeout"}
|
|
217
|
+
if _bad & set(gc.limitations):
|
|
218
|
+
return None
|
|
219
|
+
ctx: dict[str, Any] = {}
|
|
220
|
+
if gc.branch:
|
|
221
|
+
ctx["branch"] = gc.branch
|
|
222
|
+
if gc.uncommitted_changes is not None:
|
|
223
|
+
uc = gc.uncommitted_changes
|
|
224
|
+
ctx["uncommitted_files"] = len(uc.staged) + len(uc.unstaged) + len(uc.untracked)
|
|
225
|
+
if gc.change_hotspots:
|
|
226
|
+
ctx["top_hotspots"] = [
|
|
227
|
+
{"file": h.file, "commits": h.commit_count}
|
|
228
|
+
for h in gc.change_hotspots[:5]
|
|
229
|
+
]
|
|
230
|
+
return ctx if ctx else None
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _dep_risk_flags(name: str, version: "Optional[str]") -> list[str]:
|
|
234
|
+
"""Static heuristic risk flags for a single dependency. No external lookups."""
|
|
235
|
+
flags: list[str] = []
|
|
236
|
+
nl = name.lower()
|
|
237
|
+
if "spring-boot" in nl or "spring.boot" in nl:
|
|
238
|
+
if version and version.startswith("2."):
|
|
239
|
+
flags.append("spring-boot-2.x-eol")
|
|
240
|
+
if nl.startswith("javax.") or nl == "javax":
|
|
241
|
+
flags.append("javax-to-jakarta-migration-risk")
|
|
242
|
+
if "ojdbc" in nl or nl in {"com.oracle.database.jdbc", "oracle.jdbc.driver.oracledriver"}:
|
|
243
|
+
flags.append("oracle-vendor-lock")
|
|
244
|
+
return flags
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _project_deployment_risks(sm: "SourceMap") -> list[str]:
|
|
248
|
+
"""Project-level deployment risk flags derived from Java version and app server."""
|
|
249
|
+
risks: list[str] = []
|
|
250
|
+
lv = sm.language_version or ""
|
|
251
|
+
if lv in ("1.8", "8", "1.7", "7"):
|
|
252
|
+
risks.append("legacy-java-runtime")
|
|
253
|
+
if getattr(sm, "app_server_hint", None) == "weblogic" and getattr(sm, "packaging", None) == "war":
|
|
254
|
+
risks.append("legacy-app-server-deployment")
|
|
255
|
+
return risks
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _mybatis_pairing(sm: "SourceMap") -> "Optional[dict[str, Any]]":
|
|
259
|
+
"""Lightweight MyBatis mapper interface <-> XML file pairing from file_paths."""
|
|
260
|
+
from pathlib import Path as _Path
|
|
261
|
+
has_mybatis = any(
|
|
262
|
+
any(f.name.lower() == "mybatis" for f in s.frameworks)
|
|
263
|
+
for s in sm.stacks
|
|
264
|
+
)
|
|
265
|
+
if not has_mybatis:
|
|
266
|
+
return None
|
|
267
|
+
non_test = [p for p in sm.file_paths if "/test/" not in p and "/tests/" not in p]
|
|
268
|
+
mapper_interfaces = [p for p in non_test if p.endswith("Mapper.java")]
|
|
269
|
+
xml_files = [p for p in sm.file_paths if p.endswith("Mapper.xml")]
|
|
270
|
+
interface_index = {_Path(p).stem: p for p in mapper_interfaces}
|
|
271
|
+
xml_index = {_Path(p).stem: p for p in xml_files}
|
|
272
|
+
orphan_xml = [xml_index[s] for s in xml_index if s not in interface_index]
|
|
273
|
+
missing_xml = [s for s in interface_index if s not in xml_index]
|
|
274
|
+
result: dict[str, Any] = {
|
|
275
|
+
"mapper_interfaces": len(mapper_interfaces),
|
|
276
|
+
"xml_files": len(xml_files),
|
|
277
|
+
}
|
|
278
|
+
if orphan_xml:
|
|
279
|
+
result["orphan_xml"] = orphan_xml[:5]
|
|
280
|
+
if missing_xml:
|
|
281
|
+
result["missing_xml"] = missing_xml[:5]
|
|
282
|
+
return result
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def _security_surface_from_eps(eps: list) -> "Optional[dict[str, Any]]":
|
|
286
|
+
"""Extract @M3FiltroSeguridad resource names from entry point evidence strings."""
|
|
287
|
+
import re as _re
|
|
288
|
+
_NOMBRE_RE = _re.compile(r"nombreRecurso=[\"']([^\"']+)[\"']")
|
|
289
|
+
resource_names: list[str] = []
|
|
290
|
+
seen: set[str] = set()
|
|
291
|
+
for ep in eps:
|
|
292
|
+
evidence = getattr(ep, "evidence", None)
|
|
293
|
+
if not evidence:
|
|
294
|
+
continue
|
|
295
|
+
for m in _NOMBRE_RE.finditer(evidence):
|
|
296
|
+
nm = m.group(1)
|
|
297
|
+
if nm and nm not in seen:
|
|
298
|
+
seen.add(nm)
|
|
299
|
+
resource_names.append(nm)
|
|
300
|
+
return {"resource_names": resource_names} if resource_names else None
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def _bootstrap_structured(eps: list) -> "Optional[dict[str, Any]]":
|
|
304
|
+
"""Separate Java entry points into bootstrap / security / controllers groups."""
|
|
305
|
+
from pathlib import Path as _Path
|
|
306
|
+
bootstrap: list[str] = []
|
|
307
|
+
security: list[str] = []
|
|
308
|
+
controllers: list[dict] = []
|
|
309
|
+
seen_b: set[str] = set()
|
|
310
|
+
seen_s: set[str] = set()
|
|
311
|
+
seen_c: set[str] = set()
|
|
312
|
+
|
|
313
|
+
for ep in eps:
|
|
314
|
+
path = getattr(ep, "path", "")
|
|
315
|
+
kind = getattr(ep, "kind", "")
|
|
316
|
+
stem = _Path(path).stem
|
|
317
|
+
|
|
318
|
+
if kind == "application" or any(k in stem for k in ("Application", "Main", "Initializer", "Bootstrap")):
|
|
319
|
+
if path not in seen_b:
|
|
320
|
+
seen_b.add(path)
|
|
321
|
+
bootstrap.append(path)
|
|
322
|
+
elif kind == "filter" or any(k in stem for k in ("Filter", "Security", "Auth", "Jwt", "WebSecurity")):
|
|
323
|
+
if path not in seen_s:
|
|
324
|
+
seen_s.add(path)
|
|
325
|
+
security.append(path)
|
|
326
|
+
elif kind in ("rest_controller", "mvc_controller"):
|
|
327
|
+
if path not in seen_c:
|
|
328
|
+
seen_c.add(path)
|
|
329
|
+
item: dict[str, Any] = {"path": path}
|
|
330
|
+
http_path = getattr(ep, "http_path", None)
|
|
331
|
+
if http_path:
|
|
332
|
+
item["http_path"] = http_path
|
|
333
|
+
controllers.append(item)
|
|
334
|
+
|
|
335
|
+
if not bootstrap and not security:
|
|
336
|
+
return None
|
|
337
|
+
|
|
338
|
+
result: dict[str, Any] = {}
|
|
339
|
+
if bootstrap:
|
|
340
|
+
result["bootstrap"] = bootstrap
|
|
341
|
+
if security:
|
|
342
|
+
result["security"] = security
|
|
343
|
+
if controllers:
|
|
344
|
+
result["controllers"] = {
|
|
345
|
+
"count": len(controllers),
|
|
346
|
+
"sample": [{"path": c["path"]} for c in controllers[:5]],
|
|
347
|
+
}
|
|
348
|
+
return result
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def _lightweight_arch_pattern(sm: "SourceMap") -> "Optional[dict[str, Any]]":
|
|
352
|
+
"""Heuristic architecture pattern from directory names alone."""
|
|
353
|
+
if not sm.file_paths:
|
|
354
|
+
return None
|
|
355
|
+
dir_names: set[str] = set()
|
|
356
|
+
for p in sm.file_paths:
|
|
357
|
+
for part in p.replace("\\", "/").split("/")[:-1]:
|
|
358
|
+
dir_names.add(part.lower())
|
|
359
|
+
|
|
360
|
+
has_controller = bool({"controller", "controllers", "api", "rest", "web", "handler", "handlers"} & dir_names)
|
|
361
|
+
has_service = bool({"service", "services", "usecase", "usecases", "application"} & dir_names)
|
|
362
|
+
has_repository = bool({"repository", "repositories", "repo", "repos", "dao", "persistence"} & dir_names)
|
|
363
|
+
has_domain = bool({"domain", "domains", "core", "model", "models", "entity", "entities"} & dir_names)
|
|
364
|
+
has_infra = bool({"infrastructure", "infra", "adapter", "adapters"} & dir_names)
|
|
365
|
+
|
|
366
|
+
if has_controller and has_service and has_repository and has_domain:
|
|
367
|
+
return {"pattern": "ddd-layered", "confidence": 0.72 if has_infra else 0.55}
|
|
368
|
+
if bool({"ports", "port"} & dir_names) and bool({"adapter", "adapters"} & dir_names):
|
|
369
|
+
return {"pattern": "hexagonal-like", "confidence": 0.65}
|
|
370
|
+
if has_controller and bool({"model", "models", "entity", "entities"} & dir_names):
|
|
371
|
+
return {"pattern": "mvc", "confidence": 0.55}
|
|
372
|
+
if has_controller and has_service and has_repository:
|
|
373
|
+
return {"pattern": "layered", "confidence": 0.70}
|
|
374
|
+
if has_controller and has_service:
|
|
375
|
+
return {"pattern": "layered", "confidence": 0.42}
|
|
376
|
+
return None
|
|
377
|
+
|
|
378
|
+
|
|
207
379
|
def _file_relevance(sm: SourceMap, *, limit: int = _FILE_RELEVANCE_LIMIT) -> list[dict[str, Any]]:
|
|
208
380
|
from sourcecode.ranking_engine import RankingEngine
|
|
209
381
|
|
|
@@ -313,7 +485,20 @@ def _architecture_context(sm: SourceMap) -> dict[str, Any]:
|
|
|
313
485
|
arch = sm.architecture
|
|
314
486
|
if arch is not None and arch.requested:
|
|
315
487
|
pattern = arch.pattern if arch.pattern not in (None, "unknown", "flat") else None
|
|
316
|
-
|
|
488
|
+
if not pattern:
|
|
489
|
+
_hint = _lightweight_arch_pattern(sm)
|
|
490
|
+
if _hint:
|
|
491
|
+
ctx: dict[str, Any] = {
|
|
492
|
+
"summary": sm.architecture_summary,
|
|
493
|
+
"pattern": _hint["pattern"],
|
|
494
|
+
"confidence": arch.confidence,
|
|
495
|
+
"pattern_confidence": _hint["confidence"],
|
|
496
|
+
"method": arch.method,
|
|
497
|
+
}
|
|
498
|
+
if arch.limitations:
|
|
499
|
+
ctx["limitations"] = arch.limitations
|
|
500
|
+
return ctx
|
|
501
|
+
ctx = {
|
|
317
502
|
"summary": sm.architecture_summary,
|
|
318
503
|
"pattern": pattern or "insufficient_evidence",
|
|
319
504
|
"confidence": arch.confidence,
|
|
@@ -339,6 +524,18 @@ def _architecture_context(sm: SourceMap) -> dict[str, Any]:
|
|
|
339
524
|
if arch.limitations:
|
|
340
525
|
ctx["limitations"] = arch.limitations
|
|
341
526
|
return ctx
|
|
527
|
+
_hint = _lightweight_arch_pattern(sm)
|
|
528
|
+
if _hint:
|
|
529
|
+
return {
|
|
530
|
+
"summary": sm.architecture_summary,
|
|
531
|
+
"pattern": _hint["pattern"],
|
|
532
|
+
"pattern_confidence": _hint["confidence"],
|
|
533
|
+
"confidence": "low",
|
|
534
|
+
"method": "filesystem_heuristic",
|
|
535
|
+
"limitations": [
|
|
536
|
+
"architecture analyzer not requested; pattern inferred from directory names only"
|
|
537
|
+
],
|
|
538
|
+
}
|
|
342
539
|
return {
|
|
343
540
|
"summary": sm.architecture_summary,
|
|
344
541
|
"pattern": "insufficient_evidence",
|
|
@@ -395,18 +592,23 @@ def compact_view(sm: SourceMap, *, no_tree: bool = False) -> dict[str, Any]:
|
|
|
395
592
|
|
|
396
593
|
Excludes: file_tree, raw dependency lists, docs, module_graph, verbose metadata.
|
|
397
594
|
"""
|
|
398
|
-
# Key dependencies — name + version + role
|
|
595
|
+
# Key dependencies — name + version + role + risk_flags
|
|
399
596
|
key_deps: Any = None
|
|
400
597
|
if sm.dependency_summary is not None and sm.dependency_summary.requested:
|
|
401
|
-
key_deps = [
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if
|
|
409
|
-
|
|
598
|
+
key_deps = []
|
|
599
|
+
for d in sm.key_dependencies:
|
|
600
|
+
if (d.role or "unknown") not in _PRODUCTION_DEP_ROLES or d.scope in {"dev"}:
|
|
601
|
+
continue
|
|
602
|
+
entry: dict[str, Any] = {"name": d.name}
|
|
603
|
+
if d.declared_version:
|
|
604
|
+
entry["version"] = d.declared_version
|
|
605
|
+
if d.role and d.role != "runtime":
|
|
606
|
+
entry["role"] = d.role
|
|
607
|
+
flags = _dep_risk_flags(d.name, d.declared_version)
|
|
608
|
+
if flags:
|
|
609
|
+
entry["risk_flags"] = flags
|
|
610
|
+
key_deps.append(entry)
|
|
611
|
+
key_deps = key_deps[:_KEY_DEPS_CAP]
|
|
410
612
|
|
|
411
613
|
# Dependency summary — requested flag + count + source only
|
|
412
614
|
dep_summary_dict: Any = None
|
|
@@ -465,16 +667,20 @@ def compact_view(sm: SourceMap, *, no_tree: bool = False) -> dict[str, Any]:
|
|
|
465
667
|
for n in _sorted_notes[:_CODE_NOTES_CAP]
|
|
466
668
|
]
|
|
467
669
|
|
|
468
|
-
# Entry points —
|
|
670
|
+
# Entry points — bootstrap-prioritized; structured when bootstrap classes detected
|
|
469
671
|
ep_groups = _entry_point_groups(sm.entry_points)
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
672
|
+
_bootstrap_struct = _bootstrap_structured(sm.entry_points)
|
|
673
|
+
if _bootstrap_struct:
|
|
674
|
+
entry_points_compact: Any = _bootstrap_struct
|
|
675
|
+
else:
|
|
676
|
+
entry_points_compact = [
|
|
677
|
+
{
|
|
678
|
+
"path": ep["path"],
|
|
679
|
+
**({"kind": ep["kind"]} if ep.get("kind") else {}),
|
|
680
|
+
**({"confidence": ep["confidence"]} if ep.get("confidence") else {}),
|
|
681
|
+
}
|
|
682
|
+
for ep in ep_groups["production"][:_EP_PRODUCTION_CAP]
|
|
683
|
+
]
|
|
478
684
|
|
|
479
685
|
# Stacks — name + method + confidence + frameworks (names only)
|
|
480
686
|
stacks_compact = [
|
|
@@ -505,6 +711,22 @@ def compact_view(sm: SourceMap, *, no_tree: bool = False) -> dict[str, Any]:
|
|
|
505
711
|
for g in sm.analysis_gaps
|
|
506
712
|
]
|
|
507
713
|
|
|
714
|
+
# Java/Spring operational context
|
|
715
|
+
_language_version = getattr(sm, "language_version", None)
|
|
716
|
+
_packaging = getattr(sm, "packaging", None)
|
|
717
|
+
_app_server = getattr(sm, "app_server_hint", None)
|
|
718
|
+
_deployment: Any = None
|
|
719
|
+
if _packaging or _app_server:
|
|
720
|
+
_deployment = {}
|
|
721
|
+
if _packaging:
|
|
722
|
+
_deployment["packaging"] = _packaging
|
|
723
|
+
if _app_server:
|
|
724
|
+
_deployment["app_server_hint"] = _app_server
|
|
725
|
+
_deploy_risks = _project_deployment_risks(sm)
|
|
726
|
+
_security_surface = _security_surface_from_eps(sm.entry_points)
|
|
727
|
+
_mybatis = _mybatis_pairing(sm)
|
|
728
|
+
_git_ctx = _compact_git_context(sm)
|
|
729
|
+
|
|
508
730
|
result: dict[str, Any] = {
|
|
509
731
|
"schema_version": sm.metadata.schema_version,
|
|
510
732
|
"project_type": sm.project_type,
|
|
@@ -521,6 +743,18 @@ def compact_view(sm: SourceMap, *, no_tree: bool = False) -> dict[str, Any]:
|
|
|
521
743
|
"confidence_summary": conf_dict,
|
|
522
744
|
"analysis_gaps": gaps_list,
|
|
523
745
|
}
|
|
746
|
+
if _language_version:
|
|
747
|
+
result["language_version"] = _language_version
|
|
748
|
+
if _deployment:
|
|
749
|
+
result["deployment"] = _deployment
|
|
750
|
+
if _deploy_risks:
|
|
751
|
+
result["deployment_risks"] = _deploy_risks
|
|
752
|
+
if _security_surface:
|
|
753
|
+
result["security_surface"] = _security_surface
|
|
754
|
+
if _mybatis:
|
|
755
|
+
result["mybatis"] = _mybatis
|
|
756
|
+
if _git_ctx:
|
|
757
|
+
result["git_context"] = _git_ctx
|
|
524
758
|
_always_include = {"project_type", "project_summary", "architecture_summary", "dependency_summary"}
|
|
525
759
|
return {k: v for k, v in result.items() if v is not None or k in _always_include}
|
|
526
760
|
|
|
@@ -838,15 +1072,34 @@ def agent_view(sm: SourceMap) -> dict[str, Any]:
|
|
|
838
1072
|
if secondary:
|
|
839
1073
|
project["secondary_stacks"] = sorted({s.stack for s in secondary})
|
|
840
1074
|
|
|
1075
|
+
# Java operational context in project block
|
|
1076
|
+
_lv = getattr(sm, "language_version", None)
|
|
1077
|
+
_pkg = getattr(sm, "packaging", None)
|
|
1078
|
+
_app_srv = getattr(sm, "app_server_hint", None)
|
|
1079
|
+
if _lv:
|
|
1080
|
+
project["language_version"] = _lv
|
|
1081
|
+
if _pkg or _app_srv:
|
|
1082
|
+
_depl: dict[str, Any] = {}
|
|
1083
|
+
if _pkg:
|
|
1084
|
+
_depl["packaging"] = _pkg
|
|
1085
|
+
if _app_srv:
|
|
1086
|
+
_depl["app_server_hint"] = _app_srv
|
|
1087
|
+
project["deployment"] = _depl
|
|
1088
|
+
_proj_risks = _project_deployment_risks(sm)
|
|
1089
|
+
if _proj_risks:
|
|
1090
|
+
project["deployment_risks"] = _proj_risks
|
|
1091
|
+
|
|
841
1092
|
result: dict[str, Any] = {"project": project}
|
|
842
1093
|
|
|
843
|
-
# ── 2. Entry points:
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
result["
|
|
1094
|
+
# ── 2. Entry points: bootstrap-prioritized, then production ─────────────
|
|
1095
|
+
_bs = _bootstrap_structured(sm.entry_points)
|
|
1096
|
+
if _bs:
|
|
1097
|
+
result["entry_points"] = _bs
|
|
1098
|
+
else:
|
|
1099
|
+
ep_groups = _entry_point_groups(sm.entry_points)
|
|
1100
|
+
result["entry_points"] = ep_groups["production"][:_EP_PRODUCTION_CAP]
|
|
1101
|
+
if ep_groups["development"]:
|
|
1102
|
+
result["development_entry_points"] = ep_groups["development"][:_EP_DEV_CAP]
|
|
850
1103
|
|
|
851
1104
|
# ── 3. Architecture ───────────────────────────────────────────────────────
|
|
852
1105
|
result["architecture"] = _architecture_context(sm)
|
|
@@ -876,17 +1129,21 @@ def agent_view(sm: SourceMap) -> dict[str, Any]:
|
|
|
876
1129
|
if dep_groups[dep_key]:
|
|
877
1130
|
result[dep_key] = dep_groups[dep_key][:_SECONDARY_DEPS_CAP]
|
|
878
1131
|
|
|
879
|
-
# Backward-compatible compact list, now production-only.
|
|
1132
|
+
# Backward-compatible compact list, now production-only, with risk_flags.
|
|
880
1133
|
production_key_deps = [
|
|
881
1134
|
d for d in sm.key_dependencies
|
|
882
1135
|
if (d.role or "unknown") in _PRODUCTION_DEP_ROLES and d.scope not in {"dev"}
|
|
883
1136
|
]
|
|
884
1137
|
if sm.dependency_summary and sm.dependency_summary.requested and production_key_deps:
|
|
885
1138
|
_dep_skip = {"parent", "manifest_path", "workspace", "source", "ecosystem"}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
for d in
|
|
889
|
-
|
|
1139
|
+
_kd_list = []
|
|
1140
|
+
for d in production_key_deps[:_KEY_DEPS_CAP]:
|
|
1141
|
+
item = {k: v for k, v in asdict(d).items() if v is not None and k not in _dep_skip}
|
|
1142
|
+
flags = _dep_risk_flags(d.name, d.declared_version)
|
|
1143
|
+
if flags:
|
|
1144
|
+
item["risk_flags"] = flags
|
|
1145
|
+
_kd_list.append(item)
|
|
1146
|
+
result["key_dependencies"] = _kd_list
|
|
890
1147
|
|
|
891
1148
|
# ── 5. Signals — compact operational context ─────────────────────────────
|
|
892
1149
|
signals: dict[str, Any] = {}
|
|
@@ -958,9 +1215,22 @@ def agent_view(sm: SourceMap) -> dict[str, Any]:
|
|
|
958
1215
|
sem_info["hotspots"] = sem.hotspots[:10]
|
|
959
1216
|
signals["semantic_graph"] = sem_info
|
|
960
1217
|
|
|
1218
|
+
# Java/Spring: security surface and ORM structure
|
|
1219
|
+
_sec_surf = _security_surface_from_eps(sm.entry_points)
|
|
1220
|
+
if _sec_surf:
|
|
1221
|
+
signals["security_surface"] = _sec_surf
|
|
1222
|
+
_mb = _mybatis_pairing(sm)
|
|
1223
|
+
if _mb:
|
|
1224
|
+
signals["mybatis"] = _mb
|
|
1225
|
+
|
|
961
1226
|
if signals:
|
|
962
1227
|
result["signals"] = signals
|
|
963
1228
|
|
|
1229
|
+
# Git context — lightweight (top-5 hotspots, branch, uncommitted count)
|
|
1230
|
+
_gc = _compact_git_context(sm)
|
|
1231
|
+
if _gc:
|
|
1232
|
+
result["git_context"] = _gc
|
|
1233
|
+
|
|
964
1234
|
# ── 6. Confidence summary ─────────────────────────────────────────────────
|
|
965
1235
|
if sm.confidence_summary is not None:
|
|
966
1236
|
cs = sm.confidence_summary
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.example.demo.config;
|
|
2
|
+
|
|
3
|
+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|
4
|
+
import org.springframework.context.annotation.Bean;
|
|
5
|
+
import org.springframework.context.annotation.Configuration;
|
|
6
|
+
|
|
7
|
+
@Configuration
|
|
8
|
+
public class FilterConfig {
|
|
9
|
+
|
|
10
|
+
@Bean
|
|
11
|
+
public FilterRegistrationBean<SecurityFilter> securityFilter() {
|
|
12
|
+
FilterRegistrationBean<SecurityFilter> bean = new FilterRegistrationBean<>();
|
|
13
|
+
bean.setFilter(new SecurityFilter());
|
|
14
|
+
bean.addUrlPatterns("/*");
|
|
15
|
+
return bean;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.example.demo.web;
|
|
2
|
+
|
|
3
|
+
import org.springframework.web.bind.annotation.GetMapping;
|
|
4
|
+
import org.springframework.web.bind.annotation.RequestMapping;
|
|
5
|
+
import org.springframework.web.bind.annotation.RestController;
|
|
6
|
+
|
|
7
|
+
@RestController
|
|
8
|
+
@RequestMapping("/nominas")
|
|
9
|
+
@M3FiltroSeguridad(nombreRecurso = "nominas")
|
|
10
|
+
public class NominaRestController {
|
|
11
|
+
|
|
12
|
+
@GetMapping
|
|
13
|
+
public String list() {
|
|
14
|
+
return "[]";
|
|
15
|
+
}
|
|
16
|
+
}
|
sourcecode-1.11.0/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
3
|
+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
4
|
+
<mapper namespace="com.example.demo.mapper.HealthMapper">
|
|
5
|
+
<select id="findStatus" parameterType="long" resultType="String">
|
|
6
|
+
SELECT status FROM health WHERE id = #{id}
|
|
7
|
+
</select>
|
|
8
|
+
</mapper>
|