sourcecode 1.26.0__tar.gz → 1.27.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.26.0 → sourcecode-1.27.0}/PKG-INFO +3 -3
- {sourcecode-1.26.0 → sourcecode-1.27.0}/README.md +2 -2
- {sourcecode-1.26.0 → sourcecode-1.27.0}/pyproject.toml +1 -1
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/cli.py +3 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/prepare_context.py +130 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/serializer.py +68 -77
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_block5_quality.py +40 -42
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_pipeline_integrity.py +10 -9
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.continue-here.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.gitignore +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/.ruff.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/CONTRIBUTING.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/LICENSE +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/SECURITY.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/docs/privacy.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/docs/schema.md +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/raw +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/run_cli.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/__init__.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/conftest.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.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.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_classifier.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_cli.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_packaging.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_real_projects.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_redactor.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_scanner.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_summarizer.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_telemetry.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.0}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.26.0 → sourcecode-1.27.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.27.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.27.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.27.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
|
|
|
@@ -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
|
|
|
@@ -117,59 +117,57 @@ def test_symbol_definers_not_truncated() -> None:
|
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
# ---------------------------------------------------------------------------
|
|
120
|
-
# 4. agent_view
|
|
120
|
+
# 4. agent_view noise exclusions
|
|
121
121
|
# ---------------------------------------------------------------------------
|
|
122
122
|
|
|
123
|
-
def
|
|
124
|
-
"""
|
|
125
|
-
sm = _make_sm(
|
|
126
|
-
metrics_summary=MetricsSummary(requested=True, file_count=5),
|
|
127
|
-
)
|
|
128
|
-
result = agent_view(sm)
|
|
129
|
-
|
|
130
|
-
assert "agent_mode" in result
|
|
131
|
-
am = result["agent_mode"]
|
|
132
|
-
assert "--full-metrics" in am.get("suppressed_flags", [])
|
|
133
|
-
assert am.get("suppressed_note") == "computed but excluded from agent_view"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def test_agent_view_suppressed_graph_modules() -> None:
|
|
137
|
-
"""When module_graph.summary.requested=True, --graph-modules appears in suppressed_flags."""
|
|
138
|
-
mg = ModuleGraph(summary=ModuleGraphSummary(requested=True))
|
|
139
|
-
sm = _make_sm(module_graph=mg)
|
|
123
|
+
def test_agent_view_no_agent_mode_block() -> None:
|
|
124
|
+
"""agent_mode metadata block removed — static content with no signal value."""
|
|
125
|
+
sm = _make_sm(metrics_summary=MetricsSummary(requested=True, file_count=5))
|
|
140
126
|
result = agent_view(sm)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
127
|
+
assert "agent_mode" not in result
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_agent_view_no_hard_signals() -> None:
|
|
131
|
+
"""confidence_summary excludes hard/soft/ignored signals — detection internals."""
|
|
132
|
+
from sourcecode.schema import ConfidenceSummary
|
|
133
|
+
cs = ConfidenceSummary(
|
|
134
|
+
overall="high",
|
|
135
|
+
stack_confidence="high",
|
|
136
|
+
entry_point_confidence="high",
|
|
137
|
+
hard_signals=["pom.xml found", "spring-boot-starter-web in deps"],
|
|
138
|
+
soft_signals=["src/main/java present"],
|
|
139
|
+
ignored_signals=["README.md"],
|
|
140
|
+
)
|
|
141
|
+
sm = _make_sm(confidence_summary=cs)
|
|
149
142
|
result = agent_view(sm)
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
assert "
|
|
144
|
+
conf = result.get("confidence_summary", {})
|
|
145
|
+
assert "hard_signals" not in conf
|
|
146
|
+
assert "soft_signals" not in conf
|
|
147
|
+
assert "ignored_signals" not in conf
|
|
153
148
|
|
|
154
149
|
|
|
155
|
-
def
|
|
156
|
-
"""
|
|
157
|
-
|
|
150
|
+
def test_agent_view_no_env_keys_list() -> None:
|
|
151
|
+
"""signals.env_vars excludes the keys[] list — already present in compact env_map."""
|
|
152
|
+
from sourcecode.schema import EnvSummary, EnvVarRecord
|
|
153
|
+
env_map = [EnvVarRecord(key="DB_URL", required=True, category="database")]
|
|
154
|
+
env_summary = EnvSummary(requested=True, total=1, required_count=1)
|
|
155
|
+
sm = _make_sm(env_summary=env_summary, env_map=env_map)
|
|
158
156
|
result = agent_view(sm)
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
assert "suppressed_flags" not in am
|
|
163
|
-
assert "--dependencies" in am.get("auto_enabled", [])
|
|
158
|
+
env_vars = result.get("signals", {}).get("env_vars", {})
|
|
159
|
+
assert "keys" not in env_vars
|
|
164
160
|
|
|
165
161
|
|
|
166
|
-
def
|
|
167
|
-
"""
|
|
162
|
+
def test_agent_view_no_dep_groups() -> None:
|
|
163
|
+
"""Verbose dep group fields excluded — overlaps key_dependencies with noise."""
|
|
168
164
|
sm = _make_sm()
|
|
169
165
|
result = agent_view(sm)
|
|
170
166
|
|
|
171
|
-
|
|
172
|
-
assert
|
|
167
|
+
assert "production_dependencies" not in result
|
|
168
|
+
assert "dev_tools" not in result
|
|
169
|
+
assert "test_utilities" not in result
|
|
170
|
+
assert "build_tooling" not in result
|
|
173
171
|
|
|
174
172
|
|
|
175
173
|
# ---------------------------------------------------------------------------
|
|
@@ -187,8 +185,8 @@ def test_agent_view_empty_ep_lists_omitted() -> None:
|
|
|
187
185
|
assert "entry_points" in result
|
|
188
186
|
|
|
189
187
|
|
|
190
|
-
def
|
|
191
|
-
"""
|
|
188
|
+
def test_agent_view_dev_ep_excluded() -> None:
|
|
189
|
+
"""development_entry_points excluded from agent_view — noise for production-focused agents."""
|
|
192
190
|
dev_ep = EntryPoint(
|
|
193
191
|
path="webpack.config.js",
|
|
194
192
|
stack="nodejs",
|
|
@@ -199,7 +197,7 @@ def test_agent_view_dev_ep_present_when_nonempty() -> None:
|
|
|
199
197
|
sm = _make_sm(entry_points=[dev_ep])
|
|
200
198
|
result = agent_view(sm)
|
|
201
199
|
|
|
202
|
-
assert "development_entry_points" in result
|
|
200
|
+
assert "development_entry_points" not in result
|
|
203
201
|
|
|
204
202
|
|
|
205
203
|
def test_standard_view_empty_ep_lists_omitted() -> None:
|
|
@@ -141,20 +141,21 @@ class TestBenchmarkContamination:
|
|
|
141
141
|
data = _parse_agent(result.output)
|
|
142
142
|
assert data.get("entry_points") == []
|
|
143
143
|
|
|
144
|
-
def
|
|
144
|
+
def test_agent_excludes_development_and_auxiliary_eps(self, nocobase_like: Path) -> None:
|
|
145
|
+
"""agent_view only surfaces production EPs — dev/aux excluded as noise."""
|
|
145
146
|
result = runner.invoke(app, ["--agent", str(nocobase_like)])
|
|
146
147
|
assert result.exit_code == 0, result.output
|
|
147
148
|
data = _parse_agent(result.output)
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
assert "development_entry_points" not in data
|
|
151
|
+
assert "auxiliary_entry_points" not in data
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
assert
|
|
157
|
-
assert
|
|
153
|
+
entry_points = data.get("entry_points", [])
|
|
154
|
+
dev_paths = {"docs/rspress.mjs"}
|
|
155
|
+
aux_paths = {"benchmarks/run.js", "examples/demo.js"}
|
|
156
|
+
ep_paths = {ep.get("path", "") for ep in entry_points} if isinstance(entry_points, list) else set()
|
|
157
|
+
assert not (ep_paths & dev_paths), f"Dev EP leaked into entry_points: {ep_paths & dev_paths}"
|
|
158
|
+
assert not (ep_paths & aux_paths), f"Aux EP leaked into entry_points: {ep_paths & aux_paths}"
|
|
158
159
|
|
|
159
160
|
def test_production_server_survives_benchmark_coexistence(
|
|
160
161
|
self, production_nodejs: Path
|
{sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.26.0 → sourcecode-1.27.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|