sourcecode 1.35.8__py3-none-any.whl → 1.35.10__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """sourcecode — Deterministic codebase context maps for AI coding agents."""
2
2
 
3
- __version__ = "1.35.8"
3
+ __version__ = "1.35.10"
@@ -83,18 +83,30 @@ _DEF_RE = re.compile(r"\b(class|def|function|const|export\s+class|interface|type
83
83
  _JAVA_ANNOTATION_RE = re.compile(
84
84
  r'@(RestController|Controller|Service|Repository|Mapper|Entity|Data|Configuration'
85
85
  r'|EnableWebSecurity|ControllerAdvice|Transactional'
86
+ r'|RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping' # HTTP mappings
86
87
  r'|Path|Provider' # JAX-RS
87
88
  r'|ApplicationScoped|RequestScoped|SessionScoped|Singleton|Dependent' # CDI
88
89
  r'|Inject|Named' # CDI DI
89
90
  r')\b'
90
91
  )
91
92
 
93
+ # Handler-count regex — method-level only (Get/Post/Put/Delete/Patch, not class-level RequestMapping)
94
+ _HANDLER_MAPPING_RE = re.compile(r'@(Get|Post|Put|Delete|Patch)Mapping\b')
95
+
92
96
  # (annotation_set, category, relevance, why_template)
93
97
  # Checked in priority order; first match wins.
98
+ # @Controller rules use 0.80 base; _count_handlers() bonus in classify() differentiates
99
+ # by HTTP handler count. @RestController stays at 0.90 (no boost — already high tier).
94
100
  _JAVA_STEREOTYPE_RULES: list[tuple[frozenset, str, float, str]] = [
95
101
  (frozenset({"EnableWebSecurity"}), "security", 0.85, "Spring Security configuration"),
96
102
  (frozenset({"RestController"}), "api_endpoint", 0.90, "Spring REST controller — defines HTTP API surface"),
97
103
  (frozenset({"Controller", "RequestMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
104
+ (frozenset({"Controller", "GetMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
105
+ (frozenset({"Controller", "PostMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
106
+ (frozenset({"Controller", "PutMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
107
+ (frozenset({"Controller", "DeleteMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
108
+ (frozenset({"Controller", "PatchMapping"}), "api_endpoint", 0.80, "Spring MVC controller"),
109
+ (frozenset({"Controller"}), "api_endpoint", 0.72, "Spring MVC controller"),
98
110
  (frozenset({"ControllerAdvice"}), "exception_handler", 0.75, "Spring @ControllerAdvice — cross-cutting exception handling"),
99
111
  # JAX-RS
100
112
  (frozenset({"Path"}), "api_endpoint", 0.85, "JAX-RS resource — defines REST endpoint surface"),
@@ -178,15 +190,27 @@ class FileClassifier:
178
190
  if norm in self.cli_entry_paths:
179
191
  return FileClassification(norm, "cli_entrypoint", "high", 1.0, "declared production CLI entrypoint", ["entry_points"])
180
192
 
181
- if norm in self.production_entry_paths:
182
- return FileClassification(norm, "runtime_core", "high", 0.95, "declared production runtime entrypoint", ["entry_points"])
183
-
184
- # Java Spring stereotype detection (Java/Kotlin files only)
193
+ # Java Spring stereotype detection runs BEFORE the generic entrypoint fallback
194
+ # so that controllers and services keep their content-based category and relevance
195
+ # rather than collapsing to runtime_core/0.95 for every declared entry point.
185
196
  if suffix in {".java", ".kt"}:
186
197
  java_class = self._classify_java_stereotype(norm, content)
187
198
  if java_class is not None:
199
+ if java_class.category == "api_endpoint" and java_class.relevance < 0.85:
200
+ # Boost @Controller-tier (base 0.72–0.80) by handler count so controllers
201
+ # with more HTTP handlers rank above single-endpoint system controllers.
202
+ # @RestController (0.90) and JAX-RS Path (0.85) are already high-tier — skip.
203
+ h = self._count_handlers(content)
204
+ if h > 0:
205
+ bonus = min(h * 0.03, 0.12)
206
+ java_class.relevance = round(min(0.95, java_class.relevance + bonus), 3)
207
+ if norm in self.production_entry_paths and "entry_points" not in java_class.evidence:
208
+ java_class.evidence = list(java_class.evidence) + ["entry_points"]
188
209
  return java_class
189
210
 
211
+ if norm in self.production_entry_paths:
212
+ return FileClassification(norm, "runtime_core", "high", 0.95, "declared production runtime entrypoint", ["entry_points"])
213
+
190
214
  # Fix 4: call _matched_imports once per category instead of twice
191
215
  # (_has_any_import was calling _matched_imports and discarding the result,
192
216
  # then the caller invoked it again to get the evidence — halving throughput).
@@ -262,6 +286,10 @@ class FileClassifier:
262
286
  return True
263
287
  return "@dataclass" in content or "pydantic" in content.lower()
264
288
 
289
+ def _count_handlers(self, content: str) -> int:
290
+ """Count method-level HTTP handler annotations as proxy for controller complexity."""
291
+ return len(_HANDLER_MAPPING_RE.findall(content))
292
+
265
293
  def _sample(self, imports: list[str]) -> list[str]:
266
294
  return [f"import:{imp}" for imp in imports[:4]]
267
295
 
@@ -758,9 +758,17 @@ include_all: return full test_gaps list without truncating to top 20.
758
758
  Deterministic symbol-level IR summary for Java repositories. Java only.
759
759
 
760
760
  Maps to: sourcecode repo-ir <repo_path> --summary-only
761
- Returns: reverse_graph (top 10 hubs), route_surface (top 50 endpoints),
761
+ Returns: reverse_graph, route_surface (top 50 endpoints),
762
762
  subsystems (top 15), impact, analysis. Full graph nodes/edges omitted.
763
763
 
764
+ reverse_graph: dict[class_FQN → {"contained_in": [method_FQNs], ...}]
765
+ Top 10 most-referenced (highest in-degree) classes in the dependency graph.
766
+ Keys are fully-qualified class names. Iterate with:
767
+ for fqn, data in result["reverse_graph"].items(): ...
768
+ route_surface: list of endpoint dicts (method, path, handler, security).
769
+ subsystems: list of detected subsystem cluster dicts.
770
+ analysis: metadata — total_classes, total_edges, analysis_ms.
771
+
764
772
  Output is bounded to ~100 KB for LLM safety. For full IR (can exceed 10 MB
765
773
  on large repos), use the CLI: sourcecode repo-ir <path> --output ir.json
766
774
  Use get_compact_context or get_agent_context for non-Java repos.
@@ -1234,6 +1242,9 @@ _MCP_HIDDEN_CANONICAL_TOOLS: frozenset[str] = frozenset({
1234
1242
  "telemetry_status",
1235
1243
  "telemetry_enable",
1236
1244
  "telemetry_disable",
1245
+ # Human admin actions — not agent actions
1246
+ "activate", # Pro license key activation; human admin only, not an agent operation
1247
+ "config", # returns plain-text config dump (not JSON); version via `version`, telemetry via `telemetry`
1237
1248
  })
1238
1249
 
1239
1250
 
sourcecode/serializer.py CHANGED
@@ -954,12 +954,19 @@ def _file_relevance(sm: SourceMap, *, limit: int = _FILE_RELEVANCE_LIMIT) -> lis
954
954
  runtime_impact, dep_centrality, fw_signal, change_sev, test_risk
955
955
  )
956
956
 
957
- # T1 override: confirmed production entrypoints 0.92–1.00.
958
- # Only runtime_core / cli_entrypoint categories justify scores 0.92.
957
+ # T1 override: confirmed production entrypoints use content-evidence relevance as score.
958
+ # runtime_core/cli_entrypoint: 0.92 floor (bootstrap + non-Java entries).
959
+ # api_endpoint/security/exception_handler: stereotype relevance directly (0.70 floor)
960
+ # so that controllers differentiate by annotation table + handler-count bonus rather
961
+ # than collapsing to a flat 0.95.
959
962
  if path in entry_paths and cat in ("runtime_core", "cli_entrypoint"):
960
963
  score_val = round(
961
964
  min(1.0, max(0.92, file_class.relevance if file_class else 0.92)), 3
962
965
  )
966
+ elif path in entry_paths and cat in ("api_endpoint", "security", "exception_handler"):
967
+ score_val = round(
968
+ min(1.0, max(0.70, file_class.relevance if file_class else 0.75)), 3
969
+ )
963
970
  else:
964
971
  score_val = round(formula_raw, 3)
965
972
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.35.8
3
+ Version: 1.35.10
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
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
39
39
 
40
40
  **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
41
41
 
42
- ![Version](https://img.shields.io/badge/version-1.35.5-blue)
42
+ ![Version](https://img.shields.io/badge/version-1.35.10-blue)
43
43
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
44
44
 
45
45
  ---
@@ -113,7 +113,7 @@ pipx install sourcecode
113
113
 
114
114
  ```bash
115
115
  sourcecode version
116
- # sourcecode 1.35.5
116
+ # sourcecode 1.35.10
117
117
  ```
118
118
 
119
119
  ---
@@ -1,4 +1,4 @@
1
- sourcecode/__init__.py,sha256=4pSX2tiJdyiu03u0G_n4-Ww2ajE_E7piY8T-20n_IDM,103
1
+ sourcecode/__init__.py,sha256=QOiKKrOaBjN4YCa2-cbvf5ufIHCdH1ihh91pDHwXH54,104
2
2
  sourcecode/adaptive_scanner.py,sha256=XffluXKzJUXrMtjEiAOnSNPZnztdIcts17T9ouHeID0,10521
3
3
  sourcecode/architecture_analyzer.py,sha256=qh749a7ykPtGmQI1MR9y6j8TtL_jBdVYFx9YRsLqOMw,44121
4
4
  sourcecode/architecture_summary.py,sha256=z34_6v7cSwy98cof2UVciGho7SCrZ93tiqMmq5WNzRQ,20405
@@ -20,7 +20,7 @@ sourcecode/doc_analyzer.py,sha256=05bjTUbDbmnbajD_cgRnACzS8T7xxBKVX4CjkJlhZg8,24
20
20
  sourcecode/entrypoint_classifier.py,sha256=jhTYlyqDJH2AtdEcLVaRU3lYRTJuF8DkxVzl4-W3zWE,5322
21
21
  sourcecode/env_analyzer.py,sha256=aNTyYgQk5noJDfJU6FmasmESOHfiomyJw5EvZqjy6qc,22213
22
22
  sourcecode/error_schema.py,sha256=uwosfNaSujtYm11_732Hu92z5ITV040fQDaIyefSvR4,1683
23
- sourcecode/file_classifier.py,sha256=PhvKBzd_kx9fKKkSQRvV14I9bZFnQYLjG30CUsN9gJc,13019
23
+ sourcecode/file_classifier.py,sha256=A0fEABqtfVu1MfoaxnPAvGpZgneGgVXlJDhT74NYXxE,15314
24
24
  sourcecode/flow_analyzer.py,sha256=dSiuY4w49k29jW_EPXUOND9B5uVbuCA7kjnuHi-pIWA,28781
25
25
  sourcecode/git_analyzer.py,sha256=JStxTQXNjBWi_wLdwhsZs9mT-v50cSJIz4Agzn6Kh9I,13362
26
26
  sourcecode/graph_analyzer.py,sha256=DHR8fY69oU_Pi4SYaWboX6EoEFrctQKB9dsjpqwGMzw,62403
@@ -42,7 +42,7 @@ sourcecode/runtime_classifier.py,sha256=uTAD6BDCiBLUZEDRfqk718kM4RTT_vAbfkcOI2_X
42
42
  sourcecode/scanner.py,sha256=WdOQ78mMzjR1NjmKTlbxdgwinnCTfAhxCVLBEFQiFHU,8899
43
43
  sourcecode/schema.py,sha256=aHNXDf8LGyUC8ZDE_VS9kiskC2-Oswhi_WnpdGy6HDw,24897
44
44
  sourcecode/semantic_analyzer.py,sha256=TDuC3wzZR2DPm1mgrAg1YSLk2QzJoueS3TZAmyGGpCU,89417
45
- sourcecode/serializer.py,sha256=ooNZW2_fqx__BXII25eAWq-BomodvqQ6opUT_niQYCA,123403
45
+ sourcecode/serializer.py,sha256=JNIXflVkVd2WvO-nwclECdPZgHmrLgIzoBOPAGTqWzY,123882
46
46
  sourcecode/spring_event_topology.py,sha256=LvGv5RXtU_O-fVB_OO9eDD2UmZM72Jn2oUHgOo50Qm0,17157
47
47
  sourcecode/spring_findings.py,sha256=8V91iHOg9hFgg6tLLl4FSsgrF-dBqOcO2s-K5sD_goA,5417
48
48
  sourcecode/spring_impact.py,sha256=vb_cOk9dFU7YcGPeqivFcpS4OYSETT72oJYn4WC5al0,33266
@@ -76,7 +76,7 @@ sourcecode/detectors/terraform.py,sha256=cxORPR_zVLOJpHlh4e9JnFpkQsn_UnqMMom5yG6
76
76
  sourcecode/detectors/tooling.py,sha256=8CKbtxwQoABP-WyBRNmdAmHDOvAH57AR1cF4UKuWEdQ,2074
77
77
  sourcecode/mcp/__init__.py,sha256=XU4HfRGbdid8wdUA0x_4f7uKZD1z3mv_XUY_WU_T9Mw,179
78
78
  sourcecode/mcp/orchestrator.py,sha256=BMi1D6liJHI3DXiaC8yeBLLP0wXajpCP3-vnRGqrvnw,26850
79
- sourcecode/mcp/registry.py,sha256=r6YBd9OZoQ4nwg2roQkt6dAAO__e8REtPn--WKLUYIY,60206
79
+ sourcecode/mcp/registry.py,sha256=Z-deZiVowoYbYhi39ScBIgJ2y4mpQintmjifBr9hk4M,60897
80
80
  sourcecode/mcp/runner.py,sha256=-Dp2qPGRkfNTVen6bKh7WtzQqpcEtsrXoiuajvshlKk,2866
81
81
  sourcecode/mcp/server.py,sha256=lBSQCw3yFe8rZHp2GGVcfua0EJUYZmsIUbvA4GIJv9s,52210
82
82
  sourcecode/mcp/onboarding/__init__.py,sha256=sj2PWqEBmMc4zBNkomg89WtL0M6S7A9yb7_wAuSWNP4,66
@@ -90,8 +90,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
90
90
  sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
91
91
  sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
92
92
  sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
93
- sourcecode-1.35.8.dist-info/METADATA,sha256=LJSPDerXZXrHOmZrrgWCeQJme4iEyM7ePFxC4t3gDh4,21263
94
- sourcecode-1.35.8.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
95
- sourcecode-1.35.8.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
96
- sourcecode-1.35.8.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
97
- sourcecode-1.35.8.dist-info/RECORD,,
93
+ sourcecode-1.35.10.dist-info/METADATA,sha256=yWc8FeRSSMPWi8pQpbkvAEMIL7X55CgiO4jM5jk-0j4,21266
94
+ sourcecode-1.35.10.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
95
+ sourcecode-1.35.10.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
96
+ sourcecode-1.35.10.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
97
+ sourcecode-1.35.10.dist-info/RECORD,,