sourcecode 1.36.4__tar.gz → 1.36.5__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 (118) hide show
  1. {sourcecode-1.36.4 → sourcecode-1.36.5}/PKG-INFO +3 -3
  2. {sourcecode-1.36.4 → sourcecode-1.36.5}/README.md +2 -2
  3. {sourcecode-1.36.4 → sourcecode-1.36.5}/pyproject.toml +1 -1
  4. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/repository_ir.py +86 -16
  6. {sourcecode-1.36.4 → sourcecode-1.36.5}/.github/workflows/build-windows.yml +0 -0
  7. {sourcecode-1.36.4 → sourcecode-1.36.5}/.gitignore +0 -0
  8. {sourcecode-1.36.4 → sourcecode-1.36.5}/.ruff.toml +0 -0
  9. {sourcecode-1.36.4 → sourcecode-1.36.5}/CHANGELOG.md +0 -0
  10. {sourcecode-1.36.4 → sourcecode-1.36.5}/CONTRIBUTING.md +0 -0
  11. {sourcecode-1.36.4 → sourcecode-1.36.5}/LICENSE +0 -0
  12. {sourcecode-1.36.4 → sourcecode-1.36.5}/SECURITY.md +0 -0
  13. {sourcecode-1.36.4 → sourcecode-1.36.5}/raw +0 -0
  14. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/adaptive_scanner.py +0 -0
  15. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/architecture_analyzer.py +0 -0
  16. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/architecture_summary.py +0 -0
  17. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/ast_extractor.py +0 -0
  18. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/cache.py +0 -0
  19. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/canonical_ir.py +0 -0
  20. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/cir_graphs.py +0 -0
  21. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/classifier.py +0 -0
  22. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/cli.py +0 -0
  23. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/code_notes_analyzer.py +0 -0
  24. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/confidence_analyzer.py +0 -0
  25. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/context_scorer.py +0 -0
  26. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/context_summarizer.py +0 -0
  27. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/contract_model.py +0 -0
  28. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/contract_pipeline.py +0 -0
  29. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/coverage_parser.py +0 -0
  30. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/dependency_analyzer.py +0 -0
  31. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/__init__.py +0 -0
  32. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/base.py +0 -0
  33. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/csproj_parser.py +0 -0
  34. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/dart.py +0 -0
  35. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/dotnet.py +0 -0
  36. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/elixir.py +0 -0
  37. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/go.py +0 -0
  38. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/heuristic.py +0 -0
  39. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/hybrid.py +0 -0
  40. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/java.py +0 -0
  41. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/jvm_ext.py +0 -0
  42. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/nodejs.py +0 -0
  43. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/parsers.py +0 -0
  44. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/php.py +0 -0
  45. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/project.py +0 -0
  46. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/python.py +0 -0
  47. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/ruby.py +0 -0
  48. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/rust.py +0 -0
  49. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/systems.py +0 -0
  50. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/terraform.py +0 -0
  51. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/detectors/tooling.py +0 -0
  52. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/doc_analyzer.py +0 -0
  53. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/entrypoint_classifier.py +0 -0
  54. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/env_analyzer.py +0 -0
  55. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/error_schema.py +0 -0
  56. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/explain.py +0 -0
  57. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/file_chunker.py +0 -0
  58. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/file_classifier.py +0 -0
  59. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/flow_analyzer.py +0 -0
  60. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/fqn_utils.py +0 -0
  61. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/git_analyzer.py +0 -0
  62. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/graph_analyzer.py +0 -0
  63. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/license.py +0 -0
  64. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/__init__.py +0 -0
  65. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  66. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  67. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  68. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  69. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  70. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/orchestrator.py +0 -0
  71. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/registry.py +0 -0
  72. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/runner.py +0 -0
  73. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp/server.py +0 -0
  74. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/mcp_nudge.py +0 -0
  75. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/metrics_analyzer.py +0 -0
  76. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/migrate_check.py +0 -0
  77. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/output_budget.py +0 -0
  78. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/path_filters.py +0 -0
  79. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/pr_comment_renderer.py +0 -0
  80. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/pr_impact.py +0 -0
  81. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/prepare_context.py +0 -0
  82. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/progress.py +0 -0
  83. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/ranking_engine.py +0 -0
  84. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/redactor.py +0 -0
  85. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/relevance_scorer.py +0 -0
  86. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/rename_refactor.py +0 -0
  87. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/repo_classifier.py +0 -0
  88. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/ris.py +0 -0
  89. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/runtime_classifier.py +0 -0
  90. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/scanner.py +0 -0
  91. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/schema.py +0 -0
  92. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/security_config.py +0 -0
  93. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/semantic_analyzer.py +0 -0
  94. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/serializer.py +0 -0
  95. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_event_topology.py +0 -0
  96. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_findings.py +0 -0
  97. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_impact.py +0 -0
  98. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_model.py +0 -0
  99. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_security_audit.py +0 -0
  100. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_semantic.py +0 -0
  101. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/spring_tx_analyzer.py +0 -0
  102. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/summarizer.py +0 -0
  103. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/__init__.py +0 -0
  104. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/config.py +0 -0
  105. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/consent.py +0 -0
  106. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/events.py +0 -0
  107. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/filters.py +0 -0
  108. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/telemetry/transport.py +0 -0
  109. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/tree_utils.py +0 -0
  110. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/version_check.py +0 -0
  111. {sourcecode-1.36.4 → sourcecode-1.36.5}/src/sourcecode/workspace.py +0 -0
  112. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/.temp/cli-latest +0 -0
  113. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/functions/README.md +0 -0
  114. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/functions/get-license/index.ts +0 -0
  115. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
  116. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/functions/telemetry/index.ts +0 -0
  117. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/sql/license_event_ordering.sql +0 -0
  118. {sourcecode-1.36.4 → sourcecode-1.36.5}/supabase/sql/telemetry_events.sql +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.36.4
