sourcecode 1.31.28__tar.gz → 1.31.29__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 (231) hide show
  1. {sourcecode-1.31.28 → sourcecode-1.31.29}/PKG-INFO +3 -3
  2. {sourcecode-1.31.28 → sourcecode-1.31.29}/README.md +2 -2
  3. {sourcecode-1.31.28 → sourcecode-1.31.29}/pyproject.toml +1 -1
  4. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/cli.py +17 -0
  6. sourcecode-1.31.29/src/sourcecode/mcp_nudge.py +84 -0
  7. sourcecode-1.31.29/tests/test_mcp_nudge.py +153 -0
  8. {sourcecode-1.31.28 → sourcecode-1.31.29}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
  9. {sourcecode-1.31.28 → sourcecode-1.31.29}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
  10. {sourcecode-1.31.28 → sourcecode-1.31.29}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
  11. {sourcecode-1.31.28 → sourcecode-1.31.29}/.continue-here.md +0 -0
  12. {sourcecode-1.31.28 → sourcecode-1.31.29}/.github/workflows/build-windows.yml +0 -0
  13. {sourcecode-1.31.28 → sourcecode-1.31.29}/.gitignore +0 -0
  14. {sourcecode-1.31.28 → sourcecode-1.31.29}/.ruff.toml +0 -0
  15. {sourcecode-1.31.28 → sourcecode-1.31.29}/.sourcecode-cache/snapshot-3b5997a-fa5c742c.json +0 -0
  16. {sourcecode-1.31.28 → sourcecode-1.31.29}/AUDIT_REAL_REPOS.md +0 -0
  17. {sourcecode-1.31.28 → sourcecode-1.31.29}/AUDIT_v1.31.23.md +0 -0
  18. {sourcecode-1.31.28 → sourcecode-1.31.29}/CHANGELOG.md +0 -0
  19. {sourcecode-1.31.28 → sourcecode-1.31.29}/CONTRIBUTING.md +0 -0
  20. {sourcecode-1.31.28 → sourcecode-1.31.29}/LICENSE +0 -0
  21. {sourcecode-1.31.28 → sourcecode-1.31.29}/SECURITY.md +0 -0
  22. {sourcecode-1.31.28 → sourcecode-1.31.29}/docs/PRODUCT_TIERS.md +0 -0
  23. {sourcecode-1.31.28 → sourcecode-1.31.29}/docs/privacy.md +0 -0
  24. {sourcecode-1.31.28 → sourcecode-1.31.29}/docs/schema.md +0 -0
  25. {sourcecode-1.31.28 → sourcecode-1.31.29}/raw +0 -0
  26. {sourcecode-1.31.28 → sourcecode-1.31.29}/run_cli.py +0 -0
  27. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/adaptive_scanner.py +0 -0
  28. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/architecture_analyzer.py +0 -0
  29. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/architecture_summary.py +0 -0
  30. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/ast_extractor.py +0 -0
  31. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/cache.py +0 -0
  32. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/canonical_ir.py +0 -0
  33. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/classifier.py +0 -0
  34. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/code_notes_analyzer.py +0 -0
  35. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/confidence_analyzer.py +0 -0
  36. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/context_scorer.py +0 -0
  37. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/context_summarizer.py +0 -0
  38. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/contract_model.py +0 -0
  39. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/contract_pipeline.py +0 -0
  40. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/coverage_parser.py +0 -0
  41. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/dependency_analyzer.py +0 -0
  42. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/__init__.py +0 -0
  43. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/base.py +0 -0
  44. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/csproj_parser.py +0 -0
  45. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/dart.py +0 -0
  46. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/dotnet.py +0 -0
  47. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/elixir.py +0 -0
  48. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/go.py +0 -0
  49. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/heuristic.py +0 -0
  50. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/hybrid.py +0 -0
  51. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/java.py +0 -0
  52. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/jvm_ext.py +0 -0
  53. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/nodejs.py +0 -0
  54. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/parsers.py +0 -0
  55. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/php.py +0 -0
  56. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/project.py +0 -0
  57. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/python.py +0 -0
  58. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/ruby.py +0 -0
  59. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/rust.py +0 -0
  60. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/systems.py +0 -0
  61. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/terraform.py +0 -0
  62. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/detectors/tooling.py +0 -0
  63. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/doc_analyzer.py +0 -0
  64. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/entrypoint_classifier.py +0 -0
  65. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/env_analyzer.py +0 -0
  66. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/file_classifier.py +0 -0
  67. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/flow_analyzer.py +0 -0
  68. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/git_analyzer.py +0 -0
  69. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/graph_analyzer.py +0 -0
  70. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/__init__.py +0 -0
  71. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  72. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  73. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  74. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  75. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  76. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/runner.py +0 -0
  77. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/mcp/server.py +0 -0
  78. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/metrics_analyzer.py +0 -0
  79. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/output_budget.py +0 -0
  80. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/path_filters.py +0 -0
  81. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/pr_comment_renderer.py +0 -0
  82. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/prepare_context.py +0 -0
  83. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/progress.py +0 -0
  84. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/ranking_engine.py +0 -0
  85. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/redactor.py +0 -0
  86. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/relevance_scorer.py +0 -0
  87. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/repo_classifier.py +0 -0
  88. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/repository_ir.py +0 -0
  89. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/runtime_classifier.py +0 -0
  90. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/scanner.py +0 -0
  91. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/schema.py +0 -0
  92. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/semantic_analyzer.py +0 -0
  93. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/serializer.py +0 -0
  94. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/summarizer.py +0 -0
  95. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/__init__.py +0 -0
  96. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/config.py +0 -0
  97. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/consent.py +0 -0
  98. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/events.py +0 -0
  99. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/filters.py +0 -0
  100. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/telemetry/transport.py +0 -0
  101. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/tree_utils.py +0 -0
  102. {sourcecode-1.31.28 → sourcecode-1.31.29}/src/sourcecode/workspace.py +0 -0
  103. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/__init__.py +0 -0
  104. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/conftest.py +0 -0
  105. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/coverage.xml +0 -0
  106. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
  107. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/fastapi_app/src/main.py +0 -0
  108. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/go_service/cmd/api/main.go +0 -0
  109. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/go_service/go.mod +0 -0
  110. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/jacoco.xml +0 -0
  111. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/latin1_sample.java +0 -0
  112. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/latin1_sample_iso.java +0 -0
  113. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/lcov.info +0 -0
  114. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
  115. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/nextjs_app/package.json +0 -0
  116. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
  117. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
  118. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
  119. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
  120. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
  121. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
  122. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
  123. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
  124. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
  125. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
  126. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
  127. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
  128. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
  129. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
  130. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
  131. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
  132. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
  133. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
  134. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
  135. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
  136. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
  137. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
  138. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
  139. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
  140. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
  141. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
  142. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
  143. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
  144. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
  145. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
  146. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
  147. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
  148. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
  149. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_architecture_analyzer.py +0 -0
  150. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_architecture_summary.py +0 -0
  151. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_ast_extractor.py +0 -0
  152. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_audit_fixes.py +0 -0
  153. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_audit_sas_v2.py +0 -0
  154. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_block1_reliability.py +0 -0
  155. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_block2_coverage.py +0 -0
  156. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_block5_quality.py +0 -0
  157. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_broadleaf_fixes.py +0 -0
  158. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v1302.py +0 -0
  159. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v13115.py +0 -0
  160. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v1312.py +0 -0
  161. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v13122.py +0 -0
  162. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v1313.py +0 -0
  163. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v1321.py +0 -0
  164. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v16.py +0 -0
  165. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_bug_fixes_v2.py +0 -0
  166. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_cache.py +0 -0
  167. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_canonical_ir.py +0 -0
  168. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_classifier.py +0 -0
  169. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_cli.py +0 -0
  170. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_code_notes_analyzer.py +0 -0
  171. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_context_scorer.py +0 -0
  172. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_contract_pipeline.py +0 -0
  173. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_coverage_parser.py +0 -0
  174. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_cross_consistency.py +0 -0
  175. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_dependency_analyzer_node_python.py +0 -0
  176. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_dependency_analyzer_polyglot.py +0 -0
  177. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_dependency_schema.py +0 -0
  178. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_dotnet.py +0 -0
  179. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_go_rust_java.py +0 -0
  180. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_nodejs.py +0 -0
  181. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_php_ruby_dart.py +0 -0
  182. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_python.py +0 -0
  183. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_universal_managed.py +0 -0
  184. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detector_universal_systems.py +0 -0
  185. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_detectors_base.py +0 -0
  186. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_doc_analyzer_jsdom.py +0 -0
  187. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_doc_analyzer_python.py +0 -0
  188. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_encoding_regression.py +0 -0
  189. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_enterprise_benchmarks.py +0 -0
  190. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_graph_analyzer_polyglot.py +0 -0
  191. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_graph_analyzer_python_node.py +0 -0
  192. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_graph_schema.py +0 -0
  193. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_hybrid_inference.py +0 -0
  194. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration.py +0 -0
  195. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_dependencies.py +0 -0
  196. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_detection.py +0 -0
  197. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_docs.py +0 -0
  198. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_graph_modules.py +0 -0
  199. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_lqn.py +0 -0
  200. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_metrics.py +0 -0
  201. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_multistack.py +0 -0
  202. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_semantics.py +0 -0
  203. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_integration_universal.py +0 -0
  204. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_java_spring_integration.py +0 -0
  205. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_mcp_runner.py +0 -0
  206. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_mcp_serve.py +0 -0
  207. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_mcp_tools.py +0 -0
  208. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_metrics_analyzer.py +0 -0
  209. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_output_ux.py +0 -0
  210. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_packaging.py +0 -0
  211. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_phase1_improvements.py +0 -0
  212. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_pipeline_integrity.py +0 -0
  213. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_real_projects.py +0 -0
  214. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_redactor.py +0 -0
  215. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_repository_ir.py +0 -0
  216. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_scanner.py +0 -0
  217. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_schema.py +0 -0
  218. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_schema_normalization.py +0 -0
  219. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_scoring_calibration.py +0 -0
  220. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_semantic_analyzer_node.py +0 -0
  221. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_semantic_analyzer_python.py +0 -0
  222. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_semantic_import_resolution.py +0 -0
  223. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_semantic_schema.py +0 -0
  224. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_signal_hierarchy.py +0 -0
  225. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_summarizer.py +0 -0
  226. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_surface_honesty.py +0 -0
  227. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_task_differentiation.py +0 -0
  228. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_telemetry.py +0 -0
  229. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_v131_improvements.py +0 -0
  230. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_v1_10_regressions.py +0 -0
  231. {sourcecode-1.31.28 → sourcecode-1.31.29}/tests/test_workspace_analyzer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.31.28
