sourcecode 1.31.4__py3-none-any.whl → 1.31.5__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.31.4"
3
+ __version__ = "1.31.5"
sourcecode/cli.py CHANGED
@@ -401,7 +401,7 @@ def main(
401
401
  help=(
402
402
  "High-signal summary (typically 1000–3000 tokens depending on repo size): "
403
403
  "stacks, entry points, dependency summary, confidence, and gaps. "
404
- "Includes security_surface, mybatis, and transactional_boundaries for Java projects. "
404
+ "Includes security_surface (when @M3FiltroSeguridad detected), mybatis (when MyBatis framework detected), and transactional_boundaries for Java projects. "
405
405
  "Use --agent for maximum signal or --slim (when available) for minimal token footprint."
406
406
  ),
407
407
  ),
@@ -2418,14 +2418,20 @@ def repo_ir_cmd(
2418
2418
 
2419
2419
  if output_path:
2420
2420
  output_path.write_text(output, encoding="utf-8")
2421
- n_nodes = len((ir.get("graph") or {}).get("nodes") or [])
2422
- n_edges = len((ir.get("graph") or {}).get("edges") or [])
2423
2421
  size_kb = len(output.encode("utf-8")) // 1024
2424
- typer.echo(
2425
- f"IR written to {output_path} "
2426
- f"({size_kb}KB, {n_nodes} nodes, {n_edges} edges)",
2427
- err=True,
2428
- )
2422
+ if summary_only:
2423
+ typer.echo(
2424
+ f"IR written to {output_path} ({size_kb}KB, graph omitted by --summary-only)",
2425
+ err=True,
2426
+ )
2427
+ else:
2428
+ n_nodes = len((ir.get("graph") or {}).get("nodes") or [])
2429
+ n_edges = len((ir.get("graph") or {}).get("edges") or [])
2430
+ typer.echo(
2431
+ f"IR written to {output_path} "
2432
+ f"({size_kb}KB, {n_nodes} nodes, {n_edges} edges)",
2433
+ err=True,
2434
+ )
2429
2435
  else:
2430
2436
  try:
2431
2437
  _sys.stdout.buffer.write(output.encode("utf-8"))
@@ -2462,7 +2468,11 @@ def _extract_java_endpoints(root: "Path") -> "dict[str, Any]":
2462
2468
  r'@(Get|Post|Put|Delete|Patch|Request)Mapping\s*'
2463
2469
  r'(?:\(\s*(?:value\s*=\s*)?(?:"([^"]*)"|\{[^}]*\}|[^)]*)\s*\))?',
2464
2470
  )
2465
- _CLASS_RE = _re.compile(r'(?:class|interface)\s+(\w+)')
2471
+ _CLASS_RE = _re.compile(
2472
+ r'^[ \t]*(?:(?:public|protected|private|abstract|final|@\w+)\s+)*'
2473
+ r'(?:class|interface)\s+(\w+)',
2474
+ _re.MULTILINE,
2475
+ )
2466
2476
  _METHOD_RE = _re.compile(
2467
2477
  r'(?:public|protected|private)\s+\S+\s+(\w+)\s*\(',
2468
2478
  )
@@ -2540,7 +2550,45 @@ def _extract_java_endpoints(root: "Path") -> "dict[str, Any]":
2540
2550
  if "class " in block or "interface " in block:
2541
2551
  path_m = _CLASS_PATH_RE.search(block)
2542
2552
  if path_m:
2543
- class_bases = [path_m.group(1).rstrip("/")]
2553
+ captured = path_m.group(1).rstrip("/")
2554
+ # Handle string concat: @RequestMapping("lit" + ClassName.CONST)
2555
+ _CONCAT_CONST_RE = _re.compile(
2556
+ r'@RequestMapping\s*\(\s*(?:value\s*=\s*)?'
2557
+ r'["\']([^"\']*)["\'\s]*\+\s*(\w+)\.(\w+)'
2558
+ )
2559
+ cc_m = _CONCAT_CONST_RE.search(block)
2560
+ if cc_m:
2561
+ prefix_lit = cc_m.group(1)
2562
+ c_class = cc_m.group(2)
2563
+ c_field = cc_m.group(3)
2564
+ _SVAL_RE = _re.compile(
2565
+ r'static\s+final\s+String\s+'
2566
+ + _re.escape(c_field)
2567
+ + r'\s*=\s*"([^"]+)"'
2568
+ )
2569
+ resolved = None
2570
+ m_cur = _SVAL_RE.search(content)
2571
+ if m_cur:
2572
+ resolved = m_cur.group(1)
2573
+ else:
2574
+ for _jf in java_files:
2575
+ if _jf.stem == c_class:
2576
+ try:
2577
+ _jf_txt = _jf.read_text(
2578
+ encoding="utf-8", errors="replace"
2579
+ )
2580
+ m_jf = _SVAL_RE.search(_jf_txt)
2581
+ if m_jf:
2582
+ resolved = m_jf.group(1)
2583
+ break
2584
+ except OSError:
2585
+ pass
2586
+ if resolved is not None:
2587
+ class_bases = [(prefix_lit + resolved).rstrip("/")]
2588
+ else:
2589
+ class_bases = [captured] if captured else [""]
2590
+ else:
2591
+ class_bases = [captured] if captured else [""]
2544
2592
  else:
