sourcecode 1.30.5__tar.gz → 1.30.6__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.
Files changed (190) hide show
  1. {sourcecode-1.30.5 → sourcecode-1.30.6}/PKG-INFO +3 -3
  2. {sourcecode-1.30.5 → sourcecode-1.30.6}/README.md +2 -2
  3. {sourcecode-1.30.5 → sourcecode-1.30.6}/pyproject.toml +1 -1
  4. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/cli.py +6 -0
  6. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/prepare_context.py +219 -72
  7. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_v1_10_regressions.py +10 -7
  8. {sourcecode-1.30.5 → sourcecode-1.30.6}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
  9. {sourcecode-1.30.5 → sourcecode-1.30.6}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
  10. {sourcecode-1.30.5 → sourcecode-1.30.6}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
  11. {sourcecode-1.30.5 → sourcecode-1.30.6}/.continue-here.md +0 -0
  12. {sourcecode-1.30.5 → sourcecode-1.30.6}/.github/workflows/build-windows.yml +0 -0
  13. {sourcecode-1.30.5 → sourcecode-1.30.6}/.gitignore +0 -0
  14. {sourcecode-1.30.5 → sourcecode-1.30.6}/.ruff.toml +0 -0
  15. {sourcecode-1.30.5 → sourcecode-1.30.6}/CONTRIBUTING.md +0 -0
  16. {sourcecode-1.30.5 → sourcecode-1.30.6}/LICENSE +0 -0
  17. {sourcecode-1.30.5 → sourcecode-1.30.6}/SECURITY.md +0 -0
  18. {sourcecode-1.30.5 → sourcecode-1.30.6}/docs/privacy.md +0 -0
  19. {sourcecode-1.30.5 → sourcecode-1.30.6}/docs/schema.md +0 -0
  20. {sourcecode-1.30.5 → sourcecode-1.30.6}/raw +0 -0
  21. {sourcecode-1.30.5 → sourcecode-1.30.6}/run_cli.py +0 -0
  22. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/adaptive_scanner.py +0 -0
  23. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/architecture_analyzer.py +0 -0
  24. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/architecture_summary.py +0 -0
  25. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/ast_extractor.py +0 -0
  26. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/classifier.py +0 -0
  27. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/code_notes_analyzer.py +0 -0
  28. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/confidence_analyzer.py +0 -0
  29. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/context_scorer.py +0 -0
  30. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/context_summarizer.py +0 -0
  31. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/contract_model.py +0 -0
  32. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/contract_pipeline.py +0 -0
  33. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/coverage_parser.py +0 -0
  34. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/dependency_analyzer.py +0 -0
  35. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/__init__.py +0 -0
  36. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/base.py +0 -0
  37. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/csproj_parser.py +0 -0
  38. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/dart.py +0 -0
  39. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/dotnet.py +0 -0
  40. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/elixir.py +0 -0
  41. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/go.py +0 -0
  42. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/heuristic.py +0 -0
  43. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/hybrid.py +0 -0
  44. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/java.py +0 -0
  45. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/jvm_ext.py +0 -0
  46. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/nodejs.py +0 -0
  47. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/parsers.py +0 -0
  48. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/php.py +0 -0
  49. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/project.py +0 -0
  50. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/python.py +0 -0
  51. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/ruby.py +0 -0
  52. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/rust.py +0 -0
  53. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/systems.py +0 -0
  54. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/terraform.py +0 -0
  55. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/detectors/tooling.py +0 -0
  56. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/doc_analyzer.py +0 -0
  57. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/entrypoint_classifier.py +0 -0
  58. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/env_analyzer.py +0 -0
  59. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/file_classifier.py +0 -0
  60. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/flow_analyzer.py +0 -0
  61. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/git_analyzer.py +0 -0
  62. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/graph_analyzer.py +0 -0
  63. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/metrics_analyzer.py +0 -0
  64. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/progress.py +0 -0
  65. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/ranking_engine.py +0 -0
  66. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/redactor.py +0 -0
  67. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/relevance_scorer.py +0 -0
  68. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/repo_classifier.py +0 -0
  69. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/runtime_classifier.py +0 -0
  70. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/scanner.py +0 -0
  71. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/schema.py +0 -0
  72. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/semantic_analyzer.py +0 -0
  73. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/serializer.py +0 -0
  74. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/summarizer.py +0 -0
  75. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/__init__.py +0 -0
  76. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/config.py +0 -0
  77. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/consent.py +0 -0
  78. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/events.py +0 -0
  79. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/filters.py +0 -0
  80. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/telemetry/transport.py +0 -0
  81. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/tree_utils.py +0 -0
  82. {sourcecode-1.30.5 → sourcecode-1.30.6}/src/sourcecode/workspace.py +0 -0
  83. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/__init__.py +0 -0
  84. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/conftest.py +0 -0
  85. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/coverage.xml +0 -0
  86. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
  87. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/fastapi_app/src/main.py +0 -0
  88. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/go_service/cmd/api/main.go +0 -0
  89. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/go_service/go.mod +0 -0
  90. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/jacoco.xml +0 -0
  91. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/latin1_sample.java +0 -0
  92. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/latin1_sample_iso.java +0 -0
  93. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/lcov.info +0 -0
  94. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
  95. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/nextjs_app/package.json +0 -0
  96. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
  97. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
  98. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
  99. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
  100. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
  101. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
  102. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
  103. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
  104. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
  105. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
  106. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
  107. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
  108. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
  109. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
  110. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
  111. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
  112. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
  113. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
  114. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
  115. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
  116. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
  117. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
  118. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
  119. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
  120. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
  121. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
  122. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
  123. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
  124. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
  125. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
  126. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
  127. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
  128. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
  129. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_architecture_analyzer.py +0 -0
  130. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_architecture_summary.py +0 -0
  131. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_ast_extractor.py +0 -0
  132. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_block1_reliability.py +0 -0
  133. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_block2_coverage.py +0 -0
  134. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_block5_quality.py +0 -0
  135. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_bug_fixes_v16.py +0 -0
  136. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_classifier.py +0 -0
  137. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_cli.py +0 -0
  138. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_code_notes_analyzer.py +0 -0
  139. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_context_scorer.py +0 -0
  140. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_contract_pipeline.py +0 -0
  141. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_coverage_parser.py +0 -0
  142. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_cross_consistency.py +0 -0
  143. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_dependency_analyzer_node_python.py +0 -0
  144. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_dependency_analyzer_polyglot.py +0 -0
  145. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_dependency_schema.py +0 -0
  146. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_dotnet.py +0 -0
  147. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_go_rust_java.py +0 -0
  148. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_nodejs.py +0 -0
  149. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_php_ruby_dart.py +0 -0
  150. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_python.py +0 -0
  151. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_universal_managed.py +0 -0
  152. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detector_universal_systems.py +0 -0
  153. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_detectors_base.py +0 -0
  154. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_doc_analyzer_jsdom.py +0 -0
  155. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_doc_analyzer_python.py +0 -0
  156. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_encoding_regression.py +0 -0
  157. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_graph_analyzer_polyglot.py +0 -0
  158. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_graph_analyzer_python_node.py +0 -0
  159. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_graph_schema.py +0 -0
  160. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_hybrid_inference.py +0 -0
  161. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration.py +0 -0
  162. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_dependencies.py +0 -0
  163. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_detection.py +0 -0
  164. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_docs.py +0 -0
  165. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_graph_modules.py +0 -0
  166. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_lqn.py +0 -0
  167. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_metrics.py +0 -0
  168. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_multistack.py +0 -0
  169. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_semantics.py +0 -0
  170. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_integration_universal.py +0 -0
  171. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_java_spring_integration.py +0 -0
  172. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_metrics_analyzer.py +0 -0
  173. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_packaging.py +0 -0
  174. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_phase1_improvements.py +0 -0
  175. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_pipeline_integrity.py +0 -0
  176. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_real_projects.py +0 -0
  177. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_redactor.py +0 -0
  178. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_scanner.py +0 -0
  179. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_schema.py +0 -0
  180. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_schema_normalization.py +0 -0
  181. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_semantic_analyzer_node.py +0 -0
  182. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_semantic_analyzer_python.py +0 -0
  183. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_semantic_import_resolution.py +0 -0
  184. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_semantic_schema.py +0 -0
  185. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_signal_hierarchy.py +0 -0
  186. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_summarizer.py +0 -0
  187. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_surface_honesty.py +0 -0
  188. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_task_differentiation.py +0 -0
  189. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_telemetry.py +0 -0
  190. {sourcecode-1.30.5 → sourcecode-1.30.6}/tests/test_workspace_analyzer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.30.5
