sourcecode 1.30.27__py3-none-any.whl → 1.30.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 +1 -1
- sourcecode/cli.py +19 -5
- sourcecode/prepare_context.py +30 -3
- sourcecode/serializer.py +10 -0
- {sourcecode-1.30.27.dist-info → sourcecode-1.30.28.dist-info}/METADATA +3 -3
- {sourcecode-1.30.27.dist-info → sourcecode-1.30.28.dist-info}/RECORD +9 -9
- {sourcecode-1.30.27.dist-info → sourcecode-1.30.28.dist-info}/WHEEL +0 -0
- {sourcecode-1.30.27.dist-info → sourcecode-1.30.28.dist-info}/entry_points.txt +0 -0
- {sourcecode-1.30.27.dist-info → sourcecode-1.30.28.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/cli.py
CHANGED
|
@@ -424,7 +424,7 @@ def main(
|
|
|
424
424
|
no_redact: bool = typer.Option(
|
|
425
425
|
False,
|
|
426
426
|
"--no-redact",
|
|
427
|
-
help="Disable secret redaction.
|
|
427
|
+
help="Disable secret redaction of output strings. Note: env var values from the OS are never included in output regardless of this flag (security policy).",
|
|
428
428
|
),
|
|
429
429
|
version: Optional[bool] = typer.Option(
|
|
430
430
|
None,
|
|
@@ -437,7 +437,7 @@ def main(
|
|
|
437
437
|
depth: int = typer.Option(
|
|
438
438
|
4,
|
|
439
439
|
"--depth",
|
|
440
|
-
help="File tree traversal depth (default: 4). Java/Maven projects auto-adjust to 12.",
|
|
440
|
+
help="File tree traversal depth (default: 4). Java/Maven projects auto-adjust to a minimum of 12; values below 12 have no effect on Java projects.",
|
|
441
441
|
min=1,
|
|
442
442
|
max=20,
|
|
443
443
|
),
|
|
@@ -1734,6 +1734,11 @@ def prepare_context_cmd(
|
|
|
1734
1734
|
help="Emit per-phase timing to stderr (git scan ms, symptom scoring ms, total ms)",
|
|
1735
1735
|
hidden=True,
|
|
1736
1736
|
),
|
|
1737
|
+
fast: bool = typer.Option(
|
|
1738
|
+
False,
|
|
1739
|
+
"--fast",
|
|
1740
|
+
help="Skip deep analysis (content search, test gap discovery, code annotations). Uses manifest/metadata only. Target: < 6 s.",
|
|
1741
|
+
),
|
|
1737
1742
|
) -> None:
|
|
1738
1743
|
"""Task-specific context for AI coding agents.
|
|
1739
1744
|
|
|
@@ -1808,9 +1813,14 @@ def prepare_context_cmd(
|
|
|
1808
1813
|
if since:
|
|
1809
1814
|
_phase += f" since {since}"
|
|
1810
1815
|
_progress.start(_phase)
|
|
1816
|
+
if not fast:
|
|
1817
|
+
import sys as _sys
|
|
1818
|
+
if _sys.stderr.isatty():
|
|
1819
|
+
_sys.stderr.write(f"Analyzing ({task})... (deep scan may take 15–35 s for large codebases)\n")
|
|
1820
|
+
_sys.stderr.flush()
|
|
1811
1821
|
_t0 = _time.perf_counter()
|
|
1812
1822
|
try:
|
|
1813
|
-
output = builder.build(task, since=since, symptom=symptom)
|
|
1823
|
+
output = builder.build(task, since=since, symptom=symptom, fast=fast)
|
|
1814
1824
|
finally:
|
|
1815
1825
|
_progress.finish()
|
|
1816
1826
|
_t_total = (_time.perf_counter() - _t0) * 1000
|
|
@@ -1960,8 +1970,8 @@ def prepare_context_cmd(
|
|
|
1960
1970
|
_sys.stdout.buffer.write(b"\n")
|
|
1961
1971
|
_sys.stdout.buffer.flush()
|
|
1962
1972
|
if copy:
|
|
1963
|
-
_copy_to_clipboard(_nc_json)
|
|
1964
|
-
|
|
1973
|
+
if _copy_to_clipboard(_nc_json):
|
|
1974
|
+
typer.echo("✓ copied to clipboard", err=True)
|
|
1965
1975
|
raise typer.Exit()
|
|
1966
1976
|
if output.ci_decision:
|
|
1967
1977
|
out["ci_decision"] = output.ci_decision
|
|
@@ -2082,6 +2092,10 @@ def prepare_context_cmd(
|
|
|
2082
2092
|
out["symptom_note"] = output.symptom_note
|
|
2083
2093
|
if output.symptom_explain:
|
|
2084
2094
|
out["symptom_explain"] = output.symptom_explain
|
|
2095
|
+
if getattr(output, "symptom_hint", None):
|
|
2096
|
+
out["symptom_hint"] = output.symptom_hint
|
|
2097
|
+
if getattr(output, "warnings", None):
|
|
2098
|
+
out["warnings"] = output.warnings
|
|
2085
2099
|
if llm_prompt:
|
|
2086
2100
|
out["llm_prompt"] = builder.render_prompt(output)
|
|
2087
2101
|
|
sourcecode/prepare_context.py
CHANGED
|
@@ -335,6 +335,7 @@ class TaskOutput:
|
|
|
335
335
|
related_notes: list[dict] = field(default_factory=list) # fix-bug + symptom only
|
|
336
336
|
symptom_note: Optional[str] = None # fix-bug: cross-layer synonym note
|
|
337
337
|
symptom_explain: Optional[dict] = None # fix-bug: structured evidence breakdown
|
|
338
|
+
symptom_hint: Optional[str] = None # fix-bug: redirect hint when term not found in this module
|
|
338
339
|
# delta-specific impact fields
|
|
339
340
|
impact_summary: Optional[str] = None
|
|
340
341
|
affected_modules: list[str] = field(default_factory=list)
|
|
@@ -348,6 +349,7 @@ class TaskOutput:
|
|
|
348
349
|
error_code: Optional[str] = None
|
|
349
350
|
error_message: Optional[str] = None
|
|
350
351
|
error_hints: list[str] = field(default_factory=list)
|
|
352
|
+
warnings: list[dict] = field(default_factory=list) # structured warnings (REF_NOT_FOUND, etc.)
|
|
351
353
|
# CI decision state machine — machine-decidable signal
|
|
352
354
|
ci_decision: Optional[str] = None # "no_changes" | "analysis_success" | "git_ref_error" | "no_git_repo"
|
|
353
355
|
# git baseline resolution metadata
|
|
@@ -683,7 +685,7 @@ class TaskContextBuilder:
|
|
|
683
685
|
def __init__(self, root: Path) -> None:
|
|
684
686
|
self.root = root
|
|
685
687
|
|
|
686
|
-
def build(self, task_name: str, *, since: Optional[str] = None, symptom: Optional[str] = None) -> TaskOutput:
|
|
688
|
+
def build(self, task_name: str, *, since: Optional[str] = None, symptom: Optional[str] = None, fast: bool = False) -> TaskOutput:
|
|
687
689
|
if task_name not in TASKS:
|
|
688
690
|
raise ValueError(
|
|
689
691
|
f"Unknown task '{task_name}'. Available: {', '.join(TASKS)}"
|
|
@@ -880,7 +882,7 @@ class TaskContextBuilder:
|
|
|
880
882
|
improvement_opportunities: list[str] = []
|
|
881
883
|
cn_notes_for_ranking: list = []
|
|
882
884
|
|
|
883
|
-
if spec.enable_code_notes:
|
|
885
|
+
if spec.enable_code_notes and not fast:
|
|
884
886
|
from dataclasses import asdict
|
|
885
887
|
from sourcecode.code_notes_analyzer import CodeNotesAnalyzer
|
|
886
888
|
|
|
@@ -1317,6 +1319,7 @@ class TaskContextBuilder:
|
|
|
1317
1319
|
related_notes: list[dict] = []
|
|
1318
1320
|
symptom_note: Optional[str] = None
|
|
1319
1321
|
symptom_explain: Optional[dict] = None
|
|
1322
|
+
symptom_hint: Optional[str] = None
|
|
1320
1323
|
if task_name == "fix-bug" and symptom:
|
|
1321
1324
|
import re as _re
|
|
1322
1325
|
_camel_expanded = _re.sub(r'([a-z])([A-Z])', r'\1 \2', symptom)
|
|
@@ -1537,9 +1540,30 @@ class TaskContextBuilder:
|
|
|
1537
1540
|
),
|
|
1538
1541
|
}
|
|
1539
1542
|
|
|
1543
|
+
# BUG #4: LOW confidence + 0 content matches → clear suspected_areas,
|
|
1544
|
+
# emit actionable redirect instead of unrelated files.
|
|
1545
|
+
if _sx_confidence == "LOW" and not _sx_content:
|
|
1546
|
+
suspected_areas = []
|
|
1547
|
+
_is_fe_term = any(kw in _FRONTEND_SYMPTOM_MAP for kw in symptom_keywords)
|
|
1548
|
+
_root_name = self.root.name
|
|
1549
|
+
if _is_fe_term:
|
|
1550
|
+
_fe_redirect = (
|
|
1551
|
+
f"Term {symptom!r} not found in sources under {_root_name!r}. "
|
|
1552
|
+
f"This appears to be a frontend symptom. "
|
|
1553
|
+
f"Try: prepare-context fix-bug . --symptom {symptom!r} "
|
|
1554
|
+
f"(monorepo root) or target a frontend sub-project directly."
|
|
1555
|
+
)
|
|
1556
|
+
else:
|
|
1557
|
+
_fe_redirect = (
|
|
1558
|
+
f"Term {symptom!r} not found in sources under {_root_name!r}. "
|
|
1559
|
+
f"Verify the spelling or try a related term. "
|
|
1560
|
+
f"If this is a frontend symptom, run against the frontend sub-project."
|
|
1561
|
+
)
|
|
1562
|
+
symptom_hint = _fe_redirect
|
|
1563
|
+
|
|
1540
1564
|
# ── 7. Test gaps (generate-tests only) ────────────────────────────
|
|
1541
1565
|
test_gaps: list[str] = []
|
|
1542
|
-
if task_name == "generate-tests":
|
|
1566
|
+
if task_name == "generate-tests" and not fast:
|
|
1543
1567
|
def _normalize_test_stem(stem: str) -> str:
|
|
1544
1568
|
# Java: FooTest / FooTests → Foo; TestFoo → Foo
|
|
1545
1569
|
if stem.endswith("Tests"):
|
|
@@ -1683,6 +1707,8 @@ class TaskContextBuilder:
|
|
|
1683
1707
|
resolved_since_ref=_delta_baseline.get("resolved_ref") if task_name == "delta" else None,
|
|
1684
1708
|
resolution_path=_delta_baseline.get("resolution_path") if task_name == "delta" else None,
|
|
1685
1709
|
diff_validation_status=_delta_baseline.get("diff_validation_status") if task_name == "delta" else None,
|
|
1710
|
+
warnings=_delta_baseline.get("warnings", []) if task_name == "delta" else [],
|
|
1711
|
+
symptom_hint=symptom_hint if task_name == "fix-bug" else None,
|
|
1686
1712
|
)
|
|
1687
1713
|
|
|
1688
1714
|
def render_prompt(self, output: TaskOutput) -> str:
|
|
@@ -3261,6 +3287,7 @@ class TaskContextBuilder:
|
|
|
3261
3287
|
"resolution_path": "head_minus_1_fallback",
|
|
3262
3288
|
"diff_validation_status": "invalid_ref", # original ref unresolved
|
|
3263
3289
|
"error": False,
|
|
3290
|
+
"warnings": [{"code": "REF_NOT_FOUND", "ref": since, "resolved_to": "HEAD~1"}],
|
|
3264
3291
|
}
|
|
3265
3292
|
|
|
3266
3293
|
# All stages failed
|
sourcecode/serializer.py
CHANGED
|
@@ -248,6 +248,16 @@ def _compact_git_context(sm: "SourceMap") -> "Optional[dict[str, Any]]":
|
|
|
248
248
|
for f, n in _fc.most_common(5)
|
|
249
249
|
]
|
|
250
250
|
ctx["hotspots_source"] = "recent_commits"
|
|
251
|
+
if gc.recent_commits:
|
|
252
|
+
ctx["recent_commits"] = [
|
|
253
|
+
{
|
|
254
|
+
"hash": c.hash[:8],
|
|
255
|
+
"message": (c.message or "")[:80],
|
|
256
|
+
"date": (c.date or "")[:10],
|
|
257
|
+
"author": c.author or "",
|
|
258
|
+
}
|
|
259
|
+
for c in gc.recent_commits[:5]
|
|
260
|
+
]
|
|
251
261
|
return ctx if ctx else None
|
|
252
262
|
|
|
253
263
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.30.
|
|
3
|
+
Version: 1.30.28
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -221,7 +221,7 @@ Description-Content-Type: text/markdown
|
|
|
221
221
|
|
|
222
222
|
**Deterministic, behavior-aware codebase context for AI agents and PR review.**
|
|
223
223
|
|
|
224
|
-

|
|
225
225
|

|
|
226
226
|
|
|
227
227
|
---
|
|
@@ -257,7 +257,7 @@ pipx install sourcecode
|
|
|
257
257
|
|
|
258
258
|
```bash
|
|
259
259
|
sourcecode version
|
|
260
|
-
# sourcecode 1.30.
|
|
260
|
+
# sourcecode 1.30.28
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
---
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
sourcecode/__init__.py,sha256=
|
|
1
|
+
sourcecode/__init__.py,sha256=q-bCo7uGXns3U7O05C-GiuHhFOyvaN-90_kC3JSQMn0,104
|
|
2
2
|
sourcecode/adaptive_scanner.py,sha256=RTNExwWPXzjgLaRueT7UuxkPj5ZEToWjGbx1j0LSZ9E,10250
|
|
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=pYve2J1LqtYssU3lYLMDz18PT-CjN5c18QYE7R_IG1Q,7507
|
|
7
|
-
sourcecode/cli.py,sha256=
|
|
7
|
+
sourcecode/cli.py,sha256=NbVyJAEQ4Q0ngkgW_lXyvlDJcD8TTrxZEXY6RIVkBAI,95261
|
|
8
8
|
sourcecode/code_notes_analyzer.py,sha256=y1MJBnPZHYp4i6cQCXUb9ATIyifS_qMQWjw_8lPkpsU,9215
|
|
9
9
|
sourcecode/confidence_analyzer.py,sha256=H9VHYRzZhqMFlSCZffjtsMUGYLnDvrq1g5FjzyQ1hxE,16381
|
|
10
10
|
sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
|
|
@@ -22,7 +22,7 @@ sourcecode/git_analyzer.py,sha256=0Gyj-vMpIIN4nfriKXVRouNYBeJ59s6pQDX2Xu9Pq-U,13
|
|
|
22
22
|
sourcecode/graph_analyzer.py,sha256=iUK-7pSV-cvGqqD2hENdYmhnm0wcXFEyK-xnu5ul8OU,62515
|
|
23
23
|
sourcecode/metrics_analyzer.py,sha256=m0ENgtqKeBL17kUIK3fmGkgo7UfXBNHxCMj0H_Y5K7c,22750
|
|
24
24
|
sourcecode/pr_comment_renderer.py,sha256=smHslxiG14lrytCkq5nFrFu-qTHgA-t-LFYfdrfjz2o,14423
|
|
25
|
-
sourcecode/prepare_context.py,sha256=
|
|
25
|
+
sourcecode/prepare_context.py,sha256=O3gpZIJLzCH2-9zr91zOP0D4gwHND2BbgBOCplwQXj8,168540
|
|
26
26
|
sourcecode/progress.py,sha256=qn30sWaHOkjTgXsSBmiPkz7Rsbwc5oSlIe6JNEMYp_k,3149
|
|
27
27
|
sourcecode/ranking_engine.py,sha256=ZAucq_YX2KkWUuAZf4P0lhtQ_38vEFnUhuGtSZd1S0E,12970
|
|
28
28
|
sourcecode/redactor.py,sha256=xuGcadGEHaPw4qZXlMDvzMCsr4VOkdp3oBQptHyJk8c,2884
|
|
@@ -33,7 +33,7 @@ sourcecode/runtime_classifier.py,sha256=zWX3r3HCKHc-qtIobErOa8aKMmaoPYREtJKvPcBG
|
|
|
33
33
|
sourcecode/scanner.py,sha256=aM3h9-DCQ3xKpeHpHYdo2vX6T5P95HA_YwZbkAVNwmo,8288
|
|
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=
|
|
36
|
+
sourcecode/serializer.py,sha256=svaLLYyAeAd3ZWsgh0YBwu7RKm00JaKuyz3bQbLipHA,106064
|
|
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
|
|
@@ -64,8 +64,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
|
|
|
64
64
|
sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
|
|
65
65
|
sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
|
|
66
66
|
sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
|
|
67
|
-
sourcecode-1.30.
|
|
68
|
-
sourcecode-1.30.
|
|
69
|
-
sourcecode-1.30.
|
|
70
|
-
sourcecode-1.30.
|
|
71
|
-
sourcecode-1.30.
|
|
67
|
+
sourcecode-1.30.28.dist-info/METADATA,sha256=cL4bkJZO4jc-T5k1GtC5OXS99NZLU4bZSl6WxVbo70w,28956
|
|
68
|
+
sourcecode-1.30.28.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
69
|
+
sourcecode-1.30.28.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
|
|
70
|
+
sourcecode-1.30.28.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
|
|
71
|
+
sourcecode-1.30.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|