sourcecode 1.51.0__tar.gz → 1.52.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.
Files changed (120) hide show
  1. {sourcecode-1.51.0 → sourcecode-1.52.0}/PKG-INFO +3 -3
  2. {sourcecode-1.51.0 → sourcecode-1.52.0}/README.md +2 -2
  3. {sourcecode-1.51.0 → sourcecode-1.52.0}/pyproject.toml +1 -1
  4. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/repository_ir.py +28 -0
  6. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_impact.py +27 -1
  7. {sourcecode-1.51.0 → sourcecode-1.52.0}/.github/workflows/build-windows.yml +0 -0
  8. {sourcecode-1.51.0 → sourcecode-1.52.0}/.gitignore +0 -0
  9. {sourcecode-1.51.0 → sourcecode-1.52.0}/.ruff.toml +0 -0
  10. {sourcecode-1.51.0 → sourcecode-1.52.0}/CHANGELOG.md +0 -0
  11. {sourcecode-1.51.0 → sourcecode-1.52.0}/CONTRIBUTING.md +0 -0
  12. {sourcecode-1.51.0 → sourcecode-1.52.0}/LICENSE +0 -0
  13. {sourcecode-1.51.0 → sourcecode-1.52.0}/SECURITY.md +0 -0
  14. {sourcecode-1.51.0 → sourcecode-1.52.0}/raw +0 -0
  15. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/adaptive_scanner.py +0 -0
  16. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/architecture_analyzer.py +0 -0
  17. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/architecture_summary.py +0 -0
  18. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/ast_extractor.py +0 -0
  19. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/cache.py +0 -0
  20. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/canonical_ir.py +0 -0
  21. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/cir_graphs.py +0 -0
  22. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/classifier.py +0 -0
  23. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/cli.py +0 -0
  24. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/code_notes_analyzer.py +0 -0
  25. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/confidence_analyzer.py +0 -0
  26. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/context_scorer.py +0 -0
  27. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/context_summarizer.py +0 -0
  28. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/contract_model.py +0 -0
  29. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/contract_pipeline.py +0 -0
  30. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/coverage_parser.py +0 -0
  31. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/dependency_analyzer.py +0 -0
  32. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/__init__.py +0 -0
  33. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/base.py +0 -0
  34. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
  35. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/dart.py +0 -0
  36. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/dotnet.py +0 -0
  37. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/elixir.py +0 -0
  38. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/go.py +0 -0
  39. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/heuristic.py +0 -0
  40. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/hybrid.py +0 -0
  41. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/java.py +0 -0
  42. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  43. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/nodejs.py +0 -0
  44. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/parsers.py +0 -0
  45. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/php.py +0 -0
  46. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/project.py +0 -0
  47. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/python.py +0 -0
  48. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/ruby.py +0 -0
  49. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/rust.py +0 -0
  50. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/systems.py +0 -0
  51. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/terraform.py +0 -0
  52. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/detectors/tooling.py +0 -0
  53. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/doc_analyzer.py +0 -0
  54. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/entrypoint_classifier.py +0 -0
  55. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/env_analyzer.py +0 -0
  56. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/error_schema.py +0 -0
  57. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/explain.py +0 -0
  58. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/file_chunker.py +0 -0
  59. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/file_classifier.py +0 -0
  60. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/flow_analyzer.py +0 -0
  61. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/format_contract.py +0 -0
  62. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/fqn_utils.py +0 -0
  63. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/git_analyzer.py +0 -0
  64. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/graph_analyzer.py +0 -0
  65. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/license.py +0 -0
  66. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/__init__.py +0 -0
  67. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  68. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  69. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  70. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  71. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  72. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/orchestrator.py +0 -0
  73. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/registry.py +0 -0
  74. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/runner.py +0 -0
  75. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp/server.py +0 -0
  76. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/mcp_nudge.py +0 -0
  77. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/metrics_analyzer.py +0 -0
  78. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/migrate_check.py +0 -0
  79. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/openapi_surface.py +0 -0
  80. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/output_budget.py +0 -0
  81. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/path_filters.py +0 -0
  82. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/pr_comment_renderer.py +0 -0
  83. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/pr_impact.py +0 -0
  84. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/prepare_context.py +0 -0
  85. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/progress.py +0 -0
  86. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/ranking_engine.py +0 -0
  87. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/redactor.py +0 -0
  88. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/relevance_scorer.py +0 -0
  89. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/rename_refactor.py +0 -0
  90. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/repo_classifier.py +0 -0
  91. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/ris.py +0 -0
  92. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/runtime_classifier.py +0 -0
  93. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/scanner.py +0 -0
  94. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/schema.py +0 -0
  95. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/security_config.py +0 -0
  96. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/semantic_analyzer.py +0 -0
  97. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/serializer.py +0 -0
  98. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_event_topology.py +0 -0
  99. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_findings.py +0 -0
  100. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_model.py +0 -0
  101. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_security_audit.py +0 -0
  102. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_semantic.py +0 -0
  103. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
  104. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/summarizer.py +0 -0
  105. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/__init__.py +0 -0
  106. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/config.py +0 -0
  107. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/consent.py +0 -0
  108. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/events.py +0 -0
  109. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/filters.py +0 -0
  110. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/telemetry/transport.py +0 -0
  111. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/tree_utils.py +0 -0
  112. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/validation_surface.py +0 -0
  113. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/version_check.py +0 -0
  114. {sourcecode-1.51.0 → sourcecode-1.52.0}/src/sourcecode/workspace.py +0 -0
  115. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/functions/README.md +0 -0
  116. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/functions/get-license/index.ts +0 -0
  117. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  118. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/functions/telemetry/index.ts +0 -0
  119. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/sql/license_event_ordering.sql +0 -0
  120. {sourcecode-1.51.0 → sourcecode-1.52.0}/supabase/sql/telemetry_events.sql +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.51.0
