sourcecode 1.35.20__py3-none-any.whl → 1.35.22__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.20"
3
+ __version__ = "1.35.22"
sourcecode/cli.py CHANGED
@@ -3912,7 +3912,8 @@ def spring_audit_cmd(
3912
3912
  )
3913
3913
  raise typer.Exit(code=1)
3914
3914
 
3915
- file_list = find_java_files(target)
3915
+ _file_limitations: list[str] = []
3916
+ file_list = find_java_files(target, limitations=_file_limitations)
3916
3917
  if not file_list:
3917
3918
  empty_result = SpringAuditResult(
3918
3919
  spring_detected=False,
@@ -3961,6 +3962,9 @@ def spring_audit_cmd(
3961
3962
  metadata=merged_meta,
3962
3963
  ).finalize()
3963
3964
 
3965
+ if _file_limitations:
3966
+ combined.limitations.extend(_file_limitations)
3967
+
3964
3968
  # Populate git_head from repo HEAD — non-fatal.
3965
3969
  try:
3966
3970
  import subprocess as _sub_sa
@@ -4088,8 +4092,11 @@ def migrate_check_cmd(
4088
4092
  )
4089
4093
  raise typer.Exit(code=1)
4090
4094
 
4091
- file_list = find_java_files(target)
4095
+ _file_limitations: list[str] = []
4096
+ file_list = find_java_files(target, limitations=_file_limitations)
4092
4097
  report = run_migrate_check(file_list, target, min_severity=min_severity)
4098
+ if _file_limitations:
4099
+ report.limitations.extend(_file_limitations)
4093
4100
 
4094
4101
  if format == "text":
4095
4102
  output = report.to_text(min_severity=min_severity)
@@ -1142,6 +1142,78 @@ class DependencyAnalyzer:
1142
1142
  records: list[DependencyRecord] = []
1143
1143
  deps_elem = root_elem.find(f"{ns}dependencies")
1144
1144
  if deps_elem is None:
1145
+ # Multi-module aggregator POM: scan up to 5 declared submodule pom.xml files.
1146
+ modules_elem = root_elem.find(f"{ns}modules")
1147
+ if modules_elem is not None:
1148
+ submodule_records: list[DependencyRecord] = []
1149
+ submodule_limitations: list[str] = []
1150
+ seen_submodule_deps: set[str] = set()
1151
+ _all_modules = list(modules_elem.findall(f"{ns}module"))
1152
+ if len(_all_modules) > 5:
1153
+ submodule_limitations.append(
1154
+ f"MAX_SUBMODULES_REACHED: scanned 5 of {len(_all_modules)} declared Maven submodules"
1155
+ )
1156
+ for mod_elem in _all_modules[:5]:
1157
+ mod_name = (mod_elem.text or "").strip()
1158
+ if not mod_name:
1159
+ continue
1160
+ sub_pom = root / mod_name / "pom.xml"
1161
+ if not sub_pom.exists():
1162
+ continue
1163
+ try:
1164
+ sub_tree = ET.parse(sub_pom)
1165
+ except (ET.ParseError, OSError):
1166
+ continue
1167
+ sub_root = sub_tree.getroot()
1168
+ sub_ns_match = re.match(r"\{[^}]+\}", sub_root.tag)
1169
+ sub_ns = sub_ns_match.group(0) if sub_ns_match else ""
1170
+ sub_props = self._parse_maven_properties(sub_root, sub_ns)
1171
+ sub_dm = self._parse_dependency_management(sub_root, sub_ns, sub_props)
1172
+ # Inherit parent properties for version resolution
1173
+ for k, v in properties.items():
1174
+ sub_props.setdefault(k, v)
1175
+ for k, v in dm_versions.items():
1176
+ sub_dm.setdefault(k, v)
1177
+ sub_deps_elem = sub_root.find(f"{sub_ns}dependencies")
1178
+ if sub_deps_elem is None:
1179
+ continue
1180
+ for dep in sub_deps_elem.findall(f"{sub_ns}dependency"):
1181
+ gid = (dep.findtext(f"{sub_ns}groupId") or "").strip()
1182
+ aid = (dep.findtext(f"{sub_ns}artifactId") or "").strip()
1183
+ if not gid or not aid:
1184
+ continue
1185
+ dep_key = f"{gid}:{aid}"
1186
+ if dep_key in seen_submodule_deps:
1187
+ continue
1188
+ seen_submodule_deps.add(dep_key)
1189
+ ver_raw = (dep.findtext(f"{sub_ns}version") or "").strip() or None
1190
+ declared = self._resolve_maven_version(ver_raw, sub_props)
1191
+ if declared is None:
1192
+ declared = sub_dm.get(dep_key)
1193
+ scope_text = (dep.findtext(f"{sub_ns}scope") or "compile").strip().lower()
1194
+ if scope_text == "test":
1195
+ scope = "dev"
1196
+ elif scope_text == "provided":
1197
+ scope = "provided"
1198
+ else:
1199
+ scope = "direct"
1200
+ resolved_version = None
1201
+ if declared is None and parent_version:
1202
+ if gid == "org.springframework.boot":
1203
+ resolved_version = parent_version
1204
+ elif gid == "org.springframework.security" and "spring-security.version" in sub_props:
1205
+ resolved_version = sub_props["spring-security.version"]
1206
+ submodule_records.append(DependencyRecord(
1207
+ name=dep_key,
1208
+ ecosystem="java",
1209
+ scope=scope,
1210
+ declared_version=declared,
1211
+ resolved_version=resolved_version,
1212
+ source="manifest",
1213
+ manifest_path=f"{mod_name}/pom.xml",
1214
+ ))
1215
+ if submodule_records:
1216
+ return submodule_records, submodule_limitations
1145
1217
  return [], ["java: pom.xml has no <dependencies> block"]
1146
1218
 
1147
1219
  for dep in deps_elem.findall(f"{ns}dependency"):
sourcecode/mcp/server.py CHANGED
@@ -192,7 +192,48 @@ def _execute(args: list[str]) -> dict | CallToolResult:
192
192
  return _ok(result)
193
193
 
194
194
 
195
+ # Per-tool character budgets (4 chars ≈ 1 token; keeps Cursor under its 10k token limit).
196
+ # List fields are trimmed front-to-back until output fits.
197
+ _MCP_CHAR_BUDGETS: dict[str, int] = {
198
+ "get_agent_context": 38_000,
199
+ "get_spring_audit": 38_000,
200
+ "get_migration_readiness": 38_000,
201
+ }
202
+ _MCP_TRIM_FIELDS = (
203
+ "findings", "relevant_files", "key_dependencies",
204
+ "entry_points", "limitations", "gaps", "code_notes",
205
+ )
206
+
207
+
208
+ def _cap_mcp_output(tool_name: str, data: Any) -> Any:
209
+ """Trim list fields in data until JSON serialisation fits within the tool's char budget."""
210
+ budget = _MCP_CHAR_BUDGETS.get(tool_name)
211
+ if not budget or not isinstance(data, dict):
212
+ return data
213
+ if len(json.dumps(data, default=str)) <= budget:
214
+ return data
215
+ result = dict(data)
216
+ for field in _MCP_TRIM_FIELDS:
217
+ if field not in result or not isinstance(result[field], list):
218
+ continue
219
+ items = list(result[field])
220
+ while items and len(json.dumps(result, default=str)) > budget:
221
+ items = items[:-1]
222
+ result[field] = items
223
+ if len(json.dumps(result, default=str)) <= budget:
224
+ break
225
+ if len(json.dumps(result, default=str)) > budget:
226
+ result["_mcp_truncated"] = True
227
+ result["_mcp_truncation_note"] = (
228
+ f"Output capped at ~{budget // 4}k tokens for MCP compatibility. "
229
+ "Use CLI directly for full output."
230
+ )
231
+ return result
232
+
233
+
195
234
  _DEFAULT_TESTS_TIMEOUT_MS = 15_000
235
+ _DEFAULT_SPRING_AUDIT_TIMEOUT_MS = 120_000 # 2 min
236
+ _DEFAULT_IMPACT_TIMEOUT_MS = 60_000 # 1 min
196
237
 
197
238
  # Regex for MINGW paths: /c/some/path → C:/some/path
198
239
  _MINGW_PATH_RE = re.compile(r"^/([a-zA-Z])(/.*)?$")
@@ -568,7 +609,10 @@ def get_agent_context(repo_path: str = ".", git_context: bool = False) -> dict:
568
609
  args = [repo_path, "--agent"]
569
610
  if git_context:
570
611
  args.append("--git-context")
571
- return _execute(args)
612
+ result = _execute(args)
613
+ if isinstance(result, dict) and result.get("success"):
614
+ result = _ok(_cap_mcp_output("get_agent_context", result.get("data")))
615
+ return result
572
616
  except Exception as exc:
573
617
  return _err(
574
618
  f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
@@ -641,7 +685,26 @@ def get_spring_audit(repo_path: str = ".", scope: str = "all") -> dict:
641
685
  _path_err = _check_repo_path(repo_path)
642
686
  if _path_err is not None:
643
687
  return _path_err
644
- return _execute(["spring-audit", repo_path, "--scope", scope])
688
+ timeout_ms = int(os.environ.get("SOURCECODE_SPRING_AUDIT_TIMEOUT_MS", str(_DEFAULT_SPRING_AUDIT_TIMEOUT_MS)))
689
+ timeout_s = timeout_ms / 1000.0
690
+ _exec = concurrent.futures.ThreadPoolExecutor(max_workers=1)
691
+ try:
692
+ _fut = _exec.submit(_execute, ["spring-audit", repo_path, "--scope", scope])
693
+ _done, _pending = concurrent.futures.wait([_fut], timeout=timeout_s)
694
+ if _pending:
695
+ _exec.shutdown(wait=False)
696
+ return _ok({
697
+ "truncated": True,
698
+ "truncated_reason": f"timeout_{timeout_s:.0f}s",
699
+ "analysis": "timed out — repository may be too large for MCP transport",
700
+ "suggestion": f"Increase SOURCECODE_SPRING_AUDIT_TIMEOUT_MS (current: {timeout_ms}ms) or run via CLI directly",
701
+ })
702
+ result = _fut.result()
703
+ finally:
704
+ _exec.shutdown(wait=True)
705
+ if isinstance(result, dict) and result.get("success"):
706
+ result = _ok(_cap_mcp_output("get_spring_audit", result.get("data")))
707
+ return result
645
708
  except Exception as exc:
646
709
  return _err(
647
710
  f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
@@ -691,7 +754,10 @@ def get_migration_readiness(repo_path: str = ".", min_severity: str = "low") ->
691
754
  _path_err = _check_repo_path(repo_path)
692
755
  if _path_err is not None:
693
756
  return _path_err
694
- return _execute(["migrate-check", repo_path, "--min-severity", min_severity])
757
+ result = _execute(["migrate-check", repo_path, "--min-severity", min_severity])
758
+ if isinstance(result, dict) and result.get("success"):
759
+ result = _ok(_cap_mcp_output("get_migration_readiness", result.get("data")))
760
+ return result
695
761
  except Exception as exc:
696
762
  return _err(
697
763
  f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
@@ -731,7 +797,23 @@ def get_impact_chain(repo_path: str = ".", symbol: str = "", depth: int = 4) ->
731
797
  if _path_err is not None:
732
798
  return _path_err
733
799
  args = ["impact-chain", symbol.strip(), repo_path, "--depth", str(depth)]
734
- return _execute(args)
800
+ timeout_ms = int(os.environ.get("SOURCECODE_IMPACT_TIMEOUT_MS", str(_DEFAULT_IMPACT_TIMEOUT_MS)))
801
+ timeout_s = timeout_ms / 1000.0
802
+ _exec = concurrent.futures.ThreadPoolExecutor(max_workers=1)
803
+ try:
804
+ _fut = _exec.submit(_execute, args)
805
+ _done, _pending = concurrent.futures.wait([_fut], timeout=timeout_s)
806
+ if _pending:
807
+ _exec.shutdown(wait=False)
808
+ return _ok({
809
+ "truncated": True,
810
+ "truncated_reason": f"timeout_{timeout_s:.0f}s",
811
+ "analysis": "timed out — repository may be too large for MCP transport",
812
+ "suggestion": f"Increase SOURCECODE_IMPACT_TIMEOUT_MS (current: {timeout_ms}ms) or run via CLI directly",
813
+ })
814
+ return _fut.result()
815
+ finally:
816
+ _exec.shutdown(wait=True)
735
817
  except Exception as exc:
736
818
  return _err(
737
819
  f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
@@ -1148,7 +1230,23 @@ def get_impact_context(repo_path: str = ".", target: str = "", depth: int = 4) -
1148
1230
  if _path_err is not None:
1149
1231
  return _path_err
1150
1232
  args = ["impact", target.strip(), repo_path, "--depth", str(depth)]
1151
- return _execute(args)
1233
+ timeout_ms = int(os.environ.get("SOURCECODE_IMPACT_TIMEOUT_MS", str(_DEFAULT_IMPACT_TIMEOUT_MS)))
1234
+ timeout_s = timeout_ms / 1000.0
1235
+ _exec = concurrent.futures.ThreadPoolExecutor(max_workers=1)
1236
+ try:
1237
+ _fut = _exec.submit(_execute, args)
1238
+ _done, _pending = concurrent.futures.wait([_fut], timeout=timeout_s)
1239
+ if _pending:
1240
+ _exec.shutdown(wait=False)
1241
+ return _ok({
1242
+ "truncated": True,
1243
+ "truncated_reason": f"timeout_{timeout_s:.0f}s",
1244
+ "analysis": "timed out — repository may be too large for MCP transport",
1245
+ "suggestion": f"Increase SOURCECODE_IMPACT_TIMEOUT_MS (current: {timeout_ms}ms) or run via CLI directly",
1246
+ })
1247
+ return _fut.result()
1248
+ finally:
1249
+ _exec.shutdown(wait=True)
1152
1250
  except Exception as exc:
1153
1251
  return _err(
1154
1252
  f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
@@ -1269,9 +1367,22 @@ def _finalize_mcp_registry() -> None:
1269
1367
  structured_output=False,
1270
1368
  )
1271
1369
 
1272
- drift = validate_registry()
1273
- if drift:
1274
- raise RuntimeError(f"MCP registry drift detected: {drift}")
1370
+ try:
1371
+ drift = validate_registry()
1372
+ if drift:
1373
+ import warnings
1374
+ warnings.warn(
1375
+ f"MCP registry drift detected — server running with potential tool mismatch: {drift}",
1376
+ RuntimeWarning,
1377
+ stacklevel=2,
1378
+ )
1379
+ except Exception as _reg_exc:
1380
+ import warnings
1381
+ warnings.warn(
1382
+ f"MCP registry validation failed — server starting in degraded mode: {_reg_exc}",
1383
+ RuntimeWarning,
1384
+ stacklevel=2,
1385
+ )
1275
1386
 
1276
1387
 
1277
1388
  _finalize_mcp_registry()
@@ -3312,11 +3312,13 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
3312
3312
  }
3313
3313
 
3314
3314
 
3315
- def find_java_files(root: Path, *, max_files: int = 8000) -> list[str]:
3315
+ def find_java_files(root: Path, *, max_files: int = 8000, limitations: list[str] | None = None) -> list[str]:
3316
3316
  """Return relative paths to Java files under root, excluding test dirs and vendor."""
3317
3317
  results: list[str] = []
3318
+ _capped = False
3318
3319
  for p in sorted(root.rglob("*.java")):
3319
3320
  if len(results) >= max_files:
3321
+ _capped = True
3320
3322
  break
3321
3323
  try:
3322
3324
  rel = str(p.relative_to(root)).replace("\\", "/")
@@ -3334,6 +3336,10 @@ def find_java_files(root: Path, *, max_files: int = 8000) -> list[str]:
3334
3336
  if any(f in rel for f in ("/admin-client/", "/rest-client/", "/client-api/", "/api-client/")):
3335
3337
  continue
3336
3338
  results.append(rel)
3339
+ if _capped and limitations is not None:
3340
+ limitations.append(
3341
+ f"MAX_JAVA_FILES_REACHED: scanned {max_files} files — repository likely has more"
3342
+ )
3337
3343
  return results
3338
3344
 
3339
3345
 
@@ -418,12 +418,15 @@ class SecurityScanner:
418
418
  model: Optional[SpringSemanticModel] = None,
419
419
  ) -> list[SpringFinding]:
420
420
  all_findings: list[SpringFinding] = []
421
+ self._last_analysis_errors: list[str] = []
421
422
  for pattern in self.patterns:
422
423
  try:
423
424
  found = _call_pattern_analyze(pattern, cir, tx_index, root, model)
424
425
  all_findings.extend(found)
425
- except Exception:
426
- pass
426
+ except Exception as exc:
427
+ self._last_analysis_errors.append(
428
+ f"{pattern.pattern_id}: {type(exc).__name__}: {exc}"
429
+ )
427
430
  deduped = deduplicate_findings(all_findings)
428
431
  return sorted(deduped, key=lambda f: (SEVERITY_ORDER.get(f.severity, 9), f.symbol))
429
432
 
@@ -475,16 +478,20 @@ def run_security_audit(
475
478
  or cir.metadata.get("security_model", "unknown") != "unknown"
476
479
  )
477
480
 
481
+ _sec_limitations = [
482
+ "SEC-001: only emitted for annotation_based security model",
483
+ "SEC-002: generic type detection is regex-based on extends edge signatures",
484
+ "SEC-003: only detects controllers visible via cir.endpoints",
485
+ ]
486
+ for _err in getattr(scanner, "_last_analysis_errors", []):
487
+ _sec_limitations.append(f"PATTERN_ERROR: {_err}")
488
+
478
489
  result = SpringAuditResult(
479
490
  repo_id=getattr(cir, "cir_hash", "")[:16],
480
491
  spring_detected=_spring_detected,
481
492
  scope="security",
482
493
  findings=findings,
483
- limitations=[
484
- "SEC-001: only emitted for annotation_based security model",
485
- "SEC-002: generic type detection is regex-based on extends edge signatures",
486
- "SEC-003: only detects controllers visible via cir.endpoints",
487
- ],
494
+ limitations=_sec_limitations,
488
495
  metadata={
489
496
  "endpoints_analyzed": len(cir.endpoints),
490
497
  "security_model": cir.metadata.get("security_model", "unknown"),
@@ -672,12 +672,15 @@ class TxPatternEngine:
672
672
  model: Optional[SpringSemanticModel] = None,
673
673
  ) -> list[SpringFinding]:
674
674
  all_findings: list[SpringFinding] = []
675
+ self._last_analysis_errors: list[str] = []
675
676
  for pattern in self.patterns:
676
677
  try:
677
678
  found = _call_pattern_analyze(pattern, cir, tx_index, root, model)
678
679
  all_findings.extend(found)
679
- except Exception:
680
- pass
680
+ except Exception as exc:
681
+ self._last_analysis_errors.append(
682
+ f"{pattern.pattern_id}: {type(exc).__name__}: {exc}"
683
+ )
681
684
  deduped = deduplicate_findings(all_findings)
682
685
  return sorted(deduped, key=lambda f: (SEVERITY_ORDER.get(f.severity, 9), f.symbol))
683
686
 
@@ -721,15 +724,19 @@ def run_tx_audit(
721
724
 
722
725
  _spring_detected = tx_index.stats()["total"] > 0 or bool(model.bean_graph.beans)
723
726
 
727
+ _tx_limitations = [
728
+ "Self-invocation via this.method() not detected — requires AST-level analysis",
729
+ "Dynamic dispatch (interface/polymorphic calls) may produce incomplete call chains",
730
+ ]
731
+ for _err in getattr(engine, "_last_analysis_errors", []):
732
+ _tx_limitations.append(f"PATTERN_ERROR: {_err}")
733
+
724
734
  result = SpringAuditResult(
725
735
  repo_id=getattr(cir, "cir_hash", "")[:16],
726
736
  spring_detected=_spring_detected,
727
737
  scope="tx",
728
738
  findings=findings,
729
- limitations=[
730
- "Self-invocation via this.method() not detected — requires AST-level analysis",
731
- "Dynamic dispatch (interface/polymorphic calls) may produce incomplete call chains",
732
- ],
739
+ limitations=_tx_limitations,
733
740
  metadata={
734
741
  "symbols_analyzed": len(getattr(cir, "symbols", [])),
735
742
  "tx_boundaries_found": tx_index.stats()["total"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.35.20
3
+ Version: 1.35.22
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
@@ -1,4 +1,4 @@
1
- sourcecode/__init__.py,sha256=l8p-xmLEzkjJbgIarJoeYeAvJ-XevKuJ0pJk4s4nFtM,104
1
+ sourcecode/__init__.py,sha256=p3pMcJ60xxF18F5C5hvsyn5B4uh1rOmKBO_RC94DPAA,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
@@ -7,7 +7,7 @@ sourcecode/cache.py,sha256=wAyPrXN5DqiGivnMpeEuun2xHDKfBer2_oBsh6kj_vc,30447
7
7
  sourcecode/canonical_ir.py,sha256=uwpwCnJxMh_eiIVg4cOLv7-aZthvmDFcG4azCOycLkw,24281
8
8
  sourcecode/cir_graphs.py,sha256=rZi8JV4ZrAa2WSCeyNa4JIEKQ_yZzDZTsrvVz2KfuKA,8919
9
9
  sourcecode/classifier.py,sha256=2lYoSH3vOTkXZYPU7Go2WIet1-IuNzTWVhc-ULnXtgw,8024
10
- sourcecode/cli.py,sha256=YOcCerZFukibhfR5urXXfGXqX9MOyZgK_cgiOdHJH_k,237764
10
+ sourcecode/cli.py,sha256=wy5-T6Ba_hvqJoFkSROCJxOpsy_VzbYI98TlJIEeGW0,238063
11
11
  sourcecode/code_notes_analyzer.py,sha256=EJemNCNc9Dn-1RZYu-aNbK0ELzmsyC4s6FdHi3XyNEI,9392
12
12
  sourcecode/confidence_analyzer.py,sha256=_jckZSxksV-OU38vbkxfVNBnWCtlCq8Vwfg23x1uspA,19054
13
13
  sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
@@ -15,7 +15,7 @@ sourcecode/context_summarizer.py,sha256=zlbm8ytdvJToohU108-dwBmEl52xl0gXpf6PZBOW
15
15
  sourcecode/contract_model.py,sha256=nRxJKPMs1VHwFTa8AVXhGmaLjti3Lr2sjHDpWgv1bfE,3917
16
16
  sourcecode/contract_pipeline.py,sha256=gvTdDniedm_mjq4vaHqnBY2UkQ0s00gtXqzTLILNXHc,28719
17
17
  sourcecode/coverage_parser.py,sha256=q0LeZJaX1bnntLu-ImksdBsMlpsVmk_iUfSaB4eaJGo,19702
18
- sourcecode/dependency_analyzer.py,sha256=5yUBN_Z75RWmBIbsfnMasPSUn-4IaLipt0A3b3LNVfc,56310
18
+ sourcecode/dependency_analyzer.py,sha256=gvFJf9gHyUGRia3tdPz8s0aX2Re6aohMhb40uFEbjp0,60420
19
19
  sourcecode/doc_analyzer.py,sha256=05bjTUbDbmnbajD_cgRnACzS8T7xxBKVX4CjkJlhZg8,24411
20
20
  sourcecode/entrypoint_classifier.py,sha256=jhTYlyqDJH2AtdEcLVaRU3lYRTJuF8DkxVzl4-W3zWE,5322
21
21
  sourcecode/env_analyzer.py,sha256=aNTyYgQk5noJDfJU6FmasmESOHfiomyJw5EvZqjy6qc,22213
@@ -40,7 +40,7 @@ sourcecode/ranking_engine.py,sha256=ZAucq_YX2KkWUuAZf4P0lhtQ_38vEFnUhuGtSZd1S0E,
40
40
  sourcecode/redactor.py,sha256=SB4hwIvg8h-hvcqKcDWaZvA-aSyn-at-BIRwa0tUv5E,3227
41
41
  sourcecode/relevance_scorer.py,sha256=0AgEt4KrV73nioMqBgjhGjtY7L2C7L7cSyKtj3IKcrw,9408
42
42
  sourcecode/repo_classifier.py,sha256=FG1vaWKdWXsWdl-S8hjVMiTqcwgaRXkDyvK4rPcOGtQ,22681
43
- sourcecode/repository_ir.py,sha256=SOACZ4viYG8tpmL_-l4XqoX6bN4GmCeX5ZIr9tnuQyA,169298
43
+ sourcecode/repository_ir.py,sha256=5meIvsVN4WlllStxIglZznILKcI0Q2t2XMLB9aVT3uc,169561
44
44
  sourcecode/ris.py,sha256=RcqLVwC-doFcKKViYDkCjZLBqf_wzLES7-F6vHEeWzE,20419
45
45
  sourcecode/runtime_classifier.py,sha256=uTAD6BDCiBLUZEDRfqk718kM4RTT_vAbfkcOI2_Xx58,18432
46
46
  sourcecode/scanner.py,sha256=WdOQ78mMzjR1NjmKTlbxdgwinnCTfAhxCVLBEFQiFHU,8899
@@ -51,9 +51,9 @@ sourcecode/spring_event_topology.py,sha256=LvGv5RXtU_O-fVB_OO9eDD2UmZM72Jn2oUHgO
51
51
  sourcecode/spring_findings.py,sha256=8V91iHOg9hFgg6tLLl4FSsgrF-dBqOcO2s-K5sD_goA,5417
52
52
  sourcecode/spring_impact.py,sha256=Ohm2k3W4Wts8Kx8Z7DIM-J-cwGtTJBWKFBsX-WkupBQ,32943
53
53
  sourcecode/spring_model.py,sha256=IzMcM5ftw1_EHG3FGUDT7qdAMpo3eqbAE1LRuasfr_4,14739
54
- sourcecode/spring_security_audit.py,sha256=oaV-dK_5iSRwkWSJbMbzxfPbW376n3jTwnRPAspePjg,20293
54
+ sourcecode/spring_security_audit.py,sha256=AmUkqoExkNZ3YxxZf9TwkwX-f7P_SETm0QC7VqEAqh4,20618
55
55
  sourcecode/spring_semantic.py,sha256=CiAf77p48-RFrUF0zbgww4w2Xigrbo1t5M3ZCDIfV_g,12032
56
- sourcecode/spring_tx_analyzer.py,sha256=_RyXblWwMgTfUVtoceTzCrAVmlQ2Ovf0dMcBOy-0-3w,30201
56
+ sourcecode/spring_tx_analyzer.py,sha256=u4_ckdEFZUiIsHdUX4OaIhnvoTdAwrxNTFweG6vc7wE,30526
57
57
  sourcecode/summarizer.py,sha256=YspHEVeYJVmltq0FMtGZF8kIP3qiR2KLcanGL6Y7uTI,20747
58
58
  sourcecode/tree_utils.py,sha256=8GAkIfQAsvtEudIeW1l4ooH_oRtrWR8cpJQJsEa_Pfw,2093
59
59
  sourcecode/workspace.py,sha256=X_6NmNnitvT3_38V-JDChydo_sR68s249hLFlrQskU0,8271
@@ -82,7 +82,7 @@ sourcecode/mcp/__init__.py,sha256=XU4HfRGbdid8wdUA0x_4f7uKZD1z3mv_XUY_WU_T9Mw,17
82
82
  sourcecode/mcp/orchestrator.py,sha256=BMi1D6liJHI3DXiaC8yeBLLP0wXajpCP3-vnRGqrvnw,26850
83
83
  sourcecode/mcp/registry.py,sha256=XeshSuT6NMmeUZ2GCzNVcKcr-2Ljoj4qO-lvSrg17EM,63135
84
84
  sourcecode/mcp/runner.py,sha256=-Dp2qPGRkfNTVen6bKh7WtzQqpcEtsrXoiuajvshlKk,2866
85
- sourcecode/mcp/server.py,sha256=G2vGG791pEjd7NNUP7vcDPsaFUEyfnGYyYJjMiiFZls,54789
85
+ sourcecode/mcp/server.py,sha256=Zapr4lY0i4tqSXY2BfA283VzStHTohNr9N0uMnRSIIA,59911
86
86
  sourcecode/mcp/onboarding/__init__.py,sha256=sj2PWqEBmMc4zBNkomg89WtL0M6S7A9yb7_wAuSWNP4,66
87
87
  sourcecode/mcp/onboarding/applier.py,sha256=B9CneieWTpaDSDIyW3S5nrlRlBpvfqUcgi93-mm_ApQ,2135
88
88
  sourcecode/mcp/onboarding/backup.py,sha256=ihqGOR8QTX8HASRSEDyfFyXr5bkXrygPHamv4p9KTmk,1452
@@ -94,8 +94,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
94
94
  sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
95
95
  sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
96
96
  sourcecode/telemetry/transport.py,sha256=QSslxIwij8YkRWcVvxykODDrkiN_GAAEu3dUP7KIWeE,1651
97
- sourcecode-1.35.20.dist-info/METADATA,sha256=KVCGOgyCNzyPgXlmXaBGm15I45DFenMGxvduoVE6gYg,21297
98
- sourcecode-1.35.20.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
99
- sourcecode-1.35.20.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
100
- sourcecode-1.35.20.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
101
- sourcecode-1.35.20.dist-info/RECORD,,
97
+ sourcecode-1.35.22.dist-info/METADATA,sha256=myCZutK9p4r8d-O38SYo4et7pkpwASrkuJOnr_WIAac,21297
98
+ sourcecode-1.35.22.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
99
+ sourcecode-1.35.22.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
100
+ sourcecode-1.35.22.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
101
+ sourcecode-1.35.22.dist-info/RECORD,,