codecortex 0.23.4__tar.gz → 0.24.1__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.
- {codecortex-0.23.4/src/codecortex.egg-info → codecortex-0.24.1}/PKG-INFO +8 -3
- {codecortex-0.23.4 → codecortex-0.24.1}/README.md +6 -2
- {codecortex-0.23.4 → codecortex-0.24.1}/pyproject.toml +33 -1
- {codecortex-0.23.4 → codecortex-0.24.1/src/codecortex.egg-info}/PKG-INFO +8 -3
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codecortex.egg-info/SOURCES.txt +19 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codecortex.egg-info/requires.txt +1 -0
- codecortex-0.24.1/src/codeintel/__init__.py +1 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/__main__.py +30 -2
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/c4.py +2 -1
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/index.py +36 -0
- codecortex-0.24.1/src/codeintel/commands/uninstall.py +106 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/doctor.py +5 -2
- codecortex-0.24.1/src/codeintel/filelock.py +160 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/gateway.py +108 -7
- codecortex-0.24.1/src/codeintel/graph_answer.py +970 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/graph_backend.py +5 -2
- codecortex-0.24.1/src/codeintel/graph_confidence.py +155 -0
- codecortex-0.24.1/src/codeintel/graph_edges.py +89 -0
- codecortex-0.24.1/src/codeintel/graph_ops.py +712 -0
- codecortex-0.24.1/src/codeintel/graph_render.py +295 -0
- codecortex-0.24.1/src/codeintel/graph_targets.py +138 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/grapher.py +2 -5
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/installer.py +156 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/outcome.py +22 -0
- codecortex-0.24.1/src/codeintel/per_thread.py +64 -0
- codecortex-0.24.1/src/codeintel/provider.py +242 -0
- codecortex-0.24.1/src/codeintel/providers/graph.py +916 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/providers/lsp.py +288 -32
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/providers/semantic.py +159 -3
- codecortex-0.24.1/src/codeintel/query_ops.py +32 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/reindexer.py +36 -11
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/server.py +33 -11
- codecortex-0.24.1/tests/test_bench_corpus_typed.py +166 -0
- codecortex-0.24.1/tests/test_bench_gate.py +103 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_bench_oracle.py +24 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_bench_oracle_ts.py +125 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cli_commands.py +90 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_corpus.py +2 -3
- codecortex-0.24.1/tests/test_docs_trust_claims.py +194 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_doctor.py +242 -1
- codecortex-0.24.1/tests/test_edge_confidence.py +687 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_enterprise.py +5 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_gateway.py +125 -1
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_graph_failure_population.py +36 -13
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_graph_provider.py +3 -3
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_grapher.py +2 -1
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_hardening.py +92 -3
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_http_auth.py +8 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_http_server.py +1 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_incompleteness.py +1 -1
- codecortex-0.24.1/tests/test_index_incompleteness.py +237 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_installer.py +8 -1
- codecortex-0.24.1/tests/test_lsp_language_coverage.py +231 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_lsp_provider.py +173 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_mapper.py +15 -14
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_mcp_handshake.py +6 -5
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_mcp_server.py +36 -0
- codecortex-0.24.1/tests/test_missing_target.py +270 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_null_reason_and_ripple.py +26 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_onboarding.py +3 -5
- codecortex-0.24.1/tests/test_per_thread.py +101 -0
- codecortex-0.24.1/tests/test_query_budget.py +220 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_rbac.py +22 -6
- codecortex-0.24.1/tests/test_reindex_lock.py +267 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_reindexer.py +7 -0
- codecortex-0.24.1/tests/test_summary_integrity.py +2078 -0
- codecortex-0.24.1/tests/test_uninstall.py +335 -0
- codecortex-0.24.1/tests/test_upgrade_path.py +220 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_verify.py +3 -3
- codecortex-0.23.4/src/codeintel/__init__.py +0 -1
- codecortex-0.23.4/src/codeintel/graph_render.py +0 -95
- codecortex-0.23.4/src/codeintel/provider.py +0 -151
- codecortex-0.23.4/src/codeintel/providers/graph.py +0 -2445
- codecortex-0.23.4/src/codeintel/query_ops.py +0 -17
- codecortex-0.23.4/tests/test_edge_confidence.py +0 -151
- codecortex-0.23.4/tests/test_lsp_language_coverage.py +0 -100
- {codecortex-0.23.4 → codecortex-0.24.1}/LICENSE +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/setup.cfg +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codecortex.egg-info/dependency_links.txt +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codecortex.egg-info/entry_points.txt +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codecortex.egg-info/top_level.txt +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/agent_prompt.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/auth.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/c4_check.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/c4_layers.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/cache.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/__init__.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/_common.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/c4.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/doctor.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/gen_token.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/graph.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/install.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/map.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/prompt.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/query.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/reset.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/serve.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/serve_http.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/setup.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/commands/status.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/config.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/containment.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/graph_resolution.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/http_server.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/indexer.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/injector.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/lang_config.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/loc.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/logconfig.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/mapper.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/metrics.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/onboarding.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/paths.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/policy.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/progress.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/providers/__init__.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/providers/none.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/py.typed +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/redact.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/reset.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/searcher.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/semantic_db.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/source_kind.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/term.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/verify.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/viewer/__init__.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/viewer/graph_template.html +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/src/codeintel/wire_text.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_agent_prompt.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_backend_reaper.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_background_index_failure.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_c4.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_c4_check.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_c4_layers.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_c4_model.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_c4_output.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cache.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_chunking.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cli_help.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cli_install_dry_run.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cli_install_offer_injection.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_cold_process.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_config.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_could_not_ask_semantic.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_docs_ci_claims.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_docs_deadcode_withdrawal.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_e2e.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_engine_adoption.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_graph_real.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_graph_stdin.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_hard_exit.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_index_failure_reason.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_index_progress.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_indexer_binary.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_integration.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_lang_config.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_loc_census.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_lsp_real.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_model_dimension.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_never_raise.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_redaction_boundary.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_rerank.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_reset.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_semantic_provider.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_source_kind.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_staleness.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_symbol_context.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_term.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_treesitter.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_verify_call.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_version_skew.py +0 -0
- {codecortex-0.23.4 → codecortex-0.24.1}/tests/test_wire_text.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecortex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.1
|
|
4
4
|
Summary: Local-first, MCP-native code-intelligence server — graph, LSP, and semantic search behind one safe code.query tool for coding agents.
|
|
5
5
|
Author: Shammai Hamilton
|
|
6
6
|
License-Expression: MIT
|
|
@@ -31,6 +31,7 @@ Requires-Dist: tree-sitter-language-pack>=1.0
|
|
|
31
31
|
Provides-Extra: dev
|
|
32
32
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-timeout>=2.3; extra == "dev"
|
|
34
35
|
Requires-Dist: numpy>=1.24; extra == "dev"
|
|
35
36
|
Requires-Dist: ruff>=0.16; extra == "dev"
|
|
36
37
|
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
@@ -53,6 +54,10 @@ Dynamic: license-file
|
|
|
53
54
|
> been pointed at an unfamiliar codebase it has found real bugs. **Use it locally, on a developer
|
|
54
55
|
> machine, for a single user** — that is the case it is built and tested for. Before relying on it
|
|
55
56
|
> for anything beyond that, read **[Project status](#project-status)**.
|
|
57
|
+
>
|
|
58
|
+
> **New here? Read [docs/trust.md](docs/trust.md) first** — what each engine's answer is worth, a
|
|
59
|
+
> five-minute check on a symbol whose callers you already know, and the eight states your
|
|
60
|
+
> repository can be in with one command for each.
|
|
56
61
|
|
|
57
62
|

|
|
58
63
|
|
|
@@ -432,7 +437,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
432
437
|
- **[Install & registration](docs/install.md)** — what each agent host actually reads, why the registered command is an absolute path, and the three levels of proof that registration worked.
|
|
433
438
|
- **[Query flow](docs/query-flow.md)** — request lifecycle, engine selection, fan-out & merge, and why it never throws.
|
|
434
439
|
- **[Map file](docs/map-file.md)** — the static `CODE_INTEL.md` orientation layer for hosts with no MCP support.
|
|
435
|
-
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale:
|
|
440
|
+
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale: 30 k chunks indexed in ~10 min, ~233 ms warm queries, 68 MB index.
|
|
436
441
|
- Engine references: **[graph](docs/graph.md)** · **[lsp](docs/lsp.md)** · **[semantic](docs/semantic.md)**.
|
|
437
442
|
|
|
438
443
|
## CLI reference
|
|
@@ -448,7 +453,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
448
453
|
| `codeintel serve-http [--host HOST] [--port 8766] [--allow-remote] [--token TOKEN]` | Start the HTTP transport (loopback-only unless `--allow-remote`; `--token` requires a bearer token on every request) |
|
|
449
454
|
| `codeintel query --op OP --target TARGET [--engine auto] [--project-root DIR] [--json]` | Run a single query and print the result |
|
|
450
455
|
| `codeintel status [project_root]` | Show engine availability and index age |
|
|
451
|
-
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
456
|
+
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap. `--deep` puts one **real query** to each engine and requires an answer with content — a process that starts is not a process that answers, and `runnable` means the second |
|
|
452
457
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
453
458
|
| `codeintel graph [project_root] [--html] [--out FILE] [--limit N]` | Emit the call graph as `{nodes,edges}` JSON, or `--html` a self-contained interactive viewer — see [docs/graph-viewer.md](docs/graph-viewer.md) |
|
|
454
459
|
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--edges union\|imports] [--json] [--layers] [--suggest-config] [--check] [--layers-from auto\|inferred\|declared]` | Write a LikeC4 architecture model (`.c4`) of the repo's files and import graph. Indexes the repo first if it has no graph index. `--edges imports` drops the lower-confidence edges for a legible diagram; `--layers` reports inferred architectural bands; `--check` gates CI on a declared `[layers]` config, exit 2 on drift. See [An architecture model, as source](#an-architecture-model-as-source) and [docs/c4.md](docs/c4.md) |
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
> been pointed at an unfamiliar codebase it has found real bugs. **Use it locally, on a developer
|
|
14
14
|
> machine, for a single user** — that is the case it is built and tested for. Before relying on it
|
|
15
15
|
> for anything beyond that, read **[Project status](#project-status)**.
|
|
16
|
+
>
|
|
17
|
+
> **New here? Read [docs/trust.md](docs/trust.md) first** — what each engine's answer is worth, a
|
|
18
|
+
> five-minute check on a symbol whose callers you already know, and the eight states your
|
|
19
|
+
> repository can be in with one command for each.
|
|
16
20
|
|
|
17
21
|

|
|
18
22
|
|
|
@@ -392,7 +396,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
392
396
|
- **[Install & registration](docs/install.md)** — what each agent host actually reads, why the registered command is an absolute path, and the three levels of proof that registration worked.
|
|
393
397
|
- **[Query flow](docs/query-flow.md)** — request lifecycle, engine selection, fan-out & merge, and why it never throws.
|
|
394
398
|
- **[Map file](docs/map-file.md)** — the static `CODE_INTEL.md` orientation layer for hosts with no MCP support.
|
|
395
|
-
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale:
|
|
399
|
+
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale: 30 k chunks indexed in ~10 min, ~233 ms warm queries, 68 MB index.
|
|
396
400
|
- Engine references: **[graph](docs/graph.md)** · **[lsp](docs/lsp.md)** · **[semantic](docs/semantic.md)**.
|
|
397
401
|
|
|
398
402
|
## CLI reference
|
|
@@ -408,7 +412,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
408
412
|
| `codeintel serve-http [--host HOST] [--port 8766] [--allow-remote] [--token TOKEN]` | Start the HTTP transport (loopback-only unless `--allow-remote`; `--token` requires a bearer token on every request) |
|
|
409
413
|
| `codeintel query --op OP --target TARGET [--engine auto] [--project-root DIR] [--json]` | Run a single query and print the result |
|
|
410
414
|
| `codeintel status [project_root]` | Show engine availability and index age |
|
|
411
|
-
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
415
|
+
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap. `--deep` puts one **real query** to each engine and requires an answer with content — a process that starts is not a process that answers, and `runnable` means the second |
|
|
412
416
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
413
417
|
| `codeintel graph [project_root] [--html] [--out FILE] [--limit N]` | Emit the call graph as `{nodes,edges}` JSON, or `--html` a self-contained interactive viewer — see [docs/graph-viewer.md](docs/graph-viewer.md) |
|
|
414
418
|
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--edges union\|imports] [--json] [--layers] [--suggest-config] [--check] [--layers-from auto\|inferred\|declared]` | Write a LikeC4 architecture model (`.c4`) of the repo's files and import graph. Indexes the repo first if it has no graph index. `--edges imports` drops the lower-confidence edges for a legible diagram; `--layers` reports inferred architectural bands; `--check` gates CI on a declared `[layers]` config, exit 2 on drift. See [An architecture model, as source](#an-architecture-model-as-source) and [docs/c4.md](docs/c4.md) |
|
|
@@ -53,7 +53,8 @@ Changelog = "https://github.com/hamilton-sky/codeintel/blob/main/CHANGELOG.md"
|
|
|
53
53
|
codeintel = "codeintel.__main__:main"
|
|
54
54
|
|
|
55
55
|
[project.optional-dependencies]
|
|
56
|
-
dev = ["pytest>=8", "pytest-cov>=5", "numpy>=1.24", "ruff>=0.16",
|
|
56
|
+
dev = ["pytest>=8", "pytest-cov>=5", "pytest-timeout>=2.3", "numpy>=1.24", "ruff>=0.16",
|
|
57
|
+
"mypy>=1.11"]
|
|
57
58
|
|
|
58
59
|
# `bench/agent_bench.py` only. Deliberately NOT in `dev`, and emphatically not a runtime dependency:
|
|
59
60
|
# codeintel's own code makes zero outbound HTTP calls and that claim is load-bearing in the README.
|
|
@@ -161,3 +162,34 @@ follow_imports = "skip"
|
|
|
161
162
|
# case in CI, and that costs ~0.4 points. A floor pinned to today's measurement would go red on a
|
|
162
163
|
# runner's toolchain rather than on a real coverage regression. Ratchet it up deliberately.
|
|
163
164
|
addopts = "--cov=codeintel --cov-report=term-missing:skip-covered --cov-fail-under=83"
|
|
165
|
+
|
|
166
|
+
# No test may run indefinitely. The ceiling is deliberately far above any legitimate test rather
|
|
167
|
+
# than tuned to the current slowest: its job is to convert a hang into a named failure, not to
|
|
168
|
+
# police performance. Measured worst cases after the background-reindex guard landed —
|
|
169
|
+
# `test_cold_process` spawns real cold interpreters at ~60s, `test_hard_exit` runs nested pytest
|
|
170
|
+
# sessions at ~12s — so 180s leaves room for a slow CI runner and still fails in three minutes
|
|
171
|
+
# instead of never.
|
|
172
|
+
#
|
|
173
|
+
# `signal` rather than `thread`: SIGALRM fails the ONE test that overran and lets the session carry
|
|
174
|
+
# on to a normal report. pytest-timeout's `thread` method kills the whole process, which would
|
|
175
|
+
# reproduce the thing being fixed — an unexplained death partway through — with better provenance
|
|
176
|
+
# but no more information. A test that needs longer says so with
|
|
177
|
+
# `@pytest.mark.timeout(<seconds>)` and, ideally, why.
|
|
178
|
+
timeout = 180
|
|
179
|
+
timeout_method = "signal"
|
|
180
|
+
|
|
181
|
+
# A leaked socket, pipe or file handle is a defect, not a note. Promoted to an error once the
|
|
182
|
+
# suite's own leaks were closed — sixteen HTTP listeners kept open by `shutdown()` without
|
|
183
|
+
# `server_close()`, a template file, eight bare `open(...).read()` calls in `test_mapper`, and two
|
|
184
|
+
# MCP children killed without being waited on or having their pipes closed. Leaving it at
|
|
185
|
+
# `warning` is what let all of those accumulate: the count was in every run's output and had been
|
|
186
|
+
# for months.
|
|
187
|
+
#
|
|
188
|
+
# `default::ResourceWarning:_pytest.unraisableexception` is NOT an exemption for our own leaks —
|
|
189
|
+
# pytest surfaces a garbage-collected leak through that module rather than from the test that
|
|
190
|
+
# caused it, and as an error it fails whichever unrelated test happened to trigger the collection.
|
|
191
|
+
# Our leaks are caught at their own site by the first rule; this keeps the blame accurate.
|
|
192
|
+
filterwarnings = [
|
|
193
|
+
"error::ResourceWarning",
|
|
194
|
+
"default::ResourceWarning:_pytest.unraisableexception",
|
|
195
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecortex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.1
|
|
4
4
|
Summary: Local-first, MCP-native code-intelligence server — graph, LSP, and semantic search behind one safe code.query tool for coding agents.
|
|
5
5
|
Author: Shammai Hamilton
|
|
6
6
|
License-Expression: MIT
|
|
@@ -31,6 +31,7 @@ Requires-Dist: tree-sitter-language-pack>=1.0
|
|
|
31
31
|
Provides-Extra: dev
|
|
32
32
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-timeout>=2.3; extra == "dev"
|
|
34
35
|
Requires-Dist: numpy>=1.24; extra == "dev"
|
|
35
36
|
Requires-Dist: ruff>=0.16; extra == "dev"
|
|
36
37
|
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
@@ -53,6 +54,10 @@ Dynamic: license-file
|
|
|
53
54
|
> been pointed at an unfamiliar codebase it has found real bugs. **Use it locally, on a developer
|
|
54
55
|
> machine, for a single user** — that is the case it is built and tested for. Before relying on it
|
|
55
56
|
> for anything beyond that, read **[Project status](#project-status)**.
|
|
57
|
+
>
|
|
58
|
+
> **New here? Read [docs/trust.md](docs/trust.md) first** — what each engine's answer is worth, a
|
|
59
|
+
> five-minute check on a symbol whose callers you already know, and the eight states your
|
|
60
|
+
> repository can be in with one command for each.
|
|
56
61
|
|
|
57
62
|

|
|
58
63
|
|
|
@@ -432,7 +437,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
432
437
|
- **[Install & registration](docs/install.md)** — what each agent host actually reads, why the registered command is an absolute path, and the three levels of proof that registration worked.
|
|
433
438
|
- **[Query flow](docs/query-flow.md)** — request lifecycle, engine selection, fan-out & merge, and why it never throws.
|
|
434
439
|
- **[Map file](docs/map-file.md)** — the static `CODE_INTEL.md` orientation layer for hosts with no MCP support.
|
|
435
|
-
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale:
|
|
440
|
+
- **[Benchmarks](docs/benchmarks.md)** — real numbers at scale: 30 k chunks indexed in ~10 min, ~233 ms warm queries, 68 MB index.
|
|
436
441
|
- Engine references: **[graph](docs/graph.md)** · **[lsp](docs/lsp.md)** · **[semantic](docs/semantic.md)**.
|
|
437
442
|
|
|
438
443
|
## CLI reference
|
|
@@ -448,7 +453,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
448
453
|
| `codeintel serve-http [--host HOST] [--port 8766] [--allow-remote] [--token TOKEN]` | Start the HTTP transport (loopback-only unless `--allow-remote`; `--token` requires a bearer token on every request) |
|
|
449
454
|
| `codeintel query --op OP --target TARGET [--engine auto] [--project-root DIR] [--json]` | Run a single query and print the result |
|
|
450
455
|
| `codeintel status [project_root]` | Show engine availability and index age |
|
|
451
|
-
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
456
|
+
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap. `--deep` puts one **real query** to each engine and requires an answer with content — a process that starts is not a process that answers, and `runnable` means the second |
|
|
452
457
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
453
458
|
| `codeintel graph [project_root] [--html] [--out FILE] [--limit N]` | Emit the call graph as `{nodes,edges}` JSON, or `--html` a self-contained interactive viewer — see [docs/graph-viewer.md](docs/graph-viewer.md) |
|
|
454
459
|
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--edges union\|imports] [--json] [--layers] [--suggest-config] [--check] [--layers-from auto\|inferred\|declared]` | Write a LikeC4 architecture model (`.c4`) of the repo's files and import graph. Indexes the repo first if it has no graph index. `--edges imports` drops the lower-confidence edges for a legible diagram; `--layers` reports inferred architectural bands; `--check` gates CI on a declared `[layers]` config, exit 2 on drift. See [An architecture model, as source](#an-architecture-model-as-source) and [docs/c4.md](docs/c4.md) |
|
|
@@ -18,10 +18,16 @@ src/codeintel/cache.py
|
|
|
18
18
|
src/codeintel/config.py
|
|
19
19
|
src/codeintel/containment.py
|
|
20
20
|
src/codeintel/doctor.py
|
|
21
|
+
src/codeintel/filelock.py
|
|
21
22
|
src/codeintel/gateway.py
|
|
23
|
+
src/codeintel/graph_answer.py
|
|
22
24
|
src/codeintel/graph_backend.py
|
|
25
|
+
src/codeintel/graph_confidence.py
|
|
26
|
+
src/codeintel/graph_edges.py
|
|
27
|
+
src/codeintel/graph_ops.py
|
|
23
28
|
src/codeintel/graph_render.py
|
|
24
29
|
src/codeintel/graph_resolution.py
|
|
30
|
+
src/codeintel/graph_targets.py
|
|
25
31
|
src/codeintel/grapher.py
|
|
26
32
|
src/codeintel/http_server.py
|
|
27
33
|
src/codeintel/indexer.py
|
|
@@ -35,6 +41,7 @@ src/codeintel/metrics.py
|
|
|
35
41
|
src/codeintel/onboarding.py
|
|
36
42
|
src/codeintel/outcome.py
|
|
37
43
|
src/codeintel/paths.py
|
|
44
|
+
src/codeintel/per_thread.py
|
|
38
45
|
src/codeintel/policy.py
|
|
39
46
|
src/codeintel/progress.py
|
|
40
47
|
src/codeintel/provider.py
|
|
@@ -66,6 +73,7 @@ src/codeintel/commands/serve.py
|
|
|
66
73
|
src/codeintel/commands/serve_http.py
|
|
67
74
|
src/codeintel/commands/setup.py
|
|
68
75
|
src/codeintel/commands/status.py
|
|
76
|
+
src/codeintel/commands/uninstall.py
|
|
69
77
|
src/codeintel/providers/__init__.py
|
|
70
78
|
src/codeintel/providers/graph.py
|
|
71
79
|
src/codeintel/providers/lsp.py
|
|
@@ -76,6 +84,8 @@ src/codeintel/viewer/graph_template.html
|
|
|
76
84
|
tests/test_agent_prompt.py
|
|
77
85
|
tests/test_backend_reaper.py
|
|
78
86
|
tests/test_background_index_failure.py
|
|
87
|
+
tests/test_bench_corpus_typed.py
|
|
88
|
+
tests/test_bench_gate.py
|
|
79
89
|
tests/test_bench_oracle.py
|
|
80
90
|
tests/test_bench_oracle_ts.py
|
|
81
91
|
tests/test_c4.py
|
|
@@ -95,6 +105,7 @@ tests/test_corpus.py
|
|
|
95
105
|
tests/test_could_not_ask_semantic.py
|
|
96
106
|
tests/test_docs_ci_claims.py
|
|
97
107
|
tests/test_docs_deadcode_withdrawal.py
|
|
108
|
+
tests/test_docs_trust_claims.py
|
|
98
109
|
tests/test_doctor.py
|
|
99
110
|
tests/test_e2e.py
|
|
100
111
|
tests/test_edge_confidence.py
|
|
@@ -112,6 +123,7 @@ tests/test_http_auth.py
|
|
|
112
123
|
tests/test_http_server.py
|
|
113
124
|
tests/test_incompleteness.py
|
|
114
125
|
tests/test_index_failure_reason.py
|
|
126
|
+
tests/test_index_incompleteness.py
|
|
115
127
|
tests/test_index_progress.py
|
|
116
128
|
tests/test_indexer_binary.py
|
|
117
129
|
tests/test_installer.py
|
|
@@ -124,21 +136,28 @@ tests/test_lsp_real.py
|
|
|
124
136
|
tests/test_mapper.py
|
|
125
137
|
tests/test_mcp_handshake.py
|
|
126
138
|
tests/test_mcp_server.py
|
|
139
|
+
tests/test_missing_target.py
|
|
127
140
|
tests/test_model_dimension.py
|
|
128
141
|
tests/test_never_raise.py
|
|
129
142
|
tests/test_null_reason_and_ripple.py
|
|
130
143
|
tests/test_onboarding.py
|
|
144
|
+
tests/test_per_thread.py
|
|
145
|
+
tests/test_query_budget.py
|
|
131
146
|
tests/test_rbac.py
|
|
132
147
|
tests/test_redaction_boundary.py
|
|
148
|
+
tests/test_reindex_lock.py
|
|
133
149
|
tests/test_reindexer.py
|
|
134
150
|
tests/test_rerank.py
|
|
135
151
|
tests/test_reset.py
|
|
136
152
|
tests/test_semantic_provider.py
|
|
137
153
|
tests/test_source_kind.py
|
|
138
154
|
tests/test_staleness.py
|
|
155
|
+
tests/test_summary_integrity.py
|
|
139
156
|
tests/test_symbol_context.py
|
|
140
157
|
tests/test_term.py
|
|
141
158
|
tests/test_treesitter.py
|
|
159
|
+
tests/test_uninstall.py
|
|
160
|
+
tests/test_upgrade_path.py
|
|
142
161
|
tests/test_verify.py
|
|
143
162
|
tests/test_verify_call.py
|
|
144
163
|
tests/test_version_skew.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.24.1"
|
|
@@ -44,6 +44,7 @@ _COMMAND_GROUPS: list[tuple[str, list[tuple[str, str]]]] = [
|
|
|
44
44
|
("setup", "Prepare backends + index this repo (--all does it all)"),
|
|
45
45
|
("index", "Build the index every other command reads (semantic + graph)"),
|
|
46
46
|
("install", "Register codeintel with the AI agents on this machine"),
|
|
47
|
+
("uninstall", "Remove those registrations — the index is left alone"),
|
|
47
48
|
("prompt", "Print a paste-to-your-agent setup prompt for this machine"),
|
|
48
49
|
]),
|
|
49
50
|
("Check health", [
|
|
@@ -79,6 +80,7 @@ _MODULES = {
|
|
|
79
80
|
"setup": "setup",
|
|
80
81
|
"index": "index",
|
|
81
82
|
"install": "install",
|
|
83
|
+
"uninstall": "uninstall",
|
|
82
84
|
"prompt": "prompt",
|
|
83
85
|
"doctor": "doctor",
|
|
84
86
|
"status": "status",
|
|
@@ -333,6 +335,13 @@ The one-shot path on a new machine.""",
|
|
|
333
335
|
Writes the MCP server config so an agent can call codeintel. Then restart the
|
|
334
336
|
agent (or start a new session) — a running host does not reload its MCP
|
|
335
337
|
config. `codeintel doctor` lists what got registered where.""",
|
|
338
|
+
"uninstall": """examples:
|
|
339
|
+
codeintel uninstall
|
|
340
|
+
codeintel uninstall --dry-run show what would go, change nothing
|
|
341
|
+
|
|
342
|
+
Removes only codeintel's own entry from each agent config — neighbouring
|
|
343
|
+
servers and your settings are left alone. The index is NOT deleted; use
|
|
344
|
+
`codeintel reset --all` for that.""",
|
|
336
345
|
"prompt": """examples:
|
|
337
346
|
codeintel prompt
|
|
338
347
|
|
|
@@ -462,7 +471,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
462
471
|
"--json", action="store_true", help="Emit the structured status and index-age report")
|
|
463
472
|
status_parser.add_argument(
|
|
464
473
|
"--deep", action="store_true",
|
|
465
|
-
help="
|
|
474
|
+
help="Put a real query to each engine and require an answer, boot the LSP, and sample "
|
|
475
|
+
"indexed source readability (slower, read-only)")
|
|
466
476
|
|
|
467
477
|
# serve-http subcommand
|
|
468
478
|
http_parser = subparsers.add_parser(
|
|
@@ -503,6 +513,22 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
503
513
|
help="Show what would be registered, and where — write nothing",
|
|
504
514
|
)
|
|
505
515
|
|
|
516
|
+
# uninstall subcommand
|
|
517
|
+
uninstall_parser = subparsers.add_parser(
|
|
518
|
+
"uninstall", help=_DESCRIPTIONS["uninstall"], description=_DESCRIPTIONS["uninstall"])
|
|
519
|
+
uninstall_parser.add_argument(
|
|
520
|
+
"--agent",
|
|
521
|
+
choices=["auto", "claude", "codex", "gemini", "zed", "all"],
|
|
522
|
+
default="auto",
|
|
523
|
+
help="Agent to remove from (default: auto — every agent codeintel is REGISTERED with, "
|
|
524
|
+
"which is a different set from the agents installed here)",
|
|
525
|
+
)
|
|
526
|
+
uninstall_parser.add_argument(
|
|
527
|
+
"--dry-run",
|
|
528
|
+
action="store_true",
|
|
529
|
+
help="Show what would be removed, and from where — change nothing",
|
|
530
|
+
)
|
|
531
|
+
|
|
506
532
|
# map subcommand
|
|
507
533
|
map_parser = subparsers.add_parser(
|
|
508
534
|
"map", help=_DESCRIPTIONS["map"], description=_DESCRIPTIONS["map"])
|
|
@@ -575,7 +601,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
575
601
|
"doctor", help=_DESCRIPTIONS["doctor"], description=_DESCRIPTIONS["doctor"])
|
|
576
602
|
doctor_parser.add_argument("project_root", nargs="?", default=None, help="Project root (default: cwd)")
|
|
577
603
|
doctor_parser.add_argument("--deep", action="store_true",
|
|
578
|
-
help="
|
|
604
|
+
help="Ask each engine one REAL query and require content — a "
|
|
605
|
+
"process that starts is not one that answers. Also boots "
|
|
606
|
+
"serena (slower; first boot pulls it via uvx)")
|
|
579
607
|
doctor_parser.add_argument("--json", action="store_true",
|
|
580
608
|
help="Emit the structured JSON report instead of the table")
|
|
581
609
|
|
|
@@ -495,7 +495,8 @@ def build_c4_payload(project_root: Any, *, depth: int | None = None, scope: tupl
|
|
|
495
495
|
payload at an auto-fit (or requested) directory depth. Never raises -- returns a flat `reason`
|
|
496
496
|
string and empty lists on any failure."""
|
|
497
497
|
try:
|
|
498
|
-
from codeintel.
|
|
498
|
+
from codeintel.graph_render import _repo_display_name
|
|
499
|
+
from codeintel.providers.graph import GraphProvider
|
|
499
500
|
|
|
500
501
|
p = GraphProvider()
|
|
501
502
|
if not getattr(p, "available", False):
|
|
@@ -6,6 +6,11 @@ from typing import Any
|
|
|
6
6
|
|
|
7
7
|
from codeintel.commands._common import resolve_root
|
|
8
8
|
|
|
9
|
+
# How long a foreground `codeintel index` waits for another process's pass over the same repository
|
|
10
|
+
# before indexing anyway. Long enough to outlast a cold index of a large repo (measured at ~10 min
|
|
11
|
+
# for 30k chunks, docs/benchmarks.md); short enough that a hung holder cannot block it forever.
|
|
12
|
+
_LOCK_WAIT_S = 900.0
|
|
13
|
+
|
|
9
14
|
|
|
10
15
|
class _ProgressLogBridge(logging.Handler):
|
|
11
16
|
"""Routes WARNING+ log records from the indexer to a live progress counter's ``notice()``, so a
|
|
@@ -52,6 +57,35 @@ def run(args: Any) -> int:
|
|
|
52
57
|
quiet = getattr(args, "quiet", False)
|
|
53
58
|
counter = None if quiet else term.LiveCounter(console)
|
|
54
59
|
|
|
60
|
+
# Take the same per-repository lock the background reindexer takes, so a terminal `index` and
|
|
61
|
+
# a running server's background pass do not embed the whole repository twice. It covers the
|
|
62
|
+
# semantic AND graph passes, as the background pass does; the map refresh is not indexing.
|
|
63
|
+
import contextlib
|
|
64
|
+
|
|
65
|
+
from codeintel.filelock import exclusive_waiting, lock_path
|
|
66
|
+
|
|
67
|
+
def _say_waiting() -> None:
|
|
68
|
+
if not quiet: # --quiet promises the result line only, contention or not
|
|
69
|
+
print("waiting for another codeintel process to finish indexing this repository…",
|
|
70
|
+
flush=True)
|
|
71
|
+
|
|
72
|
+
lock = contextlib.ExitStack()
|
|
73
|
+
# Resolving the lock path reads the codeintel home, which raises where there is no resolvable
|
|
74
|
+
# home directory (a container UID with no passwd entry and no CODEINTEL_HOME). That must not
|
|
75
|
+
# turn into a traceback before the semantic pass's own error handling below — which reports
|
|
76
|
+
# exactly that failure as "index failed: …". A lock we cannot place is a lock we do without,
|
|
77
|
+
# by the rule in `filelock`: it may dedupe work, never stop it.
|
|
78
|
+
try:
|
|
79
|
+
path = lock_path(os.path.realpath(project_root))
|
|
80
|
+
except Exception:
|
|
81
|
+
path = None
|
|
82
|
+
if path is not None:
|
|
83
|
+
got_lock = lock.enter_context(
|
|
84
|
+
exclusive_waiting(path, _LOCK_WAIT_S, on_wait=_say_waiting))
|
|
85
|
+
if not got_lock and not quiet:
|
|
86
|
+
print(f"still locked after {int(_LOCK_WAIT_S)}s — indexing anyway; the other pass "
|
|
87
|
+
"may repeat some of this work", flush=True)
|
|
88
|
+
|
|
55
89
|
failed = False
|
|
56
90
|
# Wrap the whole semantic pass so a setup failure (e.g. an unresolvable home dir →
|
|
57
91
|
# Path.home() raising) degrades with a message, like every other subcommand, not a traceback.
|
|
@@ -146,6 +180,8 @@ def run(args: Any) -> int:
|
|
|
146
180
|
if beat:
|
|
147
181
|
beat.stop("warn", "skipped")
|
|
148
182
|
|
|
183
|
+
lock.close()
|
|
184
|
+
|
|
149
185
|
# best-effort map refresh after index (fast, kept silent — not worth a checklist row)
|
|
150
186
|
try:
|
|
151
187
|
from codeintel.mapper import MapGenerator
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""`codeintel uninstall` — remove codeintel's entry from the agent configs `install` wrote.
|
|
2
|
+
|
|
3
|
+
The inverse of `install`, and deliberately only that. It does NOT delete the semantic index: that
|
|
4
|
+
is `reset`'s job, it is expensive to rebuild (ten minutes on a large repo), and a command whose
|
|
5
|
+
name says "uninstall" quietly destroying ten minutes of work is the kind of surprise this project
|
|
6
|
+
spends most of its comments avoiding. What the index costs and how to remove it is printed instead,
|
|
7
|
+
which is the same rule every other disclosure here follows — name what was NOT done.
|
|
8
|
+
|
|
9
|
+
There is no confirmation prompt, and that is a considered difference from `reset --all`. This edits
|
|
10
|
+
one entry in a config file and `codeintel install` puts it straight back; `reset` destroys an index
|
|
11
|
+
that has to be re-embedded. `--dry-run` covers the reader who wants to look first.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from codeintel.commands._common import never_raise
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _targets(agent: str, installer_mod: Any) -> tuple[list[str], list[str]]:
|
|
20
|
+
"""`(agents, untouched)` for the requested `--agent` selection.
|
|
21
|
+
|
|
22
|
+
`auto` means "wherever codeintel is actually registered", not "agents installed on this
|
|
23
|
+
machine" — the question `install` asks. They differ in both directions that matter: an agent
|
|
24
|
+
uninstalled from this machine can still hold our entry, and an agent that is present but never
|
|
25
|
+
registered has nothing to remove and should not be reported as though it did.
|
|
26
|
+
"""
|
|
27
|
+
if agent == "auto":
|
|
28
|
+
registered = installer_mod.registered_agents()
|
|
29
|
+
return registered, [a for a in installer_mod._AGENTS if a not in registered]
|
|
30
|
+
if agent == "all":
|
|
31
|
+
return list(installer_mod._AGENTS), []
|
|
32
|
+
return [agent], []
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _dry_run_line(installer_mod: Any, agent: str) -> str:
|
|
36
|
+
"""What `--dry-run` would do to one agent's config — read-only, through the same lookup
|
|
37
|
+
`codeintel doctor` uses to notice a registration at all."""
|
|
38
|
+
spec = installer_mod._CONFIG[agent]
|
|
39
|
+
path, current = installer_mod.registered_command(spec)
|
|
40
|
+
if current is None:
|
|
41
|
+
return f"~ {agent}: no codeintel entry in {path} (no change)"
|
|
42
|
+
return f"- {agent}: would remove the codeintel entry from {path} (command: {current})"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _report(results: list) -> tuple[bool, bool, list[str]]:
|
|
46
|
+
"""Print one line per agent; return (removed_any, failed_any, legacy_paths)."""
|
|
47
|
+
removed_any = failed_any = False
|
|
48
|
+
legacy_paths: list[str] = []
|
|
49
|
+
for r in results:
|
|
50
|
+
agent, path, action = r["agent"], r["path"], r["action"]
|
|
51
|
+
if action == "removed":
|
|
52
|
+
print(f"v {agent}: removed from {path}")
|
|
53
|
+
removed_any = True
|
|
54
|
+
elif action == "absent":
|
|
55
|
+
print(f"~ {agent}: nothing registered at {path}")
|
|
56
|
+
else:
|
|
57
|
+
print(f"x {agent}: failed — {r['reason']}")
|
|
58
|
+
failed_any = True
|
|
59
|
+
if r.get("legacy"):
|
|
60
|
+
legacy_paths.append(r["legacy"])
|
|
61
|
+
return removed_any, failed_any, legacy_paths
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@never_raise("uninstall failed: {exc}", code=1)
|
|
65
|
+
def run(args: Any) -> int:
|
|
66
|
+
from codeintel import installer as installer_mod
|
|
67
|
+
|
|
68
|
+
agents, untouched = _targets(args.agent, installer_mod)
|
|
69
|
+
|
|
70
|
+
if args.agent == "auto" and not agents:
|
|
71
|
+
# Exit 0, not 1. The requested end state — codeintel is not registered with anything —
|
|
72
|
+
# already holds, and reporting "failure" for a goal that is met would make this command
|
|
73
|
+
# unusable in a teardown script that runs whether or not install ever ran.
|
|
74
|
+
print("codeintel is not registered with any agent on this machine — nothing to remove.")
|
|
75
|
+
print(f" (looked at: {', '.join(untouched)})")
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
if getattr(args, "dry_run", False):
|
|
79
|
+
for agent in agents:
|
|
80
|
+
print(_dry_run_line(installer_mod, agent))
|
|
81
|
+
print("\nDry run — nothing was changed.")
|
|
82
|
+
return 0
|
|
83
|
+
|
|
84
|
+
results = installer_mod.Installer().unregister_many(agents)
|
|
85
|
+
removed_any, failed_any, legacy_paths = _report(results)
|
|
86
|
+
|
|
87
|
+
for legacy in dict.fromkeys(legacy_paths):
|
|
88
|
+
print(f"\n! stale entry: {legacy} has an `mcpServers.codeintel` block that this host does "
|
|
89
|
+
f"NOT read (an older codeintel wrote it). It is inert, and safe to delete by hand.")
|
|
90
|
+
|
|
91
|
+
if args.agent == "auto" and untouched:
|
|
92
|
+
print(f"\n- untouched (nothing registered): {', '.join(untouched)}")
|
|
93
|
+
|
|
94
|
+
if removed_any:
|
|
95
|
+
# A host that is already running keeps the server it launched at session start, so the
|
|
96
|
+
# tools stay on screen until it is restarted — the mirror of the note `install` prints,
|
|
97
|
+
# and the same surprise in the other direction.
|
|
98
|
+
print("\nRestart your agent (or start a new session) — a running host does not reload "
|
|
99
|
+
"its MCP config, so codeintel's tools stay visible until it does.")
|
|
100
|
+
|
|
101
|
+
# Named, not done. The index is the expensive artifact and this command does not own it.
|
|
102
|
+
from codeintel.paths import codeintel_home
|
|
103
|
+
print(f"\nThe index is untouched: {codeintel_home()}")
|
|
104
|
+
print(" Remove it with `codeintel reset --all` if you are done with codeintel entirely.")
|
|
105
|
+
|
|
106
|
+
return 1 if failed_any else 0
|
|
@@ -280,7 +280,7 @@ def run_doctor(
|
|
|
280
280
|
try:
|
|
281
281
|
from codeintel.providers.graph import GraphProvider
|
|
282
282
|
engines["graph"] = _probe_engine(
|
|
283
|
-
"graph", graph, GraphProvider, lambda p: p.probe(root), on_provider
|
|
283
|
+
"graph", graph, GraphProvider, lambda p: p.probe(root, deep=deep), on_provider
|
|
284
284
|
)
|
|
285
285
|
except Exception:
|
|
286
286
|
engines["graph"] = {"engine": "graph", "status": "fail", "installed": False,
|
|
@@ -414,7 +414,10 @@ def render_doctor_text(report: dict) -> str:
|
|
|
414
414
|
ready, total, healthy = summ.get("ready", "?"), summ.get("total", "?"), summ.get("healthy")
|
|
415
415
|
count = c.bold(f"{ready} / {total}")
|
|
416
416
|
count = c.red(count) if healthy is False else (c.green(count) if healthy else count)
|
|
417
|
-
|
|
417
|
+
# Names what --deep actually does. "boot-check serena" described one third of it and the
|
|
418
|
+
# least useful third: booting is the question this tool keeps learning not to stop at.
|
|
419
|
+
tail = "" if report.get("deep") else c.dim(
|
|
420
|
+
" (run with --deep to ask each engine a real query)")
|
|
418
421
|
out.append("")
|
|
419
422
|
out.append(f" {count} engines ready for this repo.{tail}")
|
|
420
423
|
opt_down = [n for n in _ENGINES
|