scip-cli 1.3.0__tar.gz → 2.0.0__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.
- scip_cli-2.0.0/.cursor/rules/agent.mdc +133 -0
- scip_cli-2.0.0/.gitignore +53 -0
- scip_cli-2.0.0/.pre-commit-config.yaml +15 -0
- {scip_cli-1.3.0/scip_cli.egg-info → scip_cli-2.0.0}/PKG-INFO +97 -48
- scip_cli-1.3.0/PKG-INFO → scip_cli-2.0.0/README.md +88 -59
- scip_cli-2.0.0/pyproject.toml +59 -0
- scip_cli-2.0.0/scip_cli/SKILL.md +135 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/__init__.py +2 -1
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/__main__.py +75 -28
- scip_cli-2.0.0/scip_cli/analyze/__init__.py +1 -0
- scip_cli-2.0.0/scip_cli/analyze/common.py +110 -0
- scip_cli-2.0.0/scip_cli/analyze/file.py +354 -0
- scip_cli-2.0.0/scip_cli/analyze/project.py +435 -0
- scip_cli-2.0.0/scip_cli/analyze/sections.py +77 -0
- scip_cli-2.0.0/scip_cli/analyze/symbol.py +184 -0
- scip_cli-2.0.0/scip_cli/analyze/targets.py +97 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/cache.py +28 -5
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/cli_args.py +26 -1
- scip_cli-2.0.0/scip_cli/commands/analyze.py +142 -0
- scip_cli-2.0.0/scip_cli/commands/code.py +123 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/members.py +13 -14
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/rdeps.py +5 -13
- scip_cli-2.0.0/scip_cli/commands/refs.py +166 -0
- scip_cli-2.0.0/scip_cli/commands/reindex.py +69 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/search.py +98 -57
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/skill.py +7 -3
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/symbols.py +4 -6
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/config.py +3 -3
- scip_cli-2.0.0/scip_cli/debug.py +10 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/discover.py +14 -21
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/indexing.py +224 -74
- scip_cli-2.0.0/scip_cli/merge.py +108 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/output.py +56 -26
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/paths.py +37 -3
- scip_cli-2.0.0/scip_cli/project.py +42 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/queries.py +86 -75
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/scip_tool.py +25 -10
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/scope.py +1 -6
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/session.py +2 -1
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/source.py +12 -3
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/sql.py +7 -4
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/symbols.py +39 -12
- scip_cli-2.0.0/scip_cli/targets.py +17 -0
- scip_cli-2.0.0/scripts/build.sh +13 -0
- scip_cli-2.0.0/scripts/publish.sh +32 -0
- scip_cli-2.0.0/scripts/test.sh +9 -0
- scip_cli-2.0.0/tests/analyze_db.py +204 -0
- scip_cli-2.0.0/tests/conftest.py +25 -0
- scip_cli-2.0.0/tests/e2e_harness.py +101 -0
- scip_cli-2.0.0/tests/fixture_catalog.py +17 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/package.json +5 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/app/handler.ts +3 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/config.ts +1 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/consumer.ts +4 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/dead.ts +1 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/helper.ts +7 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/index.ts +3 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/user.ts +6 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/src/widget.ts +7 -0
- scip_cli-2.0.0/tests/fixtures/sample-project/tsconfig.json +8 -0
- scip_cli-2.0.0/tests/test_analyze.py +223 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_cache.py +2 -2
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_composability.py +44 -49
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_config.py +1 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_discover.py +1 -0
- scip_cli-2.0.0/tests/test_e2e.py +174 -0
- scip_cli-2.0.0/tests/test_index_prune.py +122 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_indexer_env.py +2 -1
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_merge.py +40 -21
- scip_cli-2.0.0/tests/test_multi_symbol.py +205 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_pure_functions.py +277 -270
- scip_cli-2.0.0/tests/test_qualified_symbols.py +100 -0
- scip_cli-2.0.0/tests/test_reindex.py +53 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_scip_tool.py +1 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_scope.py +7 -6
- scip_cli-2.0.0/tests/test_targets.py +17 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/tests/test_typescript_projects.py +1 -0
- scip_cli-1.3.0/MANIFEST.in +0 -4
- scip_cli-1.3.0/README.md +0 -257
- scip_cli-1.3.0/pyproject.toml +0 -13
- scip_cli-1.3.0/scip_cli/SKILL.md +0 -108
- scip_cli-1.3.0/scip_cli/commands/def_cmd.py +0 -57
- scip_cli-1.3.0/scip_cli/commands/refs.py +0 -136
- scip_cli-1.3.0/scip_cli/commands/reindex.py +0 -55
- scip_cli-1.3.0/scip_cli/constants.py +0 -14
- scip_cli-1.3.0/scip_cli/lib.py +0 -64
- scip_cli-1.3.0/scip_cli/merge.py +0 -175
- scip_cli-1.3.0/scip_cli/project.py +0 -29
- scip_cli-1.3.0/scip_cli.egg-info/SOURCES.txt +0 -51
- scip_cli-1.3.0/scip_cli.egg-info/entry_points.txt +0 -2
- scip_cli-1.3.0/scip_cli.egg-info/top_level.txt +0 -1
- scip_cli-1.3.0/setup.cfg +0 -4
- scip_cli-1.3.0/setup.py +0 -37
- scip_cli-1.3.0/tests/test_smoke_cli.py +0 -157
- {scip_cli-1.3.0 → scip_cli-2.0.0}/LICENSE +0 -0
- {scip_cli-1.3.0 → scip_cli-2.0.0}/scip_cli/commands/__init__.py +0 -0
- /scip_cli-1.3.0/scip_cli.egg-info/dependency_links.txt → /scip_cli-2.0.0/tests/__init__.py +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: scip-cli dev workflow and TDD with the shared fixture
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# scip-cli agent
|
|
7
|
+
|
|
8
|
+
**Work from repo root.** CLI usage, flags, and user gotchas: `scip-cli skill` (source: `scip_cli/SKILL.md`). Read once per task — do not duplicate SKILL here.
|
|
9
|
+
|
|
10
|
+
Use **`.venv/bin/scip-cli`** / **`.venv/bin/pytest`**. Uncommitted code: `PYTHONPATH=$PWD python -m scip_cli …` if the venv binary is stale.
|
|
11
|
+
|
|
12
|
+
## Bootstrap
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
python -m venv .venv && source .venv/bin/activate
|
|
16
|
+
pip install -e ".[dev]"
|
|
17
|
+
pre-commit install
|
|
18
|
+
scip-cli skill
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Node.js + `npx` required for integration tests (`scip-typescript`). Optional: `SCIP_CLI_DEBUG=1` (SQL to stderr, truncated).
|
|
22
|
+
|
|
23
|
+
## Lint / test
|
|
24
|
+
|
|
25
|
+
| Task | Command |
|
|
26
|
+
|------|---------|
|
|
27
|
+
| Full suite | `.venv/bin/pytest` |
|
|
28
|
+
| E2e loop | `.venv/bin/pytest tests/test_e2e.py` |
|
|
29
|
+
| Lint / format | `.venv/bin/ruff check .` / `ruff format .` |
|
|
30
|
+
|
|
31
|
+
Pre-commit: ruff + ruff-format + full pytest. E2e before commit on command changes.
|
|
32
|
+
|
|
33
|
+
## Improving this repo (do this before review subagents)
|
|
34
|
+
|
|
35
|
+
**Dogfood on the repo itself** — faster and more honest than spawning reviewers:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
.venv/bin/scip-cli reindex
|
|
39
|
+
.venv/bin/scip-cli analyze --limit 25
|
|
40
|
+
.venv/bin/scip-cli analyze --priority high --limit 25 # dead code & cycles only
|
|
41
|
+
.venv/bin/scip-cli analyze scip_cli --limit 15 # directory
|
|
42
|
+
.venv/bin/scip-cli analyze scip_cli/queries.py --limit 20 # file (+ scoped project)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Interpretation: README § *Finding easy wins with analyze*. Target = omit (project), directory, file, or symbol — not `--path` for scope.
|
|
46
|
+
|
|
47
|
+
| Priority | Section | Action |
|
|
48
|
+
|----------|---------|--------|
|
|
49
|
+
| 1 | **Cycles** | Break production file dependency cycles (`cache`↔`scope` was one) |
|
|
50
|
+
| 2 | **Unreferenced / dead exports** | No ref usage / no external refs — verify with `rg`, delete or `_` prefix |
|
|
51
|
+
| 3 | **Same-file only** | Module-private by usage — rename to `_` |
|
|
52
|
+
| 4 | **Stale types** | Low-consumer classes — merge or justify |
|
|
53
|
+
|
|
54
|
+
`analyze` skips test paths by default (`tests/`, `*.test.*`, `*.spec.*`); `--include-tests` to include. Reindex after large edits.
|
|
55
|
+
|
|
56
|
+
Do **not** spawn broad code-review agents until this pass is done (or explain why skipped).
|
|
57
|
+
|
|
58
|
+
## Analyze feedback loop (mandatory)
|
|
59
|
+
|
|
60
|
+
When you or a review subagent finds a repo issue — bug, dead code, cycle, risky hub, stale type, unused import — **stop and ask first:**
|
|
61
|
+
|
|
62
|
+
> *Could our SQLite index have predicted this, and `analyze` just doesn't surface it yet?*
|
|
63
|
+
|
|
64
|
+
If **yes** (the signal is in `documents`, `mentions`, `global_symbols`, `defn_enclosing_ranges`):
|
|
65
|
+
|
|
66
|
+
1. **Extend `analyze` first** — new or tuned SQL check in `scip_cli/analyze/`, priority in `sections.py`, tests in `tests/test_analyze.py` + `analyze_db.py`.
|
|
67
|
+
2. **Dogfood** — `reindex` → confirm the issue appears (or the false positive is filtered).
|
|
68
|
+
3. **Then** fix the production code (or document a known blind spot).
|
|
69
|
+
|
|
70
|
+
Only skip step 1 when the issue is **outside the index** (runtime, CLI UX, docs drift, git, env, concurrency, test harness).
|
|
71
|
+
|
|
72
|
+
### Retrospective: caught manually, SQLite already had it
|
|
73
|
+
|
|
74
|
+
| Issue we hit | Index signal | Analyze today | Gap / next check |
|
|
75
|
+
|--------------|--------------|---------------|------------------|
|
|
76
|
+
| `cache` ↔ `scope` import cycle | cross-file `mentions` edges | `[high] Cycles` | **Caught** — keep dogfooding cycles |
|
|
77
|
+
| Cross-file dead export (`get_refs_for_symbols`) | def with no external `mentions` | `[high] Dead exports` | **Caught** |
|
|
78
|
+
| Same-file-only dead code | def, `role=0` only in def file | `[high] Unreferenced` or `[medium] Same-file only` | **Caught** (since extended) |
|
|
79
|
+
| Same-file helper without `_` (`run_with_fallback`) | same-file `role=0` or none | `[medium] Same-file only` / unreferenced | **Caught** — rename to `_` |
|
|
80
|
+
| Typing-only dataclasses (`ProjectSettings`, `IndexScope`) | type `#` symbol, 0 consumer files | `[high] Stale types` + `stale_type_noise` | **Filtered** — index can't see annotations; document or optional `--types` |
|
|
81
|
+
| `analyze/*` section runners “dead” | no external refs | noise filter in `common.py` | **Filtered** — framework pattern |
|
|
82
|
+
| Unused import | `role=2` mention, no in-file use | `[high] Unused imports` (per file) | **Caught** on file target |
|
|
83
|
+
| Hub before editing (`resolve_symbol`, `queries.py`) | fan-in / consumer count | `[medium] Change surface` / `[low] Hotspots` | **Caught** on file target; project hubs are low tier |
|
|
84
|
+
| Symbol only used from tests | consumers all under `tests/` | `[low] Test-only consumers` | **Partial** — Python index often omits same-file `role=0`; verify with `rg` |
|
|
85
|
+
| Indexer omits same-file Python calls | no `role=0` for in-module use | unreferenced / test-only false positives | **Index gap** — not fixable in SQL alone; demoted test-only to low |
|
|
86
|
+
| Duplicate / parallel helpers | — | — | **Not in index** — `rg`, not analyze |
|
|
87
|
+
|
|
88
|
+
Add new rows to `dogfood.md` when you find another gap; implement the SQL check before the next manual review pass.
|
|
89
|
+
|
|
90
|
+
### Size / complexity checks (assessed — don’t promote to high/medium)
|
|
91
|
+
|
|
92
|
+
SQLite has **line ranges** (`defn_enclosing_ranges`) so LOC is cheap. That does **not** mean “big function” belongs next to dead exports.
|
|
93
|
+
|
|
94
|
+
| Idea | In index? | Verdict |
|
|
95
|
+
|------|-----------|---------|
|
|
96
|
+
| **LOC ≥ N** alone | Yes | **LOW at best** — noisy (`main`, argparse, legitimate parsers). Not a nuke candidate. |
|
|
97
|
+
| **LOC + fan-in** (large hub) | Yes | **Already covered** by `[low] Bottlenecks` (fan-in × fan-out). Add `loc=` to that output if helpful; don’t duplicate as medium. |
|
|
98
|
+
| **LOC + consumers** on file target | Yes | **Change surface** (medium) already sorts by consumers with line ranges — drill there. |
|
|
99
|
+
| **Symbol pressure** | Yes | **Per-symbol** `analyze Foo` shows `loc × fan_in × fan_out`. |
|
|
100
|
+
| **God class / many members** | Yes | Use `members Class` — not analyze. |
|
|
101
|
+
| **File byte size / cyclomatic complexity** | No | Out of scope for SCIP index. |
|
|
102
|
+
| **Fat file (many symbols)** | Yes | Low value; coupling/hotspots approximate module heat. |
|
|
103
|
+
|
|
104
|
+
**Rule:** size-only checks stay **low or file-drill-down**; never high/medium unless paired with a **structural smell** (cycle, dead export, zero production consumers). Prefer enriching existing low-tier lines (e.g. show `loc` on bottlenecks) over a new dashboard section.
|
|
105
|
+
|
|
106
|
+
## TDD
|
|
107
|
+
|
|
108
|
+
1. **Red** — `tests/test_e2e.py` + `fixture_catalog` constants.
|
|
109
|
+
2. **Green** — `scip_cli/commands/*.py`.
|
|
110
|
+
3. **Refactor** — unit tests for pure helpers only.
|
|
111
|
+
|
|
112
|
+
- **E2e** (`cli` fixture): in-process `main()`, TS project indexed once per session — default for behavior.
|
|
113
|
+
- **Unit**: `:memory:` SQLite, `tests/analyze_db.py`, merge/index prune tests.
|
|
114
|
+
- **No subprocess** for CLI tests; no `reindex` in e2e (mutates `~/.cache/scip-cli`).
|
|
115
|
+
- New symbols: extend `tests/fixtures/sample-project/` + `fixture_catalog.py`.
|
|
116
|
+
|
|
117
|
+
## Codebase map (contributors)
|
|
118
|
+
|
|
119
|
+
| Area | Path | Notes |
|
|
120
|
+
|------|------|-------|
|
|
121
|
+
| Commands | `scip_cli/commands/` | Thin; SQL in `queries.py` / `analyze/` |
|
|
122
|
+
| Index build | `scip_cli/indexing.py` | `index.db.next` → promote; flock; `>10` tsconfigs log progress |
|
|
123
|
+
| Variable prune | postprocess + `merge.py` | Omit const/let/var on **COPY**, not DELETE — no `variable` kind |
|
|
124
|
+
| Session | `scip_cli/session.py` | `setup()`, `resolve_one_symbol` (limit 2 for ambiguity) |
|
|
125
|
+
| Analyze filters | `scip_cli/analyze/common.py` | `is_test_path`, `analyze_noise` (`_` helpers) |
|
|
126
|
+
|
|
127
|
+
`todo.md` = tracked work; `dogfood.md` = future ideas only. Wishlist/backlog in `docs/` per workspace rules.
|
|
128
|
+
|
|
129
|
+
## Docs touch points
|
|
130
|
+
|
|
131
|
+
- User install + analyze guide → `README.md`
|
|
132
|
+
- Agent/user CLI reference → `scip_cli/SKILL.md` (must match `__main__.py` flags)
|
|
133
|
+
- After flag changes: update SKILL + README command list; run `scip-cli skill` to verify output
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
.venv
|
|
28
|
+
|
|
29
|
+
# IDE
|
|
30
|
+
.vscode/
|
|
31
|
+
.idea/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
*~
|
|
35
|
+
|
|
36
|
+
# OS
|
|
37
|
+
.DS_Store
|
|
38
|
+
Thumbs.db
|
|
39
|
+
|
|
40
|
+
# Env/secrets
|
|
41
|
+
.env
|
|
42
|
+
|
|
43
|
+
# Pytest
|
|
44
|
+
.pytest_cache/
|
|
45
|
+
|
|
46
|
+
# Project specific
|
|
47
|
+
TODO.md
|
|
48
|
+
todo.md
|
|
49
|
+
dogfood.md
|
|
50
|
+
|
|
51
|
+
# Local-only dev scripts (repo-specific smoke harnesses)
|
|
52
|
+
scripts/deep-smoke.sh
|
|
53
|
+
tmp/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.11.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: local
|
|
9
|
+
hooks:
|
|
10
|
+
- id: pytest
|
|
11
|
+
name: pytest
|
|
12
|
+
entry: pytest
|
|
13
|
+
language: python
|
|
14
|
+
pass_filenames: false
|
|
15
|
+
always_run: true
|
|
@@ -1,81 +1,78 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scip-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Fast code intelligence via SCIP indexes
|
|
5
|
-
|
|
5
|
+
Project-URL: Homepage, https://github.com/flesler/scip-cli
|
|
6
6
|
Author: Ariel Flesler
|
|
7
7
|
License: MIT
|
|
8
|
-
|
|
8
|
+
License-File: LICENSE
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
12
|
Classifier: Topic :: Software Development :: Code Generators
|
|
12
13
|
Requires-Python: >=3.9
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: build>=1; extra == 'dev'
|
|
16
|
+
Requires-Dist: pre-commit>=4.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
18
|
+
Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
13
19
|
Description-Content-Type: text/markdown
|
|
14
|
-
License-File: LICENSE
|
|
15
|
-
Dynamic: author
|
|
16
|
-
Dynamic: classifier
|
|
17
|
-
Dynamic: description
|
|
18
|
-
Dynamic: description-content-type
|
|
19
|
-
Dynamic: home-page
|
|
20
|
-
Dynamic: license
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
Dynamic: requires-python
|
|
23
|
-
Dynamic: summary
|
|
24
20
|
|
|
25
21
|
# scip-cli
|
|
26
22
|
|
|
27
23
|
[](https://badge.fury.io/py/scip-cli)
|
|
28
24
|
[](https://opensource.org/licenses/MIT)
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
Token-efficient code intelligence for AI agents. Precise refs, definitions, and repo health analysis via SCIP indexes — TypeScript/JavaScript and Python.
|
|
27
|
+
|
|
28
|
+
## Why
|
|
29
|
+
|
|
30
|
+
AI agents waste tokens on grep and file scanning. scip-cli gives them precise, type-aware code navigation in milliseconds — and `analyze` surfaces dead code, cycles, and coupling so agents (and humans) can fix real problems fast.
|
|
31
31
|
|
|
32
32
|
## Features
|
|
33
33
|
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
-
|
|
34
|
+
- **Agent-first**: Install as a skill for Claude Code, Cursor, or any AI agent — precise code navigation without burning context
|
|
35
|
+
- **Token-efficient**: One record per line, stderr for warnings, pipe-friendly output
|
|
36
|
+
- **Fast**: Direct SQLite queries — 10x to 213x faster than alternatives
|
|
37
|
+
- **`analyze`**: Find dead exports, import cycles, stale types, coupling hotspots — actionable health dashboards at project, file, or symbol scope
|
|
38
|
+
- **Auto-indexing**: Indexes on first query, caches in SQLite, zero config
|
|
38
39
|
|
|
39
40
|
## For AI Agents
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
Install as a reusable skill so your agent always knows how to navigate the codebase:
|
|
42
43
|
|
|
43
44
|
```bash
|
|
44
|
-
scip-cli skill
|
|
45
|
+
scip-cli skill ~/.claude/skills/scip-cli/ # Claude Code
|
|
46
|
+
scip-cli skill ~/.cursor/skills/scip-cli/ # Cursor
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
Or
|
|
49
|
+
Or dump the quick reference for one-off use:
|
|
48
50
|
|
|
49
51
|
```bash
|
|
50
|
-
scip-cli skill
|
|
52
|
+
scip-cli skill
|
|
51
53
|
```
|
|
52
54
|
|
|
53
|
-
This enables commands like `def`, `refs`, `search`, `symbols`, `rdeps`, and `members` - just ask "where is X?" or "find references to X".
|
|
54
|
-
|
|
55
55
|
## Installation
|
|
56
56
|
|
|
57
57
|
### 1. Install scip-cli
|
|
58
58
|
|
|
59
|
-
**From PyPI
|
|
59
|
+
**From PyPI** (end users):
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
pip install scip-cli
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
**
|
|
65
|
+
**Local development** (use a project venv — do not rely on global `pip`):
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
git clone https://github.com/flesler/scip-cli.git
|
|
69
68
|
cd scip-cli
|
|
70
|
-
|
|
69
|
+
python -m venv .venv
|
|
70
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
71
|
+
pip install -e ".[dev]"
|
|
72
|
+
scip-cli --version
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
export PYTHONPATH=/path/to/scip-cli:$PYTHONPATH
|
|
77
|
-
python -m scip_cli --help
|
|
78
|
-
```
|
|
75
|
+
`pip install -e .` keeps `scip-cli` on your PATH inside the venv while you edit the repo. Run tests with `pytest` from the same venv.
|
|
79
76
|
|
|
80
77
|
### 2. Install prerequisites (optional)
|
|
81
78
|
|
|
@@ -125,11 +122,12 @@ scip-cli <command> [arguments]
|
|
|
125
122
|
### Commands
|
|
126
123
|
|
|
127
124
|
- `refs <symbol>` - Find all references to a symbol (`--path` to scope)
|
|
128
|
-
- `
|
|
125
|
+
- `code <symbol>` - Find symbol definition with source code (`--path`, `--max-lines`, `--full`, `--offset`, `--snippet`, `--line-numbers`)
|
|
129
126
|
- `search <pattern>` - Search symbols by name pattern (`--path`)
|
|
130
127
|
- `symbols <file>` - List all symbols in a file (`--path`; bare filename OK)
|
|
131
128
|
- `rdeps <file>` - Find files that depend on a file (`--path`)
|
|
132
129
|
- `members <symbol>` - List members of a class/interface (`--path`)
|
|
130
|
+
- `analyze [target]` - SQL health dashboards (`--limit`, `--priority`, `--include-tests`). No target: project-wide; directory or file path; symbol name. See [Finding easy wins with `analyze`](#finding-easy-wins-with-analyze).
|
|
133
131
|
- `reindex` - Force re-indexing of the current project (`--path` to limit scope; repeatable)
|
|
134
132
|
- `skill [path]` - Install or dump the SKILL.md
|
|
135
133
|
|
|
@@ -140,13 +138,13 @@ scip-cli <command> [arguments]
|
|
|
140
138
|
scip-cli refs greet
|
|
141
139
|
|
|
142
140
|
# Get definition of greet
|
|
143
|
-
scip-cli
|
|
141
|
+
scip-cli code greet
|
|
144
142
|
|
|
145
143
|
# Search for symbols matching "Widget"
|
|
146
144
|
scip-cli search Widget
|
|
147
145
|
|
|
148
146
|
# Scope to a subdirectory
|
|
149
|
-
scip-cli
|
|
147
|
+
scip-cli code greet --path packages/api
|
|
150
148
|
|
|
151
149
|
# List symbols by bare filename
|
|
152
150
|
scip-cli symbols helper.ts
|
|
@@ -157,13 +155,16 @@ scip-cli rdeps src/helper.ts
|
|
|
157
155
|
# List members of a class
|
|
158
156
|
scip-cli members Widget
|
|
159
157
|
|
|
158
|
+
# Project health dashboard (or: scip-cli analyze src/foo.ts / scip-cli analyze greet)
|
|
159
|
+
scip-cli analyze
|
|
160
|
+
|
|
160
161
|
# Install skill file
|
|
161
162
|
scip-cli skill ~/.claude/skills/scip-cli/SKILL.md
|
|
162
163
|
```
|
|
163
164
|
|
|
164
165
|
### Pipelines
|
|
165
166
|
|
|
166
|
-
Stdout is one record per line; stderr carries warnings and ambiguity notices. Kinds are lowercase (`function`, `class`, `method`, `property
|
|
167
|
+
Stdout is one record per line; stderr carries warnings and ambiguity notices. Kinds are lowercase (`function`, `class`, `method`, `property`). Pipe-friendly flags: `refs --paths-only`, `search --names-only` / `--paths-only`, `members --names-only`. `rdeps` already prints bare file paths.
|
|
167
168
|
|
|
168
169
|
```bash
|
|
169
170
|
# What do importers of this file export?
|
|
@@ -176,7 +177,7 @@ scip-cli refs greet --paths-only
|
|
|
176
177
|
scip-cli search Handler --kind class --names-only | xargs -I{} scip-cli members {}
|
|
177
178
|
|
|
178
179
|
# Walk class members to their definitions
|
|
179
|
-
scip-cli members Widget --names-only | xargs -I{} scip-cli
|
|
180
|
+
scip-cli members Widget --names-only | xargs -I{} scip-cli code Widget.{}
|
|
180
181
|
```
|
|
181
182
|
|
|
182
183
|
## How It Works
|
|
@@ -206,10 +207,12 @@ Optional `.scip-cli.json` in the project root:
|
|
|
206
207
|
|
|
207
208
|
`SCIP_CLI_INDEX_WORKERS` controls parallel `scip-typescript` runs during first index (default: up to 8). Merge into one database is always serial.
|
|
208
209
|
|
|
210
|
+
Large monorepos (>10 tsconfig projects) log per-project progress to stderr during indexing; smaller repos stay quiet aside from the final `Indexed … (size)` line.
|
|
211
|
+
|
|
209
212
|
Scoped indexing without editing `.scip-cli.json`:
|
|
210
213
|
|
|
211
214
|
```bash
|
|
212
|
-
scip-cli reindex --path
|
|
215
|
+
scip-cli reindex --path packages/server
|
|
213
216
|
scip-cli reindex --path packages/api --path packages/worker
|
|
214
217
|
```
|
|
215
218
|
|
|
@@ -217,20 +220,63 @@ scip-cli reindex --path packages/api --path packages/worker
|
|
|
217
220
|
|
|
218
221
|
Run `scip-cli reindex` after changing scope, `.scip-cli.json` index settings, or when you want a fresh index.
|
|
219
222
|
|
|
220
|
-
|
|
223
|
+
## Finding easy wins with `analyze`
|
|
224
|
+
|
|
225
|
+
Use `analyze` on the repo itself before broad refactors or agent review — it surfaces cross-file issues from the SCIP index (not Python `vulture`).
|
|
226
|
+
|
|
227
|
+
**Quick pass** (after `scip-cli reindex`):
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
scip-cli analyze --limit 25
|
|
231
|
+
scip-cli analyze --priority high --limit 25 # dead exports & cycles only
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Sections are tagged `[high]`, `[medium]`, `[low]` and listed in that order.
|
|
235
|
+
|
|
236
|
+
| Tier | Project sections | Action |
|
|
237
|
+
| ---- | ---------------- | ------ |
|
|
238
|
+
| **high** | Cycles, unreferenced, dead exports, stale types | Nuke or fix cycles; delete unused; `_` prefix |
|
|
239
|
+
| **medium** | Same-file only, change surface (file target) | Module-private by usage |
|
|
240
|
+
| **low** | Test-only consumers, coupling, bottlenecks, hotspots | Noisy on Python (index omits many same-file calls); verify with `rg` |
|
|
241
|
+
|
|
242
|
+
Use `--priority high` for a quick gate; `--priority high,medium` adds context. File drill-down adds change surface and unused imports.
|
|
243
|
+
|
|
244
|
+
**What to look at first**
|
|
245
|
+
|
|
246
|
+
| Section | Easy pickings |
|
|
247
|
+
| ------- | ------------- |
|
|
248
|
+
| **Cycles** | Import/mention cycles between production files — break the edge or extract shared code |
|
|
249
|
+
| **Unreferenced** | No usage in the index at all — delete |
|
|
250
|
+
| **Dead exports** | No external refs — delete or `_` prefix |
|
|
251
|
+
| **Stale types** | Classes/types with ≤1 external consumer — merge, inline, or document why they stay |
|
|
252
|
+
| **Same-file only** | Used only inside defining file — rename to `_` |
|
|
253
|
+
| **Test-only consumers** | Cross-file refs are all from tests — promote to e2e or accept as internal |
|
|
254
|
+
|
|
255
|
+
**Per-file or package drill-down** on hubs or suspects:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
scip-cli analyze scip_cli/queries.py --limit 20 # file: scoped project + per-file + top symbols
|
|
259
|
+
scip-cli analyze scip_cli --limit 15 # directory: scoped project + each file under it
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`Dead exports in file` lists same-module symbols with no *external* refs — module-private `_helpers` are filtered out. Remaining rows are worth a manual `rg` check.
|
|
263
|
+
|
|
264
|
+
**Defaults:** project-wide and directory analyze skip `tests/`, `*.test.*`, `*.spec.*`, `conftest.py`, and `__tests__/`. Pass `--include-tests` to include them. File-target analyze always includes that file.
|
|
265
|
+
|
|
266
|
+
**Limits:** “Dead export” means no cross-file mentions in the index — not unreachable code. Same-file private helpers are expected. Re-run `reindex` after large changes; the index is a snapshot.
|
|
221
267
|
|
|
222
268
|
## Performance
|
|
223
269
|
|
|
224
|
-
Inspired by [scip-query](https://github.com/PlunderStruck/scip-query), scip-cli is a lightweight Python reimplementation optimized for speed. Compared to the original
|
|
270
|
+
Inspired by [scip-query](https://github.com/PlunderStruck/scip-query), scip-cli is a lightweight Python partial reimplementation optimized for speed. Compared to the original:
|
|
225
271
|
|
|
226
272
|
- `refs`: 6.4s → 0.03s (213x faster)
|
|
227
|
-
- `
|
|
273
|
+
- `code`: 2.8s → 0.05s (56x faster)
|
|
228
274
|
- `search`: 2.6s → 0.03s (87x faster)
|
|
229
275
|
- `symbols`: 0.3s → 0.02s (15x faster)
|
|
230
276
|
- `rdeps`: 0.2s → 0.02s (10x faster)
|
|
231
277
|
- `members`: 3.1s → 0.03s (103x faster)
|
|
232
278
|
|
|
233
|
-
The speedup comes from direct SQLite queries
|
|
279
|
+
The speedup comes from using optimized direct SQLite queries and cutting some nice but very slow goodies (like ts-morph).
|
|
234
280
|
|
|
235
281
|
## Architecture
|
|
236
282
|
|
|
@@ -243,38 +289,41 @@ scip_cli/
|
|
|
243
289
|
├── discover.py # TypeScript project discovery
|
|
244
290
|
├── merge.py # SQLite index merging
|
|
245
291
|
├── scip_tool.py # scip binary download
|
|
246
|
-
├── constants.py # Shared constants
|
|
247
292
|
├── sql.py # SQLite helpers
|
|
248
293
|
├── paths.py # --path scope filtering
|
|
249
294
|
├── project.py # Project root + language detection
|
|
250
295
|
├── cache.py # Index cache paths
|
|
296
|
+
├── scope.py # Persisted reindex scope (index-scope.json)
|
|
297
|
+
├── debug.py # SCIP_CLI_DEBUG stderr helpers
|
|
251
298
|
├── indexing.py # SCIP index build + get_db
|
|
252
299
|
├── symbols.py # Symbol parsing and kinds
|
|
253
300
|
├── queries.py # Symbol/file SQL queries
|
|
254
301
|
├── source.py # Filesystem source reads
|
|
255
302
|
├── output.py # CLI formatting helpers
|
|
256
303
|
├── session.py # setup() and single-match resolution
|
|
304
|
+
├── targets.py # file-path heuristics (tests; analyze uses analyze/targets.py)
|
|
305
|
+
├── analyze/ # SQL dashboard queries (project/file/symbol)
|
|
257
306
|
└── commands/ # Subcommand implementations
|
|
258
307
|
```
|
|
259
308
|
|
|
260
309
|
## Development
|
|
261
310
|
|
|
262
311
|
```bash
|
|
263
|
-
pip install -e .
|
|
312
|
+
pip install -e ".[dev]"
|
|
264
313
|
pytest tests/ -q
|
|
265
314
|
pytest tests/ -m integration -q # indexes tests/fixtures/sample-project (needs scip-typescript)
|
|
266
315
|
```
|
|
267
316
|
|
|
268
317
|
### Debug Logging
|
|
269
318
|
|
|
270
|
-
Set `SCIP_CLI_DEBUG=1` to enable SQL query logging to stderr:
|
|
319
|
+
Set `SCIP_CLI_DEBUG=1` to enable SQL query logging to stderr (statements truncated to 200 chars):
|
|
271
320
|
|
|
272
321
|
```bash
|
|
273
322
|
SCIP_CLI_DEBUG=1 scip-cli refs MyFunction
|
|
274
323
|
# Shows: SQL: SELECT ... | params: (...)
|
|
275
324
|
```
|
|
276
325
|
|
|
277
|
-
This is useful for testing and debugging SQL queries
|
|
326
|
+
This is useful for testing and debugging SQL queries
|
|
278
327
|
|
|
279
328
|
## License
|
|
280
329
|
|