3
+ Version: 1.52.0
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
5
  License-File: LICENSE
6
6
  Keywords: agents,ai,codebase,context,developer-tools,llm
@@ -40,7 +40,7 @@ Description-Content-Type: text/markdown
40
40
 
41
41
  **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
42
42
 
43
- ![Version](https://img.shields.io/badge/version-1.50.0-blue)
43
+ ![Version](https://img.shields.io/badge/version-1.52.0-blue)
44
44
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
45
45
 
46
46
  ---
@@ -114,7 +114,7 @@ pipx install sourcecode
114
114
 
115
115
  ```bash
116
116
  sourcecode version
117
- # sourcecode 1.44.0
117
+ # sourcecode 1.52.0
118
118
  ```
119
119
 
120
120
  ---
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
4
4
 
5
- ![Version](https://img.shields.io/badge/version-1.50.0-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.52.0-blue)
6
6
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
7
7
 
8
8
  ---
@@ -76,7 +76,7 @@ pipx install sourcecode
76
76
 
77
77
  ```bash
78
78
  sourcecode version
79
- # sourcecode 1.44.0
79
+ # sourcecode 1.52.0
80
80
  ```
81
81
 
82
82
  ---
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "1.51.0"
7
+ version = "1.52.0"
8
8
  description = "Persistent structural context and ultra-fast repeated analysis 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.51.0"
3
+ __version__ = "1.52.0"
@@ -1514,6 +1514,34 @@ def _build_relations(
1514
1514
  evidence={"type": "method_call", "value": f"new {_tgt.split('.')[-1]}(...)"},
1515
1515
  ))
1516
1516
 
1517
+ # ── Static-utility calls: `Type.method(...)` edges (G-2 / static-call gap) ──
1518
+ # A static call `AnnotationHelper.foo(...)` couples the calling class to the
1519
+ # utility type, but the call/DI graph misses it: only an `imports` edge is
1520
+ # recorded (and impact-chain skips imports), so a static helper showed 0
1521
+ # callers and impact-chain reported a false-confident "no blast radius".
1522
+ # Mirror the instantiation scan: regex over comment-stripped source, resolve the
1523
+ # receiver type via the import map (so JDK/unresolved receivers like Math/LOGGER
1524
+ # yield None and are skipped), attribute at class level. Unlike `instantiates`
1525
+ # this INCLUDES controllers — a controller statically calling a utility is a real
1526
+ # caller and has no `returns`-edge overlap. Emitted as `calls` (traversed by the
1527
+ # caller BFS). Instance calls go through lower-case variables and never match.
1528
+ if _class_syms:
1529
+ _call_targets: set[str] = set()
1530
+ for _m in re.finditer(r'\b([A-Z]\w*)\.\w+\s*\(', _source_no_comments):
1531
+ _ct_fqn = _resolve_dep_type(_m.group(1))
1532
+ if _ct_fqn:
1533
+ _call_targets.add(_ct_fqn)
1534
+ for cls_sym in _class_syms:
1535
+ for _tgt in sorted(_call_targets):
1536
+ if _tgt != cls_sym.symbol:
1537
+ edges.append(RelationEdge(
1538
+ from_symbol=cls_sym.symbol,
1539
+ to_symbol=_tgt,
1540
+ type="calls",
1541
+ confidence="medium",
1542
+ evidence={"type": "method_call", "value": f"{_tgt.split('.')[-1]}.…(…)"},
1543
+ ))
1544
+
1517
1545
  seen: set[tuple[str, str, str]] = set()
1518
1546
  unique: list[RelationEdge] = []
1519
1547
  for e in edges:
@@ -872,10 +872,35 @@ class ImpactOrchestrator:
872
872
  "An empty result is NOT proof the type is unused."
873
873
  )
874
874
 
875
+ # G-2 residual guard: something imports this symbol but no call/DI/instantiation
876
+ # edge resolved to it. With static-call edges now extracted, the common static
877
+ # utility case is covered; this catches what remains (static imports invoked
878
+ # without a qualifier, reflection, method references) — usages the call-graph
879
+ # cannot bind. An empty blast radius here is NOT proof of dead code, so it must
880
+ # not be reported as a high-confidence "safe to change".
881
+ unresolved_ref_blind_spot = False
882
+ if (
883
+ empty_blast
884
+ and class_level_seed
885
+ and not framework_di_blind_spot
886
+ and not value_type_blind_spot
887
+ ):
888
+ _rev = cir.reverse_graph.get(resolved_symbol) or {}
889
+ _importers = sorted(set(_rev.get("imports") or []))
890
+ if _importers:
891
+ unresolved_ref_blind_spot = True
892
+ warnings.append(
893
+ f"Unresolved inbound references (G-2): {len(_importers)} in-repo "
894
+ "file(s) import this symbol but no call/DI/instantiation edge "
895
+ "resolves to it — the usage may be a static import, reflection, or "
896
+ "method reference the call-graph does not model. 0 callers is NOT "
897
+ "proof this symbol is unused."
898
+ )
899
+
875
900
  confidence: str
876
901
  if resolution == "not_found":
877
902
  confidence = "low"
878
- elif framework_di_blind_spot or value_type_blind_spot:
903
+ elif framework_di_blind_spot or value_type_blind_spot or unresolved_ref_blind_spot:
879
904
  confidence = "low"
880
905
  elif resolution == "partial" or confidence_reducing:
881
906
  confidence = "medium"
@@ -908,6 +933,7 @@ class ImpactOrchestrator:
908
933
  "blind_spots": (
909
934
  (["framework_di"] if framework_di_blind_spot else [])
910
935
  + (["value_type"] if value_type_blind_spot else [])
936
+ + (["unresolved_refs"] if unresolved_ref_blind_spot else [])
911
937
  ),
912
938
  "external_supertypes": external_supertypes,
913
939
  },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes