sourcecode 0.42.0__py3-none-any.whl → 0.43.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 +1 -1
- sourcecode/cli.py +28 -0
- sourcecode/contract_model.py +1 -0
- sourcecode/contract_pipeline.py +40 -8
- sourcecode/serializer.py +29 -4
- {sourcecode-0.42.0.dist-info → sourcecode-0.43.0.dist-info}/METADATA +1 -1
- {sourcecode-0.42.0.dist-info → sourcecode-0.43.0.dist-info}/RECORD +10 -10
- {sourcecode-0.42.0.dist-info → sourcecode-0.43.0.dist-info}/WHEEL +0 -0
- {sourcecode-0.42.0.dist-info → sourcecode-0.43.0.dist-info}/entry_points.txt +0 -0
- {sourcecode-0.42.0.dist-info → sourcecode-0.43.0.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/cli.py
CHANGED
|
@@ -181,6 +181,7 @@ _OPTIONS_WITH_VALUE: frozenset[str] = frozenset({
|
|
|
181
181
|
"--dependency-depth",
|
|
182
182
|
"--rank-by",
|
|
183
183
|
"--symbol",
|
|
184
|
+
"--max-importers",
|
|
184
185
|
})
|
|
185
186
|
|
|
186
187
|
|
|
@@ -594,6 +595,17 @@ def main(
|
|
|
594
595
|
"--symbol",
|
|
595
596
|
help="Contract mode: extract localized context for a specific symbol name. Returns defining file + all importers.",
|
|
596
597
|
),
|
|
598
|
+
max_importers: int = typer.Option(
|
|
599
|
+
50,
|
|
600
|
+
"--max-importers",
|
|
601
|
+
help=(
|
|
602
|
+
"Maximum importer files returned by --symbol (default: 50). "
|
|
603
|
+
"Popular symbols can have hundreds of importers — this prevents output explosion. "
|
|
604
|
+
"Defining files are never truncated. Override: --symbol Foo --max-importers 200."
|
|
605
|
+
),
|
|
606
|
+
min=1,
|
|
607
|
+
max=10000,
|
|
608
|
+
),
|
|
597
609
|
copy: bool = typer.Option(
|
|
598
610
|
False,
|
|
599
611
|
"--copy",
|
|
@@ -770,6 +782,21 @@ def main(
|
|
|
770
782
|
code_notes = True
|
|
771
783
|
no_tree = True # agents never need the raw file tree
|
|
772
784
|
typer.echo("[agent] dependencies env-map code-notes (no-tree)", err=True)
|
|
785
|
+
# Warn about flags that are computed but excluded from agent_view output
|
|
786
|
+
_agent_suppressed: list[str] = []
|
|
787
|
+
if full_metrics:
|
|
788
|
+
_agent_suppressed.append("--full-metrics")
|
|
789
|
+
if graph_modules:
|
|
790
|
+
_agent_suppressed.append("--graph-modules")
|
|
791
|
+
if docs:
|
|
792
|
+
_agent_suppressed.append("--docs")
|
|
793
|
+
if _agent_suppressed:
|
|
794
|
+
typer.echo(
|
|
795
|
+
f"[agent] warning: {', '.join(_agent_suppressed)} computed but excluded "
|
|
796
|
+
"from --agent output — agent_view does not include these sections. "
|
|
797
|
+
"Remove these flags to skip unnecessary computation.",
|
|
798
|
+
err=True,
|
|
799
|
+
)
|
|
773
800
|
|
|
774
801
|
scanner = AdaptiveScanner(target, topology=_topology, base_depth=effective_depth)
|
|
775
802
|
raw_tree = scanner.scan_tree()
|
|
@@ -1343,6 +1370,7 @@ def main(
|
|
|
1343
1370
|
changed_only=changed_only,
|
|
1344
1371
|
symbol=symbol,
|
|
1345
1372
|
compress_types=compress_types,
|
|
1373
|
+
max_importers=max_importers,
|
|
1346
1374
|
)
|
|
1347
1375
|
sm = _replace(sm, file_contracts=_contracts, contract_summary=_contract_summary)
|
|
1348
1376
|
if symbol is not None and len(_contracts) == 0:
|
sourcecode/contract_model.py
CHANGED
sourcecode/contract_pipeline.py
CHANGED
|
@@ -175,6 +175,7 @@ class ContractPipeline:
|
|
|
175
175
|
changed_only: bool = False,
|
|
176
176
|
symbol: Optional[str] = None,
|
|
177
177
|
compress_types: bool = False,
|
|
178
|
+
max_importers: int = 50,
|
|
178
179
|
) -> tuple[list[FileContract], ContractSummary]:
|
|
179
180
|
"""Run the full extraction pipeline.
|
|
180
181
|
|
|
@@ -279,17 +280,19 @@ class ContractPipeline:
|
|
|
279
280
|
contracts = self._rank(contracts, rank_by)
|
|
280
281
|
|
|
281
282
|
# 8. Symbol filter — keep files that define or import the symbol
|
|
283
|
+
_symbol_truncation: Optional[dict] = None
|
|
282
284
|
if symbol:
|
|
283
|
-
contracts = _filter_by_symbol(contracts, symbol)
|
|
285
|
+
contracts, _symbol_truncation = _filter_by_symbol(contracts, symbol, max_importers=max_importers)
|
|
284
286
|
# When shallow scan missed the defining file (deep monorepo), fall back
|
|
285
287
|
# to a grep-based filesystem search over the full directory tree.
|
|
286
288
|
if not contracts:
|
|
287
|
-
contracts = self._symbol_deep_scan(
|
|
289
|
+
contracts, _symbol_truncation = self._symbol_deep_scan(
|
|
288
290
|
root, symbol,
|
|
289
291
|
known_paths=set(src_paths),
|
|
290
292
|
entry_paths=entry_paths,
|
|
291
293
|
changed_files=changed_files,
|
|
292
294
|
engine=engine,
|
|
295
|
+
max_importers=max_importers,
|
|
293
296
|
)
|
|
294
297
|
|
|
295
298
|
# 9. Entrypoints-only filter
|
|
@@ -313,6 +316,7 @@ class ContractPipeline:
|
|
|
313
316
|
method_breakdown=dict(method_counts),
|
|
314
317
|
ranked_by=rank_by,
|
|
315
318
|
limitations=limitations,
|
|
319
|
+
symbol_truncation=_symbol_truncation,
|
|
316
320
|
)
|
|
317
321
|
return contracts, summary
|
|
318
322
|
|
|
@@ -332,7 +336,8 @@ class ContractPipeline:
|
|
|
332
336
|
entry_paths: set[str],
|
|
333
337
|
changed_files: set[str],
|
|
334
338
|
engine: RankingEngine,
|
|
335
|
-
|
|
339
|
+
max_importers: int = 50,
|
|
340
|
+
) -> tuple[list[FileContract], dict]:
|
|
336
341
|
"""Grep-based fallback when the shallow scan missed the defining files.
|
|
337
342
|
|
|
338
343
|
Searches the full directory tree for source files containing *symbol*,
|
|
@@ -356,7 +361,7 @@ class ContractPipeline:
|
|
|
356
361
|
contract.ranking_reasons = fs.reasons
|
|
357
362
|
extra.append(contract)
|
|
358
363
|
|
|
359
|
-
return _filter_by_symbol(extra, symbol)
|
|
364
|
+
return _filter_by_symbol(extra, symbol, max_importers=max_importers)
|
|
360
365
|
|
|
361
366
|
|
|
362
367
|
# ---------------------------------------------------------------------------
|
|
@@ -412,7 +417,11 @@ def _limit_symbols(contracts: list[FileContract], max_symbols: int) -> list[File
|
|
|
412
417
|
# Symbol-aware filter
|
|
413
418
|
# ---------------------------------------------------------------------------
|
|
414
419
|
|
|
415
|
-
def _filter_by_symbol(
|
|
420
|
+
def _filter_by_symbol(
|
|
421
|
+
contracts: list[FileContract],
|
|
422
|
+
symbol: str,
|
|
423
|
+
max_importers: int = 50,
|
|
424
|
+
) -> tuple[list[FileContract], dict]:
|
|
416
425
|
"""Return contracts that define, import, or structurally reference *symbol*.
|
|
417
426
|
|
|
418
427
|
Four tiers applied in order:
|
|
@@ -423,6 +432,8 @@ def _filter_by_symbol(contracts: list[FileContract], symbol: str) -> list[FileCo
|
|
|
423
432
|
function signatures (word-boundary). Only used when tiers 1-3 fail.
|
|
424
433
|
|
|
425
434
|
Defining contracts are ranked first; importers and references follow.
|
|
435
|
+
max_importers caps tier 3 results to prevent output explosion on popular symbols.
|
|
436
|
+
Returns (contracts, truncation_metadata).
|
|
426
437
|
"""
|
|
427
438
|
sym_l = symbol.lower()
|
|
428
439
|
word_re = re.compile(
|
|
@@ -466,8 +477,14 @@ def _filter_by_symbol(contracts: list[FileContract], symbol: str) -> list[FileCo
|
|
|
466
477
|
|
|
467
478
|
# Tier 3: import matching (case-insensitive when no definers found)
|
|
468
479
|
ci_imports = len(defining) == 0
|
|
469
|
-
|
|
470
|
-
|
|
480
|
+
all_importer_paths = {c.path for c in contracts if _imports_sym(c, case=ci_imports)}
|
|
481
|
+
all_importers = [c for c in contracts if c.path in all_importer_paths and c.path not in defining_paths]
|
|
482
|
+
|
|
483
|
+
# Apply importer cap — definers are never truncated
|
|
484
|
+
total_importers = len(all_importers)
|
|
485
|
+
truncated = total_importers > max_importers
|
|
486
|
+
importers = all_importers[:max_importers] if truncated else all_importers
|
|
487
|
+
importer_paths = {c.path for c in importers}
|
|
471
488
|
|
|
472
489
|
# Tier 4: type-reference matching (only when tiers 1-3 yield nothing)
|
|
473
490
|
references: list[FileContract] = []
|
|
@@ -483,12 +500,27 @@ def _filter_by_symbol(contracts: list[FileContract], symbol: str) -> list[FileCo
|
|
|
483
500
|
seen.add(c.path)
|
|
484
501
|
merged.append(c)
|
|
485
502
|
|
|
486
|
-
|
|
503
|
+
result = sorted(merged, key=lambda c: (
|
|
487
504
|
c.path not in defining_paths,
|
|
488
505
|
c.path not in importer_paths,
|
|
489
506
|
-c.relevance_score,
|
|
490
507
|
))
|
|
491
508
|
|
|
509
|
+
truncation: dict = {
|
|
510
|
+
"symbol": symbol,
|
|
511
|
+
"definers_found": len(defining),
|
|
512
|
+
"importers_found": total_importers,
|
|
513
|
+
"importers_returned": len(importers),
|
|
514
|
+
"references_found": len(references),
|
|
515
|
+
"total_returned": len(result),
|
|
516
|
+
"truncated": truncated,
|
|
517
|
+
}
|
|
518
|
+
if truncated:
|
|
519
|
+
truncation["truncation_reason"] = "max_importers_limit"
|
|
520
|
+
truncation["override_hint"] = f"--symbol {symbol} --max-importers {total_importers}"
|
|
521
|
+
|
|
522
|
+
return result, truncation
|
|
523
|
+
|
|
492
524
|
|
|
493
525
|
# ---------------------------------------------------------------------------
|
|
494
526
|
# Deep symbol scan — grep-based fallback for shallow-scanned repos
|
sourcecode/serializer.py
CHANGED
|
@@ -722,8 +722,10 @@ def agent_view(sm: SourceMap) -> dict[str, Any]:
|
|
|
722
722
|
# production runtime is represented as entry_points=[], never by fallback.
|
|
723
723
|
ep_groups = _entry_point_groups(sm.entry_points)
|
|
724
724
|
result["entry_points"] = ep_groups["production"]
|
|
725
|
-
|
|
726
|
-
|
|
725
|
+
if ep_groups["development"]:
|
|
726
|
+
result["development_entry_points"] = ep_groups["development"]
|
|
727
|
+
if ep_groups["auxiliary"]:
|
|
728
|
+
result["auxiliary_entry_points"] = ep_groups["auxiliary"]
|
|
727
729
|
|
|
728
730
|
# ── 3. Architecture ───────────────────────────────────────────────────────
|
|
729
731
|
result["architecture"] = _architecture_context(sm)
|
|
@@ -888,6 +890,23 @@ def agent_view(sm: SourceMap) -> dict[str, Any]:
|
|
|
888
890
|
if analysis_gaps:
|
|
889
891
|
result["analysis_gaps"] = analysis_gaps
|
|
890
892
|
|
|
893
|
+
# ── 8. Agent mode metadata — explicit transparency about auto-enabled/suppressed flags ──
|
|
894
|
+
_auto_enabled: list[str] = ["--dependencies", "--env-map", "--code-notes"]
|
|
895
|
+
_suppressed: list[str] = []
|
|
896
|
+
if sm.metrics_summary is not None and sm.metrics_summary.requested:
|
|
897
|
+
_suppressed.append("--full-metrics")
|
|
898
|
+
if sm.module_graph is not None and sm.module_graph.summary.requested:
|
|
899
|
+
_suppressed.append("--graph-modules")
|
|
900
|
+
if sm.doc_summary is not None and sm.doc_summary.requested:
|
|
901
|
+
_suppressed.append("--docs")
|
|
902
|
+
agent_mode_meta: dict[str, Any] = {
|
|
903
|
+
"auto_enabled": _auto_enabled,
|
|
904
|
+
}
|
|
905
|
+
if _suppressed:
|
|
906
|
+
agent_mode_meta["suppressed_flags"] = _suppressed
|
|
907
|
+
agent_mode_meta["suppressed_note"] = "computed but excluded from agent_view"
|
|
908
|
+
result["agent_mode"] = agent_mode_meta
|
|
909
|
+
|
|
891
910
|
return result
|
|
892
911
|
|
|
893
912
|
|
|
@@ -918,9 +937,11 @@ def standard_view(sm: SourceMap, *, include_tree: bool = False) -> dict[str, Any
|
|
|
918
937
|
"architecture_summary": sm.architecture_summary,
|
|
919
938
|
"stacks": [asdict(s) for s in sm.stacks],
|
|
920
939
|
"entry_points": ep_groups["production"],
|
|
921
|
-
"development_entry_points": ep_groups["development"],
|
|
922
|
-
"auxiliary_entry_points": ep_groups["auxiliary"],
|
|
923
940
|
}
|
|
941
|
+
if ep_groups["development"]:
|
|
942
|
+
result["development_entry_points"] = ep_groups["development"]
|
|
943
|
+
if ep_groups["auxiliary"]:
|
|
944
|
+
result["auxiliary_entry_points"] = ep_groups["auxiliary"]
|
|
924
945
|
|
|
925
946
|
# Layer B — signals (only when the corresponding analyzer ran)
|
|
926
947
|
if sm.dependency_summary is not None and sm.dependency_summary.requested:
|
|
@@ -1125,6 +1146,8 @@ def _contract_view_minimal(
|
|
|
1125
1146
|
summary["degraded"] = True
|
|
1126
1147
|
summary["degraded_hint"] = "install sourcecode[ast] for full TS/JS extraction"
|
|
1127
1148
|
result["summary"] = summary
|
|
1149
|
+
if cs.symbol_truncation:
|
|
1150
|
+
result["symbol_query"] = cs.symbol_truncation
|
|
1128
1151
|
|
|
1129
1152
|
return result
|
|
1130
1153
|
|
|
@@ -1404,6 +1427,8 @@ def _contract_view_standard(
|
|
|
1404
1427
|
}
|
|
1405
1428
|
if cs.limitations:
|
|
1406
1429
|
result["contract_summary"]["limitations"] = cs.limitations
|
|
1430
|
+
if cs.symbol_truncation:
|
|
1431
|
+
result["symbol_query"] = cs.symbol_truncation
|
|
1407
1432
|
|
|
1408
1433
|
return result
|
|
1409
1434
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
sourcecode/__init__.py,sha256=
|
|
1
|
+
sourcecode/__init__.py,sha256=ktYEudER40ycgGKE7MG3VPlJ8UQQPhREtYx6twzDGUM,103
|
|
2
2
|
sourcecode/adaptive_scanner.py,sha256=6dh34C2qZXyRbw-8xBhbEwDdXanM6CRFRWayVoYITnA,10190
|
|
3
3
|
sourcecode/architecture_analyzer.py,sha256=O4AXc7l_WTzIXrcAzstqZy-TGKNaFa6p3MzpgVjaO8g,27749
|
|
4
4
|
sourcecode/architecture_summary.py,sha256=rSY5MRiaz4N1YdG0pqDTDuFjSN7PO_Zplx-dtNzv2Yo,19985
|
|
5
5
|
sourcecode/ast_extractor.py,sha256=0OHQwTUBBc9lmqPLryVeB1z8dGIC6NhLlar800CD9oI,41129
|
|
6
6
|
sourcecode/classifier.py,sha256=GKTMN8qKZX7ponSwDJfN08RrasI4CVpq1_gFBgEopps,7093
|
|
7
|
-
sourcecode/cli.py,sha256=
|
|
7
|
+
sourcecode/cli.py,sha256=tsubK4RGYtqQEtknH5bKYgsJmeTWfEWk_DSujbZYb70,68783
|
|
8
8
|
sourcecode/code_notes_analyzer.py,sha256=rRd8bFYV0krjlxxQV0wenwE9K7pVpUQSR7KvSvUQKw4,9226
|
|
9
9
|
sourcecode/confidence_analyzer.py,sha256=HxJMPLI5ulqtkncnv98W4iVO6yMbpQo87VuxiuNbDmY,12167
|
|
10
10
|
sourcecode/context_summarizer.py,sha256=CiQrfBEzun949bWvmLabWoj2HhPn6Lw62ofqnsy0FlQ,6503
|
|
11
|
-
sourcecode/contract_model.py,sha256=
|
|
12
|
-
sourcecode/contract_pipeline.py,sha256=
|
|
11
|
+
sourcecode/contract_model.py,sha256=gCf9-Kj0G7l0lvRTAcRfFAfMgs1Rpizv4mKovQLYUkw,3434
|
|
12
|
+
sourcecode/contract_pipeline.py,sha256=dTOvoaJy-S_hLZtpqpLxjb0dmnPyGnKabLUzS3DlJ-s,24278
|
|
13
13
|
sourcecode/coverage_parser.py,sha256=q0LeZJaX1bnntLu-ImksdBsMlpsVmk_iUfSaB4eaJGo,19702
|
|
14
14
|
sourcecode/dependency_analyzer.py,sha256=Exq0BfInvfS5iAg9xAr6WI2uPNuotkIudTKcYJcRhB8,52757
|
|
15
15
|
sourcecode/doc_analyzer.py,sha256=TttdS7mndKQhyJCfJnnAsyGCJrf-TIL7oXxDlTLUFKE,21248
|
|
@@ -28,7 +28,7 @@ sourcecode/runtime_classifier.py,sha256=zWX3r3HCKHc-qtIobErOa8aKMmaoPYREtJKvPcBG
|
|
|
28
28
|
sourcecode/scanner.py,sha256=aM3h9-DCQ3xKpeHpHYdo2vX6T5P95HA_YwZbkAVNwmo,8288
|
|
29
29
|
sourcecode/schema.py,sha256=ofEge9hTWHOTjeWt7ceCDQWzP-uhhenrYX2usjW2KVU,22759
|
|
30
30
|
sourcecode/semantic_analyzer.py,sha256=16EFTgM7ooW0m5gNUKOlTSn7IEMLSzKmzQn-cWaSqjs,82604
|
|
31
|
-
sourcecode/serializer.py,sha256=
|
|
31
|
+
sourcecode/serializer.py,sha256=h7KuMcDi7K-BcnDbXZu8q5MTE3PwyIZcU8Is4_Vv32Q,58107
|
|
32
32
|
sourcecode/summarizer.py,sha256=ZuzIdm3t8A-d5MuQL0TSNLrd-L0IQIuguIxeNXMNJf8,16070
|
|
33
33
|
sourcecode/tree_utils.py,sha256=Fj9OIuUksBvgibNd3feog0sMDjVypJzPexp5lvMoYWI,1424
|
|
34
34
|
sourcecode/workspace.py,sha256=fQlVoNx8S-fSHpKoJ0JBvEHCFkxszH0KZVJed1i3TRk,6845
|
|
@@ -59,8 +59,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
|
|
|
59
59
|
sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
|
|
60
60
|
sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
|
|
61
61
|
sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
|
|
62
|
-
sourcecode-0.
|
|
63
|
-
sourcecode-0.
|
|
64
|
-
sourcecode-0.
|
|
65
|
-
sourcecode-0.
|
|
66
|
-
sourcecode-0.
|
|
62
|
+
sourcecode-0.43.0.dist-info/METADATA,sha256=7-5QNqOmUMepNrGq4TmK5JAy-QDIHyWyb8-RdxaRQ0k,25209
|
|
63
|
+
sourcecode-0.43.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
64
|
+
sourcecode-0.43.0.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
|
|
65
|
+
sourcecode-0.43.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
|
|
66
|
+
sourcecode-0.43.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|