2545
2593
  arr_m = _CLASS_ARRAY_PATH_RE.search(block)
2546
2594
  if arr_m:
@@ -59,8 +59,13 @@ class HeuristicDetector(AbstractDetector):
59
59
  paths = flatten_file_tree(context.file_tree)
60
60
  counts: Counter[str] = Counter()
61
61
  for path in paths:
62
- if path.startswith("."):
62
+ if path.startswith(".") or _is_auxiliary_path(path):
63
63
  continue
64
+ # Skip JS/TS files bundled as Java static resources (not Node.js source)
65
+ if path.endswith((".js", ".ts", ".tsx", ".jsx", ".mjs")):
66
+ _np = path.replace("\\", "/")
67
+ if "src/main/resources/" in _np or "src/main/webapp/" in _np:
68
+ continue
64
69
  for extension, stack in _EXTENSION_MAP.items():
65
70
  if path.endswith(extension):
66
71
  counts[stack] += 1
sourcecode/serializer.py CHANGED
@@ -409,7 +409,10 @@ def _spring_profiles_context(sm: "SourceMap") -> "Optional[dict[str, Any]]":
409
409
  else:
410
410
  matches = [
411
411
  p for p in sm.file_paths
412
- if pfx in Path(p).stem.lower() and p.endswith(".java")
412
+ if (Path(p).stem.lower() == pfx
413
+ or Path(p).stem.lower().startswith(pfx + "-")
414
+ or Path(p).stem.lower().endswith("-" + pfx))
415
+ and p.endswith(".java")
413
416
  ]
414
417
  if matches:
415
418
  per_profile[profile] = [Path(p).name for p in matches[:5]]
@@ -534,6 +537,8 @@ def _bootstrap_structured(eps: list) -> "Optional[dict[str, Any]]":
534
537
 
535
538
  for ep in eps:
536
539
  path = getattr(ep, "path", "")
540
+ if "/test/" in path or "/tests/" in path:
541
+ continue
537
542
  kind = getattr(ep, "kind", "")
538
543
  stem = _Path(path).stem
539
544
 
@@ -587,8 +592,9 @@ def _bootstrap_structured(eps: list) -> "Optional[dict[str, Any]]":
587
592
  module_names.append(module)
588
593
 
589
594
  _ctrl_note = (
590
- f"{controller_methods} @RequestMapping methods across "
595
+ f"{controller_methods} detected entry-point methods across "
591
596
  f"{controller_classes} controller classes"
597
+ f" (use 'sourcecode endpoints' for full surface)"
592
598
  )
593
599
  if len(module_names) > 30:
594
600
  # Group by first path segment under ddd/ (inferred domain area)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.31.4
3
+ Version: 1.31.5
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
  **Deterministic, behavior-aware codebase context for AI agents and PR review.**
227
227
 
