sourcecode 1.31.26__py3-none-any.whl → 1.31.28__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.26"
3
+ __version__ = "1.31.28"
@@ -332,6 +332,7 @@ def ir_dict_to_canonical(
332
332
  "spring_events": ir.get("spring_events") or {},
333
333
  "score_basis": (ir.get("impact") or {}).get("score_basis", "none"),
334
334
  "reverse_graph_size": len(ir.get("reverse_graph") or {}),
335
+ "security_model": ir.get("security_model", "unknown"),
335
336
  }
336
337
 
337
338
  cir_hash = _compute_cir_hash(
@@ -452,6 +453,7 @@ def project_endpoint_surface(cir: CanonicalRepositoryIR) -> dict:
452
453
  "endpoints": endpoints,
453
454
  "total": len(endpoints),
454
455
  "no_security_signal": no_security_signal,
456
+ "security_model": cir.metadata.get("security_model", "unknown"),
455
457
  # Legacy field alias — same count, kept for backward compat
456
458
  "undocumented": no_security_signal,
457
459
  }
sourcecode/cli.py CHANGED
@@ -739,12 +739,15 @@ def main(
739
739
  # compact is designed to be a bounded summary; --full removes truncation limits,
740
740
  # which contradicts compact's purpose. Use --agent --full for expanded output.
741
741
  if compact and full:
742
- typer.echo(
743
- "Error: --compact and --full are mutually exclusive. "
744
- "--compact produces a bounded summary; --full removes truncation limits and "
745
- "is meant for --agent mode. Use --agent --full for expanded output.",
746
- err=True,
747
- )
742
+ import json as _json_flags, sys as _sys_flags
743
+ _sys_flags.stdout.write(_json_flags.dumps({
744
+ "error": "incompatible_flags",
745
+ "message": "--compact and --full are mutually exclusive. "
746
+ "--compact produces a bounded summary; --full removes truncation limits "
747
+ "and is meant for --agent mode. Use --agent --full for expanded output.",
748
+ "exit_code": 1,
749
+ }, ensure_ascii=False) + "\n")
750
+ _sys_flags.stdout.flush()
748
751
  raise typer.Exit(code=1)
749
752
 
750
753
  # P0-2 FIX: --full without --compact or --agent has no effect in contract/raw mode.
@@ -1127,10 +1130,14 @@ def main(
1127
1130
 
1128
1131
  # --compact implicitly enables lightweight analysis passes so that
1129
1132
  # dependency_summary, env_summary and code_notes_summary are never null.
1133
+ # architecture=True is also enabled so that architecture.confidence is
1134
+ # consistent with --agent (which auto-enables architecture). The
1135
+ # ArchitectureAnalyzer is path-based and adds negligible latency.
1130
1136
  if compact:
1131
1137
  dependencies = True
1132
1138
  env_map = True
1133
1139
  code_notes = True
1140
+ architecture = True
1134
1141
 
1135
1142
  dependency_analyzer = DependencyAnalyzer() if dependencies else None
1136
1143
  graph_analyzer = GraphAnalyzer() if graph_modules else None
sourcecode/mcp/server.py CHANGED
@@ -158,9 +158,12 @@ def get_endpoints(repo_path: str = ".") -> dict:
158
158
  Returns: endpoints list with method, path, controller, handler fields;
159
159
  security dict when authorization annotations are present
160
160
  (policy: roles_allowed|permit_all|deny_all|authenticated|...);
161
- total (int) and no_security_signal (int) counts.
162
- no_security_signal counts endpoints with no recognized auth annotation
163
- repos using framework-level auth (e.g. Keycloak) may show high counts.
161
+ total (int), no_security_signal (int), and security_model (str) fields.
162
+ no_security_signal counts endpoints with no recognized auth annotation.
163
+ security_model values: "filter_based" (centralized Spring Security config
164
+ high no_security_signal is expected and does NOT mean endpoints are unprotected),
165
+ "annotation_based" (per-endpoint annotations only), "mixed" (both),
166
+ "unknown" (no security signals detected).
164
167
  Supports Spring MVC (@GetMapping etc.) and JAX-RS (@GET/@POST etc.).
165
168
  Security annotations detected: @RolesAllowed, @PermitAll, @DenyAll,
166
169
  @Authenticated, @PreAuthorize, @Secured, @SecurityRequirement, @M3FiltroSeguridad.
@@ -450,6 +453,36 @@ def get_impact_context(repo_path: str = ".", target: str = "", depth: int = 4) -
450
453
  )
451
454
 
452
455
 
456
+ @mcp.tool()
457
+ def modernize_context(repo_path: str = ".", format: str = "json") -> dict:
458
+ """Analyzes codebase for modernization opportunities: dead zones, hotspot scores, upgrade candidates.
459
+
460
+ Maps to: sourcecode modernize <repo_path>
461
+ Returns: hotspot_candidates (high fan-in + git churn), dead_zone_candidates (isolated classes),
462
+ high_coupling_nodes, subsystem_summary, cross_module_tangles, recommendation.
463
+
464
+ Best for: refactor planning, identifying where to start, finding safe removal candidates.
465
+ Use get_compact_context or get_agent_context first for project orientation.
466
+
467
+ repo_path: absolute path to the Java repository (default: current working directory).
468
+ format: output format — "json" (default). Only json is supported; yaml is not available
469
+ for modernize output.
470
+ """
471
+ _raw = repo_path
472
+ try:
473
+ if not isinstance(repo_path, str):
474
+ return _err("repo_path must be a string", "INVALID_ARGUMENT")
475
+ if not isinstance(format, str) or format not in ("json", "yaml"):
476
+ return _err("format must be 'json' or 'yaml'", "INVALID_ARGUMENT")
477
+ repo_path = _normalize_repo_path(repo_path)
478
+ return _execute(["modernize", repo_path])
479
+ except Exception as exc:
480
+ return _err(
481
+ f"Internal error: {type(exc).__name__}: {exc} — repo_path recibido: {_raw}",
482
+ "INTERNAL_ERROR",
483
+ )
484
+
485
+
453
486
  _TELEMETRY_ACTIONS = frozenset({"status", "enable", "disable"})
454
487
 
455
488
 
@@ -1134,6 +1134,27 @@ class TaskContextBuilder:
1134
1134
  # No-git and invalid-ref cases were already handled in step 0 (early returns).
1135
1135
  if task_name == "review-pr":
1136
1136
  if not _pr_scope_files:
1137
+ # Distinguish: no_staged_changes (CI, no --since) vs no_diff (empty range)
1138
+ if _pr_scope_source == "no_staged_changes":
1139
+ _no_diff_msg = (
1140
+ "No --since ref provided and no staged changes found. "
1141
+ "Use --since <ref>"
1142
+ )
1143
+ return TaskOutput(
1144
+ task="review-pr", goal=spec.goal,
1145
+ project_summary=None, architecture_summary=None,
1146
+ relevant_files=[], suspected_areas=[],
1147
+ improvement_opportunities=[], test_gaps=[],
1148
+ key_dependencies=[], code_notes_summary=None,
1149
+ limitations=[], confidence="low",
1150
+ error_code="no_diff_source",
1151
+ error_message=_no_diff_msg,
1152
+ gaps=[_no_diff_msg],
1153
+ ci_decision="no_diff_source",
1154
+ scope_source=_pr_scope_source,
1155
+ scope_files=[],
1156
+ repo_root=str(_pr_git_root),
1157
+ )
1137
1158
  _no_diff_hint = "review-pr requires changed files or --since <ref>."
1138
1159
  return TaskOutput(
1139
1160
  task="review-pr", goal=spec.goal,
@@ -1221,6 +1242,76 @@ class TaskContextBuilder:
1221
1242
  symptom=symptom if task_name == "fix-bug" else None,
1222
1243
  )
1223
1244
 
1245
+ # ── Fast-mode fallback: never return empty relevant_files when source files exist ──
1246
+ # When --fast is active on a large repo, all_paths may be restricted to a handful of
1247
+ # changed/noise files that all get filtered out by _rank_files. Inject fallback signals:
1248
+ # 1. detected entry points (already computed, zero I/O cost)
1249
+ # 2. recently committed files (git log -10 --name-only)
1250
+ # 3. files matching symptom keywords in path (when fix-bug + --symptom)
1251
+ if fast and not relevant_files and task_name not in ("delta", "review-pr"):
1252
+ import subprocess as _sp_fb
1253
+ _fb_seen: set[str] = set()
1254
+ _fb_candidates: list[RelevantFile] = []
1255
+
1256
+ # 1. Entry points from detection
1257
+ for _ep in entry_points:
1258
+ _ep_path = _ep.path.replace("\\", "/")
1259
+ if _ep_path not in _fb_seen and (self.root / _ep_path).exists():
1260
+ _fb_candidates.append(RelevantFile(
1261
+ path=_ep_path,
1262
+ role="entrypoint",
1263
+ score=0.5,
1264
+ reason="fast-mode fallback: detected entry point",
1265
+ why="entry_point signal from manifest/annotation detection",
1266
+ ))
1267
+ _fb_seen.add(_ep_path)
1268
+
1269
+ # 2. Recently committed files (git log -10 --name-only)
1270
+ try:
1271
+ _gl_r = _sp_fb.run(
1272
+ ["git", "log", "--name-only", "--pretty=format:", "-10"],
1273
+ capture_output=True, text=True, cwd=str(self.root), timeout=5,
1274
+ )
1275
+ for _gl_f in _gl_r.stdout.splitlines():
1276
+ _gl_f = _gl_f.strip().replace("\\", "/")
1277
+ if (not _gl_f or _gl_f in _fb_seen):
1278
+ continue
1279
+ if Path(_gl_f).suffix.lower() not in _ALL_EXTENSIONS:
1280
+ continue
1281
+ if not (self.root / _gl_f).exists():
1282
+ continue
1283
+ _fb_candidates.append(RelevantFile(
1284
+ path=_gl_f,
1285
+ role="source",
1286
+ score=0.3,
1287
+ reason="fast-mode fallback: recently committed file (git log -10)",
1288
+ why="recent commit history signal",
1289
+ ))
1290
+ _fb_seen.add(_gl_f)
1291
+ except Exception:
1292
+ pass
1293
+
1294
+ # 3. Symptom keyword path matches (fix-bug only)
1295
+ if task_name == "fix-bug" and symptom:
1296
+ import re as _re_fb
1297
+ _fb_kws = [w.lower() for w in _re_fb.split(r"[\s\W]+", symptom) if len(w) > 2]
1298
+ for _fb_p in all_paths:
1299
+ if _fb_p in _fb_seen:
1300
+ continue
1301
+ if Path(_fb_p).suffix.lower() not in _ALL_EXTENSIONS:
1302
+ continue
1303
+ if any(kw in _fb_p.lower() for kw in _fb_kws):
1304
+ _fb_candidates.append(RelevantFile(
1305
+ path=_fb_p,
1306
+ role="source",
1307
+ score=0.2,
1308
+ reason=f"fast-mode fallback: path matches symptom ({symptom!r})",
1309
+ why="symptom keyword in file path",
1310
+ ))
1311
+ _fb_seen.add(_fb_p)
1312
+
1313
+ relevant_files = _fb_candidates[:20]
1314
+
1224
1315
  # ── IC-006: fix-bug suspected_areas — recompute from ranked files + bug notes ──
1225
1316
  # relevant_files is now ranked by RankingEngine (git churn, fan_in, centrality, notes).
1226
1317
  # suspected_areas should reflect that ranking, not raw comment count.
@@ -2569,24 +2660,15 @@ class TaskContextBuilder:
2569
2660
  if DiffSourceType.WORKTREE_STAGED.value not in sources:
2570
2661
  sources.append(DiffSourceType.WORKTREE_STAGED.value)
2571
2662
 
2572
- # ── HEAD~1 fallback working tree clean, surface last commit ────────
2573
- # Without --since: if no unstaged/staged changes exist, fall back to the
2574
- # last committed diff so a clean tree never silently returns no_changes.
2663
+ # ── FIX-P1: no --since + clean working tree no_staged_changes signal ──
2664
+ # Previously: silently fell back to HEAD~1 diff, masking a missing --since.
2665
+ # Now: emit "no_staged_changes" scope so the caller can return no_diff_source
2666
+ # (exit 1) and prompt the user to provide --since.
2667
+ # Rationale: in CI, the tree is always clean; without --since there is no
2668
+ # meaningful diff to review. Local dev should stage changes before review-pr.
2575
2669
  if since is None and not committed_files and not uncommitted_files:
2576
- head_ok = _run("git", "rev-parse", "--verify", "HEAD~1")
2577
- if head_ok is not None: # HEAD~1 exists
2578
- head_committed = _run("git", "diff", "--name-only", "--relative", "HEAD~1..HEAD")
2579
- if head_committed:
2580
- committed_files = head_committed
2581
- sources.append(DiffSourceType.HEAD_MINUS_1.value)
2582
- else:
2583
- # First commit — no HEAD~1; diff against git empty tree
2584
- _GIT_EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
2585
- first_committed = _run("git", "diff", "--name-only", "--relative",
2586
- _GIT_EMPTY_TREE, "HEAD")
2587
- if first_committed:
2588
- committed_files = first_committed
2589
- sources.append("initial_commit")
2670
+ # Return sentinel step 5d converts this to no_diff_source (exit 1).
2671
+ return [], "no_staged_changes", [], []
2590
2672
 
2591
2673
  # ── Drop paths outside self.root ──────────────────────────────────────
2592
2674
  def _drop_outside(lst: list[str]) -> list[str]:
@@ -192,6 +192,15 @@ _SECURITY_MARKER_ANNOTATIONS: frozenset[str] = frozenset({
192
192
  "@PermitAll", "@DenyAll", "@Authenticated",
193
193
  })
194
194
 
195
+ # Annotations on config classes that indicate a centralized security filter chain
196
+ # (Spring Security / Spring Boot). When present, per-endpoint no_security_signal
197
+ # is expected and does NOT mean endpoints are unprotected.
198
+ _FILTER_SECURITY_ANNOTATIONS: frozenset[str] = frozenset({
199
+ "@EnableWebSecurity",
200
+ "@EnableMethodSecurity",
201
+ "@EnableGlobalMethodSecurity",
202
+ })
203
+
195
204
  _MODIFIER_WORDS: frozenset[str] = frozenset({
196
205
  "public", "private", "protected", "static", "final", "abstract",
197
206
  "synchronized", "native", "strictfp", "transient", "volatile", "default",
@@ -1711,6 +1720,7 @@ def _detect_subsystems(all_fqns: list[str], relations: list[RelationEdge]) -> li
1711
1720
  "label": label,
1712
1721
  "package_prefix": pkg_prefix,
1713
1722
  "member_count": len(members),
1723
+ "members": members,
1714
1724
  "summary": summary,
1715
1725
  })
1716
1726
  return result
@@ -2132,17 +2142,47 @@ def _assemble(
2132
2142
  "change_set": change_set_out,
2133
2143
  }
2134
2144
 
2135
- _route_surface = _build_route_surface(sorted_syms, route_diffs, extends_map={
2145
+ _extends_map = {
2136
2146
  e.from_symbol: e.to_symbol.split(".")[-1]
2137
2147
  for e in sorted_rels if e.type == "extends"
2138
- })
2148
+ }
2149
+ _route_surface = _build_route_surface(sorted_syms, route_diffs, extends_map=_extends_map)
2139
2150
  _analysis_gaps = _compute_analysis_gaps(sorted_syms, spring_summary, _route_surface, sorted_rels)
2140
2151
 
2152
+ # Detect filter-based security model for the assembled IR.
2153
+ # Stored here so CIR projections (project_endpoint_surface) can read it without
2154
+ # re-parsing symbols.
2155
+ _class_syms_asm = [s for s in sorted_syms if s.type in ("class", "interface")]
2156
+ _filter_based_asm = (
2157
+ any(
2158
+ ann in _FILTER_SECURITY_ANNOTATIONS
2159
+ for sym in _class_syms_asm
2160
+ for ann in sym.annotations
2161
+ )
2162
+ or any(
2163
+ _extends_map.get(sym.symbol, "") == "WebSecurityConfigurerAdapter"
2164
+ for sym in _class_syms_asm
2165
+ )
2166
+ )
2167
+ _has_ann_sec_asm = any(
2168
+ r.get("security_annotations") for r in _route_surface
2169
+ if isinstance(r, dict)
2170
+ )
2171
+ if _filter_based_asm and _has_ann_sec_asm:
2172
+ _security_model_asm = "mixed"
2173
+ elif _filter_based_asm:
2174
+ _security_model_asm = "filter_based"
2175
+ elif _has_ann_sec_asm:
2176
+ _security_model_asm = "annotation_based"
2177
+ else:
2178
+ _security_model_asm = "unknown"
2179
+
2141
2180
  return {
2142
2181
  **_base,
2143
2182
  "route_surface": _route_surface,
2144
2183
  "spring_events": _spring_events,
2145
2184
  "analysis_gaps": _analysis_gaps,
2185
+ "security_model": _security_model_asm,
2146
2186
  "audit": {
2147
2187
  "dropped_fields": dropped_fields,
2148
2188
  },
@@ -2908,10 +2948,39 @@ def extract_java_endpoints(root: Path) -> "dict[str, Any]":
2908
2948
  # Note: repos may use framework-level security (e.g. Keycloak itself) with no
2909
2949
  # per-endpoint annotations — this count reflects annotation-based coverage only.
2910
2950
  no_security_signal = sum(1 for e in endpoints if "security" not in e)
2951
+
2952
+ # Detect filter-based security: centralized Spring Security config class.
2953
+ # When present, high no_security_signal is expected — security is enforced by
2954
+ # the filter chain, not per-endpoint annotations.
2955
+ _class_syms = [s for s in all_symbols if s.type in ("class", "interface")]
2956
+ _filter_based = (
2957
+ # Config class annotated with EnableWebSecurity / EnableMethodSecurity
2958
+ any(
2959
+ ann in _FILTER_SECURITY_ANNOTATIONS
2960
+ for sym in _class_syms
2961
+ for ann in sym.annotations
2962
+ )
2963
+ # Class extends WebSecurityConfigurerAdapter (pre-Spring 5.7 style)
2964
+ or any(
2965
+ extends_map.get(sym.symbol, "") == "WebSecurityConfigurerAdapter"
2966
+ for sym in _class_syms
2967
+ )
2968
+ )
2969
+ _has_annotation_security = any("security" in e for e in endpoints)
2970
+ if _filter_based and _has_annotation_security:
2971
+ security_model = "mixed"
2972
+ elif _filter_based:
2973
+ security_model = "filter_based"
2974
+ elif _has_annotation_security:
2975
+ security_model = "annotation_based"
2976
+ else:
2977
+ security_model = "unknown"
2978
+
2911
2979
  return {
2912
2980
  "endpoints": endpoints,
2913
2981
  "total": len(endpoints),
2914
2982
  "no_security_signal": no_security_signal,
2983
+ "security_model": security_model,
2915
2984
  # Keep legacy field name for backward compat, now means same as no_security_signal
2916
2985
  "undocumented": no_security_signal,
2917
2986
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.31.26
3
+ Version: 1.31.28
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
  **AI-ready change intelligence for Java/Spring enterprise monoliths.**
227
227
 
228
- ![Version](https://img.shields.io/badge/version-1.31.26-blue)
228
+ ![Version](https://img.shields.io/badge/version-1.31.28-blue)
229
229
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
230
230
 
231
231
  ---
@@ -263,7 +263,7 @@ pipx install sourcecode
263
263
 
264
264
  ```bash
265
265
  sourcecode version
266
- # sourcecode 1.31.26
266
+ # sourcecode 1.31.28
267
267
  ```
268
268
 
269
269
  ---
@@ -1,12 +1,12 @@
1
- sourcecode/__init__.py,sha256=_0ipTmYmgGPKfHgZjMg0xBa-rDMdz89QQ6mQQ0rq9ng,104
1
+ sourcecode/__init__.py,sha256=u-6FWeYcsHBD4kgFtNzOZPQeoIf-YlQrC_JzWDvNiaA,104
2
2
  sourcecode/adaptive_scanner.py,sha256=XffluXKzJUXrMtjEiAOnSNPZnztdIcts17T9ouHeID0,10521
3
3
  sourcecode/architecture_analyzer.py,sha256=Ry3aYT9dc7XuLmWLT5IZ93RkCf_P14Qtew0nGPvUl_8,42184
4
4
  sourcecode/architecture_summary.py,sha256=z34_6v7cSwy98cof2UVciGho7SCrZ93tiqMmq5WNzRQ,20405
5
5
  sourcecode/ast_extractor.py,sha256=_btmeOJIe3t-NicF94D5ZAesa2YIJ0_QNExGnbHxGFE,50578
6
6
  sourcecode/cache.py,sha256=TiYa3ECjBKtvlfCk7GvQ9v6gZkAITpH3ow9PubA7sUo,22946
7
- sourcecode/canonical_ir.py,sha256=NZu0XICv__hkQGKzW2LNQLRqb1L28K2p_WQCQKS5Zlk,23141
7
+ sourcecode/canonical_ir.py,sha256=_HM3AUmKSdna9u4dCoU6rpgSA6HdF8gzOKZykIUCNGY,23277
8
8
  sourcecode/classifier.py,sha256=yWeq6agTjkFa3zuNa-gdVIHtjoBoPoVlJnX-b7tdVJs,7851
9
- sourcecode/cli.py,sha256=illoqX3tEq9E_i2QEP4aUWPwFxb1IYdWwUbOobv4pyw,151737
9
+ sourcecode/cli.py,sha256=YRHo7R58Nf-NYASQNCW39AjsJnOi5mrl5iziaPdMUxk,152204
10
10
  sourcecode/code_notes_analyzer.py,sha256=EJemNCNc9Dn-1RZYu-aNbK0ELzmsyC4s6FdHi3XyNEI,9392
11
11
  sourcecode/confidence_analyzer.py,sha256=_jckZSxksV-OU38vbkxfVNBnWCtlCq8Vwfg23x1uspA,19054
12
12
  sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
@@ -26,13 +26,13 @@ sourcecode/metrics_analyzer.py,sha256=m0ENgtqKeBL17kUIK3fmGkgo7UfXBNHxCMj0H_Y5K7
26
26
  sourcecode/output_budget.py,sha256=43307mJEyUPU3MI-QEQoVxrcAvNyUzdzF_SAPgisBQE,6603
27
27
  sourcecode/path_filters.py,sha256=ROFRQ8eSLBEMiixK9f45-RO7um4VEEcjoD5AA4I427I,3739
28
28
  sourcecode/pr_comment_renderer.py,sha256=smHslxiG14lrytCkq5nFrFu-qTHgA-t-LFYfdrfjz2o,14423
29
- sourcecode/prepare_context.py,sha256=_WZqHLqdRD5YftN7ebm2jXd1c-iJpNE8TzVKjK6LUbE,196037
29
+ sourcecode/prepare_context.py,sha256=RxzyMoxgGmMdwqxMwd9CoEsOJARgKJ6YrZte_FeH68A,200168
30
30
  sourcecode/progress.py,sha256=qn30sWaHOkjTgXsSBmiPkz7Rsbwc5oSlIe6JNEMYp_k,3149
31
31
  sourcecode/ranking_engine.py,sha256=ZAucq_YX2KkWUuAZf4P0lhtQ_38vEFnUhuGtSZd1S0E,12970
32
32
  sourcecode/redactor.py,sha256=xuGcadGEHaPw4qZXlMDvzMCsr4VOkdp3oBQptHyJk8c,2884
33
33
  sourcecode/relevance_scorer.py,sha256=MYF4FFkveAQps9SmTeTlh6ODiBz2F--_hWNeHMLtUHQ,8405
34
34
  sourcecode/repo_classifier.py,sha256=FG1vaWKdWXsWdl-S8hjVMiTqcwgaRXkDyvK4rPcOGtQ,22681
35
- sourcecode/repository_ir.py,sha256=sp6IdcZbFAQjznUthMBu_6Mu5RBxVP72d5Vw0hKnH7o,148437
35
+ sourcecode/repository_ir.py,sha256=gzgveIWxgT77JwUxS2dxEuLp6UbVnrHEkVo4a8x4QfY,151066
36
36
  sourcecode/runtime_classifier.py,sha256=uTAD6BDCiBLUZEDRfqk718kM4RTT_vAbfkcOI2_Xx58,18432
37
37
  sourcecode/scanner.py,sha256=WdOQ78mMzjR1NjmKTlbxdgwinnCTfAhxCVLBEFQiFHU,8899
38
38
  sourcecode/schema.py,sha256=aHNXDf8LGyUC8ZDE_VS9kiskC2-Oswhi_WnpdGy6HDw,24897
@@ -64,7 +64,7 @@ sourcecode/detectors/terraform.py,sha256=cxORPR_zVLOJpHlh4e9JnFpkQsn_UnqMMom5yG6
64
64
  sourcecode/detectors/tooling.py,sha256=8CKbtxwQoABP-WyBRNmdAmHDOvAH57AR1cF4UKuWEdQ,2074
65
65
  sourcecode/mcp/__init__.py,sha256=XU4HfRGbdid8wdUA0x_4f7uKZD1z3mv_XUY_WU_T9Mw,179
66
66
  sourcecode/mcp/runner.py,sha256=7PnFjKYbgxFeDnqVeSntXHxZX7ZtK3-krDkEuVjI24M,1386
67
- sourcecode/mcp/server.py,sha256=8dktvqpjk2dYdnTsE0KHjZFkAR-3AQNcC3n-ITMmwKk,19864
67
+ sourcecode/mcp/server.py,sha256=DVXWcmGiAjNQe3fxJS-AUH03rsA_VFjS6048f8RMkt0,21540
68
68
  sourcecode/mcp/onboarding/__init__.py,sha256=sj2PWqEBmMc4zBNkomg89WtL0M6S7A9yb7_wAuSWNP4,66
69
69
  sourcecode/mcp/onboarding/applier.py,sha256=yfSMT0NKdZsjavtLkC8yQ7OtkfepOl5IXGByqg6bdEY,1894
70
70
  sourcecode/mcp/onboarding/backup.py,sha256=ihqGOR8QTX8HASRSEDyfFyXr5bkXrygPHamv4p9KTmk,1452
@@ -76,8 +76,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
76
76
  sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
77
77
  sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
78
78
  sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
79
- sourcecode-1.31.26.dist-info/METADATA,sha256=SyYqOW4T_PHgFlrJp2dwlPbiET16QlhdlduJB3LAtzU,31103
80
- sourcecode-1.31.26.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
81
- sourcecode-1.31.26.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
82
- sourcecode-1.31.26.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
83
- sourcecode-1.31.26.dist-info/RECORD,,
79
+ sourcecode-1.31.28.dist-info/METADATA,sha256=IopWHYcmGBKmum7GTpRUesF4DHPc1bSC4kVW3-BDYuU,31103
80
+ sourcecode-1.31.28.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
81
+ sourcecode-1.31.28.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
82
+ sourcecode-1.31.28.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
83
+ sourcecode-1.31.28.dist-info/RECORD,,