Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [8.2.0] — Unreleased

### Confidence Fields on Non-Deep Output (test fix)

Previously, the `confidence` / `confidence_distribution` fields were only
attached to `query` / `impact` / `dead-code` output when the `--deep` flag
was passed (which triggers LSP verification). This meant consumers of the
default (non-deep) output had no way to know the analysis provenance. The
hybrid engine's module docstring already documents the intended semantics
(`high` = LSP verified, `medium` = AST matched, `low` = regex only), and
`HybridEngine.enhance_*` methods already set `confidence = MEDIUM` when LSP
is not active — but those methods were only invoked from the `--deep`
post-processing path in `codelens.py`, never from the command `execute()`
entry points.

This fix completes the partially-implemented feature by attaching baseline
`confidence = "medium"` (and `confidence_distribution` for `dead-code`) at
command execution time, before the `--deep` post-processing layer runs.
When `--deep` is later applied, LSP verification may override individual
fields to `high` or `low` as before.

### Added (confidence fields)

- **`query` command** — top-level `confidence` field is now always present
on `found` results (value: `"medium"` for AST-based analysis, `"high"` or
`"low"` when `--deep` + LSP verifies).
- **`impact` command** — top-level `confidence` field is now always present
on `status: ok` results.
- **`dead-code` command** — each finding in `results` now carries a
`confidence` field; `stats.confidence_distribution` (counts of
`high` / `medium` / `low`) is now always present.

### Non-Breaking (confidence fields)

- All previously-passing tests continue to pass.
- The new fields are additive — no existing field is removed or renamed.
- When `--deep` is used, the `--deep` post-processing layer in
`codelens.py` still runs and may override the baseline confidence based
on LSP verification, exactly as before.
- The `confidence` field is also surfaced in the `--format ai` normalized
output via the existing `_META_KEYS` extraction in
`formatters/__init__.py`.

### Token-Efficient Output + Pagination (issue #17)

Adds a 5th output format (`compact`) and pagination to all list-type commands
Expand Down
37 changes: 37 additions & 0 deletions scripts/commands/dead_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,43 @@ def execute(args, workspace):
result["removal_safety"] = "caution"
result["dependency_count"] = with_refs
result["recommended_action"] = "Review before removing. Some dead code may still be referenced indirectly." if with_refs > 0 else "Safe to remove. No references found."

# Attach baseline confidence (medium = AST-based analysis per hybrid_engine.py
# docstring) to each finding and add confidence_distribution to stats.
# HybridEngine.verify_dead_code sets confidence=MEDIUM on every finding when
# LSP is not active (deep=False). add_confidence_to_result backfills any
# remaining findings and computes the distribution. When --deep is later
# applied in codelens.py post-processing, LSP verification may override
# individual findings to HIGH or LOW.
try:
from hybrid_engine import create_hybrid_engine, add_confidence_to_result
engine = create_hybrid_engine(workspace, deep=False)
all_findings = []
for cat_items in result.get("results", {}).values():
if isinstance(cat_items, list):
all_findings.extend(cat_items)
if all_findings:
engine.verify_dead_code(all_findings)
add_confidence_to_result(result)
engine.cleanup()
except Exception:
# Best-effort fallback: manually attach medium confidence + distribution
all_findings = []
for cat_items in result.get("results", {}).values():
if isinstance(cat_items, list):
all_findings.extend(cat_items)
for f in all_findings:
if isinstance(f, dict) and "confidence" not in f:
f["confidence"] = "medium"
if all_findings:
dist = {"high": 0, "medium": 0, "low": 0}
for f in all_findings:
c = f.get("confidence", "medium") if isinstance(f, dict) else "medium"
if c in dist:
dist[c] += 1
if "stats" not in result:
result["stats"] = {}
result["stats"]["confidence_distribution"] = dist
return result


Expand Down
12 changes: 12 additions & 0 deletions scripts/commands/impact.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ def execute(args, workspace):
result["recommended_action"] = "Proceed with caution. Review affected code before changing."
else:
result["recommended_action"] = "Safe to proceed. No dependent code found."

# Attach baseline confidence (medium = AST-based analysis per hybrid_engine.py
# docstring). HybridEngine.enhance_impact sets confidence=MEDIUM when LSP is
# not active (deep=False). When --deep is later applied in codelens.py
# post-processing, LSP verification may override this to HIGH or LOW.
try:
from hybrid_engine import create_hybrid_engine
engine = create_hybrid_engine(workspace, deep=False)
engine.enhance_impact(result, args.name)
engine.cleanup()
except Exception:
result.setdefault("confidence", "medium")
return result


Expand Down
25 changes: 24 additions & 1 deletion scripts/commands/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,30 @@ def add_args(parser):
def execute(args, workspace):
limit = None if getattr(args, 'all', False) else getattr(args, 'limit', 20)
fuzzy = getattr(args, 'fuzzy', False)
return cmd_query(args.name, workspace, args.domain, args.file, limit=limit, fuzzy=fuzzy)
result = cmd_query(args.name, workspace, args.domain, args.file, limit=limit, fuzzy=fuzzy)
_attach_baseline_confidence(result, args.name, workspace)
return result


def _attach_baseline_confidence(result: Dict[str, Any], query_name: str, workspace: str) -> None:
"""Attach baseline confidence to query results.

Per ``hybrid_engine.py`` module docstring, CodeLens's default analysis path
(tree-sitter AST) corresponds to MEDIUM confidence. ``HybridEngine.enhance_query``
sets ``confidence=MEDIUM`` when LSP is not active (``deep=False``). When the
user later passes ``--deep``, ``codelens.py`` post-processing calls
``enhance_query`` again with ``deep=True`` and may override this to HIGH or
LOW based on LSP verification.
"""
if not isinstance(result, dict) or not result.get("found"):
return
try:
from hybrid_engine import create_hybrid_engine
engine = create_hybrid_engine(workspace, deep=False)
engine.enhance_query(result, query_name)
engine.cleanup()
except Exception:
result.setdefault("confidence", "medium")


def cmd_query(query_name: str, workspace: str, domain: str = None,
Expand Down
Loading