3
+ Version: 1.30.6
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
  **Deterministic, behavior-aware codebase context for AI agents and PR review.**
223
223
 
224
- ![Version](https://img.shields.io/badge/version-1.30.5-blue)
224
+ ![Version](https://img.shields.io/badge/version-1.30.6-blue)
225
225
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
226
226
 
227
227
  ---
@@ -257,7 +257,7 @@ pipx install sourcecode
257
257
 
258
258
  ```bash
259
259
  sourcecode version
260
- # sourcecode 1.30.5
260
+ # sourcecode 1.30.6
261
261
  ```
262
262
 
263
263
  ---
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Deterministic, behavior-aware codebase context for AI agents and PR review.**
4
4
 
5
- ![Version](https://img.shields.io/badge/version-1.30.5-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.30.6-blue)
6
6
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
7
7
 
8
8
  ---
@@ -38,7 +38,7 @@ pipx install sourcecode
38
38
 
39
39
  ```bash
40
40
  sourcecode version
41
- # sourcecode 1.30.5
41
+ # sourcecode 1.30.6
42
42
  ```
43
43
 
44
44
  ---
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "1.30.5"
7
+ version = "1.30.6"
8
8
  description = "Deterministic codebase context for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """sourcecode — Deterministic codebase context maps for AI coding agents."""
2
2
 
3
- __version__ = "1.30.5"
3
+ __version__ = "1.30.6"
@@ -1874,6 +1874,12 @@ def prepare_context_cmd(
1874
1874
  out["impact_summary"] = output.impact_summary
1875
1875
  if output.why_these_files:
1876
1876
  out["reasoning"] = output.why_these_files
1877
+ # git-first scope metadata
1878
+ out["scope"] = {
1879
+ "source": output.scope_source or "git_diff",
1880
+ "files": output.scope_files,
1881
+ "repo_root": output.repo_root or "",
1882
+ }
1877
1883
  if output.limitations:
1878
1884
  out["limitations"] = output.limitations
1879
1885
  if output.symptom:
@@ -353,6 +353,10 @@ class TaskOutput:
353
353
  suggested_review_order: list[str] = field(default_factory=list)
354
354
  execution_paths: list[dict] = field(default_factory=list)
355
355
  behavioral_impact: list[dict] = field(default_factory=list)
356
+ # git-first scope metadata (review-pr only)
357
+ scope_source: Optional[str] = None # "git_diff" | "staged" | "untracked" | "full_scan_fallback"
358
+ scope_files: list[str] = field(default_factory=list)
359
+ repo_root: Optional[str] = None
356
360
 
357
361
 
358
362
  # ─────────────────────────────────────────────────────────────────────────────
@@ -440,23 +444,81 @@ class TaskContextBuilder:
440
444
  )
441
445
  spec = TASKS[task_name]
442
446
 
447
+ # ── 0. review-pr: git-first scope resolution (before any filesystem scan) ─
448
+ _pr_git_root: Optional[Path] = None
449
+ _pr_scope_files: Optional[list[str]] = None
450
+ _pr_scope_source: str = "full_scan_fallback"
451
+
452
+ if task_name == "review-pr":
453
+ _pr_git_root = self._resolve_git_root()
454
+ if _pr_git_root is None:
455
+ return TaskOutput(
456
+ task="review-pr", goal=spec.goal,
457
+ project_summary=None, architecture_summary=None,
458
+ relevant_files=[], suspected_areas=[],
459
+ improvement_opportunities=[], test_gaps=[],
460
+ key_dependencies=[], code_notes_summary=None,
461
+ limitations=[], confidence="low",
462
+ error_code="no_git_repo",
463
+ error_message="review-pr requires a git repository.",
464
+ ci_decision="no_git_repo",
465
+ scope_source="full_scan_fallback",
466
+ repo_root=str(self.root),
467
+ )
468
+ _raw_scope, _pr_scope_source = self._get_pr_scope_files(since=since)
469
+ if _raw_scope is None:
470
+ # Explicit --since ref is invalid
471
+ _avail_pr, _sug_pr = self._get_available_refs(since or "")
472
+ _pr_hints: list[str] = []
473
+ if _sug_pr:
474
+ _pr_hints.append(f"Did you mean '{_sug_pr}'?")
475
+ if _avail_pr:
476
+ _pr_hints.append(f"Available refs: {', '.join(_avail_pr[:8])}")
477
+ return TaskOutput(
478
+ task="review-pr", goal=spec.goal,
479
+ project_summary=None, architecture_summary=None,
480
+ relevant_files=[], suspected_areas=[],
481
+ improvement_opportunities=[], test_gaps=[],
482
+ key_dependencies=[], code_notes_summary=None,
483
+ limitations=[], confidence="low",
484
+ since=since,
485
+ error_code="git_ref_not_found",
486
+ error_message=f"Base ref '{since}' not found in this repository.",
487
+ error_hints=_pr_hints,
488
+ gaps=[f"Cannot compute PR diff: git ref '{since}' not found."] + _pr_hints,
489
+ ci_decision="git_ref_error",
490
+ scope_source="git_diff",
491
+ repo_root=str(_pr_git_root),
492
+ )
493
+ _pr_scope_files = _raw_scope
494
+ # _pr_scope_files == [] means no diff; handled in step 5d
495
+
496
+ _use_git_first = task_name == "review-pr"
497
+
443
498
  # ── 1. Scan ────────────────────────────────────────────────────────
444
499
  from sourcecode.adaptive_scanner import AdaptiveScanner
445
500
  from sourcecode.repo_classifier import RepoClassifier
446
501
  from sourcecode.tree_utils import flatten_file_tree
447
-
448
- _topology = RepoClassifier().classify(self.root)
449
- # Shallow pre-scan to detect Java manifests before choosing depth.
450
502
  from sourcecode.scanner import FileScanner as _FileScanner
451
- _pre = _FileScanner(self.root, max_depth=1)
452
- _pre_manifests = _pre.find_manifests()
503
+
504
+ _pre_manifests = _FileScanner(self.root, max_depth=1).find_manifests()
453
505
  _java_names = {"pom.xml", "build.gradle", "build.gradle.kts"}
454
506
  _is_java = any(Path(m).name in _java_names for m in _pre_manifests)
455
- _base_depth = 12 if _is_java else 6
456
- scanner = AdaptiveScanner(self.root, topology=_topology, base_depth=_base_depth)
457
- file_tree = scanner.scan_tree()
458
- manifests = scanner.find_manifests()
459
- all_paths = [p.replace("\\", "/") for p in flatten_file_tree(file_tree)]
507
+ manifests = _pre_manifests
508
+
509
+ if _use_git_first:
510
+ # Git-first: no full filesystem traversal — skip AdaptiveScanner.
511
+ # all_paths = scope files + siblings in same directories (bounded context
512
+ # for behavioral_impact reverse lookups without scanning the whole repo).
513
+ file_tree: dict = {}
514
+ all_paths = self._expand_scope_for_analysis(_pr_scope_files or [])
515
+ else:
516
+ _topology = RepoClassifier().classify(self.root)
517
+ _base_depth = 12 if _is_java else 6
518
+ scanner = AdaptiveScanner(self.root, topology=_topology, base_depth=_base_depth)
519
+ file_tree = scanner.scan_tree()
520
+ manifests = scanner.find_manifests()
521
+ all_paths = [p.replace("\\", "/") for p in flatten_file_tree(file_tree)]
460
522
 
461
523
  # Warn when Java project has no Mapper.xml — suggests files below scan depth.
462
524
  _mybatis_warning: dict | None = None
@@ -487,25 +549,26 @@ class TaskContextBuilder:
487
549
  else:
488
550
  stacks, entry_points, _ = detector.detect(self.root, file_tree, _detection_manifests)
489
551
 
490
- # Iterate workspaces to collect per-workspace stacks and entry points —
491
- # same approach as the main CLI (cli.py lines 971-1041).
492
- for workspace in workspace_analysis.workspaces:
493
- ws_root = self.root / workspace.path
494
- if not ws_root.exists() or not ws_root.is_dir():
495
- continue
496
- _ws_topology = RepoClassifier().classify(ws_root)
497
- _ws_scanner = AdaptiveScanner(ws_root, topology=_ws_topology, base_depth=6)
498
- _ws_tree = _ws_scanner.scan_tree()
499
- _ws_manifests = _ws_scanner.find_manifests()
500
- _ws_stacks, _ws_eps, _ = detector.detect(ws_root, _ws_tree, _ws_manifests)
501
- stacks.extend(
502
- _replace(s, root=workspace.path, workspace=workspace.path, primary=False)
503
- for s in _ws_stacks
504
- )
505
- entry_points.extend(
506
- _replace(ep, path=f"{workspace.path}/{ep.path}")
507
- for ep in _ws_eps
508
- )
552
+ if not _use_git_first:
553
+ # Workspace sub-scans: each runs AdaptiveScanner on a workspace root.
554
+ # Skipped for review-pr would re-trigger full traversal per workspace.
555
+ for workspace in workspace_analysis.workspaces:
556
+ ws_root = self.root / workspace.path
557
+ if not ws_root.exists() or not ws_root.is_dir():
558
+ continue
559
+ _ws_topology = RepoClassifier().classify(ws_root)
560
+ _ws_scanner = AdaptiveScanner(ws_root, topology=_ws_topology, base_depth=6)
561
+ _ws_tree = _ws_scanner.scan_tree()
562
+ _ws_manifests = _ws_scanner.find_manifests()
563
+ _ws_stacks, _ws_eps, _ = detector.detect(ws_root, _ws_tree, _ws_manifests)
564
+ stacks.extend(
565
+ _replace(s, root=workspace.path, workspace=workspace.path, primary=False)
566
+ for s in _ws_stacks
567
+ )
568
+ entry_points.extend(
569
+ _replace(ep, path=f"{workspace.path}/{ep.path}")
570
+ for ep in _ws_eps
571
+ )
509
572
 
510
573
  stacks, project_type = detector.classify_results(
511
574
  file_tree, stacks, entry_points,
@@ -669,49 +732,10 @@ class TaskContextBuilder:
669
732
  elif _delta_raw:
670
733
  _delta_files = set(_delta_raw)
671
734
 
672
- # ── 5d. review-pr: git-first gate ──────────────────────────────────────
735
+ # ── 5d. review-pr: set _delta_files from pre-resolved git scope ──────────
736
+ # No-git and invalid-ref cases were already handled in step 0 (early returns).
673
737
  if task_name == "review-pr":
674
- if not self._is_git_repo():
675
- return TaskOutput(
676
- task="review-pr", goal=spec.goal,
677
- project_summary=None, architecture_summary=None,
678
- relevant_files=[], suspected_areas=[],
679
- improvement_opportunities=[], test_gaps=[],
680
- key_dependencies=[], code_notes_summary=None,
681
- limitations=[], confidence="low",
682
- error_code="no_git_repo",
683
- error_message="review-pr requires a git repository.",
684
- ci_decision="no_git_repo",
685
- )
686
- if since is None:
687
- # review-pr with no --since: check only uncommitted changes.
688
- # _get_git_changed_files(since=None) defaults to HEAD~1 which
689
- # returns the last *committed* diff — a false positive here.
690
- _pr_raw: Optional[list[str]] = self._get_uncommitted_changed_files()
691
- else:
692
- _pr_raw = self._get_git_changed_files(since=since)
693
- if _pr_raw is None:
694
- _avail_pr, _sug_pr = self._get_available_refs(since or "")
695
- _pr_hints: list[str] = []
696
- if _sug_pr:
697
- _pr_hints.append(f"Did you mean '{_sug_pr}'?")
698
- if _avail_pr:
699
- _pr_hints.append(f"Available refs: {', '.join(_avail_pr[:8])}")
700
- return TaskOutput(
701
- task="review-pr", goal=spec.goal,
702
- project_summary=None, architecture_summary=None,
703
- relevant_files=[], suspected_areas=[],
704
- improvement_opportunities=[], test_gaps=[],
705
- key_dependencies=[], code_notes_summary=None,
706
- limitations=[], confidence="low",
707
- since=since,
708
- error_code="git_ref_not_found",
709
- error_message=f"Base ref '{since}' not found in this repository.",
710
- error_hints=_pr_hints,
711
- gaps=[f"Cannot compute PR diff: git ref '{since}' not found."] + _pr_hints,
712
- ci_decision="git_ref_error",
713
- )
714
- if not _pr_raw:
738
+ if not _pr_scope_files:
715
739
  _no_diff_hint = "review-pr requires changed files or --since <ref>."
716
740
  return TaskOutput(
717
741
  task="review-pr", goal=spec.goal,
@@ -724,8 +748,11 @@ class TaskContextBuilder:
724
748
  error_message=f"No PR diff detected. {_no_diff_hint}",
725
749
  gaps=[f"No PR diff detected. {_no_diff_hint}"],
726
750
  ci_decision="no_changes",
751
+ scope_source=_pr_scope_source,
752
+ scope_files=[],
753
+ repo_root=str(_pr_git_root),
727
754
  )
728
- _delta_files = set(_pr_raw)
755
+ _delta_files = set(_pr_scope_files)
729
756
 
730
757
  # ── 5c. review-pr suspected_areas (needs git uncommitted_files) ──────
731
758
  if task_name == "review-pr" and spec.enable_code_notes:
@@ -1127,6 +1154,10 @@ class TaskContextBuilder:
1127
1154
  suggested_review_order=_pr_suggested_review_order,
1128
1155
  execution_paths=_execution_paths,
1129
1156
  behavioral_impact=_behavioral_impact,
1157
+ # git-first scope metadata
1158
+ scope_source=_pr_scope_source if task_name == "review-pr" else None,
1159
+ scope_files=list(_pr_scope_files) if task_name == "review-pr" and _pr_scope_files else [],
1160
+ repo_root=str(_pr_git_root) if task_name == "review-pr" and _pr_git_root else None,
1130
1161
  )
1131
1162
 
1132
1163
  def render_prompt(self, output: TaskOutput) -> str:
@@ -1418,6 +1449,122 @@ class TaskContextBuilder:
1418
1449
  def _is_source(self, path: str) -> bool:
1419
1450
  return Path(path).suffix.lower() in _SOURCE_EXTENSIONS
1420
1451
 
1452
+ def _resolve_git_root(self) -> Optional[Path]:
1453
+ """Return the absolute git repo root, or None if not in a git repo."""
1454
+ import subprocess
1455
+ try:
1456
+ r = subprocess.run(
1457
+ ["git", "rev-parse", "--show-toplevel"],
1458
+ cwd=str(self.root),
1459
+ capture_output=True, text=True,
1460
+ encoding="utf-8", errors="replace", timeout=5,
1461
+ )
1462
+ if r.returncode == 0 and r.stdout.strip():
1463
+ return Path(r.stdout.strip())
1464
+ except (subprocess.TimeoutExpired, FileNotFoundError):
1465
+ pass
1466
+ return None
1467
+
1468
+ def _get_pr_scope_files(self, since: Optional[str] = None) -> tuple[Optional[list[str]], str]:
1469
+ """Return (files, scope_source) for review-pr scope resolution.
1470
+
1471
+ Returns (None, _) only when since is explicitly provided but the ref is invalid.
1472
+ Returns ([], _) when git is available but no changes are found.
1473
+ scope_source is a comma-separated list of active sources (git_diff, staged, untracked).
1474
+ """
1475
+ import subprocess
1476
+
1477
+ def _run(*cmd: str) -> Optional[list[str]]:
1478
+ try:
1479
+ r = subprocess.run(
1480
+ list(cmd), cwd=str(self.root),
1481
+ capture_output=True, text=True,
1482
+ encoding="utf-8", errors="replace", timeout=10,
1483
+ )
1484
+ return (
1485
+ [ln.strip() for ln in (r.stdout or "").splitlines() if ln.strip()]
1486
+ if r.returncode == 0 else None
1487
+ )
1488
+ except (subprocess.TimeoutExpired, FileNotFoundError):
1489
+ return None
1490
+
1491
+ files: set[str] = set()
1492
+ sources: list[str] = []
1493
+
1494
+ if since is not None:
1495
+ committed = _run("git", "diff", "--name-only", "--relative", since, "HEAD")
1496
+ if committed is None:
1497
+ return None, "git_diff" # invalid ref — hard error
1498
+ if committed:
1499
+ files.update(committed)
1500
+ sources.append("git_diff")
1501
+ else:
1502
+ # Working tree vs HEAD~1: covers last commit + all uncommitted changes
1503
+ h1_diff = _run("git", "diff", "--name-only", "--relative", "HEAD~1")
1504
+ if h1_diff:
1505
+ files.update(h1_diff)
1506
+ sources.append("git_diff")
1507
+ # Working tree vs HEAD: uncommitted only (may add new unstaged files)
1508
+ h_diff = _run("git", "diff", "--name-only", "--relative", "HEAD")
1509
+ if h_diff:
1510
+ new = set(h_diff) - files
1511
+ if new:
1512
+ files.update(new)
1513
+ if "git_diff" not in sources:
1514
+ sources.append("git_diff")
1515
+ # Staged changes not yet committed
1516
+ staged = _run("git", "diff", "--name-only", "--cached", "--relative")
1517
+ if staged:
1518
+ new = set(staged) - files
1519
+ if new:
1520
+ files.update(new)
1521
+ sources.append("staged")
1522
+
1523
+ # Untracked files (both cases)
1524
+ status = _run("git", "status", "--porcelain", "--short")
1525
+ if status:
1526
+ for line in status:
1527
+ if line.startswith("??") and len(line) > 3:
1528
+ f = line[3:].strip()
1529
+ if f and not f.endswith("/") and f not in files:
1530
+ files.add(f)
1531
+ if "untracked" not in sources:
1532
+ sources.append("untracked")
1533
+
1534
+ # Drop paths outside self.root (../… prefix means above cwd — occurs when
1535
+ # self.root is a subdirectory of the git repo and git status shows repo-level files).
1536
+ files = {f for f in files if not f.startswith("../") and not f.startswith("..\\")}
1537
+
1538
+ scope_source = ",".join(sources) if sources else "git_diff"
1539
+ return sorted(files), scope_source
1540
+
1541
+ def _expand_scope_for_analysis(self, scope_files: list[str]) -> list[str]:
1542
+ """Add sibling files in the same directories as scope_files (depth=1 expansion).
1543
+
1544
+ Gives behavioral_impact engine context for reverse lookups (e.g. controllers
1545
+ in the same package as changed services) without traversing the full repo.
1546
+ """
1547
+ expanded: set[str] = set(scope_files)
1548
+ seen_dirs: set[Path] = set()
1549
+
1550
+ for f in scope_files:
1551
+ parent = Path(f).parent
1552
+ if parent in seen_dirs:
1553
+ continue
1554
+ seen_dirs.add(parent)
1555
+ full_parent = self.root / parent
1556
+ if not full_parent.is_dir():
1557
+ continue
1558
+ try:
1559
+ for entry in full_parent.iterdir():
1560
+ if entry.is_file():
1561
+ rel = str(entry.relative_to(self.root)).replace("\\", "/")
1562
+ expanded.add(rel)
1563
+ except OSError:
1564
+ pass
1565
+
1566
+ return sorted(f for f in expanded if (self.root / f).exists())
1567
+
1421
1568
  def _is_git_repo(self) -> bool:
1422
1569
  import subprocess
1423
1570
  try:
@@ -552,10 +552,11 @@ class TestReviewPrSuspectedAreas:
552
552
  assert "ci_decision" in data
553
553
 
554
554
  def test_review_pr_no_diff_error_when_git_but_no_changes(self, monkeypatch):
555
- # Simulate: is_git_repo=True but no uncommitted changes
555
+ # Simulate: git repo present but no changed files in scope
556
+ from pathlib import Path as _Path
556
557
  from sourcecode import prepare_context as _pc
557
- monkeypatch.setattr(_pc.TaskContextBuilder, "_is_git_repo", lambda self: True)
558
- monkeypatch.setattr(_pc.TaskContextBuilder, "_get_uncommitted_changed_files", lambda self: [])
558
+ monkeypatch.setattr(_pc.TaskContextBuilder, "_resolve_git_root", lambda self: _Path(str(FIXTURE)))
559
+ monkeypatch.setattr(_pc.TaskContextBuilder, "_get_pr_scope_files", lambda self, since=None: ([], "git_diff"))
559
560
  result = _invoke("prepare-context", "review-pr", str(FIXTURE))
560
561
  assert result.exit_code == 1
561
562
  data = _json(result)
@@ -563,12 +564,14 @@ class TestReviewPrSuspectedAreas:
563
564
  assert data.get("ci_decision") == "no_changes"
564
565
 
565
566
  def test_review_pr_with_mocked_diff_returns_pr_fields(self, monkeypatch):
566
- # Simulate: valid git repo with one changed controller file (no --since → uncommitted path)
567
+ # Simulate: valid git repo with one changed controller file
568
+ from pathlib import Path as _Path
567
569
  from sourcecode import prepare_context as _pc
568
- monkeypatch.setattr(_pc.TaskContextBuilder, "_is_git_repo", lambda self: True)
570
+ _changed = ["src/main/java/com/example/UserController.java"]
571
+ monkeypatch.setattr(_pc.TaskContextBuilder, "_resolve_git_root", lambda self: _Path(str(FIXTURE)))
569
572
  monkeypatch.setattr(
570
- _pc.TaskContextBuilder, "_get_uncommitted_changed_files",
571
- lambda self: ["src/main/java/com/example/UserController.java"],
573
+ _pc.TaskContextBuilder, "_get_pr_scope_files",
574
+ lambda self, since=None: (_changed, "git_diff"),
572
575
  )
573
576
  result = _invoke("prepare-context", "review-pr", str(FIXTURE))
574
577
  assert result.exit_code == 0, result.output
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes