sourcecode 1.23.0__tar.gz → 1.26.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.23.0 → sourcecode-1.26.0}/PKG-INFO +56 -11
- {sourcecode-1.23.0 → sourcecode-1.26.0}/README.md +55 -10
- {sourcecode-1.23.0 → sourcecode-1.26.0}/pyproject.toml +1 -1
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/cli.py +19 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/prepare_context.py +163 -107
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.continue-here.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.gitignore +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/.ruff.toml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/CONTRIBUTING.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/LICENSE +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/SECURITY.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/docs/privacy.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/docs/schema.md +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/raw +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/run_cli.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/__init__.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/conftest.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_classifier.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_cli.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_python.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_packaging.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_real_projects.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_redactor.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_scanner.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_schema.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_summarizer.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_telemetry.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.0}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.23.0 → sourcecode-1.26.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.26.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.26.0
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
---
|
|
@@ -263,7 +263,7 @@ sourcecode version
|
|
|
263
263
|
## Quickstart
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
|
-
# High-signal summary (
|
|
266
|
+
# High-signal summary (1000–3000 tokens depending on repo size) — recommended starting point
|
|
267
267
|
sourcecode --compact
|
|
268
268
|
|
|
269
269
|
# Add git hotspots and uncommitted file count
|
|
@@ -311,8 +311,9 @@ Example output for a Spring Boot project (`--compact`):
|
|
|
311
311
|
|
|
312
312
|
| Flag | Alias | Default | Description |
|
|
313
313
|
|------|-------|---------|-------------|
|
|
314
|
-
| `--compact` | | off |
|
|
314
|
+
| `--compact` | | off | High-signal summary (1000–3000 tokens): stacks, entry points, dependencies, risk flags, confidence, gaps. Includes `security_surface`, `mybatis`, and `transactional_boundaries` for Java projects. |
|
|
315
315
|
| `--agent` | | off | Structured noise-free JSON for AI agents: identity, entry points, dependencies, confidence, gaps. Auto-enables dependency, env-var, and code-notes analysis. |
|
|
316
|
+
| `--full` | | off | Remove truncation limits on `transactional_boundaries`, `mybatis.dto_mappers`, and other capped lists. |
|
|
316
317
|
| `--git-context` | `-g` | off | Include git activity: recent commits, change hotspots, and uncommitted changes. |
|
|
317
318
|
| `--changed-only` | | off | Limit output to git-modified files (staged, unstaged, untracked). Forces compact output. |
|
|
318
319
|
| `--depth` | | `4` | File tree traversal depth (1–20). Java/Maven projects auto-adjust to 12. |
|
|
@@ -342,16 +343,18 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
342
343
|
| `refactor` | Structural problems, improvement opportunities, high-annotation files | Code quality review |
|
|
343
344
|
| `generate-tests` | Source files without test pairs, coverage gap analysis | Writing missing tests |
|
|
344
345
|
| `review-pr` | Uncommitted/changed files + architectural impact | Pre-merge review |
|
|
345
|
-
| `delta` |
|
|
346
|
+
| `delta` | Changed files with multi-hop impact analysis, structural import graph, system-level impact summary | Incremental CI/review context |
|
|
346
347
|
|
|
347
348
|
### Options
|
|
348
349
|
|
|
349
350
|
| Option | Description |
|
|
350
351
|
|--------|-------------|
|
|
351
352
|
| `--since REF` | Git ref for `delta` task (e.g. `HEAD~3`, `main`, `v1.2.0`). Required for `delta`; ignored for other tasks. |
|
|
353
|
+
| `--symptom TEXT` | *(fix-bug only)* Keyword hint for the bug — boosts matching files and surfaces related code notes. |
|
|
352
354
|
| `--llm-prompt` | Append a ready-to-use LLM prompt to the output. |
|
|
353
355
|
| `--dry-run` | Show what would be analyzed without running it. |
|
|
354
356
|
| `--copy` / `-c` | Copy output to clipboard after a successful run. |
|
|
357
|
+
| `--output` / `-o` | Write output to a file. |
|
|
355
358
|
| `--task-help` | List all tasks with descriptions and exit. |
|
|
356
359
|
|
|
357
360
|
### Examples
|
|
@@ -360,11 +363,8 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
360
363
|
# Explain the current repo
|
|
361
364
|
sourcecode prepare-context explain
|
|
362
365
|
|
|
363
|
-
#
|
|
364
|
-
sourcecode prepare-context
|
|
365
|
-
|
|
366
|
-
# Focus on bug-prone files
|
|
367
|
-
sourcecode prepare-context fix-bug
|
|
366
|
+
# Focus on bug-prone files, with a symptom hint
|
|
367
|
+
sourcecode prepare-context fix-bug --symptom "NullPointerException in OrderService"
|
|
368
368
|
|
|
369
369
|
# Incremental context: files changed since branch diverged from main
|
|
370
370
|
sourcecode prepare-context delta . --since main
|
|
@@ -378,6 +378,51 @@ sourcecode prepare-context --task-help
|
|
|
378
378
|
|
|
379
379
|
---
|
|
380
380
|
|
|
381
|
+
## `delta` — incremental impact analysis
|
|
382
|
+
|
|
383
|
+
The `delta` task is the recommended mode for CI pipelines and PR reviews. It goes beyond listing changed files: it builds a structural import graph and propagates impact transitively up to 3 hops.
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
sourcecode prepare-context delta [PATH] --since REF
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Output fields:**
|
|
390
|
+
|
|
391
|
+
| Field | Description |
|
|
392
|
+
|-------|-------------|
|
|
393
|
+
| `changed_files` | Files modified in the git range |
|
|
394
|
+
| `relevant_files` | Changed files + files pulled in by the import graph (scored by artifact type and hop distance) |
|
|
395
|
+
| `impact_summary` | Human-readable summary: artifact types changed and active risk areas |
|
|
396
|
+
| `affected_modules` | DDD domain modules touched by the change |
|
|
397
|
+
| `risk_areas` | Per-area severity breakdown (`security`, `api`, `persistence`, etc.) |
|
|
398
|
+
| `change_type` | Closed taxonomy: `behavioral_change`, `structural_change`, `configuration_change`, `dependency_change`, `security_change` |
|
|
399
|
+
| `system_impact` | Subsystems affected, behavioral changes, runtime impact notes |
|
|
400
|
+
| `dependency_graph_summary` | Verified structural import edges (hop 1–3) and `propagation_depth`. **Only real imports — no heuristics, no test files.** |
|
|
401
|
+
| `impact_score_per_file` | Per-file numeric impact score (0–1) |
|
|
402
|
+
| `since` | The git ref used |
|
|
403
|
+
| `gaps` | What the analysis could not determine |
|
|
404
|
+
|
|
405
|
+
**How the import graph works:**
|
|
406
|
+
|
|
407
|
+
1. Each changed file is classified by artifact type (`controller`, `service`, `repository`, `security`, `spring_config`, etc.).
|
|
408
|
+
2. A BFS traversal walks the import graph **repo-wide** (not restricted to the same module), up to 3 hops deep.
|
|
409
|
+
3. `dependency_graph_summary.edges` only contains verified `import` / `@Autowired` / constructor-injection relationships. Test files and heuristic proximity matches are excluded from edges (they appear in `relevant_files` only if they have real imports of changed files).
|
|
410
|
+
4. Score decays 30% per hop: a directly-changed `SecurityConfig.java` scores 0.90; its direct importer scores 0.63; a transitive importer scores 0.44.
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# Changed service → controller → facade (3 hops)
|
|
414
|
+
sourcecode prepare-context delta . --since main
|
|
415
|
+
|
|
416
|
+
# Output includes:
|
|
417
|
+
# dependency_graph_summary.edges:
|
|
418
|
+
# hop-1: OrderService.java → OrderRepository.java
|
|
419
|
+
# hop-2: OrderRepository.java → OrderController.java
|
|
420
|
+
# hop-3: OrderController.java → OrderFacade.java
|
|
421
|
+
# propagation_depth: 3
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
381
426
|
## Output schema
|
|
382
427
|
|
|
383
428
|
All outputs include a `confidence_summary` block with `overall`, `stack`, and `entry_points` confidence levels (`high` / `medium` / `low`), plus an `analysis_gaps` list describing what could not be analyzed and why.
|
|
@@ -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.26.0
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
---
|
|
@@ -44,7 +44,7 @@ sourcecode version
|
|
|
44
44
|
## Quickstart
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
# High-signal summary (
|
|
47
|
+
# High-signal summary (1000–3000 tokens depending on repo size) — recommended starting point
|
|
48
48
|
sourcecode --compact
|
|
49
49
|
|
|
50
50
|
# Add git hotspots and uncommitted file count
|
|
@@ -92,8 +92,9 @@ Example output for a Spring Boot project (`--compact`):
|
|
|
92
92
|
|
|
93
93
|
| Flag | Alias | Default | Description |
|
|
94
94
|
|------|-------|---------|-------------|
|
|
95
|
-
| `--compact` | | off |
|
|
95
|
+
| `--compact` | | off | High-signal summary (1000–3000 tokens): stacks, entry points, dependencies, risk flags, confidence, gaps. Includes `security_surface`, `mybatis`, and `transactional_boundaries` for Java projects. |
|
|
96
96
|
| `--agent` | | off | Structured noise-free JSON for AI agents: identity, entry points, dependencies, confidence, gaps. Auto-enables dependency, env-var, and code-notes analysis. |
|
|
97
|
+
| `--full` | | off | Remove truncation limits on `transactional_boundaries`, `mybatis.dto_mappers`, and other capped lists. |
|
|
97
98
|
| `--git-context` | `-g` | off | Include git activity: recent commits, change hotspots, and uncommitted changes. |
|
|
98
99
|
| `--changed-only` | | off | Limit output to git-modified files (staged, unstaged, untracked). Forces compact output. |
|
|
99
100
|
| `--depth` | | `4` | File tree traversal depth (1–20). Java/Maven projects auto-adjust to 12. |
|
|
@@ -123,16 +124,18 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
123
124
|
| `refactor` | Structural problems, improvement opportunities, high-annotation files | Code quality review |
|
|
124
125
|
| `generate-tests` | Source files without test pairs, coverage gap analysis | Writing missing tests |
|
|
125
126
|
| `review-pr` | Uncommitted/changed files + architectural impact | Pre-merge review |
|
|
126
|
-
| `delta` |
|
|
127
|
+
| `delta` | Changed files with multi-hop impact analysis, structural import graph, system-level impact summary | Incremental CI/review context |
|
|
127
128
|
|
|
128
129
|
### Options
|
|
129
130
|
|
|
130
131
|
| Option | Description |
|
|
131
132
|
|--------|-------------|
|
|
132
133
|
| `--since REF` | Git ref for `delta` task (e.g. `HEAD~3`, `main`, `v1.2.0`). Required for `delta`; ignored for other tasks. |
|
|
134
|
+
| `--symptom TEXT` | *(fix-bug only)* Keyword hint for the bug — boosts matching files and surfaces related code notes. |
|
|
133
135
|
| `--llm-prompt` | Append a ready-to-use LLM prompt to the output. |
|
|
134
136
|
| `--dry-run` | Show what would be analyzed without running it. |
|
|
135
137
|
| `--copy` / `-c` | Copy output to clipboard after a successful run. |
|
|
138
|
+
| `--output` / `-o` | Write output to a file. |
|
|
136
139
|
| `--task-help` | List all tasks with descriptions and exit. |
|
|
137
140
|
|
|
138
141
|
### Examples
|
|
@@ -141,11 +144,8 @@ sourcecode prepare-context TASK [PATH] [OPTIONS]
|
|
|
141
144
|
# Explain the current repo
|
|
142
145
|
sourcecode prepare-context explain
|
|
143
146
|
|
|
144
|
-
#
|
|
145
|
-
sourcecode prepare-context
|
|
146
|
-
|
|
147
|
-
# Focus on bug-prone files
|
|
148
|
-
sourcecode prepare-context fix-bug
|
|
147
|
+
# Focus on bug-prone files, with a symptom hint
|
|
148
|
+
sourcecode prepare-context fix-bug --symptom "NullPointerException in OrderService"
|
|
149
149
|
|
|
150
150
|
# Incremental context: files changed since branch diverged from main
|
|
151
151
|
sourcecode prepare-context delta . --since main
|
|
@@ -159,6 +159,51 @@ sourcecode prepare-context --task-help
|
|
|
159
159
|
|
|
160
160
|
---
|
|
161
161
|
|
|
162
|
+
## `delta` — incremental impact analysis
|
|
163
|
+
|
|
164
|
+
The `delta` task is the recommended mode for CI pipelines and PR reviews. It goes beyond listing changed files: it builds a structural import graph and propagates impact transitively up to 3 hops.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
sourcecode prepare-context delta [PATH] --since REF
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Output fields:**
|
|
171
|
+
|
|
172
|
+
| Field | Description |
|
|
173
|
+
|-------|-------------|
|
|
174
|
+
| `changed_files` | Files modified in the git range |
|
|
175
|
+
| `relevant_files` | Changed files + files pulled in by the import graph (scored by artifact type and hop distance) |
|
|
176
|
+
| `impact_summary` | Human-readable summary: artifact types changed and active risk areas |
|
|
177
|
+
| `affected_modules` | DDD domain modules touched by the change |
|
|
178
|
+
| `risk_areas` | Per-area severity breakdown (`security`, `api`, `persistence`, etc.) |
|
|
179
|
+
| `change_type` | Closed taxonomy: `behavioral_change`, `structural_change`, `configuration_change`, `dependency_change`, `security_change` |
|
|
180
|
+
| `system_impact` | Subsystems affected, behavioral changes, runtime impact notes |
|
|
181
|
+
| `dependency_graph_summary` | Verified structural import edges (hop 1–3) and `propagation_depth`. **Only real imports — no heuristics, no test files.** |
|
|
182
|
+
| `impact_score_per_file` | Per-file numeric impact score (0–1) |
|
|
183
|
+
| `since` | The git ref used |
|
|
184
|
+
| `gaps` | What the analysis could not determine |
|
|
185
|
+
|
|
186
|
+
**How the import graph works:**
|
|
187
|
+
|
|
188
|
+
1. Each changed file is classified by artifact type (`controller`, `service`, `repository`, `security`, `spring_config`, etc.).
|
|
189
|
+
2. A BFS traversal walks the import graph **repo-wide** (not restricted to the same module), up to 3 hops deep.
|
|
190
|
+
3. `dependency_graph_summary.edges` only contains verified `import` / `@Autowired` / constructor-injection relationships. Test files and heuristic proximity matches are excluded from edges (they appear in `relevant_files` only if they have real imports of changed files).
|
|
191
|
+
4. Score decays 30% per hop: a directly-changed `SecurityConfig.java` scores 0.90; its direct importer scores 0.63; a transitive importer scores 0.44.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Changed service → controller → facade (3 hops)
|
|
195
|
+
sourcecode prepare-context delta . --since main
|
|
196
|
+
|
|
197
|
+
# Output includes:
|
|
198
|
+
# dependency_graph_summary.edges:
|
|
199
|
+
# hop-1: OrderService.java → OrderRepository.java
|
|
200
|
+
# hop-2: OrderRepository.java → OrderController.java
|
|
201
|
+
# hop-3: OrderController.java → OrderFacade.java
|
|
202
|
+
# propagation_depth: 3
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
162
207
|
## Output schema
|
|
163
208
|
|
|
164
209
|
All outputs include a `confidence_summary` block with `overall`, `stack`, and `entry_points` confidence levels (`high` / `medium` / `low`), plus an `analysis_gaps` list describing what could not be analyzed and why.
|
|
@@ -1773,6 +1773,25 @@ def prepare_context_cmd(
|
|
|
1773
1773
|
out["affected_entry_points"] = output.affected_entry_points
|
|
1774
1774
|
# Delta-specific impact fields
|
|
1775
1775
|
if task == "delta":
|
|
1776
|
+
if output.error_code:
|
|
1777
|
+
# Hard error — emit structured error JSON and exit, skip normal delta fields
|
|
1778
|
+
_err_out: dict[str, Any] = {
|
|
1779
|
+
"task": output.task,
|
|
1780
|
+
"error": output.error_code,
|
|
1781
|
+
"since": output.since,
|
|
1782
|
+
"message": output.error_message,
|
|
1783
|
+
}
|
|
1784
|
+
if output.error_hints:
|
|
1785
|
+
_err_out["hint"] = output.error_hints
|
|
1786
|
+
_err_json = json.dumps(_err_out, indent=2, ensure_ascii=False)
|
|
1787
|
+
if output_path is not None:
|
|
1788
|
+
output_path.write_text(_err_json, encoding="utf-8")
|
|
1789
|
+
else:
|
|
1790
|
+
import sys as _sys
|
|
1791
|
+
_sys.stdout.buffer.write(_err_json.encode("utf-8"))
|
|
1792
|
+
_sys.stdout.buffer.write(b"\n")
|
|
1793
|
+
_sys.stdout.buffer.flush()
|
|
1794
|
+
raise typer.Exit(code=1)
|
|
1776
1795
|
if output.since:
|
|
1777
1796
|
out["since"] = output.since
|
|
1778
1797
|
if output.impact_summary:
|
|
@@ -333,6 +333,10 @@ class TaskOutput:
|
|
|
333
333
|
change_type: list[str] = field(default_factory=list)
|
|
334
334
|
dependency_graph_summary: dict = field(default_factory=dict)
|
|
335
335
|
impact_score_per_file: dict = field(default_factory=dict)
|
|
336
|
+
# error state (git ref not found, etc.)
|
|
337
|
+
error_code: Optional[str] = None
|
|
338
|
+
error_message: Optional[str] = None
|
|
339
|
+
error_hints: list[str] = field(default_factory=list)
|
|
336
340
|
|
|
337
341
|
|
|
338
342
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -618,7 +622,34 @@ class TaskContextBuilder:
|
|
|
618
622
|
_delta_files: Optional[set[str]] = None
|
|
619
623
|
if task_name == "delta":
|
|
620
624
|
_delta_raw = self._get_git_changed_files(since=since)
|
|
621
|
-
if _delta_raw:
|
|
625
|
+
if _delta_raw is None:
|
|
626
|
+
# Explicit --since ref couldn't be resolved — hard error, no fallback
|
|
627
|
+
_avail_branches, _suggested = self._get_available_refs(since or "")
|
|
628
|
+
_hints: list[str] = []
|
|
629
|
+
if _suggested:
|
|
630
|
+
_hints.append(f"Did you mean '{_suggested}'?")
|
|
631
|
+
if _avail_branches:
|
|
632
|
+
_hints.append(f"Available refs: {', '.join(_avail_branches[:8])}")
|
|
633
|
+
return TaskOutput(
|
|
634
|
+
task="delta",
|
|
635
|
+
goal="Produce incremental context for changed files — avoids re-reading the full repo.",
|
|
636
|
+
project_summary=None,
|
|
637
|
+
architecture_summary=None,
|
|
638
|
+
relevant_files=[],
|
|
639
|
+
suspected_areas=[],
|
|
640
|
+
improvement_opportunities=[],
|
|
641
|
+
test_gaps=[],
|
|
642
|
+
key_dependencies=[],
|
|
643
|
+
code_notes_summary=None,
|
|
644
|
+
limitations=[],
|
|
645
|
+
confidence="low",
|
|
646
|
+
since=since,
|
|
647
|
+
error_code="git_ref_not_found",
|
|
648
|
+
error_message=f"Git reference '{since}' does not exist in this repository.",
|
|
649
|
+
error_hints=_hints,
|
|
650
|
+
gaps=[f"Cannot compute delta: git ref '{since}' not found."] + _hints,
|
|
651
|
+
)
|
|
652
|
+
elif _delta_raw:
|
|
622
653
|
_delta_files = set(_delta_raw)
|
|
623
654
|
|
|
624
655
|
# ── 5c. review-pr suspected_areas (needs git uncommitted_files) ──────
|
|
@@ -1777,118 +1808,108 @@ class TaskContextBuilder:
|
|
|
1777
1808
|
path=path, role=role, score=rel_score, reason=reason, why=why_str
|
|
1778
1809
|
)))
|
|
1779
1810
|
why[path] = why_str
|
|
1780
|
-
|
|
1781
|
-
trigger_full = next((f for f in changed_files if Path(f).name == trigger_name), None)
|
|
1782
|
-
if trigger_full:
|
|
1783
|
-
graph_edges.append({"from": trigger_full, "to": path, "edge_type": "module_proximity", "hop": 1})
|
|
1811
|
+
# module_proximity is heuristic (not a verified import) — excluded from structural graph
|
|
1784
1812
|
|
|
1785
1813
|
related.sort(key=lambda x: (-x[0], x[1]))
|
|
1786
1814
|
relevant.extend(rf for _, _, rf in related[:10])
|
|
1787
1815
|
|
|
1788
|
-
# ──
|
|
1789
|
-
#
|
|
1790
|
-
#
|
|
1791
|
-
|
|
1816
|
+
# ── Steps 3b–3c: BFS multi-hop import propagation (repo-wide, 3 hops max) ─
|
|
1817
|
+
# Each hop expands from whatever was found in the previous hop into ALL
|
|
1818
|
+
# remaining source files — not restricted to original module/dir.
|
|
1819
|
+
# This enables A→B→C discovery even when B and C are in different modules.
|
|
1820
|
+
_BFS_SCANNABLE = frozenset({".py", ".java", ".kt", ".ts", ".js", ".tsx", ".jsx", ".mjs"})
|
|
1821
|
+
_bfs_all_sources = [
|
|
1792
1822
|
p for p in all_paths
|
|
1793
|
-
if
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
)
|
|
1823
|
+
if Path(p).suffix.lower() in _BFS_SCANNABLE
|
|
1824
|
+
]
|
|
1825
|
+
|
|
1826
|
+
_bfs_seen: set[str] = {rf.path for rf in relevant}
|
|
1827
|
+
_bfs_frontier: list[str] = [
|
|
1828
|
+
f for f in changed_files
|
|
1829
|
+
if Path(f).suffix.lower() in _BFS_SCANNABLE
|
|
1800
1830
|
]
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1831
|
+
|
|
1832
|
+
# (max results added from this hop, max_candidates scanned per seed)
|
|
1833
|
+
_BFS_HOP_BUDGET = [
|
|
1834
|
+
(8, 60), # hop 1 — broad: callers of changed files
|
|
1835
|
+
(6, 50), # hop 2 — transitives: callers of hop-1 files
|
|
1836
|
+
(4, 30), # hop 3 — deep transitives: callers of hop-2 files
|
|
1837
|
+
]
|
|
1838
|
+
|
|
1839
|
+
# (hop_num, score, path, RelevantFile) — merged across all hops then added to relevant
|
|
1840
|
+
_bfs_collected: list[tuple[int, float, str, RelevantFile]] = []
|
|
1841
|
+
|
|
1842
|
+
for _hop_num, (_max_results, _max_cands) in enumerate(_BFS_HOP_BUDGET, start=1):
|
|
1843
|
+
if not _bfs_frontier:
|
|
1844
|
+
break
|
|
1845
|
+
|
|
1846
|
+
_bfs_candidates = [p for p in _bfs_all_sources if p not in _bfs_seen]
|
|
1847
|
+
if not _bfs_candidates:
|
|
1848
|
+
break
|
|
1849
|
+
|
|
1850
|
+
_hop_dep_map = self._scan_import_dependents(
|
|
1851
|
+
changed_paths=_bfs_frontier,
|
|
1852
|
+
candidate_paths=_bfs_candidates,
|
|
1853
|
+
max_candidates=_max_cands,
|
|
1805
1854
|
)
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1855
|
+
|
|
1856
|
+
# collect (score, path) pairs for this hop to build the next frontier
|
|
1857
|
+
_hop_scored: list[tuple[float, str]] = []
|
|
1858
|
+
|
|
1859
|
+
for _seed_path, _dep_paths in _hop_dep_map.items():
|
|
1860
|
+
_seed_atype = (
|
|
1861
|
+
classifications[_seed_path]["artifact_type"]
|
|
1862
|
+
if _seed_path in classifications
|
|
1863
|
+
else self._classify_changed_file(_seed_path)["artifact_type"]
|
|
1864
|
+
)
|
|
1865
|
+
for _dep_path in _dep_paths:
|
|
1866
|
+
if _dep_path in _bfs_seen:
|
|
1812
1867
|
continue
|
|
1813
|
-
|
|
1814
|
-
|
|
1868
|
+
_bfs_seen.add(_dep_path)
|
|
1869
|
+
|
|
1870
|
+
_dep_cls = self._classify_changed_file(_dep_path)
|
|
1871
|
+
if _dep_cls["is_noise"]:
|
|
1815
1872
|
continue
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
f" |
|
|
1825
|
-
f" |
|
|
1873
|
+
|
|
1874
|
+
_dep_atype = _dep_cls["artifact_type"]
|
|
1875
|
+
_dep_score_base = _ARTIFACT_SCORE.get(_dep_atype, 0.45)
|
|
1876
|
+
# score decays 30% per hop so transitives rank below direct dependents
|
|
1877
|
+
_dep_score = round(_dep_score_base * (0.70 ** _hop_num), 2)
|
|
1878
|
+
_dep_role = _role_in_system(_dep_path, _dep_atype, _dep_path in ep_paths)
|
|
1879
|
+
|
|
1880
|
+
_why_str = (
|
|
1881
|
+
f"artifact_type: {_dep_atype} | role_in_system: {_dep_role}"
|
|
1882
|
+
f" | impact_area: {_classify_impact_area(_dep_path, _dep_cls['risk_areas'], _dep_atype)}"
|
|
1883
|
+
f" | propagation_risk: {_PROPAGATION_RISK.get(_dep_atype, 'low')}"
|
|
1884
|
+
f" | change_effect: {_CHANGE_EFFECT.get(_dep_atype, 'modifies application logic')}"
|
|
1885
|
+
f" | pulled_by: hop-{_hop_num} import from {Path(_seed_path).name}"
|
|
1826
1886
|
)
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1887
|
+
_reason = (
|
|
1888
|
+
f"hop-{_hop_num} import-dependent of {Path(_seed_path).name}"
|
|
1889
|
+
f" ({_seed_atype}) | score: {_dep_score:.2f}"
|
|
1890
|
+
)
|
|
1891
|
+
why[_dep_path] = _why_str
|
|
1892
|
+
# Tests are consumers, not structural dependencies — exclude from import graph.
|
|
1893
|
+
# They remain in relevant_files but must not seed further BFS hops.
|
|
1894
|
+
_is_test = _dep_atype == "test"
|
|
1895
|
+
if not _is_test:
|
|
1896
|
+
graph_edges.append({
|
|
1897
|
+
"from": _seed_path, "to": _dep_path,
|
|
1898
|
+
"edge_type": "import_dependency", "hop": _hop_num,
|
|
1899
|
+
})
|
|
1900
|
+
_hop_scored.append((_dep_score, _dep_path))
|
|
1901
|
+
_bfs_collected.append((_hop_num, _dep_score, _dep_path, RelevantFile(
|
|
1902
|
+
path=_dep_path, role=_dep_role, score=_dep_score,
|
|
1903
|
+
reason=_reason, why=_why_str,
|
|
1831
1904
|
)))
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
dep_path
|
|
1841
|
-
for dep_paths in (_import_dep_map.values() if _import_candidates else [])
|
|
1842
|
-
for dep_path in dep_paths
|
|
1843
|
-
))
|
|
1844
|
-
if _hop1_seeds:
|
|
1845
|
-
_hop2_seen = {rf.path for rf in relevant}
|
|
1846
|
-
_hop2_candidates = [
|
|
1847
|
-
p for p in all_paths
|
|
1848
|
-
if p not in _hop2_seen
|
|
1849
|
-
and Path(p).suffix.lower() in {".py", ".java", ".kt", ".ts", ".js", ".tsx", ".jsx", ".mjs"}
|
|
1850
|
-
and (
|
|
1851
|
-
_extract_ddd_domain(p) in affected_modules_set
|
|
1852
|
-
or str(Path(p).parent).replace("\\", "/") in changed_dirs
|
|
1853
|
-
)
|
|
1854
|
-
]
|
|
1855
|
-
if _hop2_candidates:
|
|
1856
|
-
_hop2_dep_map = self._scan_import_dependents(
|
|
1857
|
-
changed_paths=_hop1_seeds,
|
|
1858
|
-
candidate_paths=_hop2_candidates,
|
|
1859
|
-
max_candidates=20,
|
|
1860
|
-
)
|
|
1861
|
-
_hop2_extra: list[tuple[float, str, RelevantFile]] = []
|
|
1862
|
-
for hop1_path, dep_paths in _hop2_dep_map.items():
|
|
1863
|
-
hop1_cls = self._classify_changed_file(hop1_path)
|
|
1864
|
-
hop1_atype = hop1_cls["artifact_type"]
|
|
1865
|
-
for dep_path in dep_paths:
|
|
1866
|
-
if dep_path in _hop2_seen:
|
|
1867
|
-
continue
|
|
1868
|
-
dep_cls = self._classify_changed_file(dep_path)
|
|
1869
|
-
if dep_cls["is_noise"]:
|
|
1870
|
-
continue
|
|
1871
|
-
dep_atype = dep_cls["artifact_type"]
|
|
1872
|
-
dep_base = _ARTIFACT_SCORE.get(dep_atype, 0.45)
|
|
1873
|
-
dep_score = round(dep_base * 0.50, 2)
|
|
1874
|
-
dep_role = _role_in_system(dep_path, dep_atype, dep_path in ep_paths)
|
|
1875
|
-
why_str = (
|
|
1876
|
-
f"artifact_type: {dep_atype} | role_in_system: {dep_role}"
|
|
1877
|
-
f" | impact_area: {_classify_impact_area(dep_path, dep_cls['risk_areas'], dep_atype)}"
|
|
1878
|
-
f" | propagation_risk: {_PROPAGATION_RISK.get(dep_atype, 'low')}"
|
|
1879
|
-
f" | change_effect: {_CHANGE_EFFECT.get(dep_atype, 'modifies application logic')}"
|
|
1880
|
-
f" | pulled_by: hop-2 import from {Path(hop1_path).name}"
|
|
1881
|
-
)
|
|
1882
|
-
reason = f"hop-2 import-dependent of {Path(hop1_path).name} ({hop1_atype}) | score: {dep_score:.2f}"
|
|
1883
|
-
_hop2_extra.append((dep_score, dep_path, RelevantFile(
|
|
1884
|
-
path=dep_path, role=dep_role, score=dep_score,
|
|
1885
|
-
reason=reason, why=why_str,
|
|
1886
|
-
)))
|
|
1887
|
-
why[dep_path] = why_str
|
|
1888
|
-
_hop2_seen.add(dep_path)
|
|
1889
|
-
graph_edges.append({"from": hop1_path, "to": dep_path, "edge_type": "import_dependency", "hop": 2})
|
|
1890
|
-
_hop2_extra.sort(key=lambda x: (-x[0], x[1]))
|
|
1891
|
-
relevant.extend(rf for _, _, rf in _hop2_extra[:5])
|
|
1905
|
+
|
|
1906
|
+
# next frontier = top-N files by score from this hop
|
|
1907
|
+
_hop_scored.sort(key=lambda x: -x[0])
|
|
1908
|
+
_bfs_frontier = [p for _, p in _hop_scored[:_max_results]]
|
|
1909
|
+
|
|
1910
|
+
# merge into relevant: closer hops first, then higher score; cap total at 20
|
|
1911
|
+
_bfs_collected.sort(key=lambda x: (x[0], -x[1], x[2]))
|
|
1912
|
+
relevant.extend(rf for _, _, _, rf in _bfs_collected[:20])
|
|
1892
1913
|
|
|
1893
1914
|
# ── Step 3d: per-file impact scores, change_type, system_impact ─────────
|
|
1894
1915
|
# Downstream fanout: count graph edges originating from each changed file
|
|
@@ -2054,9 +2075,13 @@ class TaskContextBuilder:
|
|
|
2054
2075
|
}
|
|
2055
2076
|
|
|
2056
2077
|
# ── Step 6: analysis gaps ──────────────────────────────────────────────
|
|
2057
|
-
|
|
2078
|
+
_bfs_note = (
|
|
2079
|
+
f"BFS multi-hop import propagation repo-wide (propagation_depth={_max_hop})"
|
|
2080
|
+
if _max_hop >= 1
|
|
2081
|
+
else "no import-link propagation (no scannable changed files)"
|
|
2082
|
+
)
|
|
2058
2083
|
analysis_gaps: list[str] = [
|
|
2059
|
-
f"Related file expansion
|
|
2084
|
+
f"Related file expansion: type-aware chain expansion + {_bfs_note} + module/directory heuristics",
|
|
2060
2085
|
]
|
|
2061
2086
|
if noise_count > 0 and meaningful > 0:
|
|
2062
2087
|
analysis_gaps.append(
|
|
@@ -2093,9 +2118,13 @@ class TaskContextBuilder:
|
|
|
2093
2118
|
impact_score_per_file,
|
|
2094
2119
|
)
|
|
2095
2120
|
|
|
2096
|
-
def _get_git_changed_files(self, since: Optional[str] = None) -> list[str]:
|
|
2121
|
+
def _get_git_changed_files(self, since: Optional[str] = None) -> Optional[list[str]]:
|
|
2097
2122
|
"""Get files changed since a git ref (default: HEAD~1) relative to self.root.
|
|
2098
2123
|
|
|
2124
|
+
Returns None when `since` is explicitly provided but cannot be resolved —
|
|
2125
|
+
this is an error state, not "no changes". Callers must distinguish None
|
|
2126
|
+
(ref invalid) from [] (ref valid, no changes).
|
|
2127
|
+
|
|
2099
2128
|
Uses --relative so paths are relative to cwd (self.root), not the git repo
|
|
2100
2129
|
root. This is critical for monorepos where self.root is a subpath of the
|
|
2101
2130
|
git root and git diff would otherwise return prefixed paths that don't match
|
|
@@ -2118,9 +2147,13 @@ class TaskContextBuilder:
|
|
|
2118
2147
|
line.strip() for line in (result.stdout or "").splitlines()
|
|
2119
2148
|
if line.strip()
|
|
2120
2149
|
]
|
|
2150
|
+
# Non-zero exit with explicit ref = ref doesn't exist — no silent fallback
|
|
2151
|
+
if since:
|
|
2152
|
+
return None
|
|
2121
2153
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
2122
|
-
|
|
2123
|
-
|
|
2154
|
+
if since:
|
|
2155
|
+
return None
|
|
2156
|
+
# No explicit since: fall back to uncommitted changes
|
|
2124
2157
|
try:
|
|
2125
2158
|
result = subprocess.run(
|
|
2126
2159
|
["git", "diff", "--name-only", "--relative"],
|
|
@@ -2136,3 +2169,26 @@ class TaskContextBuilder:
|
|
|
2136
2169
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
2137
2170
|
pass
|
|
2138
2171
|
return []
|
|
2172
|
+
|
|
2173
|
+
def _get_available_refs(self, invalid_ref: str) -> tuple[list[str], Optional[str]]:
|
|
2174
|
+
"""Return (available_branch_names, suggested_alternative) for error hints."""
|
|
2175
|
+
import subprocess
|
|
2176
|
+
branches: list[str] = []
|
|
2177
|
+
suggested: Optional[str] = None
|
|
2178
|
+
try:
|
|
2179
|
+
r = subprocess.run(
|
|
2180
|
+
["git", "branch", "-a", "--format=%(refname:short)"],
|
|
2181
|
+
cwd=str(self.root),
|
|
2182
|
+
capture_output=True, text=True, timeout=5,
|
|
2183
|
+
)
|
|
2184
|
+
if r.returncode == 0:
|
|
2185
|
+
all_refs = [b.strip() for b in r.stdout.splitlines() if b.strip()]
|
|
2186
|
+
branches = [b for b in all_refs if "HEAD" not in b][:10]
|
|
2187
|
+
ref_lower = invalid_ref.lower()
|
|
2188
|
+
if ref_lower == "master" and any(b.rstrip("/").endswith("main") for b in all_refs):
|
|
2189
|
+
suggested = "main"
|
|
2190
|
+
elif ref_lower == "main" and any(b.rstrip("/").endswith("master") for b in all_refs):
|
|
2191
|
+
suggested = "master"
|
|
2192
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
2193
|
+
pass
|
|
2194
|
+
return branches, suggested
|
{sourcecode-1.23.0 → sourcecode-1.26.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.23.0 → sourcecode-1.26.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.23.0 → sourcecode-1.26.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
|