228
- ![Version](https://img.shields.io/badge/version-1.31.4-blue)
228
+ ![Version](https://img.shields.io/badge/version-1.31.5-blue)
229
229
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
230
230
 
231
231
  ---
@@ -261,7 +261,7 @@ pipx install sourcecode
261
261
 
262
262
  ```bash
263
263
  sourcecode version
264
- # sourcecode 1.31.4
264
+ # sourcecode 1.31.5
265
265
  ```
266
266
 
267
267
  ---
@@ -1,10 +1,10 @@
1
- sourcecode/__init__.py,sha256=P8MbrmTVGyjN1Uy_38VxYTdrjIoEPOf9I4Xn71cCRs8,103
1
+ sourcecode/__init__.py,sha256=INTl4i-9L8tLlPUGq6eihBx0YEE8OQu6cHtsMNAu_vc,103
2
2
  sourcecode/adaptive_scanner.py,sha256=XffluXKzJUXrMtjEiAOnSNPZnztdIcts17T9ouHeID0,10521
3
3
  sourcecode/architecture_analyzer.py,sha256=MyBa0Hf5HmkudZQDLKrjcWDKETXETXl0mQX1swtTwAA,39091
4
4
  sourcecode/architecture_summary.py,sha256=z34_6v7cSwy98cof2UVciGho7SCrZ93tiqMmq5WNzRQ,20405
5
5
  sourcecode/ast_extractor.py,sha256=XgrZg2DcWcUm9r87cRG3KGO7IK2TIL_N-CvhSbUmmh4,49901
6
6
  sourcecode/classifier.py,sha256=-0t0HLc9L9UleMLfclfLM3AXhBjUb_AYyBPDbvgWtac,7755
7
- sourcecode/cli.py,sha256=dcHIYDvDpcIzbExxKuemtElk3RClLRWaaO2RU9R8Hoc,123945
7
+ sourcecode/cli.py,sha256=IDe_6kp4hgqPX6YLA-Gu6-rlwbyT4iXfuYJhG4pmhe0,126525
8
8
  sourcecode/code_notes_analyzer.py,sha256=y1MJBnPZHYp4i6cQCXUb9ATIyifS_qMQWjw_8lPkpsU,9215
9
9
  sourcecode/confidence_analyzer.py,sha256=ZUn-Nywi5TEQcuozqK_vfOyPT-a1dYYO42elAtVFV-k,16412
10
10
  sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
@@ -33,7 +33,7 @@ sourcecode/runtime_classifier.py,sha256=zWX3r3HCKHc-qtIobErOa8aKMmaoPYREtJKvPcBG
33
33
  sourcecode/scanner.py,sha256=WdOQ78mMzjR1NjmKTlbxdgwinnCTfAhxCVLBEFQiFHU,8899
34
34
  sourcecode/schema.py,sha256=fj3BZ3IcnNV4j21BFIEvz8Qnw_vZoqIbzzRg-qQ-nd0,24530
35
35
  sourcecode/semantic_analyzer.py,sha256=12TwXYkYbDcBdu0heX_EmfPM2EkO8a_r5osf0SaeQbs,88956
36
- sourcecode/serializer.py,sha256=KHVqwUK53axF10detPzqgmIY2P31rjLLJ_9T9Eyqp-E,111647
36
+ sourcecode/serializer.py,sha256=1y9DAkH2aBzlsmkHcSSc-t72_4fv9RZIuG4uhhGG5QE,111933
37
37
  sourcecode/summarizer.py,sha256=lPlKhMh28nueXkPo2xKeD3DUFYVGRlJMIdY-8TSM-ls,17486
38
38
  sourcecode/tree_utils.py,sha256=8GAkIfQAsvtEudIeW1l4ooH_oRtrWR8cpJQJsEa_Pfw,2093
39
39
  sourcecode/workspace.py,sha256=X_6NmNnitvT3_38V-JDChydo_sR68s249hLFlrQskU0,8271
@@ -44,7 +44,7 @@ sourcecode/detectors/dart.py,sha256=QbqaL5v18-_ort75HihVBt8MsKUfOcFDF8IpWFLiXpI,
44
44
  sourcecode/detectors/dotnet.py,sha256=oi8zq3AfUItlK3h_qM81vOe1ZVTIU9LBKIlIrRDuqOs,6864
45
45
  sourcecode/detectors/elixir.py,sha256=jCpvt5Yi6jvplc80ovRtWh17q-11ZGo9qX7o8b57TJE,1713
46
46
  sourcecode/detectors/go.py,sha256=2r66uRQfeTWsqxr4HDhT6vExZErby0t46QXLHVBRv9w,2782
47
- sourcecode/detectors/heuristic.py,sha256=bCqqgbHavl4Sse3dqT8mwmo1wAdgeJr7VyXOmfClLKo,3387
47
+ sourcecode/detectors/heuristic.py,sha256=7cRxrip4yIaggYzZJB6ef8yHKh-gHgiH_pXMFcjlyFU,3723
48
48
  sourcecode/detectors/hybrid.py,sha256=IGFRUVsAZ1ooRlFdznCeJAV6vy1yVDx-VyghvLtddXc,9101
49
49
  sourcecode/detectors/java.py,sha256=ldvaDZJADAKslOpS5qJ0bxexgeY6h_4Yx4NCtHio7J8,24203
50
50
  sourcecode/detectors/jvm_ext.py,sha256=EgHJ5W8EE-ZTN9V607mVzohyKgZE8Mc2jCi-DF8RAZU,2616
@@ -72,8 +72,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
72
72
  sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
73
73
  sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
74
74
  sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
75
- sourcecode-1.31.4.dist-info/METADATA,sha256=JZXcuZYPozOjtbIY_xnVgUNwMF1aEU12mV4m2T__E1A,29083
76
- sourcecode-1.31.4.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
77
- sourcecode-1.31.4.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
78
- sourcecode-1.31.4.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
79
- sourcecode-1.31.4.dist-info/RECORD,,
75
+ sourcecode-1.31.5.dist-info/METADATA,sha256=UcfeOr7ZaZWAjC3WByNVOIoPw3VlJPF3pS9Fo7f-Ch0,29083
76
+ sourcecode-1.31.5.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
77
+ sourcecode-1.31.5.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
78
+ sourcecode-1.31.5.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
79
+ sourcecode-1.31.5.dist-info/RECORD,,