3
+ Version: 1.36.5
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.36.4-blue)
43
+ ![Version](https://img.shields.io/badge/version-1.36.5-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.36.4
117
+ # sourcecode 1.36.5
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.36.4-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.36.5-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.36.4
79
+ # sourcecode 1.36.5
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.36.4"
7
+ version = "1.36.5"
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.36.4"
3
+ __version__ = "1.36.5"
@@ -486,6 +486,31 @@ def _normalize_type_name(raw: str) -> str:
486
486
  return raw.strip()
487
487
 
488
488
 
489
+ def _split_supertype_list(raw: str) -> list[str]:
490
+ """Split an ``extends``/``implements`` clause into individual base type names.
491
+
492
+ Handles multiple supertypes (interfaces may extend several) and strips generic
493
+ type arguments *before* splitting so that commas inside ``<...>`` do not corrupt
494
+ the result. e.g. ``"VetRepository, Repository<Vet, Integer>"`` → ``["VetRepository",
495
+ "Repository"]``.
496
+ """
497
+ if not raw or not raw.strip():
498
+ return []
499
+ # Iteratively remove (possibly nested) generic parameters so any commas they
500
+ # contain are gone before we split on the top-level commas.
501
+ prev = None
502
+ stripped = raw
503
+ while prev != stripped:
504
+ prev = stripped
505
+ stripped = re.sub(r'<[^<>]*>', '', stripped)
506
+ bases: list[str] = []
507
+ for piece in stripped.split(","):
508
+ base = re.sub(r'<.*', '', piece).strip()
509
+ if base:
510
+ bases.append(base)
511
+ return bases
512
+
513
+
489
514
  def _parse_param_types(params_str: str) -> list[str]:
490
515
  """Parse "(Long id, @Valid String name)" → ["Long", "String"].
491
516
 
@@ -1166,29 +1191,29 @@ def _build_relations(
1166
1191
  class_fqn = f"{package}.{name}" if package else name
1167
1192
 
1168
1193
  if extends_str:
1169
- base = re.sub(r'<.*', '', extends_str).strip()
1170
- to = import_map.get(base, base)
1171
- edges.append(RelationEdge(
1172
- from_symbol=class_fqn,
1173
- to_symbol=to,
1174
- type="extends",
1175
- confidence="high",
1176
- evidence={"type": "signature", "value": f"extends {extends_str}"},
1177
- ))
1194
+ # An interface may extend multiple interfaces (e.g.
1195
+ # `extends VetRepository, Repository<Vet, Integer>`); split on top-level
1196
+ # commas so each base produces its own edge and the reverse graph sees
1197
+ # every supertype (not a single mangled token).
1198
+ for base in _split_supertype_list(extends_str):
1199
+ to = import_map.get(base, base)
1200
+ edges.append(RelationEdge(
1201
+ from_symbol=class_fqn,
1202
+ to_symbol=to,
1203
+ type="extends",
1204
+ confidence="high",
1205
+ evidence={"type": "signature", "value": f"extends {extends_str}"},
1206
+ ))
1178
1207
 
1179
1208
  if implements_str:
1180
- for iface in implements_str.split(","):
1181
- iface = iface.strip()
1182
- base = re.sub(r'<.*', '', iface).strip()
1183
- if not base:
1184
- continue
1209
+ for base in _split_supertype_list(implements_str):
1185
1210
  to = import_map.get(base, base)
1186
1211
  edges.append(RelationEdge(
1187
1212
  from_symbol=class_fqn,
1188
1213
  to_symbol=to,
1189
1214
  type="implements",
1190
1215
  confidence="high",
1191
- evidence={"type": "signature", "value": f"implements {iface}"},
1216
+ evidence={"type": "signature", "value": f"implements {base}"},
1192
1217
  ))
1193
1218
 
1194
1219
  # mapped_to edges: controller class → class-level @RequestMapping path prefix.
@@ -2973,6 +2998,11 @@ def build_repo_ir(
2973
2998
  '@Aspect', '@Aggregate', '@Document',
2974
2999
  # Spring Data
2975
3000
  '@Query', '@NamedQuery',
3001
+ # Profile-gated beans/interfaces (e.g. Spring Data repository specializations
3002
+ # like `@Profile("spring-data-jpa") interface FooRepo extends FooRepository`).
3003
+ # Without this marker such interfaces are pre-scan-skipped and their
3004
+ # extends/implements edges are lost — making them invisible to impact analysis.
3005
+ '@Profile',
2976
3006
  )
2977
3007
  # Pre-pass: collect custom meta-annotation names from @interface definitions
2978
3008
  # that compose known Spring stereotypes (e.g. @DomainService = @Service + @Transactional).
@@ -3517,6 +3547,40 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
3517
3547
  "note": "interface-based Spring MVC controller — URL mapped via XML",
3518
3548
  })
3519
3549
 
3550
+ # Detect controllers whose HTTP mappings live on an IMPLEMENTED interface that is
3551
+ # not part of the scanned source surface. The dominant case is openapi-generator
3552
+ # "interface-only" output (e.g. PetV2Api, VetsApi) emitted under
3553
+ # target/generated-sources, which the scanner excludes. Such a controller carries
3554
+ # @RestController/@Controller and an `implements XxxApi` clause but contributes no
3555
+ # method-level routes, so its endpoints are invisible. Emit an explicit warning so
3556
+ # an empty/partial surface is not silently misread as "no endpoints / no security".
3557
+ _CONTROLLER_ANNS = {"@RestController", "@Controller"}
3558
+ _IMPLEMENTS_RE = _re.compile(r'\bimplements\s+(.+)$')
3559
+ _routed_fqns = {route.get("effective_class") for route in routes}
3560
+ interface_defined_controllers: list[str] = []
3561
+ endpoint_warnings: list[str] = []
3562
+ for sym in all_symbols:
3563
+ if sym.type != "class":
3564
+ continue
3565
+ if not (_CONTROLLER_ANNS & set(sym.annotations)):
3566
+ continue
3567
+ if sym.symbol in _routed_fqns:
3568
+ continue # already contributes routes — surface is captured
3569
+ m = _IMPLEMENTS_RE.search(sym.signature or "")
3570
+ if not m:
3571
+ continue
3572
+ ifaces = _split_supertype_list(m.group(1))
3573
+ api_ifaces = [i for i in ifaces if i.endswith("Api")]
3574
+ if not api_ifaces:
3575
+ continue
3576
+ interface_defined_controllers.append(sym.symbol)
3577
+ endpoint_warnings.append(
3578
+ f"{sym.symbol.split('.')[-1]} implements {', '.join(api_ifaces)}: HTTP "
3579
+ "mappings are declared on the implemented interface (commonly generated by "
3580
+ "openapi-generator under target/generated-sources, which is not scanned). "
3581
+ "Endpoint surface for this controller is NOT captured."
3582
+ )
3583
+
3520
3584
  endpoints: list[dict] = []
3521
3585
  for route in routes:
3522
3586
  handler = (
@@ -3643,7 +3707,7 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
3643
3707
  if e.get("security", {}).get("policy") == "none_detected"
3644
3708
  )
3645
3709
 
3646
- return {
3710
+ result: dict[str, Any] = {
3647
3711
  "endpoints": endpoints,
3648
3712
  "total": len(endpoints),
3649
3713
  "no_security_signal": no_security_signal,
@@ -3651,6 +3715,12 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
3651
3715
  # Keep legacy field name for backward compat, now means same as no_security_signal
3652
3716
  "undocumented": no_security_signal,
3653
3717
  }
3718
+ # Surface incomplete-endpoint warnings (interface-defined controllers) only when
3719
+ # present, to keep output backward-compatible for the common case.
3720
+ if endpoint_warnings:
3721
+ result["warnings"] = endpoint_warnings
3722
+ result["interface_defined_controllers"] = interface_defined_controllers
3723
+ return result
3654
3724
 
3655
3725
 
3656
3726
  def find_java_files(root: Path, *, max_files: int = 8000, limitations: list[str] | None = None) -> list[str]:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes