sourcecode 0.34.0__py3-none-any.whl → 0.36.0__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__ = "0.34.0"
3
+ __version__ = "0.36.0"
@@ -296,11 +296,20 @@ def _ts_exports(root: Any, src: bytes) -> list[ExportRecord]:
296
296
  handled = True
297
297
 
298
298
  if not handled and is_default:
299
- # export default <expression>
299
+ # export default <expression> — preserve local binding name when available
300
300
  for child in node.children:
301
301
  if child.type not in ("export", "default", ";") and not child.type.startswith("comment"):
302
- name_n = _find_child(child, "identifier", "type_identifier")
303
- name = _text(name_n, src) if name_n else "default"
302
+ if child.type in ("identifier", "type_identifier"):
303
+ # export default app → name="app"
304
+ name = _text(child, src)
305
+ elif child.type == "call_expression":
306
+ # export default defineConfig({}) → name="defineConfig"
307
+ fn_n = _find_child(child, "identifier")
308
+ name = _text(fn_n, src) if fn_n else "default"
309
+ else:
310
+ # object/array/other expression — look one level deep
311
+ name_n = _find_child(child, "identifier", "type_identifier")
312
+ name = _text(name_n, src) if name_n else "default"
304
313
  records.append(ExportRecord(name=name, kind="default"))
305
314
  break
306
315
 
@@ -373,7 +382,8 @@ def _ts_types(root: Any, src: bytes) -> list[TypeDefinition]:
373
382
  continue
374
383
  name = _text(name_n, src)
375
384
  fields: list[TypeField] = []
376
- body_n = _find_child(node, "object_type")
385
+ # "interface_body" in tree-sitter-typescript >= 0.21; "object_type" in older builds
386
+ body_n = _find_child(node, "interface_body", "object_type")
377
387
  if body_n:
378
388
  for prop in _walk(body_n):
379
389
  if prop.type in ("property_signature", "method_signature"):
@@ -385,7 +395,7 @@ def _ts_types(root: Any, src: bytes) -> list[TypeDefinition]:
385
395
  required = not any(c.type == "?" for c in prop.children)
386
396
  fields.append(TypeField(name=prop_name, type=type_text, required=required))
387
397
  extends: list[str] = []
388
- heritage_n = _find_child(node, "extends_type_clause", "class_heritage")
398
+ heritage_n = _find_child(node, "extends_type_clause", "extends_clause", "class_heritage")
389
399
  if heritage_n:
390
400
  for ext_n in _walk(heritage_n):
391
401
  if ext_n.type == "type_identifier":
@@ -429,6 +439,25 @@ def _ts_hooks(root: Any, src: bytes) -> list[str]:
429
439
  return sorted(used)
430
440
 
431
441
 
442
+ def _merge_imports(imports: list[ImportRecord]) -> list[ImportRecord]:
443
+ """Merge multiple ImportRecords with the same source into one.
444
+
445
+ Tree-sitter correctly captures `import { A }` and `import type { B }` from
446
+ the same module as two separate statements. Merging them produces a compact,
447
+ predictable contract where each source appears exactly once.
448
+ """
449
+ merged: dict[str, ImportRecord] = {}
450
+ for imp in imports:
451
+ if imp.source in merged:
452
+ existing = merged[imp.source]
453
+ combined_symbols = sorted(set(existing.symbols) | set(imp.symbols))
454
+ kind = existing.kind if existing.kind != "side_effect" else imp.kind
455
+ merged[imp.source] = ImportRecord(source=imp.source, symbols=combined_symbols, kind=kind)
456
+ else:
457
+ merged[imp.source] = imp
458
+ return list(merged.values())
459
+
460
+
432
461
  def _extract_ts_js_tree_sitter(path: str, source: str, lang_obj: Any, language: str) -> FileContract:
433
462
  try:
434
463
  parser = _get_parser(lang_obj)
@@ -436,7 +465,7 @@ def _extract_ts_js_tree_sitter(path: str, source: str, lang_obj: Any, language:
436
465
  tree = parser.parse(src_bytes)
437
466
  root = tree.root_node
438
467
 
439
- imports = _ts_imports(root, src_bytes)
468
+ imports = _merge_imports(_ts_imports(root, src_bytes))
440
469
  exports = _ts_exports(root, src_bytes)
441
470
  exported_names = {e.name for e in exports}
442
471
  functions = _ts_functions(root, src_bytes, exported_names)
@@ -672,7 +701,7 @@ def _heuristic_ts_types(source: str) -> list[TypeDefinition]:
672
701
  return types
673
702
 
674
703
 
675
- def _extract_ts_js_heuristic(path: str, source: str, language: str) -> FileContract:
704
+ def _extract_ts_js_heuristic(path: str, source: str, language: str, *, ts_installed: bool = False) -> FileContract:
676
705
  imports = _heuristic_ts_imports(source)
677
706
  exports = _heuristic_ts_exports(source)
678
707
  exported_names = {e.name for e in exports}
@@ -691,6 +720,12 @@ def _extract_ts_js_heuristic(path: str, source: str, language: str) -> FileContr
691
720
  if not imp.source.startswith(".") and not imp.source.startswith("/")
692
721
  })
693
722
 
723
+ # Distinguish "tree-sitter absent" from "language parser not loaded"
724
+ if ts_installed:
725
+ lim = f"ts_lang_missing: tree-sitter parser for {language!r} not loaded; install sourcecode[ast]"
726
+ else:
727
+ lim = "tree_sitter_unavailable: install sourcecode[ast] for full TS/JS extraction"
728
+
694
729
  return FileContract(
695
730
  path=path,
696
731
  language=language,
@@ -701,7 +736,7 @@ def _extract_ts_js_heuristic(path: str, source: str, language: str) -> FileContr
701
736
  hooks_used=hooks_used,
702
737
  dependencies=deps,
703
738
  extraction_method="heuristic",
704
- limitations=["tree_sitter_unavailable: install sourcecode[ast] for full TS/JS extraction"],
739
+ limitations=[lim],
705
740
  )
706
741
 
707
742
 
@@ -1019,7 +1054,7 @@ class AstExtractor:
1019
1054
  if lang_obj is not None:
1020
1055
  contract = _extract_ts_js_tree_sitter(rel_path, source, lang_obj, language)
1021
1056
  else:
1022
- contract = _extract_ts_js_heuristic(rel_path, source, language)
1057
+ contract = _extract_ts_js_heuristic(rel_path, source, language, ts_installed=True)
1023
1058
  else:
1024
1059
  contract = _extract_ts_js_heuristic(rel_path, source, language)
1025
1060
 
@@ -8,6 +8,8 @@ Produces a list of FileContracts ranked by semantic importance,
8
8
  with fan-in/fan-out computed from the import graph.
9
9
  """
10
10
 
11
+ import os
12
+ import re
11
13
  import subprocess
12
14
  from collections import Counter
13
15
  from pathlib import Path
@@ -25,6 +27,23 @@ from sourcecode.schema import EntryPoint, MonorepoPackageInfo
25
27
  _MAX_FILES = 500 # hard cap on files extracted per run
26
28
  _SRC_EXTENSIONS: frozenset[str] = frozenset(_LANGUAGE_MAP.keys())
27
29
 
30
+ # Role-based score adjustments applied after contract extraction.
31
+ # Runtime roles get a boost; config/util are neutral or penalized.
32
+ _ROLE_SCORE: dict[str, float] = {
33
+ "entrypoint": 0.15,
34
+ "service": 0.10,
35
+ "route": 0.10,
36
+ "api": 0.08,
37
+ "middleware": 0.06,
38
+ "store": 0.05,
39
+ "model": 0.05,
40
+ "hook": 0.05,
41
+ "component": 0.03,
42
+ "util": 0.00,
43
+ "config": -0.10,
44
+ "unknown": 0.00,
45
+ }
46
+
28
47
  RankStrategy = Literal["relevance", "centrality", "git-churn"]
29
48
 
30
49
 
@@ -206,9 +225,9 @@ class ContractPipeline:
206
225
  if changed_only:
207
226
  src_paths = [p for p in src_paths if p in changed_files]
208
227
 
209
- # Apply max_files cap
210
- if len(src_paths) > self.max_files:
211
- # Pre-rank by static relevance to pick best candidates
228
+ # Apply max_files cap — bypass when symbol search to ensure defining files are found.
229
+ # A symbol query over a large repo needs all files; result set is small after filtering.
230
+ if symbol is None and len(src_paths) > self.max_files:
212
231
  src_paths = sorted(
213
232
  src_paths,
214
233
  key=lambda p: (p in entry_paths, scorer.score(p)),
@@ -255,23 +274,19 @@ class ContractPipeline:
255
274
  # 7. Rank
256
275
  contracts = self._rank(contracts, rank_by)
257
276
 
258
- # 8. Symbol filter — keep files that export or use the symbol
277
+ # 8. Symbol filter — keep files that define or import the symbol
259
278
  if symbol:
260
- symbol_contracts = [
261
- c for c in contracts
262
- if any(e.name == symbol for e in c.exports)
263
- or any(f.name == symbol for f in c.functions)
264
- or symbol in {t.name for t in c.types}
265
- ]
266
- # Also pull in direct importers (fan_in sourcing)
267
- importer_paths = {
268
- c.path for c in contracts
269
- for imp in c.imports
270
- if symbol in imp.symbols
271
- }
272
- importer_contracts = [c for c in contracts if c.path in importer_paths]
273
- symbol_contracts = list({c.path: c for c in symbol_contracts + importer_contracts}.values())
274
- contracts = sorted(symbol_contracts, key=lambda c: -c.relevance_score)
279
+ contracts = _filter_by_symbol(contracts, symbol)
280
+ # When shallow scan missed the defining file (deep monorepo), fall back
281
+ # to a grep-based filesystem search over the full directory tree.
282
+ if not contracts:
283
+ contracts = self._symbol_deep_scan(
284
+ root, symbol,
285
+ known_paths=set(src_paths),
286
+ entry_paths=entry_paths,
287
+ changed_files=changed_files,
288
+ scorer=scorer,
289
+ )
275
290
 
276
291
  # 9. Entrypoints-only filter
277
292
  if entrypoints_only and not symbol:
@@ -323,6 +338,9 @@ class ContractPipeline:
323
338
  churn_score = min(churn.get(c.path, 0) / 20.0, 0.1)
324
339
  base += churn_score
325
340
 
341
+ # Role-based boost: runtime roles score higher than auxiliary
342
+ base += _ROLE_SCORE.get(c.role, 0.0)
343
+
326
344
  return min(1.0, base)
327
345
 
328
346
  def _rank(self, contracts: list[FileContract], rank_by: RankStrategy) -> list[FileContract]:
@@ -334,6 +352,38 @@ class ContractPipeline:
334
352
  # Default: relevance
335
353
  return sorted(contracts, key=lambda c: (-c.is_entrypoint, -c.relevance_score))
336
354
 
355
+ def _symbol_deep_scan(
356
+ self,
357
+ root: Path,
358
+ symbol: str,
359
+ known_paths: set[str],
360
+ entry_paths: set[str],
361
+ changed_files: set[str],
362
+ scorer: RelevanceScorer,
363
+ ) -> list[FileContract]:
364
+ """Grep-based fallback when the shallow scan missed the defining files.
365
+
366
+ Searches the full directory tree for source files containing *symbol*,
367
+ extracts contracts for candidates not already processed, then re-applies
368
+ the symbol filter. Fan-in/fan-out are not computed for these contracts.
369
+ """
370
+ candidates = _find_symbol_files(root, symbol, known_paths, scorer)
371
+ if not candidates:
372
+ return []
373
+
374
+ extra: list[FileContract] = []
375
+ for rel_path in candidates[:300]: # cap to prevent excessive extraction
376
+ abs_path = root / rel_path
377
+ contract = self._extractor.extract(abs_path, root)
378
+ if contract is None:
379
+ continue
380
+ contract.is_entrypoint = rel_path in entry_paths
381
+ contract.is_changed = rel_path in changed_files
382
+ contract.relevance_score = scorer.score(rel_path)
383
+ extra.append(contract)
384
+
385
+ return _filter_by_symbol(extra, symbol)
386
+
337
387
 
338
388
  # ---------------------------------------------------------------------------
339
389
  # Helpers
@@ -348,7 +398,6 @@ def _compress_contract_types(c: FileContract) -> None:
348
398
  (r"React\.ReactNode", "ReactNode"),
349
399
  (r"React\.ReactElement", "ReactElement"),
350
400
  ]
351
- import re
352
401
  for fn in c.functions:
353
402
  for pattern, repl in _replacements:
354
403
  fn.signature = re.sub(pattern, repl, fn.signature)
@@ -385,6 +434,162 @@ def _limit_symbols(contracts: list[FileContract], max_symbols: int) -> list[File
385
434
  return result
386
435
 
387
436
 
437
+ # ---------------------------------------------------------------------------
438
+ # Symbol-aware filter
439
+ # ---------------------------------------------------------------------------
440
+
441
+ def _filter_by_symbol(contracts: list[FileContract], symbol: str) -> list[FileContract]:
442
+ """Return contracts that define, import, or structurally reference *symbol*.
443
+
444
+ Four tiers applied in order:
445
+ 1. Exact name match — export/function/type names.
446
+ 2. Case-insensitive name match when tier 1 yields nothing.
447
+ 3. Import symbol match — name appears in import symbol list.
448
+ 4. Type-reference match — symbol in extends clauses, field types, or
449
+ function signatures (word-boundary). Only used when tiers 1-3 fail.
450
+
451
+ Defining contracts are ranked first; importers and references follow.
452
+ """
453
+ sym_l = symbol.lower()
454
+ word_re = re.compile(
455
+ r"(?<![A-Za-z0-9_])" + re.escape(symbol) + r"(?![A-Za-z0-9_])",
456
+ re.IGNORECASE,
457
+ )
458
+
459
+ def _defines(c: FileContract, case: bool) -> bool:
460
+ cmp = (lambda a, b: a.lower() == b.lower()) if case else (lambda a, b: a == b)
461
+ return (
462
+ any(cmp(e.name, symbol) for e in c.exports)
463
+ or any(cmp(f.name, symbol) for f in c.functions)
464
+ or any(cmp(t.name, symbol) for t in c.types)
465
+ )
466
+
467
+ def _imports_sym(c: FileContract, case: bool) -> bool:
468
+ if case:
469
+ return any(sym_l == s.lower() for imp in c.imports for s in imp.symbols)
470
+ return any(symbol in imp.symbols for imp in c.imports)
471
+
472
+ def _references_type(c: FileContract) -> bool:
473
+ """Tier 4: symbol appears in extends clauses, field types, or signatures."""
474
+ for t in c.types:
475
+ if any(sym_l in ext.lower() for ext in t.extends):
476
+ return True
477
+ for field in t.fields:
478
+ if sym_l in field.type.lower():
479
+ return True
480
+ for f in c.functions:
481
+ if word_re.search(f.signature):
482
+ return True
483
+ return False
484
+
485
+ # Tier 1: exact name match
486
+ defining = [c for c in contracts if _defines(c, case=False)]
487
+ # Tier 2: case-insensitive name match
488
+ if not defining:
489
+ defining = [c for c in contracts if _defines(c, case=True)]
490
+
491
+ defining_paths = {c.path for c in defining}
492
+
493
+ # Tier 3: import matching (case-insensitive when no definers found)
494
+ ci_imports = len(defining) == 0
495
+ importer_paths = {c.path for c in contracts if _imports_sym(c, case=ci_imports)}
496
+ importers = [c for c in contracts if c.path in importer_paths and c.path not in defining_paths]
497
+
498
+ # Tier 4: type-reference matching (only when tiers 1-3 yield nothing)
499
+ references: list[FileContract] = []
500
+ if not defining and not importers:
501
+ ref_paths = {c.path for c in contracts if _references_type(c)}
502
+ references = [c for c in contracts if c.path in ref_paths]
503
+
504
+ # Merge in priority order: defining > importers > type-references
505
+ seen: set[str] = set()
506
+ merged: list[FileContract] = []
507
+ for c in defining + importers + references:
508
+ if c.path not in seen:
509
+ seen.add(c.path)
510
+ merged.append(c)
511
+
512
+ return sorted(merged, key=lambda c: (
513
+ c.path not in defining_paths,
514
+ c.path not in importer_paths,
515
+ -c.relevance_score,
516
+ ))
517
+
518
+
519
+ # ---------------------------------------------------------------------------
520
+ # Deep symbol scan — grep-based fallback for shallow-scanned repos
521
+ # ---------------------------------------------------------------------------
522
+
523
+ _DEEP_SCAN_NOISE_DIRS: frozenset[str] = frozenset({
524
+ "node_modules", ".git", "dist", "build", "__pycache__",
525
+ ".venv", "venv", "target", ".next", ".nuxt", ".turbo", "coverage",
526
+ ".nyc_output", ".mypy_cache", ".pytest_cache",
527
+ })
528
+
529
+
530
+ def _find_symbol_files(
531
+ root: Path,
532
+ symbol: str,
533
+ known_paths: set[str],
534
+ scorer: RelevanceScorer,
535
+ ) -> list[str]:
536
+ """Find source files outside *known_paths* that contain *symbol* as text.
537
+
538
+ Uses subprocess grep when available (fast); falls back to os.walk + read.
539
+ Returns repo-relative paths, noise-filtered.
540
+ """
541
+ found: list[str] = []
542
+
543
+ # Try grep (fast, available on Linux/Mac)
544
+ try:
545
+ result = subprocess.run(
546
+ [
547
+ "grep", "-rl",
548
+ "--include=*.ts", "--include=*.tsx",
549
+ "--include=*.js", "--include=*.jsx",
550
+ "--include=*.py",
551
+ symbol, ".",
552
+ ],
553
+ cwd=str(root),
554
+ capture_output=True,
555
+ text=True,
556
+ timeout=20,
557
+ )
558
+ for line in result.stdout.splitlines():
559
+ line = line.strip()
560
+ if line.startswith("./"):
561
+ line = line[2:]
562
+ line = line.replace("\\", "/")
563
+ if line and line not in known_paths and not scorer.is_noise(line):
564
+ found.append(line)
565
+ return found
566
+ except Exception:
567
+ pass
568
+
569
+ # Python fallback — os.walk + text search
570
+ for dirpath, dirnames, filenames in os.walk(str(root)):
571
+ dirnames[:] = sorted(d for d in dirnames if d not in _DEEP_SCAN_NOISE_DIRS)
572
+ for fname in filenames:
573
+ if Path(fname).suffix.lower() not in _SRC_EXTENSIONS:
574
+ continue
575
+ full = os.path.join(dirpath, fname)
576
+ try:
577
+ rel = Path(full).relative_to(root)
578
+ rel_str = str(rel).replace("\\", "/")
579
+ except ValueError:
580
+ continue
581
+ if rel_str in known_paths or scorer.is_noise(rel_str):
582
+ continue
583
+ try:
584
+ content = Path(full).read_text(encoding="utf-8", errors="replace")
585
+ if symbol in content:
586
+ found.append(rel_str)
587
+ except OSError:
588
+ pass
589
+
590
+ return found
591
+
592
+
388
593
  # ---------------------------------------------------------------------------
389
594
  # Dependency graph emission
390
595
  # ---------------------------------------------------------------------------
@@ -104,6 +104,18 @@ _LOW_RUNTIME_STEMS: frozenset[str] = frozenset({
104
104
  "gruntfile", "gulpfile", "webpack.config", "vite.config",
105
105
  "rollup.config", "babel.config", "jest.config", "vitest.config",
106
106
  "tsconfig", "jsconfig", ".eslintrc", ".prettierrc", ".editorconfig",
107
+ # doc-site tooling
108
+ "rspress", "rspress.config", "docusaurus.config", "docusaurus",
109
+ "vuepress.config", "vuepress", "nextra.config",
110
+ "astro.config", "gatsby.config", "gatsby-config",
111
+ # build/workspace orchestration
112
+ "turbo", "turbo.config", "nx", "nx.config", "lerna",
113
+ "esbuild.config", "swc.config", "postcss.config",
114
+ "tailwind.config", "tailwind",
115
+ # storybook
116
+ "main.storybook", "preview.storybook",
117
+ # playwright / cypress / e2e
118
+ "playwright.config", "cypress.config",
107
119
  })
108
120
 
109
121
  _HIGH_VALUE_SUFFIXES: frozenset[str] = frozenset({
@@ -169,15 +181,16 @@ class RelevanceScorer:
169
181
  if (any(m in f"/{norm}/" for m in _TEST_DIR_MARKERS)
170
182
  or any(fname.startswith(p.strip(".")) or p in fname
171
183
  for p in _TEST_FILE_PATTERNS)):
172
- base -= 0.25
184
+ base -= 0.30
173
185
 
174
- # Config/tooling filename penalty
186
+ # Config/tooling filename penalty — stronger than before
175
187
  if stem.lower() in _LOW_RUNTIME_STEMS:
176
- base -= 0.2
188
+ base -= 0.30
177
189
 
178
- # Auxiliary dir penalty
190
+ # Auxiliary dir penalty (docs, examples, demos, fixtures, scripts…)
191
+ # Aggressive: these almost never belong in top-ranked agent context
179
192
  if self._is_auxiliary(norm):
180
- base -= 0.2
193
+ base -= 0.40
181
194
 
182
195
  return max(0.0, min(1.0, base))
183
196
 
sourcecode/serializer.py CHANGED
@@ -964,7 +964,9 @@ def _contract_view_minimal(
964
964
  # Compact summary
965
965
  if sm.contract_summary is not None:
966
966
  cs = sm.contract_summary
967
- degraded = bool(cs.method_breakdown.get("heuristic", 0))
967
+ # degraded only when tree-sitter is actually unavailable — not when individual
968
+ # files fall back due to parse errors or size limits.
969
+ degraded = any("tree_sitter_unavailable" in lim for lim in cs.limitations)
968
970
  summary: dict[str, Any] = {
969
971
  "files": cs.extracted_files,
970
972
  "total": cs.total_files,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 0.34.0
3
+ Version: 0.36.0
4
4
  Summary: Deterministic codebase context for AI coding agents
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -1,14 +1,14 @@
1
- sourcecode/__init__.py,sha256=fYdoUeHpMCvt6KgjSCq7EwaVElY_1iqG4Ugp2NKdgxU,103
1
+ sourcecode/__init__.py,sha256=X_JznUsRmn3yELdS1V1zFgnDITiz-h3a451D5eLoTnY,103
2
2
  sourcecode/architecture_analyzer.py,sha256=H6noGgVArUJ25z1qC0fFA0KvJJeHZYyhKvKSkOyWHUk,23096
3
3
  sourcecode/architecture_summary.py,sha256=rSY5MRiaz4N1YdG0pqDTDuFjSN7PO_Zplx-dtNzv2Yo,19985
4
- sourcecode/ast_extractor.py,sha256=qiYWdXXdKpTVqTt2fRIHrkZJUTnpHPvPJKYchV_dnWE,39219
4
+ sourcecode/ast_extractor.py,sha256=0OHQwTUBBc9lmqPLryVeB1z8dGIC6NhLlar800CD9oI,41129
5
5
  sourcecode/classifier.py,sha256=GKTMN8qKZX7ponSwDJfN08RrasI4CVpq1_gFBgEopps,7093
6
6
  sourcecode/cli.py,sha256=O1ObfcxvhMYMXjd6otx6G0fE9ethIAX4qDUpUUjOxgY,63167
7
7
  sourcecode/code_notes_analyzer.py,sha256=rRd8bFYV0krjlxxQV0wenwE9K7pVpUQSR7KvSvUQKw4,9226
8
8
  sourcecode/confidence_analyzer.py,sha256=HxJMPLI5ulqtkncnv98W4iVO6yMbpQo87VuxiuNbDmY,12167
9
9
  sourcecode/context_summarizer.py,sha256=CiQrfBEzun949bWvmLabWoj2HhPn6Lw62ofqnsy0FlQ,6503
10
10
  sourcecode/contract_model.py,sha256=vr-9WHf0EBlbnuZGtTpUvSnbbjCBsm0q0tpLyxBJ-xI,3287
11
- sourcecode/contract_pipeline.py,sha256=3L3-JoSNtTy3s9rkhjwLnYpdVQeWr3SuEm0Bu3ren3M,15648
11
+ sourcecode/contract_pipeline.py,sha256=Pu9SjgkngLgWoFaNj2ftKsk4lPngophW4840h0FvuEw,23187
12
12
  sourcecode/coverage_parser.py,sha256=q0LeZJaX1bnntLu-ImksdBsMlpsVmk_iUfSaB4eaJGo,19702
13
13
  sourcecode/dependency_analyzer.py,sha256=Exq0BfInvfS5iAg9xAr6WI2uPNuotkIudTKcYJcRhB8,52757
14
14
  sourcecode/doc_analyzer.py,sha256=Ec3orx6vBKsh5cNM3-F4y2Got2KuKx8w3dErwtdtM-A,19891
@@ -20,12 +20,12 @@ sourcecode/graph_analyzer.py,sha256=hMOsLLz9B0UnQ4xwbHdgr3bFvqpw0bQ8kN-xmEn3Krk,
20
20
  sourcecode/metrics_analyzer.py,sha256=4uh11v-Q0gdrN87BOxuFWUym3N3AOkOuy21K5N8peB8,20126
21
21
  sourcecode/prepare_context.py,sha256=vxEzr8czS3MFbdTx4hBJQlJLrl9cuvbHdL3ZokxFkvo,31384
22
22
  sourcecode/redactor.py,sha256=xuGcadGEHaPw4qZXlMDvzMCsr4VOkdp3oBQptHyJk8c,2884
23
- sourcecode/relevance_scorer.py,sha256=w-vOYcTWB-c2OAi8F5-y16ZB1QMPPtvxUNJnMrzGKCo,7470
23
+ sourcecode/relevance_scorer.py,sha256=ea7_7AHVgahVEWK3ebKOpG67agzG_pGICu5f2KgzrIA,8133
24
24
  sourcecode/runtime_classifier.py,sha256=zWX3r3HCKHc-qtIobErOa8aKMmaoPYREtJKvPcBGPjQ,14792
25
25
  sourcecode/scanner.py,sha256=aM3h9-DCQ3xKpeHpHYdo2vX6T5P95HA_YwZbkAVNwmo,8288
26
26
  sourcecode/schema.py,sha256=AShu_bcP30TYaw4Dl1nYy8aFnBCKxrUli3LhU3MZTjs,20739
27
27
  sourcecode/semantic_analyzer.py,sha256=asQfJf-EhzYaOTA-iMuZsrVXtbW7SV2WEKCxgsxa88Y,79413
28
- sourcecode/serializer.py,sha256=en11Au-YhpO1hYPugbCCPNvHkqBiTSRuGVoiLxDAKeQ,49888
28
+ sourcecode/serializer.py,sha256=8ONhYuJ25AjMfZImwveYjVSHjIFDCuBRjCKNjs94bEA,50057
29
29
  sourcecode/summarizer.py,sha256=ZuzIdm3t8A-d5MuQL0TSNLrd-L0IQIuguIxeNXMNJf8,16070
30
30
  sourcecode/tree_utils.py,sha256=Fj9OIuUksBvgibNd3feog0sMDjVypJzPexp5lvMoYWI,1424
31
31
  sourcecode/workspace.py,sha256=fQlVoNx8S-fSHpKoJ0JBvEHCFkxszH0KZVJed1i3TRk,6845
@@ -56,8 +56,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
56
56
  sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
57
57
  sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
58
58
  sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
59
- sourcecode-0.34.0.dist-info/METADATA,sha256=Xg-K2zPoLVH0BfwsjhgqyFyVamkBsPfp6o8mxZdl-HY,25209
60
- sourcecode-0.34.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
61
- sourcecode-0.34.0.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
62
- sourcecode-0.34.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
63
- sourcecode-0.34.0.dist-info/RECORD,,
59
+ sourcecode-0.36.0.dist-info/METADATA,sha256=vQc2-46U5UyDGNaaVWbr5Jb7_eBOgJAYIPpYAD_aiwA,25209
60
+ sourcecode-0.36.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
61
+ sourcecode-0.36.0.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
62
+ sourcecode-0.36.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
63
+ sourcecode-0.36.0.dist-info/RECORD,,