sourcecode 1.26.0__tar.gz → 1.28.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.28.0/.continue-here.md +108 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/PKG-INFO +3 -3
- {sourcecode-1.26.0 → sourcecode-1.28.0}/README.md +2 -2
- {sourcecode-1.26.0 → sourcecode-1.28.0}/pyproject.toml +1 -1
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/cli.py +3 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/prepare_context.py +133 -2
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/serializer.py +68 -77
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_block5_quality.py +40 -42
- sourcecode-1.28.0/tests/test_encoding_regression.py +138 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_pipeline_integrity.py +10 -9
- sourcecode-1.26.0/.continue-here.md +0 -173
- sourcecode-1.26.0/tests/test_encoding_regression.py +0 -62
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.gitignore +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/.ruff.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/CONTRIBUTING.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/LICENSE +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/SECURITY.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/docs/privacy.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/docs/schema.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/raw +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/run_cli.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/conftest.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_cli.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_packaging.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_real_projects.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_redactor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_telemetry.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.28.0}/tests/test_workspace_analyzer.py +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Continue Here — atlas-cli --agent token reduction
|
|
2
|
+
|
|
3
|
+
**Paused:** 2026-05-16 (sesión 4)
|
|
4
|
+
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
+
**Branch:** master
|
|
6
|
+
**Commit:** `f1cb001 corrigiendo bug --agent que duplicaba tokens sin justificación` (committed)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Estado actual
|
|
11
|
+
|
|
12
|
+
Sesión 4: refactorización de `agent_view()` en `serializer.py` completada. **Todo committed.** Working tree limpio.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Qué se hizo esta sesión
|
|
17
|
+
|
|
18
|
+
### Problema resuelto
|
|
19
|
+
|
|
20
|
+
`--agent` producía ~11.337 tokens en SAS vs ~5.885 de `--compact`, con contenido casi idéntico. Objetivo: reducir tokens significativamente manteniendo solo lo que diferencia `--agent`.
|
|
21
|
+
|
|
22
|
+
### Cambios en `agent_view()` (`src/sourcecode/serializer.py`)
|
|
23
|
+
|
|
24
|
+
| Cambio | Impacto |
|
|
25
|
+
|--------|---------|
|
|
26
|
+
| Elimina `production_dependencies` / `dev_tools` / `test_utilities` / `build_tooling` (dep_groups asdict completo) | Mayor fuente de bloat: -3.000-5.000 tokens en repos grandes |
|
|
27
|
+
| `key_dependencies`: de asdict+50 items → `name+version+role+risk_flags` solo, cap 20 | -500-1.500 tokens |
|
|
28
|
+
| Elimina `confidence_summary.hard_signals` / `soft_signals` / `ignored_signals` | -500-1.000 tokens |
|
|
29
|
+
| Elimina bloque `agent_mode` (contenido estático sin señal) | -80 tokens siempre |
|
|
30
|
+
| Elimina `signals.env_vars.keys[]` (duplica compact `env_map`) | -300-500 tokens |
|
|
31
|
+
| `signals.code_notes.top` cap 10→5, strip a `kind+path+line+text` | -200 tokens |
|
|
32
|
+
| Entry points (no-bootstrap): strip a `path+kind+confidence` (como compact) | reducción moderada |
|
|
33
|
+
| Elimina `development_entry_points` (noise para agentes de producción) | pequeña |
|
|
34
|
+
| `architecture.layers` capado a 5 | pequeña |
|
|
35
|
+
|
|
36
|
+
**Reducción estimada para SAS:** −40–60% tokens vs `--agent` anterior.
|
|
37
|
+
|
|
38
|
+
### Campos que permanecen únicos de `--agent`
|
|
39
|
+
|
|
40
|
+
| Campo | Por qué justifica tokens extra vs `--compact` |
|
|
41
|
+
|-------|----------------------------------------------|
|
|
42
|
+
| `file_relevance` (top-20 scored) | Compact no tiene equivalente. Agente sabe qué leer sin explorar. |
|
|
43
|
+
| `architecture.layers` | Compact solo tiene `architecture_summary` string. |
|
|
44
|
+
| `suspicious_dependencies` | Deps declarados sin import observado. Compact no lo tiene. |
|
|
45
|
+
| `confidence_reasons` | Explicación accionable de secciones low-confidence. Compact no lo tiene. |
|
|
46
|
+
|
|
47
|
+
### Tests actualizados
|
|
48
|
+
|
|
49
|
+
- `tests/test_block5_quality.py` — 5 tests de `agent_mode` reemplazados por tests de las nuevas garantías (no `agent_mode`, no `hard_signals`, no `env_vars.keys`, no dep_groups)
|
|
50
|
+
- `tests/test_pipeline_integrity.py` — `test_agent_splits_development_and_auxiliary_eps` → verifica que dev/aux EPs NO aparecen
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Tests al pausar
|
|
55
|
+
|
|
56
|
+
Suite completa (sin fallos pre-existentes): **todo verde**
|
|
57
|
+
|
|
58
|
+
Fallos pre-existentes (no relacionados, ya presentes antes):
|
|
59
|
+
- `test_block2_coverage.py::test_java_marked_unsupported` — DocRecord bug en doc_analyzer.py
|
|
60
|
+
- `test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile` — versión typer mismatch
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Pendiente / próximos pasos opcionales
|
|
65
|
+
|
|
66
|
+
1. **Smoke test en saint-server** para medir tokens reales antes/después:
|
|
67
|
+
```bash
|
|
68
|
+
sourcecode saint-server --agent --output /tmp/agent_new.json
|
|
69
|
+
python3 -c "import json,sys; d=json.load(open('/tmp/agent_new.json')); print('agent tokens (est):', len(json.dumps(d))//4)"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
2. **Verificar que `suspicious_dependencies` es útil en repos reales** — en repos Python/JS (no JVM, donde el index de imports no funciona). En JVM siempre vacío por diseño.
|
|
73
|
+
|
|
74
|
+
3. **Ajustar caps según medición real**: si `file_relevance` (20 files) sigue siendo el mayor contribuyente de tokens, considerar reducir a 15. Medir con `--full` vs default.
|
|
75
|
+
|
|
76
|
+
4. **Smoke tests delta pendientes** de sesión anterior — ver sección "Smoke tests sesión 3" en historial de commits.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Para retomar
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd /Users/user/Downloads/atlas-cli
|
|
84
|
+
git log --oneline -3
|
|
85
|
+
# debe mostrar: f1cb001 corrigiendo bug --agent que duplicaba tokens sin justificación
|
|
86
|
+
|
|
87
|
+
python3 -m pytest tests/ \
|
|
88
|
+
--ignore=tests/test_block2_coverage.py \
|
|
89
|
+
--deselect=tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions \
|
|
90
|
+
-q
|
|
91
|
+
# Expected: todo verde
|
|
92
|
+
|
|
93
|
+
# Verificación rápida agent_view
|
|
94
|
+
python3 -c "
|
|
95
|
+
from sourcecode.serializer import agent_view
|
|
96
|
+
from sourcecode.schema import SourceMap, StackInfo, SourceMapMetadata
|
|
97
|
+
sm = SourceMap(stacks=[StackInfo(stack='python', primary=True)], project_type='python', project_summary='test')
|
|
98
|
+
r = agent_view(sm)
|
|
99
|
+
assert 'agent_mode' not in r
|
|
100
|
+
assert 'production_dependencies' not in r
|
|
101
|
+
assert 'hard_signals' not in r.get('confidence_summary', {})
|
|
102
|
+
print('OK — agent_mode/dep_groups/hard_signals all absent')
|
|
103
|
+
"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
*Pausado 2026-05-16 sesión 4 — gsd:pause-work*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.28.0
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -221,7 +221,7 @@ Description-Content-Type: text/markdown
|
|
|
221
221
|
|
|
222
222
|
**Compressed AI-ready context for Java/Spring enterprise codebases.**
|
|
223
223
|
|
|
224
|
-

|
|
225
225
|

|
|
226
226
|
|
|
227
227
|
---
|
|
@@ -255,7 +255,7 @@ pipx install sourcecode
|
|
|
255
255
|
|
|
256
256
|
```bash
|
|
257
257
|
sourcecode version
|
|
258
|
-
# sourcecode 1.
|
|
258
|
+
# sourcecode 1.28.0
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
---
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Compressed AI-ready context for Java/Spring enterprise codebases.**
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -36,7 +36,7 @@ pipx install sourcecode
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
sourcecode version
|
|
39
|
-
# sourcecode 1.
|
|
39
|
+
# sourcecode 1.28.0
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
---
|
|
@@ -1777,6 +1777,7 @@ def prepare_context_cmd(
|
|
|
1777
1777
|
# Hard error — emit structured error JSON and exit, skip normal delta fields
|
|
1778
1778
|
_err_out: dict[str, Any] = {
|
|
1779
1779
|
"task": output.task,
|
|
1780
|
+
"ci_decision": output.ci_decision or "git_ref_error",
|
|
1780
1781
|
"error": output.error_code,
|
|
1781
1782
|
"since": output.since,
|
|
1782
1783
|
"message": output.error_message,
|
|
@@ -1792,6 +1793,8 @@ def prepare_context_cmd(
|
|
|
1792
1793
|
_sys.stdout.buffer.write(b"\n")
|
|
1793
1794
|
_sys.stdout.buffer.flush()
|
|
1794
1795
|
raise typer.Exit(code=1)
|
|
1796
|
+
if output.ci_decision:
|
|
1797
|
+
out["ci_decision"] = output.ci_decision
|
|
1795
1798
|
if output.since:
|
|
1796
1799
|
out["since"] = output.since
|
|
1797
1800
|
if output.impact_summary:
|
|
@@ -337,6 +337,12 @@ class TaskOutput:
|
|
|
337
337
|
error_code: Optional[str] = None
|
|
338
338
|
error_message: Optional[str] = None
|
|
339
339
|
error_hints: list[str] = field(default_factory=list)
|
|
340
|
+
# CI decision state machine — machine-decidable signal
|
|
341
|
+
ci_decision: Optional[str] = None # "no_changes" | "analysis_success" | "git_ref_error"
|
|
342
|
+
# git baseline resolution metadata
|
|
343
|
+
resolved_since_ref: Optional[str] = None # actual ref/hash used for the diff
|
|
344
|
+
resolution_path: Optional[str] = None # "exact_local_ref"|"remote_tracking_ref"|"symbolic_ref"|"head_minus_1_fallback"|"uncommitted_changes"|"unresolvable"
|
|
345
|
+
diff_validation_status: Optional[str] = None # "valid_non_empty"|"valid_empty"|"invalid_ref"
|
|
340
346
|
|
|
341
347
|
|
|
342
348
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -648,6 +654,7 @@ class TaskContextBuilder:
|
|
|
648
654
|
error_message=f"Git reference '{since}' does not exist in this repository.",
|
|
649
655
|
error_hints=_hints,
|
|
650
656
|
gaps=[f"Cannot compute delta: git ref '{since}' not found."] + _hints,
|
|
657
|
+
ci_decision="git_ref_error",
|
|
651
658
|
)
|
|
652
659
|
elif _delta_raw:
|
|
653
660
|
_delta_files = set(_delta_raw)
|
|
@@ -937,6 +944,11 @@ class TaskContextBuilder:
|
|
|
937
944
|
change_type=_delta_change_type,
|
|
938
945
|
dependency_graph_summary=_delta_dep_graph_summary,
|
|
939
946
|
impact_score_per_file=_delta_impact_score_per_file,
|
|
947
|
+
ci_decision=(
|
|
948
|
+
"no_changes" if task_name == "delta" and not changed_files
|
|
949
|
+
else "analysis_success" if task_name == "delta"
|
|
950
|
+
else None
|
|
951
|
+
),
|
|
940
952
|
)
|
|
941
953
|
|
|
942
954
|
def render_prompt(self, output: TaskOutput) -> str:
|
|
@@ -2118,6 +2130,124 @@ class TaskContextBuilder:
|
|
|
2118
2130
|
impact_score_per_file,
|
|
2119
2131
|
)
|
|
2120
2132
|
|
|
2133
|
+
def _resolve_git_baseline(self, since: Optional[str]) -> dict[str, Any]:
|
|
2134
|
+
"""Resolve git baseline for delta diff using a 4-stage fallback chain.
|
|
2135
|
+
|
|
2136
|
+
Resolution order when `since` is provided:
|
|
2137
|
+
1. exact local ref (git rev-parse --verify <since>)
|
|
2138
|
+
2. remote-tracking ref (origin/<since>)
|
|
2139
|
+
3. symbolic ref (git symbolic-ref refs/remotes/origin/HEAD)
|
|
2140
|
+
4. HEAD~1 fallback
|
|
2141
|
+
|
|
2142
|
+
When `since` is None:
|
|
2143
|
+
1. uncommitted changes (git diff --name-only --relative)
|
|
2144
|
+
2. HEAD~1 fallback
|
|
2145
|
+
|
|
2146
|
+
Returns dict with keys:
|
|
2147
|
+
files: list[str] — changed paths (empty = confirmed no changes)
|
|
2148
|
+
resolved_ref: str — ref actually used for the diff
|
|
2149
|
+
resolution_path: str — which strategy resolved it
|
|
2150
|
+
diff_validation_status: str — "valid_non_empty"|"valid_empty"|"invalid_ref"
|
|
2151
|
+
error: bool — True only when ALL strategies failed
|
|
2152
|
+
"""
|
|
2153
|
+
import subprocess
|
|
2154
|
+
|
|
2155
|
+
def _run(*args: str, timeout: int = 5) -> tuple[bool, str]:
|
|
2156
|
+
try:
|
|
2157
|
+
r = subprocess.run(
|
|
2158
|
+
["git", *args], cwd=str(self.root),
|
|
2159
|
+
capture_output=True, text=True,
|
|
2160
|
+
encoding="utf-8", errors="replace", timeout=timeout,
|
|
2161
|
+
)
|
|
2162
|
+
return r.returncode == 0, (r.stdout or "").strip()
|
|
2163
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
2164
|
+
return False, ""
|
|
2165
|
+
|
|
2166
|
+
def _verify(ref: str) -> bool:
|
|
2167
|
+
ok, _ = _run("rev-parse", "--verify", ref)
|
|
2168
|
+
return ok
|
|
2169
|
+
|
|
2170
|
+
def _diff(ref: str) -> Optional[list[str]]:
|
|
2171
|
+
ok, out = _run("diff", "--name-only", "--relative", ref, "HEAD", timeout=10)
|
|
2172
|
+
if not ok:
|
|
2173
|
+
return None
|
|
2174
|
+
return [line.strip() for line in out.splitlines() if line.strip()]
|
|
2175
|
+
|
|
2176
|
+
def _make(files: list[str], ref: str, path: str) -> dict[str, Any]:
|
|
2177
|
+
return {
|
|
2178
|
+
"files": files,
|
|
2179
|
+
"resolved_ref": ref,
|
|
2180
|
+
"resolution_path": path,
|
|
2181
|
+
"diff_validation_status": "valid_non_empty" if files else "valid_empty",
|
|
2182
|
+
"error": False,
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
if since:
|
|
2186
|
+
# Stage 1: exact local ref
|
|
2187
|
+
if _verify(since):
|
|
2188
|
+
files = _diff(since)
|
|
2189
|
+
if files is not None:
|
|
2190
|
+
return _make(files, since, "exact_local_ref")
|
|
2191
|
+
|
|
2192
|
+
# Stage 2: remote-tracking ref (origin/<since>)
|
|
2193
|
+
remote_ref = f"origin/{since}"
|
|
2194
|
+
if _verify(remote_ref):
|
|
2195
|
+
files = _diff(remote_ref)
|
|
2196
|
+
if files is not None:
|
|
2197
|
+
return _make(files, remote_ref, "remote_tracking_ref")
|
|
2198
|
+
|
|
2199
|
+
# Stage 3: symbolic ref (origin/HEAD → e.g. origin/main)
|
|
2200
|
+
ok, symref = _run("symbolic-ref", "refs/remotes/origin/HEAD")
|
|
2201
|
+
if ok and symref:
|
|
2202
|
+
short = symref.removeprefix("refs/remotes/")
|
|
2203
|
+
if _verify(short):
|
|
2204
|
+
files = _diff(short)
|
|
2205
|
+
if files is not None:
|
|
2206
|
+
return _make(files, short, "symbolic_ref")
|
|
2207
|
+
|
|
2208
|
+
# Stage 4: HEAD~1 fallback — original ref was invalid
|
|
2209
|
+
if _verify("HEAD~1"):
|
|
2210
|
+
files = _diff("HEAD~1")
|
|
2211
|
+
if files is not None:
|
|
2212
|
+
return {
|
|
2213
|
+
"files": files,
|
|
2214
|
+
"resolved_ref": "HEAD~1",
|
|
2215
|
+
"resolution_path": "head_minus_1_fallback",
|
|
2216
|
+
"diff_validation_status": "invalid_ref", # original ref unresolved
|
|
2217
|
+
"error": False,
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
# All stages failed
|
|
2221
|
+
return {
|
|
2222
|
+
"files": [],
|
|
2223
|
+
"resolved_ref": since,
|
|
2224
|
+
"resolution_path": "unresolvable",
|
|
2225
|
+
"diff_validation_status": "invalid_ref",
|
|
2226
|
+
"error": True,
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
else:
|
|
2230
|
+
# No since: uncommitted changes first
|
|
2231
|
+
ok, out = _run("diff", "--name-only", "--relative", timeout=10)
|
|
2232
|
+
if ok:
|
|
2233
|
+
files = [line.strip() for line in out.splitlines() if line.strip()]
|
|
2234
|
+
if files:
|
|
2235
|
+
return _make(files, "HEAD", "uncommitted_changes")
|
|
2236
|
+
|
|
2237
|
+
# HEAD~1 fallback
|
|
2238
|
+
if _verify("HEAD~1"):
|
|
2239
|
+
files = _diff("HEAD~1")
|
|
2240
|
+
if files is not None:
|
|
2241
|
+
return _make(files or [], "HEAD~1", "head_minus_1_fallback")
|
|
2242
|
+
|
|
2243
|
+
return {
|
|
2244
|
+
"files": [],
|
|
2245
|
+
"resolved_ref": "HEAD",
|
|
2246
|
+
"resolution_path": "unresolvable",
|
|
2247
|
+
"diff_validation_status": "invalid_ref",
|
|
2248
|
+
"error": True,
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2121
2251
|
def _get_git_changed_files(self, since: Optional[str] = None) -> Optional[list[str]]:
|
|
2122
2252
|
"""Get files changed since a git ref (default: HEAD~1) relative to self.root.
|
|
2123
2253
|
|
|
@@ -2179,10 +2309,11 @@ class TaskContextBuilder:
|
|
|
2179
2309
|
r = subprocess.run(
|
|
2180
2310
|
["git", "branch", "-a", "--format=%(refname:short)"],
|
|
2181
2311
|
cwd=str(self.root),
|
|
2182
|
-
capture_output=True, text=True,
|
|
2312
|
+
capture_output=True, text=True,
|
|
2313
|
+
encoding="utf-8", errors="replace", timeout=5,
|
|
2183
2314
|
)
|
|
2184
2315
|
if r.returncode == 0:
|
|
2185
|
-
all_refs = [b.strip() for b in r.stdout.splitlines() if b.strip()]
|
|
2316
|
+
all_refs = [b.strip() for b in (r.stdout or "").splitlines() if b.strip()]
|
|
2186
2317
|
branches = [b for b in all_refs if "HEAD" not in b][:10]
|
|
2187
2318
|
ref_lower = invalid_ref.lower()
|
|
2188
2319
|
if ref_lower == "master" and any(b.rstrip("/").endswith("main") for b in all_refs):
|
|
@@ -1450,17 +1450,26 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1450
1450
|
"""Opinionated output for AI agents — structured, noise-free, gap-aware.
|
|
1451
1451
|
|
|
1452
1452
|
Output order:
|
|
1453
|
-
1. project
|
|
1454
|
-
2. entry_points
|
|
1455
|
-
3. architecture
|
|
1456
|
-
4.
|
|
1457
|
-
5.
|
|
1458
|
-
6.
|
|
1459
|
-
7.
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1453
|
+
1. project → identity: type, summary, primary stack, frameworks
|
|
1454
|
+
2. entry_points → where execution starts (path+kind+confidence)
|
|
1455
|
+
3. architecture → pattern, layers (capped at 5)
|
|
1456
|
+
4. file_relevance → top-20 scored files — primary agent value-add
|
|
1457
|
+
5. runtime_packages → monorepo package roles (when available)
|
|
1458
|
+
6. key_dependencies → production deps: name+version+role+risk_flags (cap 20)
|
|
1459
|
+
7. suspicious_dependencies → declared but never imported (cap 5)
|
|
1460
|
+
8. signals → env summary, top-5 code notes, tests, Spring/JVM context
|
|
1461
|
+
9. git_context → top-5 hotspots, branch, uncommitted count
|
|
1462
|
+
10. confidence_summary → overall quality + anomalies (no internal signals)
|
|
1463
|
+
11. confidence_reasons → actionable reasons for low-confidence sections
|
|
1464
|
+
12. analysis_gaps → what's uncertain or missing
|
|
1465
|
+
|
|
1466
|
+
Never includes: file_tree, file_paths, raw dep lists, dep_groups detail,
|
|
1467
|
+
hard/soft/ignored signals, env var key list, metrics, docs, agent_mode meta.
|
|
1463
1468
|
"""
|
|
1469
|
+
_AGENT_KEY_DEPS_CAP = 20
|
|
1470
|
+
_AGENT_LAYERS_CAP = 5
|
|
1471
|
+
_AGENT_CODE_NOTES_CAP = 5
|
|
1472
|
+
|
|
1464
1473
|
# ── 1. Identity ──────────────────────────────────────────────────────────
|
|
1465
1474
|
primary = next((s for s in sm.stacks if s.primary), sm.stacks[0] if sm.stacks else None)
|
|
1466
1475
|
|
|
@@ -1509,14 +1518,23 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1509
1518
|
result["entry_points"] = _bs
|
|
1510
1519
|
else:
|
|
1511
1520
|
ep_groups = _entry_point_groups(sm.entry_points)
|
|
1512
|
-
result["entry_points"] =
|
|
1513
|
-
|
|
1514
|
-
|
|
1521
|
+
result["entry_points"] = [
|
|
1522
|
+
{
|
|
1523
|
+
"path": ep["path"],
|
|
1524
|
+
**({"kind": ep["kind"]} if ep.get("kind") else {}),
|
|
1525
|
+
**({"confidence": ep["confidence"]} if ep.get("confidence") else {}),
|
|
1526
|
+
}
|
|
1527
|
+
for ep in ep_groups["production"][:_EP_PRODUCTION_CAP]
|
|
1528
|
+
]
|
|
1515
1529
|
|
|
1516
|
-
# ── 3. Architecture
|
|
1517
|
-
|
|
1530
|
+
# ── 3. Architecture — pattern + layers (capped) ───────────────────────────
|
|
1531
|
+
_arch_ctx = _architecture_context(sm)
|
|
1532
|
+
if "layers" in _arch_ctx and len(_arch_ctx["layers"]) > _AGENT_LAYERS_CAP:
|
|
1533
|
+
_arch_ctx = dict(_arch_ctx)
|
|
1534
|
+
_arch_ctx["layers"] = _arch_ctx["layers"][:_AGENT_LAYERS_CAP]
|
|
1535
|
+
result["architecture"] = _arch_ctx
|
|
1518
1536
|
|
|
1519
|
-
# ──
|
|
1537
|
+
# ── 4. File relevance: top-scored files — primary agent value-add ────────
|
|
1520
1538
|
_FR_AGENT_CAP = 20
|
|
1521
1539
|
_total_paths = len(sm.file_paths)
|
|
1522
1540
|
relevant_files = _file_relevance(sm, limit=_FR_AGENT_CAP if not full else _total_paths)
|
|
@@ -1528,7 +1546,7 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1528
1546
|
"Use --full to see all."
|
|
1529
1547
|
)
|
|
1530
1548
|
|
|
1531
|
-
# ──
|
|
1549
|
+
# ── 5. Monorepo package roles (when available), capped ───────────────────
|
|
1532
1550
|
if sm.monorepo_packages:
|
|
1533
1551
|
_noise_roles = {"benchmark_layer", "tooling_layer", "docs_layer", "test_layer"}
|
|
1534
1552
|
operational_pkgs = [
|
|
@@ -1539,32 +1557,36 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1539
1557
|
if operational_pkgs:
|
|
1540
1558
|
result["runtime_packages"] = operational_pkgs[:_MONOREPO_PKGS_CAP]
|
|
1541
1559
|
|
|
1542
|
-
# ──
|
|
1543
|
-
#
|
|
1544
|
-
|
|
1545
|
-
if dep_groups["production_dependencies"]:
|
|
1546
|
-
result["production_dependencies"] = dep_groups["production_dependencies"][:_PROD_DEPS_CAP]
|
|
1547
|
-
for dep_key in ("dev_tools", "test_utilities", "build_tooling", "suspicious_dependencies"):
|
|
1548
|
-
if dep_groups[dep_key]:
|
|
1549
|
-
result[dep_key] = dep_groups[dep_key][:_SECONDARY_DEPS_CAP]
|
|
1550
|
-
|
|
1551
|
-
# Backward-compatible compact list, now production-only, with risk_flags.
|
|
1560
|
+
# ── 6. Key dependencies: name+version+role+risk_flags only, cap 20 ───────
|
|
1561
|
+
# dep_groups verbose detail (production_dependencies, dev_tools, etc.) excluded —
|
|
1562
|
+
# fully overlaps key_dependencies with added noise from full asdict fields.
|
|
1552
1563
|
production_key_deps = [
|
|
1553
1564
|
d for d in sm.key_dependencies
|
|
1554
1565
|
if (d.role or "unknown") in _PRODUCTION_DEP_ROLES and d.scope not in {"dev"}
|
|
1555
1566
|
]
|
|
1556
1567
|
if sm.dependency_summary and sm.dependency_summary.requested and production_key_deps:
|
|
1557
|
-
_dep_skip = {"parent", "manifest_path", "workspace", "source", "ecosystem"}
|
|
1558
1568
|
_kd_list = []
|
|
1559
|
-
for d in production_key_deps[:
|
|
1560
|
-
|
|
1569
|
+
for d in production_key_deps[:_AGENT_KEY_DEPS_CAP]:
|
|
1570
|
+
entry: dict[str, Any] = {"name": d.name}
|
|
1571
|
+
if d.declared_version:
|
|
1572
|
+
entry["version"] = d.declared_version
|
|
1573
|
+
if d.role and d.role != "runtime":
|
|
1574
|
+
entry["role"] = d.role
|
|
1561
1575
|
flags = _dep_risk_flags(d.name, d.declared_version)
|
|
1562
1576
|
if flags:
|
|
1563
|
-
|
|
1564
|
-
_kd_list.append(
|
|
1577
|
+
entry["risk_flags"] = flags
|
|
1578
|
+
_kd_list.append(entry)
|
|
1565
1579
|
result["key_dependencies"] = _kd_list
|
|
1566
1580
|
|
|
1567
|
-
# ──
|
|
1581
|
+
# ── 7. Suspicious dependencies: declared but no static import observed ────
|
|
1582
|
+
dep_groups = _dependency_groups(sm)
|
|
1583
|
+
if dep_groups["suspicious_dependencies"]:
|
|
1584
|
+
result["suspicious_dependencies"] = [
|
|
1585
|
+
{"name": d.get("name", ""), "reason": d.get("reason", "")}
|
|
1586
|
+
for d in dep_groups["suspicious_dependencies"][:_SECONDARY_DEPS_CAP]
|
|
1587
|
+
]
|
|
1588
|
+
|
|
1589
|
+
# ── 8. Signals — compact operational context ─────────────────────────────
|
|
1568
1590
|
signals: dict[str, Any] = {}
|
|
1569
1591
|
|
|
1570
1592
|
if sm.env_summary and sm.env_summary.requested and sm.env_summary.total > 0:
|
|
@@ -1580,15 +1602,6 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1580
1602
|
elif (sm.env_summary.spring_profiles or sm.env_summary.profiles_scanned):
|
|
1581
1603
|
_raw_profiles = sm.env_summary.spring_profiles or sm.env_summary.profiles_scanned
|
|
1582
1604
|
signals["env_vars"]["spring_profiles"] = sorted(set(_raw_profiles))
|
|
1583
|
-
if sm.env_map:
|
|
1584
|
-
_sorted_env = sorted(
|
|
1585
|
-
sm.env_map,
|
|
1586
|
-
key=lambda e: (not getattr(e, "required", False), getattr(e, "key", "")),
|
|
1587
|
-
)
|
|
1588
|
-
signals["env_vars"]["keys"] = [
|
|
1589
|
-
{k: v for k, v in asdict(e).items() if v is not None and v != "" and v != []}
|
|
1590
|
-
for e in _sorted_env[:10]
|
|
1591
|
-
]
|
|
1592
1605
|
|
|
1593
1606
|
if sm.code_notes_summary and sm.code_notes_summary.requested and sm.code_notes_summary.total > 0:
|
|
1594
1607
|
by_kind = {k: v for k, v in sm.code_notes_summary.by_kind.items() if v > 0}
|
|
@@ -1602,8 +1615,14 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1602
1615
|
key=lambda n: (_SEVERITY_ORDER.get(getattr(n, "kind", "").upper(), 9), getattr(n, "path", "")),
|
|
1603
1616
|
)
|
|
1604
1617
|
_code_notes_signal["top"] = [
|
|
1605
|
-
{
|
|
1606
|
-
|
|
1618
|
+
{
|
|
1619
|
+
"kind": getattr(n, "kind", ""),
|
|
1620
|
+
"path": getattr(n, "path", ""),
|
|
1621
|
+
"line": getattr(n, "line", None),
|
|
1622
|
+
**({"text": _truncate_note(getattr(n, "text", ""), 120)} if getattr(n, "text", "") else {}),
|
|
1623
|
+
}
|
|
1624
|
+
for n in _sorted_notes[:_AGENT_CODE_NOTES_CAP]
|
|
1625
|
+
if getattr(n, "kind", "").upper() in _SEVERITY_ORDER
|
|
1607
1626
|
]
|
|
1608
1627
|
if _code_notes_signal:
|
|
1609
1628
|
signals["code_notes"] = _code_notes_signal
|
|
@@ -1651,12 +1670,13 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1651
1670
|
if signals:
|
|
1652
1671
|
result["signals"] = signals
|
|
1653
1672
|
|
|
1654
|
-
# Git context — lightweight (top-5 hotspots, branch, uncommitted count)
|
|
1673
|
+
# ── 9. Git context — lightweight (top-5 hotspots, branch, uncommitted count)
|
|
1655
1674
|
_gc = _compact_git_context(sm)
|
|
1656
1675
|
if _gc:
|
|
1657
1676
|
result["git_context"] = _gc
|
|
1658
1677
|
|
|
1659
|
-
# ──
|
|
1678
|
+
# ── 10. Confidence summary — overall quality + anomalies only ─────────────
|
|
1679
|
+
# hard_signals/soft_signals/ignored_signals are detection internals — excluded.
|
|
1660
1680
|
if sm.confidence_summary is not None:
|
|
1661
1681
|
cs = sm.confidence_summary
|
|
1662
1682
|
conf: dict[str, Any] = {
|
|
@@ -1665,23 +1685,11 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1665
1685
|
"entry_points": cs.entry_point_confidence,
|
|
1666
1686
|
"sections": _section_confidence(sm),
|
|
1667
1687
|
}
|
|
1668
|
-
if cs.hard_signals:
|
|
1669
|
-
_MAX_HARD_SIGNALS = 20
|
|
1670
|
-
_hs = cs.hard_signals
|
|
1671
|
-
_hs_total = len(_hs)
|
|
1672
|
-
conf["hard_signals"] = _hs[:_MAX_HARD_SIGNALS]
|
|
1673
|
-
if _hs_total > _MAX_HARD_SIGNALS:
|
|
1674
|
-
conf["hard_signals_truncated"] = True
|
|
1675
|
-
conf["hard_signals_total"] = _hs_total
|
|
1676
|
-
if cs.soft_signals:
|
|
1677
|
-
conf["soft_signals"] = cs.soft_signals
|
|
1678
|
-
if cs.ignored_signals:
|
|
1679
|
-
conf["ignored_signals"] = cs.ignored_signals
|
|
1680
1688
|
if cs.anomalies:
|
|
1681
1689
|
conf["anomalies"] = cs.anomalies
|
|
1682
1690
|
result["confidence_summary"] = conf
|
|
1683
1691
|
|
|
1684
|
-
# ──
|
|
1692
|
+
# ── 11. Confidence reasons: actionable explanation of low-confidence sections
|
|
1685
1693
|
_conf_reasons = _confidence_reasons(sm)
|
|
1686
1694
|
if _conf_reasons:
|
|
1687
1695
|
result["confidence_reasons"] = _conf_reasons
|
|
@@ -1691,7 +1699,7 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1691
1699
|
# No reasons found → low was overly conservative; upgrade to high
|
|
1692
1700
|
result["confidence_summary"].setdefault("sections", {})["architecture"] = "high"
|
|
1693
1701
|
|
|
1694
|
-
# ──
|
|
1702
|
+
# ── 12. Analysis gaps ─────────────────────────────────────────────────────
|
|
1695
1703
|
analysis_gaps: list[dict[str, Any]] = []
|
|
1696
1704
|
|
|
1697
1705
|
if sm.analysis_gaps:
|
|
@@ -1727,23 +1735,6 @@ def agent_view(sm: SourceMap, *, full: bool = False) -> dict[str, Any]:
|
|
|
1727
1735
|
if analysis_gaps:
|
|
1728
1736
|
result["analysis_gaps"] = analysis_gaps
|
|
1729
1737
|
|
|
1730
|
-
# ── 8. Agent mode metadata — explicit transparency about auto-enabled/suppressed flags ──
|
|
1731
|
-
_auto_enabled: list[str] = ["--dependencies", "--env-map", "--code-notes"]
|
|
1732
|
-
_suppressed: list[str] = []
|
|
1733
|
-
if sm.metrics_summary is not None and sm.metrics_summary.requested:
|
|
1734
|
-
_suppressed.append("--full-metrics")
|
|
1735
|
-
if sm.module_graph is not None and sm.module_graph.summary.requested:
|
|
1736
|
-
_suppressed.append("--graph-modules")
|
|
1737
|
-
if sm.doc_summary is not None and sm.doc_summary.requested:
|
|
1738
|
-
_suppressed.append("--docs")
|
|
1739
|
-
agent_mode_meta: dict[str, Any] = {
|
|
1740
|
-
"auto_enabled": _auto_enabled,
|
|
1741
|
-
}
|
|
1742
|
-
if _suppressed:
|
|
1743
|
-
agent_mode_meta["suppressed_flags"] = _suppressed
|
|
1744
|
-
agent_mode_meta["suppressed_note"] = "computed but excluded from agent_view"
|
|
1745
|
-
result["agent_mode"] = agent_mode_meta
|
|
1746
|
-
|
|
1747
1738
|
return result
|
|
1748
1739
|
|
|
1749
1740
|
|