3
+ Version: 1.31.29
4
4
  Summary: Deterministic codebase context for AI coding agents
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -225,7 +225,7 @@ Description-Content-Type: text/markdown
225
225
 
226
226
  **AI-ready change intelligence for Java/Spring enterprise monoliths.**
227
227
 
228
- ![Version](https://img.shields.io/badge/version-1.31.28-blue)
228
+ ![Version](https://img.shields.io/badge/version-1.31.29-blue)
229
229
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
230
230
 
231
231
  ---
@@ -263,7 +263,7 @@ pipx install sourcecode
263
263
 
264
264
  ```bash
265
265
  sourcecode version
266
- # sourcecode 1.31.28
266
+ # sourcecode 1.31.29
267
267
  ```
268
268
 
269
269
  ---
@@ -2,7 +2,7 @@
2
2
 
3
3
  **AI-ready change intelligence for Java/Spring enterprise monoliths.**
4
4
 
5
- ![Version](https://img.shields.io/badge/version-1.31.28-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.31.29-blue)
6
6
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
7
7
 
8
8
  ---
@@ -40,7 +40,7 @@ pipx install sourcecode
40
40
 
41
41
  ```bash
42
42
  sourcecode version
43
- # sourcecode 1.31.28
43
+ # sourcecode 1.31.29
44
44
  ```
45
45
 
46
46
  ---
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "1.31.28"
7
+ version = "1.31.29"
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.31.28"
3
+ __version__ = "1.31.29"
@@ -1952,6 +1952,10 @@ def main(
1952
1952
  if _copy_to_clipboard(content):
1953
1953
  typer.echo("✓ copied to clipboard", err=True)
1954
1954
 
1955
+ # 8. One-time MCP setup nudge (stderr only — does not affect exit code or stdout)
1956
+ from sourcecode.mcp_nudge import nudge_mcp_if_needed as _nudge
1957
+ _nudge()
1958
+
1955
1959
 
1956
1960
  # ── prepare-context output helpers ────────────────────────────────────────────
1957
1961
 
@@ -2554,6 +2558,9 @@ def prepare_context_cmd(
2554
2558
  if _copy_to_clipboard(_pc_content):
2555
2559
  typer.echo("✓ copied to clipboard", err=True)
2556
2560
 
2561
+ from sourcecode.mcp_nudge import nudge_mcp_if_needed as _nudge
2562
+ _nudge()
2563
+
2557
2564
 
2558
2565
  # ── Telemetry commands ────────────────────────────────────────────────────────
2559
2566
 
@@ -2899,6 +2906,9 @@ def impact_cmd(
2899
2906
  if result.get("resolution") == "not_found":
2900
2907
  raise typer.Exit(code=1)
2901
2908
 
2909
+ from sourcecode.mcp_nudge import nudge_mcp_if_needed as _nudge
2910
+ _nudge()
2911
+
2902
2912
 
2903
2913
  # ── endpoints ─────────────────────────────────────────────────────────────────
2904
2914
 
@@ -2969,6 +2979,9 @@ def endpoints_cmd(
2969
2979
  if _copy_to_clipboard(output):
2970
2980
  typer.echo("✓ copied to clipboard", err=True)
2971
2981
 
2982
+ from sourcecode.mcp_nudge import nudge_mcp_if_needed as _nudge
2983
+ _nudge()
2984
+
2972
2985
 
2973
2986
  # ── Enterprise Workflow Commands ──────────────────────────────────────────────
2974
2987
  #
@@ -3574,6 +3587,10 @@ def mcp_init(
3574
3587
  typer.echo("")
3575
3588
  typer.echo(" Remove: sourcecode mcp remove")
3576
3589
 
3590
+ # Clear nudge flag: next run finds is_installed=True → no nudge.
3591
+ from sourcecode.mcp_nudge import clear_nudge_flag as _clear_nudge
3592
+ _clear_nudge()
3593
+
3577
3594
 
3578
3595
  @mcp_app.command("status")
3579
3596
  def mcp_status() -> None:
@@ -0,0 +1,84 @@
1
+ """MCP setup nudge — one-time stderr hint after successful analysis commands.
2
+
3
+ Fires when:
4
+ 1. At least one known MCP client (Claude Desktop, Cursor) is installed
5
+ 2. sourcecode is NOT yet registered in that client's config
6
+ 3. The nudge hasn't been shown this session (~/.sourcecode/nudge_shown flag)
7
+
8
+ Cleared by: a successful `sourcecode mcp init` (deletes the flag so the
9
+ post-init detection finds is_installed=True and never nudges again).
10
+
11
+ Side effects: writes only to stderr — stdout (JSON/YAML output) is untouched.
12
+ Exit code of the calling command is unaffected.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ # Stable path used as a session-level "already shown" sentinel.
20
+ _FLAG: Path = Path.home() / ".sourcecode" / "nudge_shown"
21
+
22
+ _MSG = (
23
+ "→ Claude Desktop detected. "
24
+ "Run `sourcecode mcp init` to enable agent integration.\n"
25
+ )
26
+
27
+ # Module-level imports so names are patchable in tests.
28
+ # Falls back to no-op stubs if onboarding package is unavailable.
29
+ try:
30
+ from sourcecode.mcp.onboarding.detector import detect_clients # noqa: PLC0415
31
+ from sourcecode.mcp.onboarding.applier import is_installed, read_config # noqa: PLC0415
32
+ _IMPORTS_OK = True
33
+ except Exception: # pragma: no cover
34
+ _IMPORTS_OK = False
35
+
36
+ def detect_clients() -> list: # type: ignore[misc]
37
+ return []
38
+
39
+ def is_installed(config: dict) -> bool: # type: ignore[misc]
40
+ return False
41
+
42
+ def read_config(path: Path) -> dict: # type: ignore[misc]
43
+ return {}
44
+
45
+
46
+ def nudge_mcp_if_needed() -> None:
47
+ """Print MCP setup nudge to stderr at most once (until mcp init succeeds)."""
48
+ # Fast path: already shown this session.
49
+ if _FLAG.exists():
50
+ return
51
+
52
+ try:
53
+ clients = detect_clients()
54
+ except Exception: # pragma: no cover
55
+ return
56
+
57
+ needs_nudge = any(
58
+ c.app_installed and not is_installed(read_config(c.config_path))
59
+ for c in clients
60
+ )
61
+
62
+ if not needs_nudge:
63
+ return
64
+
65
+ # Write nudge and persist flag.
66
+ sys.stderr.write(_MSG)
67
+ sys.stderr.flush()
68
+ try:
69
+ _FLAG.parent.mkdir(parents=True, exist_ok=True)
70
+ _FLAG.touch()
71
+ except OSError:
72
+ pass # Non-fatal: nudge will fire again next run, which is acceptable.
73
+
74
+
75
+ def clear_nudge_flag() -> None:
76
+ """Delete the session flag so post-mcp-init runs don't re-show the nudge.
77
+
78
+ Called by `mcp init` after a successful installation. On the next run,
79
+ detection finds is_installed=True → needs_nudge=False → no nudge shown.
80
+ """
81
+ try:
82
+ _FLAG.unlink(missing_ok=True)
83
+ except OSError:
84
+ pass
@@ -0,0 +1,153 @@
1
+ """Tests for sourcecode.mcp_nudge — one-time MCP setup nudge."""
2
+ from __future__ import annotations
3
+
4
+ import sys
5
+ from pathlib import Path
6
+ from unittest.mock import MagicMock, patch
7
+
8
+ import pytest
9
+
10
+ import sourcecode.mcp_nudge as nudge_mod
11
+ from sourcecode.mcp_nudge import nudge_mcp_if_needed, clear_nudge_flag
12
+
13
+
14
+ # ── helpers ───────────────────────────────────────────────────────────────────
15
+
16
+ def _make_client(app_installed: bool, config_path: Path) -> MagicMock:
17
+ client = MagicMock()
18
+ client.app_installed = app_installed
19
+ client.config_path = config_path
20
+ return client
21
+
22
+
23
+ # ── nudge_mcp_if_needed ───────────────────────────────────────────────────────
24
+
25
+ class TestNudgeMcpIfNeeded:
26
+ """Core nudge logic — isolation via tmp_path flag dir."""
27
+
28
+ def _run(self, flag_path: Path, clients, is_installed_val: bool, capsys) -> str:
29
+ """Invoke nudge_mcp_if_needed with patched flag, clients and is_installed."""
30
+ with (
31
+ patch.object(nudge_mod, "_FLAG", flag_path),
32
+ patch("sourcecode.mcp_nudge.detect_clients", return_value=clients),
33
+ patch("sourcecode.mcp_nudge.is_installed", return_value=is_installed_val),
34
+ patch("sourcecode.mcp_nudge.read_config", return_value={}),
35
+ ):
36
+ nudge_mcp_if_needed()
37
+ return capsys.readouterr().err
38
+
39
+ def test_nudge_shown_when_desktop_installed_not_configured(self, tmp_path, capsys):
40
+ """Client installed, not in config → nudge printed."""
41
+ flag = tmp_path / "nudge_shown"
42
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
43
+ stderr = self._run(flag, [client], is_installed_val=False, capsys=capsys)
44
+ assert "sourcecode mcp init" in stderr
45
+ assert flag.exists(), "Flag must be created after nudge"
46
+
47
+ def test_no_nudge_when_already_configured(self, tmp_path, capsys):
48
+ """Client installed AND already in config → no nudge."""
49
+ flag = tmp_path / "nudge_shown"
50
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
51
+ stderr = self._run(flag, [client], is_installed_val=True, capsys=capsys)
52
+ assert stderr == ""
53
+ assert not flag.exists()
54
+
55
+ def test_no_nudge_when_client_not_installed(self, tmp_path, capsys):
56
+ """Client NOT installed → no nudge even if config absent."""
57
+ flag = tmp_path / "nudge_shown"
58
+ client = _make_client(app_installed=False, config_path=tmp_path / "config.json")
59
+ stderr = self._run(flag, [client], is_installed_val=False, capsys=capsys)
60
+ assert stderr == ""
61
+ assert not flag.exists()
62
+
63
+ def test_no_nudge_when_flag_exists(self, tmp_path, capsys):
64
+ """Flag already present → no nudge (second run in same session)."""
65
+ flag = tmp_path / "nudge_shown"
66
+ flag.touch()
67
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
68
+ stderr = self._run(flag, [client], is_installed_val=False, capsys=capsys)
69
+ assert stderr == ""
70
+
71
+ def test_no_nudge_when_no_clients(self, tmp_path, capsys):
72
+ """No clients detected → no nudge."""
73
+ flag = tmp_path / "nudge_shown"
74
+ stderr = self._run(flag, [], is_installed_val=False, capsys=capsys)
75
+ assert stderr == ""
76
+ assert not flag.exists()
77
+
78
+ def test_second_call_no_repeat(self, tmp_path, capsys):
79
+ """Nudge fires once; second call (flag now exists) is silent."""
80
+ flag = tmp_path / "nudge_shown"
81
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
82
+
83
+ with (
84
+ patch.object(nudge_mod, "_FLAG", flag),
85
+ patch("sourcecode.mcp_nudge.detect_clients", return_value=[client]),
86
+ patch("sourcecode.mcp_nudge.is_installed", return_value=False),
87
+ patch("sourcecode.mcp_nudge.read_config", return_value={}),
88
+ ):
89
+ nudge_mcp_if_needed()
90
+ capsys.readouterr() # consume first write
91
+ nudge_mcp_if_needed()
92
+
93
+ second_stderr = capsys.readouterr().err
94
+ assert second_stderr == ""
95
+
96
+ def test_nudge_message_exact_text(self, tmp_path, capsys):
97
+ """Message matches spec exactly."""
98
+ flag = tmp_path / "nudge_shown"
99
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
100
+ stderr = self._run(flag, [client], is_installed_val=False, capsys=capsys)
101
+ assert stderr == (
102
+ "→ Claude Desktop detected. "
103
+ "Run `sourcecode mcp init` to enable agent integration.\n"
104
+ )
105
+
106
+ def test_import_error_is_silent(self, tmp_path, capsys):
107
+ """If onboarding modules can't be imported, nudge fails silently."""
108
+ flag = tmp_path / "nudge_shown"
109
+ with (
110
+ patch.object(nudge_mod, "_FLAG", flag),
111
+ patch.dict("sys.modules", {
112
+ "sourcecode.mcp.onboarding.detector": None, # type: ignore[dict-item]
113
+ "sourcecode.mcp.onboarding.applier": None, # type: ignore[dict-item]
114
+ }),
115
+ ):
116
+ nudge_mcp_if_needed() # must not raise
117
+ assert capsys.readouterr().err == ""
118
+
119
+
120
+ # ── clear_nudge_flag ──────────────────────────────────────────────────────────
121
+
122
+ class TestClearNudgeFlag:
123
+ def test_clears_existing_flag(self, tmp_path):
124
+ flag = tmp_path / "nudge_shown"
125
+ flag.touch()
126
+ with patch.object(nudge_mod, "_FLAG", flag):
127
+ clear_nudge_flag()
128
+ assert not flag.exists()
129
+
130
+ def test_noop_when_flag_absent(self, tmp_path):
131
+ flag = tmp_path / "nudge_shown"
132
+ with patch.object(nudge_mod, "_FLAG", flag):
133
+ clear_nudge_flag() # must not raise
134
+ assert not flag.exists()
135
+
136
+ def test_after_clear_nudge_fires_again_if_not_configured(self, tmp_path, capsys):
137
+ """After mcp init clears flag, if somehow not configured, nudge re-fires."""
138
+ flag = tmp_path / "nudge_shown"
139
+ flag.touch()
140
+ client = _make_client(app_installed=True, config_path=tmp_path / "config.json")
141
+
142
+ with patch.object(nudge_mod, "_FLAG", flag):
143
+ clear_nudge_flag()
144
+
145
+ with (
146
+ patch.object(nudge_mod, "_FLAG", flag),
147
+ patch("sourcecode.mcp_nudge.detect_clients", return_value=[client]),
148
+ patch("sourcecode.mcp_nudge.is_installed", return_value=False),
149
+ patch("sourcecode.mcp_nudge.read_config", return_value={}),
150
+ ):
151
+ nudge_mcp_if_needed()
152
+
153
+ assert "mcp init" in capsys.readouterr().err
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes