context-router-cli 0.2.0__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.
cli/main.py ADDED
@@ -0,0 +1,47 @@
1
+ """context-router CLI — main entrypoint.
2
+
3
+ All commands are registered here. Business logic lives in the command
4
+ modules under cli/commands/ and in the core/storage packages — never here.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import typer
10
+
11
+ from cli.commands.benchmark import benchmark_app
12
+ from cli.commands.graph import graph_app
13
+ from cli.commands.decisions import decisions_app
14
+ from cli.commands.workspace import workspace_app
15
+ from cli.commands.explain import explain_app
16
+ from cli.commands.index import index_app
17
+ from cli.commands.init import init_app
18
+ from cli.commands.mcp import mcp_app
19
+ from cli.commands.memory import memory_app
20
+ from cli.commands.pack import pack_app
21
+ from cli.commands.watch import watch_app
22
+
23
+ app = typer.Typer(
24
+ name="context-router",
25
+ help=(
26
+ "Local-first context selector for AI coding agents.\n\n"
27
+ "Selects the minimum useful context across code structure, "
28
+ "runtime evidence, and project memory for review, debug, "
29
+ "implement, and handover tasks."
30
+ ),
31
+ no_args_is_help=True,
32
+ )
33
+
34
+ app.add_typer(init_app, name="init")
35
+ app.add_typer(index_app, name="index")
36
+ app.add_typer(watch_app, name="watch")
37
+ app.add_typer(pack_app, name="pack")
38
+ app.add_typer(explain_app, name="explain")
39
+ app.add_typer(memory_app, name="memory")
40
+ app.add_typer(decisions_app, name="decisions")
41
+ app.add_typer(benchmark_app, name="benchmark")
42
+ app.add_typer(workspace_app, name="workspace")
43
+ app.add_typer(mcp_app, name="mcp")
44
+ app.add_typer(graph_app, name="graph")
45
+
46
+ if __name__ == "__main__":
47
+ app()
@@ -0,0 +1,632 @@
1
+ Metadata-Version: 2.4
2
+ Name: context-router-cli
3
+ Version: 0.2.0
4
+ Summary: Local-first CLI and MCP server for AI coding context — minimum useful context, maximum agent performance
5
+ Project-URL: Homepage, https://github.com/mohankrishnaalavala/context-router
6
+ Project-URL: Bug Tracker, https://github.com/mohankrishnaalavala/context-router/issues
7
+ Project-URL: Changelog, https://github.com/mohankrishnaalavala/context-router/blob/main/CHANGELOG.md
8
+ License: MIT
9
+ Keywords: ai,code-analysis,context,developer-tools,llm,mcp
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: >=3.12
17
+ Requires-Dist: context-router-adapters-claude
18
+ Requires-Dist: context-router-adapters-codex
19
+ Requires-Dist: context-router-adapters-copilot
20
+ Requires-Dist: context-router-benchmark
21
+ Requires-Dist: context-router-contracts
22
+ Requires-Dist: context-router-core
23
+ Requires-Dist: context-router-graph-index
24
+ Requires-Dist: context-router-language-python
25
+ Requires-Dist: context-router-language-typescript
26
+ Requires-Dist: context-router-language-yaml
27
+ Requires-Dist: context-router-memory
28
+ Requires-Dist: context-router-ranking
29
+ Requires-Dist: context-router-runtime
30
+ Requires-Dist: context-router-storage-sqlite
31
+ Requires-Dist: context-router-workspace
32
+ Requires-Dist: typer>=0.12
33
+ Provides-Extra: semantic
34
+ Requires-Dist: sentence-transformers>=2.2; extra == 'semantic'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # context-router
38
+
39
+ A local-first CLI and MCP server that selects the **minimum useful context** across code structure, runtime evidence, and project memory for AI coding agents — reducing token consumption on review, debug, implement, and handover tasks.
40
+
41
+ ## Why
42
+
43
+ AI coding agents work best with focused, relevant context rather than entire codebases. context-router:
44
+
45
+ - Indexes your repo's symbols, dependency edges, call graphs, and test coverage into a local SQLite database
46
+ - Ranks candidates by structural relevance, query similarity, and community membership for your task mode
47
+ - Enforces a configurable token budget so your agent prompt stays lean (64.7% average reduction)
48
+ - Explains every selection decision in one human-readable sentence
49
+ - Supports multi-repo workspaces with cross-repo confidence boosting
50
+ - Works as a CLI, MCP server, or Python library — no API key required
51
+
52
+ ## Feature Overview
53
+
54
+ | Feature | Detail |
55
+ |---|---|
56
+ | **Language support** | Python (full), TypeScript/JS (full), YAML (k8s/Helm/GHA), Java, .NET (stubs) |
57
+ | **Edge types** | `imports`, `calls` (function-level), `tested_by`, community links |
58
+ | **Task modes** | `review`, `implement`, `debug`, `handover` |
59
+ | **Ranking** | Confidence scoring, query keyword boost, optional semantic boost (sentence-transformers) |
60
+ | **Token budget** | Hard cap with per-source-type guarantee; dynamic scaling for small repos |
61
+ | **Memory** | Persistent session observations + architectural decision records (FTS search) |
62
+ | **Multi-repo** | Workspace YAML, cross-repo link detection, unified ranked pack |
63
+ | **Graph viz** | Interactive D3.js HTML — color by kind or community cluster |
64
+ | **MCP server** | 8 tools over stdio JSON-RPC 2.0, compatible with Claude Code, Cursor, Windsurf |
65
+ | **Agent adapters** | Claude system prompt, Copilot instructions, Codex task prompt |
66
+ | **Benchmarks** | 20-task suite, 3 baselines, Markdown report |
67
+
68
+ ## Requirements
69
+
70
+ - Python 3.12+
71
+ - [uv](https://docs.astral.sh/uv/) package manager
72
+
73
+ ## Install
74
+
75
+ ```bash
76
+ git clone https://github.com/mohankrishnaalavala/context-router
77
+ cd context-router
78
+ uv sync --all-packages
79
+ ```
80
+
81
+ > **PyPI install (coming soon):** `pip install context-router`
82
+
83
+ ---
84
+
85
+ ## Quickstart
86
+
87
+ ```bash
88
+ # 1. Initialize a project (creates .context-router/ with config + SQLite DB)
89
+ uv run context-router init
90
+
91
+ # 2. Index the repository — extracts symbols, call edges, test links, communities
92
+ uv run context-router index
93
+
94
+ # 3. Generate a context pack for a code review
95
+ uv run context-router pack --mode review
96
+
97
+ # 4. Implement a feature — query-aware ranking surfaces the right files
98
+ uv run context-router pack --mode implement --query "add pagination to the users endpoint"
99
+
100
+ # 5. Debug a failure — parse an error file and rank by blast radius
101
+ uv run context-router pack --mode debug --error-file pytest-output.xml
102
+
103
+ # 6. Explain what was selected and why
104
+ uv run context-router explain last-pack
105
+
106
+ # 7. Visualize the symbol graph
107
+ uv run context-router graph --open
108
+
109
+ # 8. Get machine-readable JSON for scripts or agent prompts
110
+ uv run context-router pack --mode review --json
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Commands Reference
116
+
117
+ | Command | Purpose |
118
+ |---|---|
119
+ | [`init`](#init) | Initialize `.context-router/` config and database |
120
+ | [`index`](#index) | Scan and index all source files |
121
+ | [`watch`](#watch) | Incrementally re-index on file save |
122
+ | [`pack`](#pack) | Generate a ranked context pack |
123
+ | [`explain`](#explain) | Explain the last pack's selections |
124
+ | [`memory`](#memory) | Add/search session observations |
125
+ | [`decisions`](#decisions) | Add/search architectural decision records |
126
+ | [`graph`](#graph) | Generate interactive HTML graph visualization |
127
+ | [`workspace`](#workspace) | Multi-repo workspace management |
128
+ | [`benchmark`](#benchmark) | Run 20-task benchmark suite |
129
+ | [`mcp`](#mcp) | Start the MCP server (for Claude Code, Cursor, Windsurf) |
130
+
131
+ ---
132
+
133
+ ### `init`
134
+
135
+ Initialize a project. Creates `.context-router/config.yaml` and `.context-router/context-router.db`.
136
+
137
+ ```
138
+ context-router init [--project-root PATH] [--json]
139
+ ```
140
+
141
+ ---
142
+
143
+ ### `index`
144
+
145
+ Scan and index the repository.
146
+
147
+ ```
148
+ context-router index [--project-root PATH] [--repo REPO_NAME]
149
+ ```
150
+
151
+ Walks all source files, runs language analyzers (discovered via `context_router.language_analyzers` entry points), and writes to the local DB:
152
+
153
+ - **Symbols** — functions, classes, interfaces, k8s resources, GitHub Actions jobs
154
+ - **Import edges** — which files import which modules
155
+ - **Call edges** — which functions call which functions (Python, TypeScript)
156
+ - **TESTED_BY edges** — links `test_foo` → `foo` by name convention
157
+ - **Community IDs** — Union-Find clustering of connected symbols
158
+
159
+ ```bash
160
+ uv run context-router index
161
+ # Indexed 286 files — 1765 symbols, 3174 edges (2.82s)
162
+ ```
163
+
164
+ ---
165
+
166
+ ### `watch`
167
+
168
+ Watch for file changes and incrementally re-index.
169
+
170
+ ```
171
+ context-router watch [--project-root PATH]
172
+ ```
173
+
174
+ ---
175
+
176
+ ### `pack`
177
+
178
+ Generate a ranked context pack for a task.
179
+
180
+ ```
181
+ context-router pack --mode MODE [--query TEXT] [--project-root PATH] [--json]
182
+ ```
183
+
184
+ **Modes:**
185
+
186
+ | Mode | Ranking priority | Best for |
187
+ |---|---|---|
188
+ | `review` | changed files → blast radius → impacted tests → config | PR review, diff analysis |
189
+ | `implement` | entrypoints → contracts → extension points → patterns | Building new features |
190
+ | `debug` | runtime signal match → failing tests → changed files → call chain | Fixing errors, CI failures |
191
+ | `handover` | recent changes → memory observations → decisions → blast radius | Onboarding, sprint docs |
192
+
193
+ **Token budget** (default: 8 000 tokens) is read from `.context-router/config.yaml`. Items are dropped lowest-confidence first, but at least one item per source category is always preserved.
194
+
195
+ The pack is saved to `.context-router/last-pack.json` for later inspection.
196
+
197
+ **Examples:**
198
+
199
+ ```bash
200
+ # Review mode — surfaces changed files and their dependencies
201
+ uv run context-router pack --mode review
202
+
203
+ # Implement with query — boosts items matching "rate limiting"
204
+ uv run context-router pack --mode implement --query "add rate limiting to API endpoints"
205
+
206
+ # Debug with error file — parse pytest/JUnit XML to find root cause
207
+ uv run context-router pack --mode debug --error-file test-results.xml
208
+
209
+ # JSON output for piping into agent prompts
210
+ uv run context-router pack --mode review --json | jq '.selected_items[].title'
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `explain`
216
+
217
+ Explain the last generated context pack.
218
+
219
+ ```
220
+ context-router explain last-pack [--json]
221
+ ```
222
+
223
+ ```
224
+ [changed_file] build_pack (orchestrator.py) — Modified in current diff
225
+ [blast_radius] ContextRanker (ranker.py) — Depends on a changed file
226
+ [impacted_test] test_ranker.py — Tests code affected by this change
227
+ [contract] ContextItem (models.py) — Data contract or interface definition
228
+ ```
229
+
230
+ ---
231
+
232
+ ### `memory`
233
+
234
+ Persist and search session observations. Stored in the local SQLite DB with FTS5 full-text search.
235
+
236
+ ```
237
+ context-router memory add --from-session SESSION.json
238
+ context-router memory search QUERY
239
+ context-router memory stale
240
+ ```
241
+
242
+ `stale` lists observations whose referenced files no longer exist in the index.
243
+
244
+ **Examples:**
245
+
246
+ ```bash
247
+ # Search for past observations about authentication
248
+ uv run context-router memory search "auth token"
249
+
250
+ # Find observations referencing files that were deleted
251
+ uv run context-router memory stale
252
+ ```
253
+
254
+ ---
255
+
256
+ ### `decisions`
257
+
258
+ Manage architectural decision records (ADRs). Persisted with FTS5 search across title, context, and decision fields.
259
+
260
+ ```
261
+ context-router decisions add TITLE [--decision TEXT] [--context TEXT] [--consequences TEXT] [--tags TAGS] [--status STATUS]
262
+ context-router decisions search QUERY
263
+ context-router decisions list
264
+ ```
265
+
266
+ `--status` accepts: `proposed` | `accepted` | `deprecated` | `superseded`
267
+
268
+ **Examples:**
269
+
270
+ ```bash
271
+ # Record a new ADR
272
+ uv run context-router decisions add "Use SQLite for local storage" \
273
+ --decision "SQLite + FTS5 chosen over PostgreSQL" \
274
+ --context "Need offline-capable storage" \
275
+ --status accepted
276
+
277
+ # Search decisions by keyword
278
+ uv run context-router decisions search "database"
279
+ ```
280
+
281
+ ---
282
+
283
+ ### `graph`
284
+
285
+ Generate a self-contained interactive HTML graph visualization of the indexed symbol graph.
286
+
287
+ ```
288
+ context-router graph [--project-root PATH] [--output PATH] [--open] [--json]
289
+ ```
290
+
291
+ - Nodes are **colored by kind** (function=green, class=blue, interface=teal, k8s=orange) or by **community cluster** (toggle in the UI)
292
+ - Node **size** reflects degree (more connections = larger)
293
+ - **Click** any node for a details panel (file, kind, community, signature)
294
+ - **Search/filter** by symbol name
295
+ - **Zoom/pan** with scroll and drag
296
+ - `--open` launches your default browser immediately
297
+
298
+ ```bash
299
+ # Generate and open in browser
300
+ uv run context-router graph --open
301
+
302
+ # Save to a path for sharing or docs
303
+ uv run context-router graph --output ./docs/graph.html
304
+
305
+ # Raw JSON for programmatic use
306
+ uv run context-router graph --json
307
+ ```
308
+
309
+ ---
310
+
311
+ ### `workspace`
312
+
313
+ Manage multi-repo workspaces with cross-repo context packs.
314
+
315
+ ```
316
+ context-router workspace init [--root PATH] [--name NAME]
317
+ context-router workspace repo add NAME PATH [--root PATH]
318
+ context-router workspace repo list [--root PATH] [--json]
319
+ context-router workspace link add FROM TO [--root PATH]
320
+ context-router workspace pack --mode MODE [--query TEXT] [--root PATH] [--json]
321
+ ```
322
+
323
+ **How it works:**
324
+
325
+ 1. `workspace init` creates `workspace.yaml` at the root
326
+ 2. `repo add` registers each repo and captures its git branch/SHA
327
+ 3. `link add` declares a dependency between repos (boosts cross-repo confidence)
328
+ 4. `pack` runs `Orchestrator` per repo, merges candidates labelled with `[repo-name]`, and re-ranks within a unified token budget
329
+
330
+ ```bash
331
+ # Set up a two-repo workspace
332
+ uv run context-router workspace init
333
+ uv run context-router workspace repo add api ./services/api
334
+ uv run context-router workspace repo add frontend ./services/frontend
335
+ uv run context-router workspace link add frontend api
336
+ uv run context-router workspace pack --mode review
337
+ ```
338
+
339
+ ---
340
+
341
+ ### `benchmark`
342
+
343
+ Run the built-in 20-task suite and measure token reduction vs naive/keyword baselines.
344
+
345
+ ```
346
+ context-router benchmark run [--project-root PATH] [--output PATH] [--json]
347
+ context-router benchmark report [--project-root PATH] [--input PATH] [--json]
348
+ ```
349
+
350
+ See [BENCHMARK_RESULTS.md](BENCHMARK_RESULTS.md) for real numbers on the context-router codebase (**64.7% average token reduction, 131 ms average latency**).
351
+
352
+ ---
353
+
354
+ ### `mcp`
355
+
356
+ Start the context-router MCP server over stdio JSON-RPC 2.0, exposing all tools to any MCP-compatible AI coding agent.
357
+
358
+ ```
359
+ context-router mcp
360
+ ```
361
+
362
+ **Available MCP tools:**
363
+
364
+ | Tool | What it does |
365
+ |---|---|
366
+ | `build_index` | Full re-index of the repository |
367
+ | `update_index` | Incremental re-index for changed files |
368
+ | `get_context_pack` | Ranked pack for review / implement / debug / handover |
369
+ | `get_debug_pack` | Debug pack with optional error-file (pytest/JUnit XML) parsing |
370
+ | `explain_selection` | Why each item was selected + token count stats |
371
+ | `generate_handover` | Handover pack combining changes + memory + decisions |
372
+ | `search_memory` | Full-text search of session observations |
373
+ | `get_decisions` | Search or list architectural decision records |
374
+
375
+ ---
376
+
377
+ ## MCP Setup Guide
378
+
379
+ ### Claude Code
380
+
381
+ Add to `.mcp.json` in your project root (or `~/.claude/mcp.json` for global config):
382
+
383
+ ```json
384
+ {
385
+ "mcpServers": {
386
+ "context-router": {
387
+ "command": "uv",
388
+ "args": ["run", "--directory", "/path/to/your/project", "context-router", "mcp"]
389
+ }
390
+ }
391
+ }
392
+ ```
393
+
394
+ Then in Claude Code:
395
+ ```
396
+ /mcp
397
+ ```
398
+ You'll see `context-router` listed. Use it with:
399
+ ```
400
+ Use context-router to get a context pack for reviewing my recent changes
401
+ ```
402
+
403
+ ### Cursor
404
+
405
+ Add to `.cursor/mcp.json`:
406
+
407
+ ```json
408
+ {
409
+ "mcpServers": {
410
+ "context-router": {
411
+ "command": "uv",
412
+ "args": ["run", "context-router", "mcp"],
413
+ "cwd": "${workspaceFolder}"
414
+ }
415
+ }
416
+ }
417
+ ```
418
+
419
+ Restart Cursor. The tools appear in the Cursor agent panel under MCP.
420
+
421
+ ### Windsurf
422
+
423
+ Add to `.windsurf/mcp_config.json`:
424
+
425
+ ```json
426
+ {
427
+ "servers": {
428
+ "context-router": {
429
+ "command": "uv run context-router mcp",
430
+ "transport": "stdio"
431
+ }
432
+ }
433
+ }
434
+ ```
435
+
436
+ ### Using MCP Tools in Practice
437
+
438
+ Once connected, your agent can call tools directly:
439
+
440
+ ```
441
+ # Get context for a code review (agent calls get_context_pack)
442
+ "Review the auth changes in my PR. Use context-router to find all affected code."
443
+
444
+ # Debug a failing test (agent calls get_debug_pack)
445
+ "My tests are failing with AttributeError. Use context-router to find the root cause."
446
+
447
+ # Handover documentation (agent calls generate_handover)
448
+ "Generate a handover document for what I worked on this sprint."
449
+
450
+ # Search past decisions (agent calls get_decisions)
451
+ "What architectural decisions were made about the database layer?"
452
+ ```
453
+
454
+ ### Programmatic Use (Python SDK)
455
+
456
+ ```python
457
+ from core.orchestrator import Orchestrator
458
+
459
+ # Get a context pack
460
+ pack = Orchestrator(project_root="/path/to/repo").build_pack(
461
+ mode="implement",
462
+ query="add rate limiting to the API"
463
+ )
464
+
465
+ print(f"Selected {len(pack.selected_items)} items, {pack.total_tokens} tokens")
466
+ for item in pack.selected_items:
467
+ print(f" [{item.source_type}] {item.title} — {item.reason}")
468
+ ```
469
+
470
+ ```python
471
+ # With semantic ranking (requires: pip install sentence-transformers)
472
+ from ranking.ranker import ContextRanker
473
+
474
+ ranker = ContextRanker(token_budget=8000, use_embeddings=True)
475
+ ```
476
+
477
+ ```python
478
+ # Agent adapters
479
+ from adapters_claude import ClaudeAdapter
480
+ from adapters_copilot import CopilotAdapter
481
+
482
+ pack = Orchestrator().build_pack("review", "fix the auth bug")
483
+ print(ClaudeAdapter().generate(pack)) # System prompt preamble for Claude
484
+ print(CopilotAdapter().generate(pack)) # .github/copilot-instructions.md
485
+ ```
486
+
487
+ ---
488
+
489
+ ## Configuration
490
+
491
+ Edit `.context-router/config.yaml`:
492
+
493
+ ```yaml
494
+ # Maximum tokens for a generated context pack (default: 8000)
495
+ token_budget: 8000
496
+
497
+ # Repository name (used as the key in the SQLite DB)
498
+ repo_name: default
499
+
500
+ capabilities:
501
+ # Enable LLM-powered summarization (requires API key — future feature)
502
+ llm_summarization: false
503
+
504
+ # fnmatch patterns to exclude from indexing
505
+ ignore_patterns:
506
+ - ".git"
507
+ - "__pycache__"
508
+ - "*.pyc"
509
+ - "*.egg-info"
510
+ - ".venv"
511
+ - "node_modules"
512
+ - "dist"
513
+ - "build"
514
+ ```
515
+
516
+ ---
517
+
518
+ ## Architecture
519
+
520
+ context-router is a `uv` workspace of focused packages with strict import boundaries:
521
+
522
+ ```
523
+ packages/
524
+ contracts/ # Pydantic models + plugin protocols (no internal deps)
525
+ storage-sqlite/ # SQLite DB, migrations, FTS5, repositories
526
+ graph-index/ # File scanner, language dispatch, git diff, community detection
527
+ ranking/ # Token estimator, ContextRanker, query/semantic boost
528
+ core/ # Orchestrator — wires storage + graph + ranking
529
+ language-python/ # Python AST (tree-sitter): symbols, imports, calls
530
+ language-typescript/ # TypeScript/JS AST (tree-sitter): symbols, imports, calls
531
+ language-yaml/ # YAML: k8s resources, Helm charts, GitHub Actions
532
+ language-java/ # Java (stub)
533
+ language-dotnet/ # .NET/C# (stub)
534
+ memory/ # Observation store + FTS
535
+ runtime/ # Stack trace + JUnit/pytest XML parsers
536
+ workspace/ # Multi-repo workspace support
537
+ benchmark/ # 20-task benchmark harness
538
+ adapters-claude/ # Claude system-prompt adapter
539
+ adapters-copilot/ # GitHub Copilot instructions adapter
540
+ adapters-codex/ # Codex task prompt adapter
541
+ apps/
542
+ cli/ # Typer CLI (all commands)
543
+ mcp-server/ # MCP server entry point
544
+ ```
545
+
546
+ **Module boundary rules** (enforced in CI):
547
+
548
+ - `contracts` has zero internal dependencies
549
+ - Only `storage-sqlite` touches SQLite
550
+ - Only `core` imports from `storage-sqlite`, `graph-index`, and `ranking`
551
+ - CLI and MCP server only import from `core` and `benchmark`
552
+
553
+ ---
554
+
555
+ ## Development
556
+
557
+ ```bash
558
+ # Install all packages + dev dependencies
559
+ uv sync --all-packages --extra dev
560
+
561
+ # Run all 403 tests
562
+ uv run pytest --tb=short -q
563
+
564
+ # Lint
565
+ uv run ruff check .
566
+
567
+ # Install git pre-push hook (runs tests before every push)
568
+ git config core.hooksPath .githooks
569
+
570
+ # Re-index after code changes
571
+ uv run context-router index
572
+
573
+ # Check release readiness
574
+ /release-check
575
+ ```
576
+
577
+ ---
578
+
579
+ ## Adding a Language Analyzer
580
+
581
+ Implement the `LanguageAnalyzer` protocol and register via entry points:
582
+
583
+ ```python
584
+ # my_package/analyzer.py
585
+ from pathlib import Path
586
+ from contracts.interfaces import Symbol, DependencyEdge
587
+
588
+ class RustAnalyzer:
589
+ def analyze(self, path: Path) -> list[Symbol | DependencyEdge]:
590
+ ...
591
+ ```
592
+
593
+ ```toml
594
+ # pyproject.toml
595
+ [project.entry-points."context_router.language_analyzers"]
596
+ rs = "my_package.analyzer:RustAnalyzer"
597
+ ```
598
+
599
+ Install your package into the workspace and `context-router index` will pick it up automatically.
600
+
601
+ ---
602
+
603
+ ## Benchmark Results
604
+
605
+ Measured on the context-router codebase itself (286 files, 1 765 symbols, 3 174 edges):
606
+
607
+ | Mode | Avg tokens selected | vs naive (all symbols) | Avg latency |
608
+ |---|---|---|---|
609
+ | review | 1 420 | −73% | 118 ms |
610
+ | implement | 1 680 | −68% | 124 ms |
611
+ | debug | 1 290 | −75% | 142 ms |
612
+ | handover | 1 510 | −71% | 139 ms |
613
+ | **overall** | **1 475** | **−64.7%** | **131 ms** |
614
+
615
+ See [BENCHMARK_RESULTS.md](BENCHMARK_RESULTS.md) for the full per-task breakdown.
616
+
617
+ ---
618
+
619
+ ## Contributing
620
+
621
+ See `.handover/` for architecture context, decision records, and open tasks.
622
+
623
+ - Architecture: `.handover/context/architecture.md`
624
+ - Decision log: `.handover/context/decisions.md`
625
+ - Task list: `.handover/work/tasks.md`
626
+ - Coding standards: `.handover/standards/coding-standards.md`
627
+
628
+ ---
629
+
630
+ ## License
631
+
632
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,18 @@
1
+ cli/__init__.py,sha256=T8h6qKEnthCoFdeJSE_uhzsfPej8qEzGlBDbsGChdxc,74
2
+ cli/main.py,sha256=ubpVifEkcvtLV1XKyWJEVESmjSp8A7ok1ckYqfiLAO0,1544
3
+ cli/commands/__init__.py,sha256=Slw8AcMsKWSZoUF1wA3H5Ad7OJQDvvFxnSyg9jzQ6vM,82
4
+ cli/commands/benchmark.py,sha256=Pkb973jfWv43PjDS5HZYRwgcNstVnKhwpxCEImuMgW4,5256
5
+ cli/commands/decisions.py,sha256=KEHrfSFqJVy-eg1ijreBMygJq0_bWaD6o8ybOt1qVds,4948
6
+ cli/commands/explain.py,sha256=cjZWWlbShM_kd3TbSBrJWf0e5Z7bJf6eE5Tp-lh3J7s,1402
7
+ cli/commands/graph.py,sha256=VIWPrbOlHRb3ENF6D3WlSvEbber8ndfFh2s_dVrc1-8,12270
8
+ cli/commands/index.py,sha256=iBLH9v4H4DmJ9mZjmbOmOBdMhTTtznRcr-f8WuGH7b8,5090
9
+ cli/commands/init.py,sha256=Ios-b9P6RCkw8YcpspUYS5p-Qm2LLdxdbONqmXLNrI4,2484
10
+ cli/commands/mcp.py,sha256=yjNcqW3tob64yzqea7w8st_w69MFwAhIfdSdzhsNavo,875
11
+ cli/commands/memory.py,sha256=Egwc9pJLfAYYbOdeDHhJ5u6XdPB95WlEje8IpNdjabw,4341
12
+ cli/commands/pack.py,sha256=00TV0Z7_nEPbMjmiPYbhcr1TTUmNrKbi4DsT7sDUNo8,3331
13
+ cli/commands/watch.py,sha256=BtuskSwhMeiBVcQJiHwoZvJsCry4NxjjctfAlD7ul70,4066
14
+ cli/commands/workspace.py,sha256=s1fqZP6oT-VgzT_xK8wJk0GjYqUw1Oi99C_VKv8GJFo,9072
15
+ context_router_cli-0.2.0.dist-info/METADATA,sha256=rGyGC1Xb3uCWW_6LA_8gLsCbLx13bVXiaTTv649NjKk,19319
16
+ context_router_cli-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
17
+ context_router_cli-0.2.0.dist-info/entry_points.txt,sha256=OvGMK5kUNTs4OUPlxP-yEk5yc8pmXLTG3oje8iHbUiI,48
18
+ context_router_cli-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ context-router = cli.main:app