diff --git a/README.md b/README.md index f22726f..76d5708 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,13 @@ python3 scripts/codelens.py query "myFunction" --lite | `medium` | Caution. Run tests. | | `low` | Safe, proceed. | +## Interpreting Signals + +- `reference_count` / caller count = **how often** something is called, not how important it is. A function called once in the payment flow can be more critical than a utility called 50×. +- To judge importance, run `trace --direction up ` to find **who** calls it, then weigh by context (payment, auth, hot path). +- Use `--format compact` for AI/script consumption (token-efficient single-char keys), `--lite` for minimal output in large repos. +- First `scan` is intentionally slower — it builds the SQLite graph. Subsequent runs are incremental (pass `--incremental` to only re-scan changed files). + ## Supported Languages & Frameworks **Tree-sitter parsed (AST-level):** HTML, CSS, SCSS, JavaScript, TypeScript, TSX/JSX, Rust, Python, Vue SFC, Svelte, Blade diff --git a/SKILL.md b/SKILL.md index a134186..1a6fb91 100755 --- a/SKILL.md +++ b/SKILL.md @@ -251,6 +251,26 @@ query "name" → context (if exists) → side-effect → write → scan --increm --- +## Reading the Output — Signal vs. Metric + +| Metric | What it actually means | How to interpret | +|--------|------------------------|------------------| +| `reference_count` / caller count | **Popularity** — how often a symbol is referenced | Not a criticality signal. A payment-flow function called once is more critical than a utility called 50×. | +| `status: dead` | Nothing references it | Flag for removal — but verify it's not an entry point (HTTP handler, CLI subcommand, exported API). | +| `status: duplicate_ref` | Referenced from many places | List all callers with `trace --direction up` before changing. | +| `high_complexity` | Cyclomatic complexity ≥ threshold | Hotspot for bugs, not necessarily important. Cross-reference with `trace --direction up`. | + +**To judge importance:** run `trace --direction up ` to see **who** calls it, then weigh by context (payment, auth, hot path) — not by raw count. + +**To reduce noise:** +- `--format compact` — token-efficient single-char keys (AI/script consumption) +- `--lite` — minimal output (decision-making mode, per-command tailored) +- `--detail minimal` (summary) — critical-severity findings only + +**First scan is slow by design** — it builds the SQLite graph. Subsequent scans are incremental (`--incremental`). + +--- + ## Integration with AI Agent ### CLI Integration (Recommended) diff --git a/scripts/commands/scan.py b/scripts/commands/scan.py index 11d40c7..9a68a79 100644 --- a/scripts/commands/scan.py +++ b/scripts/commands/scan.py @@ -1,5 +1,6 @@ """Scan command — Scan workspace and build registry.""" +import argparse import os import json import time @@ -65,6 +66,17 @@ def add_args(parser): """Add scan-specific arguments to the parser.""" + # Issue #180: surface incremental behavior + noise-reduction flags directly + # in `codelens scan --help`. The flags themselves are added by the dispatcher + # in codelens.py; this epilog just points users at them. + parser.formatter_class = argparse.RawDescriptionHelpFormatter + parser.epilog = ( + "Notes:\n" + " First scan builds the SQLite graph (slower). Subsequent scans are\n" + " incremental — pass --incremental to only re-scan changed files.\n" + " Reduce noise in large repos with --format compact (token-efficient\n" + " single-char keys for AI/script consumption) or --lite (minimal output)." + ) parser.add_argument("workspace", nargs="?", default=None, help="Path to workspace root (auto-detected if omitted)") parser.add_argument("--incremental", action="store_true", diff --git a/scripts/commands/summary.py b/scripts/commands/summary.py index ae15bb6..50b0dac 100644 --- a/scripts/commands/summary.py +++ b/scripts/commands/summary.py @@ -12,6 +12,7 @@ overwhelmed with thousands of findings, most of which are low-priority. """ +import argparse import os import re import time @@ -88,6 +89,16 @@ def _detect_android_identity(workspace: str) -> Dict[str, Any]: def add_args(parser): + # Issue #180: surface noise-reduction flags directly in `codelens summary --help`. + # summary already auto-adapts detail level to codebase size; the epilog points + # users at the additional output-shaping flags added by the dispatcher. + parser.formatter_class = argparse.RawDescriptionHelpFormatter + parser.epilog = ( + "Notes:\n" + " For AI/script consumption, use --format compact (token-efficient\n" + " single-char keys) or --lite (minimal output). For large repos,\n" + " --detail minimal restricts findings to critical severity only." + ) parser.add_argument("workspace", nargs="?", default=None, help="Path to workspace root (auto-detected if omitted)") parser.add_argument("--focus", choices=["security", "quality", "architecture", "all"], diff --git a/scripts/commands/trace.py b/scripts/commands/trace.py index c1932f9..19dc67f 100644 --- a/scripts/commands/trace.py +++ b/scripts/commands/trace.py @@ -1,11 +1,23 @@ """Trace command — Trace deep call chain from a symbol.""" +import argparse from trace_engine import trace_symbol, MAX_CHAIN_RESULTS from commands import register_command def add_args(parser): """Add trace-specific arguments to the parser.""" + # Issue #180: surface noise-reduction flags directly in `codelens trace --help`. + # trace output can be deep (--depth default 10) — point users at compact/lite + # so they don't drown in chain entries when called from AI/script context. + parser.formatter_class = argparse.RawDescriptionHelpFormatter + parser.epilog = ( + "Notes:\n" + " Use --direction up to find callers (who depends on this symbol),\n" + " --direction down to find callees. For AI/script consumption, use\n" + " --format compact (token-efficient single-char keys) or --lite\n" + " (minimal output). Paginate with --limit / --offset." + ) parser.add_argument("name", help="Symbol name to trace") parser.add_argument("workspace", nargs="?", default=None, help="Path to workspace root (auto-detected if omitted)")