diffcontext 0.5.6__tar.gz → 0.5.7__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.
- {diffcontext-0.5.6 → diffcontext-0.5.7}/PKG-INFO +1 -1
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/__init__.py +1 -1
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/mcp_server.py +41 -11
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/PKG-INFO +1 -1
- {diffcontext-0.5.6 → diffcontext-0.5.7}/LICENSE +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/README.md +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/_warn_once.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/cache.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/cli/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/context/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/context/compiler.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/context/selector.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/diff/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/diff/git_diff.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/diff/state_manager.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/graph_builder.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/history.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/impact/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/impact/blast_radius.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/impact/scoring.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/impact/traversal.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/impact/visualizer.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/languages/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/languages/typescript.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/lexical.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/models.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/parser.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/pipeline.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/py.typed +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/rerank/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/rerank/features.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/rerank/model.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/resolver.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/scanner.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/symbols.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/verify/__init__.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/verify/cases.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/verify/history.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext/verify/sufficiency.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/SOURCES.txt +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/dependency_links.txt +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/entry_points.txt +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/requires.txt +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/diffcontext.egg-info/top_level.txt +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/pyproject.toml +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/setup.cfg +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_cache.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_cache_fallback.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_compiler_meta.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_core.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_cutoff.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_determinism.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_downstream_eval.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_git_diff.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_harness_api.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_history.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_incremental.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_index_scoping.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_lexical.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_mcp_server.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_rerank.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_semantic_ablation.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_semantic_audit.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_semantic_gap.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_semantic_metrics.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_semantic_mine.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_service_clone.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_src_layout.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_stats.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_token_budget.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_typescript_adapter.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_verify.py +0 -0
- {diffcontext-0.5.6 → diffcontext-0.5.7}/tests/test_version.py +0 -0
|
@@ -32,7 +32,7 @@ Usage as a library:
|
|
|
32
32
|
print(ctx.reduction_pct) # how much code was filtered out
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
|
-
__version__ = "0.5.
|
|
35
|
+
__version__ = "0.5.7"
|
|
36
36
|
|
|
37
37
|
# Public, semver-covered API. Everything not listed here (graph_builder,
|
|
38
38
|
# resolver, symbols, scanner, parser internals) is importable but carries no
|
|
@@ -96,6 +96,11 @@ def main():
|
|
|
96
96
|
related functions the model needs to make the change safely — packed
|
|
97
97
|
into max_tokens with a disclosure header showing what was dropped.
|
|
98
98
|
|
|
99
|
+
Uses the gap cutoff by default (~6-9 symbols at ~4x precision vs
|
|
100
|
+
top-20, costing ~30% recall) — MCP consumers are budget-sensitive,
|
|
101
|
+
so the default is precise, not exhaustive. The total count of
|
|
102
|
+
dropped symbols is always shown in the meta header.
|
|
103
|
+
|
|
99
104
|
Optionally pass task_description (the bug report or issue text) to
|
|
100
105
|
bias retrieval toward symbols relevant to the described problem —
|
|
101
106
|
the one signal the graph alone can't provide.
|
|
@@ -139,23 +144,34 @@ def main():
|
|
|
139
144
|
impact = analyze_impact(
|
|
140
145
|
idx, changed, query_text=task_description, query_weight=query_weight,
|
|
141
146
|
)
|
|
142
|
-
|
|
147
|
+
# Gap cutoff by default: ~6-9 symbols at ~4x precision vs top-20,
|
|
148
|
+
# costing ~30% recall. MCP consumers are budget-sensitive — the
|
|
149
|
+
# default should be precise, not exhaustive.
|
|
150
|
+
ctx = compile(idx, impact, max_tokens=max_tokens, meta=meta, cutoff="gap")
|
|
143
151
|
return ctx.text
|
|
144
152
|
|
|
145
153
|
@server.tool()
|
|
146
154
|
def find_impact(
|
|
147
155
|
repo_path: str = "",
|
|
148
156
|
symbol: str = "",
|
|
157
|
+
limit: int = 0,
|
|
149
158
|
) -> str:
|
|
150
159
|
"""Find what breaks if you change a symbol.
|
|
151
160
|
|
|
152
161
|
Returns the blast radius: direct callers, direct callees, and
|
|
153
|
-
transitive impact
|
|
162
|
+
transitive impact, ranked by impact score. Default cap is 10
|
|
163
|
+
symbols — a reviewer brief must be short enough to read. Pass
|
|
164
|
+
limit > 0 to override with a different cap, or limit=0 for all.
|
|
165
|
+
|
|
166
|
+
The total count is always shown ("339 impacted, showing top 9")
|
|
167
|
+
so nothing is hidden — the cap is a display choice, not
|
|
168
|
+
information loss.
|
|
154
169
|
|
|
155
170
|
Args:
|
|
156
171
|
repo_path: Absolute path to the repository. If omitted, uses
|
|
157
172
|
the --repo from server startup.
|
|
158
173
|
symbol: Symbol ID (e.g. ./src/auth.py:validate_jwt).
|
|
174
|
+
limit: Max symbols to show. 0 = all (default 10).
|
|
159
175
|
"""
|
|
160
176
|
from diffcontext.pipeline import analyze_impact, warn_unknown_symbols
|
|
161
177
|
|
|
@@ -164,12 +180,22 @@ def main():
|
|
|
164
180
|
warn_unknown_symbols(idx, [symbol])
|
|
165
181
|
impact = analyze_impact(idx, [symbol], hybrid=False)
|
|
166
182
|
|
|
183
|
+
# Rank all impacted symbols by score (excluding the changed symbol).
|
|
184
|
+
ranked = sorted(
|
|
185
|
+
((sid, sc) for sid, sc in impact.scores.items() if sid != symbol),
|
|
186
|
+
key=lambda x: x[1], reverse=True,
|
|
187
|
+
)
|
|
188
|
+
total = len(ranked)
|
|
189
|
+
|
|
190
|
+
cap = limit if limit > 0 else 10
|
|
191
|
+
show = min(cap, total)
|
|
192
|
+
|
|
167
193
|
lines = [f"Changed: {symbol}"]
|
|
168
|
-
lines.append(f"\
|
|
169
|
-
for
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
194
|
+
lines.append(f"\n{total} impacted, showing top {show}:")
|
|
195
|
+
for sid, sc in ranked[:show]:
|
|
196
|
+
lines.append(f" {sid} (score: {sc:.0f})")
|
|
197
|
+
if total > show:
|
|
198
|
+
lines.append(f"\n... and {total - show} more (pass limit={total} to see all)")
|
|
173
199
|
return "\n".join(lines)
|
|
174
200
|
|
|
175
201
|
@server.tool()
|
|
@@ -180,9 +206,11 @@ def main():
|
|
|
180
206
|
) -> str:
|
|
181
207
|
"""Explain why symbols were included or dropped from context.
|
|
182
208
|
|
|
183
|
-
Returns the included symbols (with scores and token costs) and
|
|
184
|
-
|
|
185
|
-
|
|
209
|
+
Returns the included symbols (with scores and token costs) and the
|
|
210
|
+
top dropped symbols (scored but cut by the token budget), so an agent
|
|
211
|
+
can inspect or filter the selection. Dropped symbols are capped at
|
|
212
|
+
10 by default (gap cutoff) — the total count is always shown so
|
|
213
|
+
nothing is hidden.
|
|
186
214
|
|
|
187
215
|
Args:
|
|
188
216
|
repo_path: Absolute path to the repository. If omitted, uses
|
|
@@ -203,13 +231,15 @@ def main():
|
|
|
203
231
|
"score": round(item.score, 1), "tokens": item.token_estimate}
|
|
204
232
|
for item in ctx.items
|
|
205
233
|
]
|
|
234
|
+
total_dropped = len(ctx.dropped_symbols)
|
|
206
235
|
dropped = [
|
|
207
236
|
{"id": sid, "score": round(impact.scores.get(sid, 0.0), 1)}
|
|
208
|
-
for sid in ctx.dropped_symbols
|
|
237
|
+
for sid in ctx.dropped_symbols[:10]
|
|
209
238
|
]
|
|
210
239
|
result = {
|
|
211
240
|
"included_symbols": included,
|
|
212
241
|
"dropped_symbols": dropped,
|
|
242
|
+
"dropped_symbols_total": total_dropped,
|
|
213
243
|
"total_tokens": ctx.token_estimate,
|
|
214
244
|
"symbol_count": ctx.symbol_count,
|
|
215
245
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|