codecortex 0.15.4__tar.gz → 0.16.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.
Files changed (119) hide show
  1. {codecortex-0.15.4/src/codecortex.egg-info → codecortex-0.16.0}/PKG-INFO +79 -34
  2. {codecortex-0.15.4 → codecortex-0.16.0}/README.md +78 -33
  3. {codecortex-0.15.4 → codecortex-0.16.0/src/codecortex.egg-info}/PKG-INFO +79 -34
  4. {codecortex-0.15.4 → codecortex-0.16.0}/src/codecortex.egg-info/SOURCES.txt +11 -1
  5. codecortex-0.16.0/src/codeintel/__init__.py +1 -0
  6. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/__main__.py +14 -0
  7. codecortex-0.16.0/src/codeintel/agent_prompt.py +107 -0
  8. codecortex-0.16.0/src/codeintel/commands/prompt.py +33 -0
  9. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/status.py +10 -0
  10. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/doctor.py +75 -0
  11. codecortex-0.16.0/src/codeintel/graph_backend.py +281 -0
  12. codecortex-0.16.0/src/codeintel/graph_render.py +95 -0
  13. codecortex-0.16.0/src/codeintel/graph_resolution.py +274 -0
  14. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/onboarding.py +2 -0
  15. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/providers/graph.py +696 -677
  16. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/server.py +9 -0
  17. codecortex-0.16.0/tests/test_agent_prompt.py +86 -0
  18. codecortex-0.16.0/tests/test_backend_reaper.py +57 -0
  19. codecortex-0.16.0/tests/test_corpus.py +890 -0
  20. codecortex-0.16.0/tests/test_docs_ci_claims.py +99 -0
  21. codecortex-0.16.0/tests/test_docs_deadcode_withdrawal.py +149 -0
  22. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_doctor.py +2 -0
  23. codecortex-0.16.0/tests/test_graph_failure_population.py +850 -0
  24. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_graph_provider.py +112 -156
  25. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_graph_real.py +14 -37
  26. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_hardening.py +5 -0
  27. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_incompleteness.py +21 -6
  28. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_loc_census.py +3 -0
  29. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_onboarding.py +1 -0
  30. codecortex-0.16.0/tests/test_reset.py +671 -0
  31. codecortex-0.16.0/tests/test_version_skew.py +124 -0
  32. codecortex-0.15.4/src/codeintel/__init__.py +0 -1
  33. codecortex-0.15.4/tests/test_corpus.py +0 -335
  34. codecortex-0.15.4/tests/test_graph_failure_population.py +0 -206
  35. codecortex-0.15.4/tests/test_reset.py +0 -181
  36. {codecortex-0.15.4 → codecortex-0.16.0}/LICENSE +0 -0
  37. {codecortex-0.15.4 → codecortex-0.16.0}/pyproject.toml +0 -0
  38. {codecortex-0.15.4 → codecortex-0.16.0}/setup.cfg +0 -0
  39. {codecortex-0.15.4 → codecortex-0.16.0}/src/codecortex.egg-info/dependency_links.txt +0 -0
  40. {codecortex-0.15.4 → codecortex-0.16.0}/src/codecortex.egg-info/entry_points.txt +0 -0
  41. {codecortex-0.15.4 → codecortex-0.16.0}/src/codecortex.egg-info/requires.txt +0 -0
  42. {codecortex-0.15.4 → codecortex-0.16.0}/src/codecortex.egg-info/top_level.txt +0 -0
  43. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/auth.py +0 -0
  44. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/cache.py +0 -0
  45. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/__init__.py +0 -0
  46. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/_common.py +0 -0
  47. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/doctor.py +0 -0
  48. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/gen_token.py +0 -0
  49. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/graph.py +0 -0
  50. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/index.py +0 -0
  51. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/install.py +0 -0
  52. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/map.py +0 -0
  53. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/query.py +0 -0
  54. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/reset.py +0 -0
  55. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/serve.py +0 -0
  56. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/serve_http.py +0 -0
  57. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/commands/setup.py +0 -0
  58. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/config.py +0 -0
  59. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/containment.py +0 -0
  60. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/gateway.py +0 -0
  61. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/grapher.py +0 -0
  62. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/http_server.py +0 -0
  63. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/indexer.py +0 -0
  64. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/injector.py +0 -0
  65. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/installer.py +0 -0
  66. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/loc.py +0 -0
  67. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/logconfig.py +0 -0
  68. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/mapper.py +0 -0
  69. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/metrics.py +0 -0
  70. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/outcome.py +0 -0
  71. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/policy.py +0 -0
  72. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/provider.py +0 -0
  73. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/providers/__init__.py +0 -0
  74. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/providers/lsp.py +0 -0
  75. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/providers/none.py +0 -0
  76. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/providers/semantic.py +0 -0
  77. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/py.typed +0 -0
  78. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/redact.py +0 -0
  79. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/reindexer.py +0 -0
  80. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/reset.py +0 -0
  81. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/searcher.py +0 -0
  82. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/semantic_db.py +0 -0
  83. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/source_kind.py +0 -0
  84. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/term.py +0 -0
  85. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/verify.py +0 -0
  86. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/viewer/__init__.py +0 -0
  87. {codecortex-0.15.4 → codecortex-0.16.0}/src/codeintel/viewer/graph_template.html +0 -0
  88. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_cache.py +0 -0
  89. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_chunking.py +0 -0
  90. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_cli_commands.py +0 -0
  91. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_cli_help.py +0 -0
  92. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_cold_process.py +0 -0
  93. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_config.py +0 -0
  94. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_e2e.py +0 -0
  95. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_engine_adoption.py +0 -0
  96. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_enterprise.py +0 -0
  97. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_gateway.py +0 -0
  98. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_graph_stdin.py +0 -0
  99. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_grapher.py +0 -0
  100. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_http_auth.py +0 -0
  101. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_http_server.py +0 -0
  102. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_installer.py +0 -0
  103. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_integration.py +0 -0
  104. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_lsp_provider.py +0 -0
  105. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_lsp_real.py +0 -0
  106. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_mapper.py +0 -0
  107. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_mcp_handshake.py +0 -0
  108. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_mcp_server.py +0 -0
  109. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_model_dimension.py +0 -0
  110. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_never_raise.py +0 -0
  111. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_rbac.py +0 -0
  112. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_reindexer.py +0 -0
  113. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_rerank.py +0 -0
  114. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_semantic_provider.py +0 -0
  115. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_source_kind.py +0 -0
  116. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_term.py +0 -0
  117. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_treesitter.py +0 -0
  118. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_verify.py +0 -0
  119. {codecortex-0.15.4 → codecortex-0.16.0}/tests/test_verify_call.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codecortex
3
- Version: 0.15.4
3
+ Version: 0.16.0
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
@@ -95,39 +95,61 @@ It's one call: `code.query(op, target, engine="auto")`. In `auto` mode (the defa
95
95
  | Everything about one symbol | `context` | graph + lsp | both views merged |
96
96
  | **Impact of your uncommitted edits** | `changed` | graph | changed files → impacted symbols |
97
97
  | Refactor-risk hotspots | `hotspots` | graph | highest complexity / fan-in symbols |
98
- | Unreferenced (dead) code | `deadcode` | graph | non-test symbols with no callers, **verified against the source** — [treat as candidates, not instructions](#deadcode-is-a-candidate-list-not-a-delete-list) |
98
+ | Unreferenced (dead) code | `deadcode` | graph | **withdrawn and now retired** — a labelled corpus measured its precision at 25%; safe-nulls with `reason: "op-withdrawn"`, and no flag brings it back — [the measurement, and what to use instead](#deadcode-is-retired) |
99
99
 
100
100
  Pin one engine with `--engine graph│lsp│semantic`, or fan out with `--engine both` / `all` to merge results.
101
101
 
102
- #### `deadcode` is a candidate list, not a delete list
102
+ `callers`, `callees` and `impact` resolve the target by its **unqualified name**. When several
103
+ symbols share it, each matched symbol's rows are reported separately under its own heading and the
104
+ result says how many it found — narrow to one with a qualified target (`core.Group.invoke`) or a file
105
+ hint (`invoke@src/click/testing.py`); see
106
+ [when several symbols share a name](docs/graph.md#when-several-symbols-share-a-name).
103
107
 
104
- `deadcode` is the one op whose output invites a destructive action, so it gets an explicit caveat.
105
- Every hit is re-read and verified against the source before it is reported, which removes the
106
- common false positives — but **no reachability analysis sees every caller.** Dynamic dispatch,
107
- registries and decorators, `getattr` lookups, entry points declared in packaging metadata, plugin
108
- discovery, reflection, and calls from languages the graph does not parse are all invisible to it.
109
- Through `0.14.x` it was systematically wrong on callback-heavy code and confident about it; that
110
- class of defect is fixed, but the underlying limit is structural and permanent.
108
+ #### `deadcode` is retired
111
109
 
112
- **So: review each hit before deleting anything, and never wire `deadcode` into an agent that
113
- deletes without a human in the loop.** Used as a ranked list of *places worth looking*, it is
114
- genuinely useful. Used as a work order, it will eventually remove live code.
110
+ `deadcode` no longer exists. Asking for it returns a safe-null (`reason: "op-withdrawn"`) with a hint
111
+ naming what to use instead, and **no flag brings it back** the implementation has been deleted.
115
112
 
116
- **Example "who uses `safe_null_result`?"**
113
+ It was withdrawn pending one condition: *"it returns when a labelled corpus measures its precision
114
+ and recall — not before."* That corpus now exists, in
115
+ [`tests/test_corpus.py`](tests/test_corpus.py), and the measurement is what retired it.
117
116
 
118
- ```jsonc
119
- // request
120
- { "op": "callers", "target": "safe_null_result", "engine": "auto" }
117
+ **How it was measured.** Two pinned real Python repositories (`pallets/click`, `psf/requests`), with
118
+ every function and method collected from the **AST** — 2,425 definitions, `async def` and class
119
+ methods included, because a verification whose population comes from a pattern like `^\s*def ` cannot
120
+ see half of them. Each is labelled live or dead with the reference behind the label recorded beside
121
+ it. The oracle errs toward *live*: a decorator, a dunder, an override of an external interface, a
122
+ string-dispatch mention, or public-API status is each enough to call a symbol live, so "dead" is only
123
+ what survives all of them. That biases the numbers against the op, which is the correct direction for
124
+ a check whose output is an instruction to delete code. Known-answer canaries are planted in both trees
125
+ so recall has a denominator at all.
121
126
 
122
- // response — always this exact envelope; `result` is ready-to-read markdown
123
- {
124
- "ok": true, "op": "callers", "target": "safe_null_result",
125
- "engine": "graph", "cached": false,
126
- "result": "## Callers of safe_null_result (7)\n- …gateway [USAGE] (src/codeintel/gateway.py)\n- …providers.graph [USAGE] (src/codeintel/providers/graph.py)\n- …server [USAGE] (src/codeintel/server.py)\n- … (4 more)"
127
- }
128
- ```
127
+ **The numbers.**
128
+
129
+ | | precision | recall |
130
+ |---|---|---|
131
+ | as shipped | **25%** (6 of 24) | 60% (6 of 10) |
132
+ | with the two repairs this codebase already contains elsewhere | 89% (8 of 9) | 80% (8 of 10) |
133
+
134
+ And the measurement that decided it — **real code only, canaries removed**: the op as shipped named
135
+ **18 candidates across those two repositories, and every one of them was live.** All 18 were Makefile
136
+ targets, which the graph backend indexes as `Function` nodes. Repaired, it names exactly one, and
137
+ that one is `MockRequest.get_type` in requests — a method `http.cookiejar` calls by duck-typed
138
+ convention, whose name appears once in the source.
139
+
140
+ **Why it was not repaired further.** The verification was a name-frequency scan over the source, so it
141
+ fails on exactly one condition: a symbol whose name appears once and is called by a convention
142
+ outside the source. Two repositories produced three distinct instances of that condition — non-code
143
+ nodes labelled `Function`, interpreter-called dunders, and stdlib duck-typed protocol methods — and
144
+ the earlier TypeScript evidence adds a rollup plugin hook and object-literal properties. The set is
145
+ not enumerable: no specification lists `get_type`. Every repository added revealed a new member of it.
146
+
147
+ Weighed against that: in 2,425 real definitions across two maintained repositories there was **not
148
+ one** dead private symbol to find. An op whose measured yield on real code is zero true positives has
149
+ no benefit to set against that error rate.
129
150
 
130
- The agent hands `result` straight to the model. If the graph backend isn't installed, the identical call returns `"result": null, "reason": "engine-unavailable"` — no exception, and the agent just falls back to its own search.
151
+ **Use `callers` on a specific symbol instead.** "Does anything call this?" is exactly the question
152
+ `deadcode` was trying to answer in bulk, and `callers` answers it accurately, one symbol at a time.
131
153
 
132
154
  ## What makes it good
133
155
 
@@ -175,6 +197,21 @@ codeintel install # registers with the agents you actually have insta
175
197
  codeintel query --op search --target "authentication middleware"
176
198
  ```
177
199
 
200
+ ### Or: have your agent set it up
201
+
202
+ Prefer to let your coding agent run the steps? Generate a paste-ready prompt, tailored to this
203
+ machine and agent:
204
+
205
+ ```bash
206
+ codeintel prompt # this repo — probes health, emits only the steps still outstanding
207
+ codeintel prompt --fresh | pbcopy # the full sequence from `pip install`, to send a friend
208
+ ```
209
+
210
+ It runs a `doctor` probe and prints a block you copy into Claude Code / Codex / Gemini / Zed: the
211
+ exact remaining commands (or "just restart me" when everything is already healthy and registered),
212
+ a `doctor --deep` verification, and the reminder to restart the agent so the MCP tools load. The
213
+ prompt goes to stdout (so `| pbcopy` grabs exactly it); the "paste this" note goes to stderr.
214
+
178
215
  ### Enable native Codex integration
179
216
 
180
217
  `codeintel` is an MCP server, so Codex can call its tools directly rather than invoking the CLI.
@@ -358,6 +395,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
358
395
  | `codeintel help` | Every command grouped by task, with descriptions and examples (also the bare `codeintel`). A mistyped command suggests what you meant. |
359
396
  | `codeintel install [--agent auto\|claude\|codex\|gemini\|zed\|all] [--no-verify] [--relative-command]` | Register codeintel with the agents installed on this machine (`auto`, the default), then prove it by completing a real MCP handshake against the registered command |
360
397
  | `codeintel setup [project_root] [--all] [--index] [--warm] [--install-uv] [--install-deps] [--json]` | Prepare backends + index this repo (`--all` = one command: do everything automatable, idempotent); ends with a health report + **Next:** steps |
398
+ | `codeintel prompt [project_root] [--agent auto\|claude\|codex\|gemini\|zed] [--fresh] [--deep]` | Print a paste-to-your-agent setup prompt; probes health and emits only the outstanding steps (or "just restart me" when already healthy). `--fresh` = the full sequence from `pip install`, to send a friend |
361
399
  | `codeintel index [project_root]` | Index a project for semantic search |
362
400
  | `codeintel serve` | Start the MCP server (stdio transport) |
363
401
  | `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) |
@@ -511,26 +549,33 @@ back to grep rather than crashing.
511
549
 
512
550
  | Area | Why |
513
551
  |---|---|
514
- | `deadcode` | It suggests deletions and cannot see every caller — [read the caveat](#deadcode-is-a-candidate-list-not-a-delete-list). |
552
+ | `deadcode` | Withdrawn, then **retired** (`reason: "op-withdrawn"`) a labelled corpus measured 25% precision. Use `callers` on a specific symbol instead — [the measurement](#deadcode-is-retired). |
515
553
  | Non-loopback serving | `serve-http` is stdlib `http.server`. It binds loopback by default for a reason; front it with a reverse proxy and see [docs/deploy.md](docs/deploy.md). |
516
554
  | RBAC between **untrusting** tenants | It separates privilege levels among callers you already trust. It is not a wall against an adversary with write access to their own root — see the warning in [docs/deploy.md](docs/deploy.md). |
517
555
  | Unattended automation | Anything that acts on a result without a human reading it deserves a pilot first. |
518
556
 
519
557
  **On the test numbers.** The suite is large and the coverage floor is enforced, but read the figure
520
- with its caveat: the graph and LSP backends are external binaries that are **not installed in CI**,
521
- so those two engines are exercised against hand-authored mocks rather than the real wire contract,
522
- and the release canary which does assert on real answer text against a built wheel — currently
523
- covers the semantic engine only. Line coverage measures how much of the intended behavior runs, not
524
- how much of reality it has met.
558
+ with its caveat. In the **main test job** the graph and LSP backends are absent, so their live tests
559
+ skip and those engines run against hand-authored mocks rather than the real wire contract. Separate
560
+ jobs cover the contract itself: `graph-contract` installs the pinned `codebase-memory-mcp` and runs
561
+ the live graph tests and **fails if they skipped**, because a silently-skipped contract test is
562
+ how a total backend outage stayed green here once — while the nightly corpus job runs that same
563
+ real backend against pinned third-party repositories. `lsp-contract` runs the live serena tests but
564
+ is **`continue-on-error`**: serena is fetched from an upstream git HEAD this project does not
565
+ control, so a breakage there must be visible without blocking an unrelated release. Read that as
566
+ the LSP wire contract being *watched* rather than *gated*. The release canary — the only check that
567
+ asserts on real answer text from a built wheel — still covers **the semantic engine only**.
568
+
569
+ Line coverage measures how much of the intended behavior runs, not how much of reality it has met.
525
570
 
526
571
  **The honest one-paragraph version.** codeintel has been run on very few repositories its author did
527
572
  not write, and that is where its bugs have come from — every fix in `0.15.x` came from pointing it
528
573
  at an unfamiliar codebase. Its characteristic failure mode is **answering confidently from the
529
574
  wrong index rather than failing loudly**, which the never-raise contract makes harder to notice: a
530
575
  wrong answer and a right one are the same shape. Run `codeintel doctor` before trusting a repo-wide
531
- answer, treat `deadcode` as candidates for review, and if something looks off please
532
- [report it](#reporting-a-problem) — an issue from someone who is not the author is the single most
533
- useful thing this project can receive right now.
576
+ answer and `deadcode` in particular is retired rather than merely caveated (see above) — and if
577
+ something looks off please [report it](#reporting-a-problem) — an issue from someone who is not the
578
+ author is the single most useful thing this project can receive right now.
534
579
 
535
580
  **Engine coverage depends on external binaries.** Semantic search works out of the box. The graph
536
581
  engine needs `codebase-memory-mcp` and the LSP engine needs `uvx` on `PATH` — without them those
@@ -58,39 +58,61 @@ It's one call: `code.query(op, target, engine="auto")`. In `auto` mode (the defa
58
58
  | Everything about one symbol | `context` | graph + lsp | both views merged |
59
59
  | **Impact of your uncommitted edits** | `changed` | graph | changed files → impacted symbols |
60
60
  | Refactor-risk hotspots | `hotspots` | graph | highest complexity / fan-in symbols |
61
- | Unreferenced (dead) code | `deadcode` | graph | non-test symbols with no callers, **verified against the source** — [treat as candidates, not instructions](#deadcode-is-a-candidate-list-not-a-delete-list) |
61
+ | Unreferenced (dead) code | `deadcode` | graph | **withdrawn and now retired** — a labelled corpus measured its precision at 25%; safe-nulls with `reason: "op-withdrawn"`, and no flag brings it back — [the measurement, and what to use instead](#deadcode-is-retired) |
62
62
 
63
63
  Pin one engine with `--engine graph│lsp│semantic`, or fan out with `--engine both` / `all` to merge results.
64
64
 
65
- #### `deadcode` is a candidate list, not a delete list
65
+ `callers`, `callees` and `impact` resolve the target by its **unqualified name**. When several
66
+ symbols share it, each matched symbol's rows are reported separately under its own heading and the
67
+ result says how many it found — narrow to one with a qualified target (`core.Group.invoke`) or a file
68
+ hint (`invoke@src/click/testing.py`); see
69
+ [when several symbols share a name](docs/graph.md#when-several-symbols-share-a-name).
66
70
 
67
- `deadcode` is the one op whose output invites a destructive action, so it gets an explicit caveat.
68
- Every hit is re-read and verified against the source before it is reported, which removes the
69
- common false positives — but **no reachability analysis sees every caller.** Dynamic dispatch,
70
- registries and decorators, `getattr` lookups, entry points declared in packaging metadata, plugin
71
- discovery, reflection, and calls from languages the graph does not parse are all invisible to it.
72
- Through `0.14.x` it was systematically wrong on callback-heavy code and confident about it; that
73
- class of defect is fixed, but the underlying limit is structural and permanent.
71
+ #### `deadcode` is retired
74
72
 
75
- **So: review each hit before deleting anything, and never wire `deadcode` into an agent that
76
- deletes without a human in the loop.** Used as a ranked list of *places worth looking*, it is
77
- genuinely useful. Used as a work order, it will eventually remove live code.
73
+ `deadcode` no longer exists. Asking for it returns a safe-null (`reason: "op-withdrawn"`) with a hint
74
+ naming what to use instead, and **no flag brings it back** the implementation has been deleted.
78
75
 
79
- **Example "who uses `safe_null_result`?"**
76
+ It was withdrawn pending one condition: *"it returns when a labelled corpus measures its precision
77
+ and recall — not before."* That corpus now exists, in
78
+ [`tests/test_corpus.py`](tests/test_corpus.py), and the measurement is what retired it.
80
79
 
81
- ```jsonc
82
- // request
83
- { "op": "callers", "target": "safe_null_result", "engine": "auto" }
80
+ **How it was measured.** Two pinned real Python repositories (`pallets/click`, `psf/requests`), with
81
+ every function and method collected from the **AST** — 2,425 definitions, `async def` and class
82
+ methods included, because a verification whose population comes from a pattern like `^\s*def ` cannot
83
+ see half of them. Each is labelled live or dead with the reference behind the label recorded beside
84
+ it. The oracle errs toward *live*: a decorator, a dunder, an override of an external interface, a
85
+ string-dispatch mention, or public-API status is each enough to call a symbol live, so "dead" is only
86
+ what survives all of them. That biases the numbers against the op, which is the correct direction for
87
+ a check whose output is an instruction to delete code. Known-answer canaries are planted in both trees
88
+ so recall has a denominator at all.
84
89
 
85
- // response — always this exact envelope; `result` is ready-to-read markdown
86
- {
87
- "ok": true, "op": "callers", "target": "safe_null_result",
88
- "engine": "graph", "cached": false,
89
- "result": "## Callers of safe_null_result (7)\n- …gateway [USAGE] (src/codeintel/gateway.py)\n- …providers.graph [USAGE] (src/codeintel/providers/graph.py)\n- …server [USAGE] (src/codeintel/server.py)\n- … (4 more)"
90
- }
91
- ```
90
+ **The numbers.**
91
+
92
+ | | precision | recall |
93
+ |---|---|---|
94
+ | as shipped | **25%** (6 of 24) | 60% (6 of 10) |
95
+ | with the two repairs this codebase already contains elsewhere | 89% (8 of 9) | 80% (8 of 10) |
96
+
97
+ And the measurement that decided it — **real code only, canaries removed**: the op as shipped named
98
+ **18 candidates across those two repositories, and every one of them was live.** All 18 were Makefile
99
+ targets, which the graph backend indexes as `Function` nodes. Repaired, it names exactly one, and
100
+ that one is `MockRequest.get_type` in requests — a method `http.cookiejar` calls by duck-typed
101
+ convention, whose name appears once in the source.
102
+
103
+ **Why it was not repaired further.** The verification was a name-frequency scan over the source, so it
104
+ fails on exactly one condition: a symbol whose name appears once and is called by a convention
105
+ outside the source. Two repositories produced three distinct instances of that condition — non-code
106
+ nodes labelled `Function`, interpreter-called dunders, and stdlib duck-typed protocol methods — and
107
+ the earlier TypeScript evidence adds a rollup plugin hook and object-literal properties. The set is
108
+ not enumerable: no specification lists `get_type`. Every repository added revealed a new member of it.
109
+
110
+ Weighed against that: in 2,425 real definitions across two maintained repositories there was **not
111
+ one** dead private symbol to find. An op whose measured yield on real code is zero true positives has
112
+ no benefit to set against that error rate.
92
113
 
93
- The agent hands `result` straight to the model. If the graph backend isn't installed, the identical call returns `"result": null, "reason": "engine-unavailable"` — no exception, and the agent just falls back to its own search.
114
+ **Use `callers` on a specific symbol instead.** "Does anything call this?" is exactly the question
115
+ `deadcode` was trying to answer in bulk, and `callers` answers it accurately, one symbol at a time.
94
116
 
95
117
  ## What makes it good
96
118
 
@@ -138,6 +160,21 @@ codeintel install # registers with the agents you actually have insta
138
160
  codeintel query --op search --target "authentication middleware"
139
161
  ```
140
162
 
163
+ ### Or: have your agent set it up
164
+
165
+ Prefer to let your coding agent run the steps? Generate a paste-ready prompt, tailored to this
166
+ machine and agent:
167
+
168
+ ```bash
169
+ codeintel prompt # this repo — probes health, emits only the steps still outstanding
170
+ codeintel prompt --fresh | pbcopy # the full sequence from `pip install`, to send a friend
171
+ ```
172
+
173
+ It runs a `doctor` probe and prints a block you copy into Claude Code / Codex / Gemini / Zed: the
174
+ exact remaining commands (or "just restart me" when everything is already healthy and registered),
175
+ a `doctor --deep` verification, and the reminder to restart the agent so the MCP tools load. The
176
+ prompt goes to stdout (so `| pbcopy` grabs exactly it); the "paste this" note goes to stderr.
177
+
141
178
  ### Enable native Codex integration
142
179
 
143
180
  `codeintel` is an MCP server, so Codex can call its tools directly rather than invoking the CLI.
@@ -321,6 +358,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
321
358
  | `codeintel help` | Every command grouped by task, with descriptions and examples (also the bare `codeintel`). A mistyped command suggests what you meant. |
322
359
  | `codeintel install [--agent auto\|claude\|codex\|gemini\|zed\|all] [--no-verify] [--relative-command]` | Register codeintel with the agents installed on this machine (`auto`, the default), then prove it by completing a real MCP handshake against the registered command |
323
360
  | `codeintel setup [project_root] [--all] [--index] [--warm] [--install-uv] [--install-deps] [--json]` | Prepare backends + index this repo (`--all` = one command: do everything automatable, idempotent); ends with a health report + **Next:** steps |
361
+ | `codeintel prompt [project_root] [--agent auto\|claude\|codex\|gemini\|zed] [--fresh] [--deep]` | Print a paste-to-your-agent setup prompt; probes health and emits only the outstanding steps (or "just restart me" when already healthy). `--fresh` = the full sequence from `pip install`, to send a friend |
324
362
  | `codeintel index [project_root]` | Index a project for semantic search |
325
363
  | `codeintel serve` | Start the MCP server (stdio transport) |
326
364
  | `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) |
@@ -474,26 +512,33 @@ back to grep rather than crashing.
474
512
 
475
513
  | Area | Why |
476
514
  |---|---|
477
- | `deadcode` | It suggests deletions and cannot see every caller — [read the caveat](#deadcode-is-a-candidate-list-not-a-delete-list). |
515
+ | `deadcode` | Withdrawn, then **retired** (`reason: "op-withdrawn"`) a labelled corpus measured 25% precision. Use `callers` on a specific symbol instead — [the measurement](#deadcode-is-retired). |
478
516
  | Non-loopback serving | `serve-http` is stdlib `http.server`. It binds loopback by default for a reason; front it with a reverse proxy and see [docs/deploy.md](docs/deploy.md). |
479
517
  | RBAC between **untrusting** tenants | It separates privilege levels among callers you already trust. It is not a wall against an adversary with write access to their own root — see the warning in [docs/deploy.md](docs/deploy.md). |
480
518
  | Unattended automation | Anything that acts on a result without a human reading it deserves a pilot first. |
481
519
 
482
520
  **On the test numbers.** The suite is large and the coverage floor is enforced, but read the figure
483
- with its caveat: the graph and LSP backends are external binaries that are **not installed in CI**,
484
- so those two engines are exercised against hand-authored mocks rather than the real wire contract,
485
- and the release canary which does assert on real answer text against a built wheel — currently
486
- covers the semantic engine only. Line coverage measures how much of the intended behavior runs, not
487
- how much of reality it has met.
521
+ with its caveat. In the **main test job** the graph and LSP backends are absent, so their live tests
522
+ skip and those engines run against hand-authored mocks rather than the real wire contract. Separate
523
+ jobs cover the contract itself: `graph-contract` installs the pinned `codebase-memory-mcp` and runs
524
+ the live graph tests and **fails if they skipped**, because a silently-skipped contract test is
525
+ how a total backend outage stayed green here once — while the nightly corpus job runs that same
526
+ real backend against pinned third-party repositories. `lsp-contract` runs the live serena tests but
527
+ is **`continue-on-error`**: serena is fetched from an upstream git HEAD this project does not
528
+ control, so a breakage there must be visible without blocking an unrelated release. Read that as
529
+ the LSP wire contract being *watched* rather than *gated*. The release canary — the only check that
530
+ asserts on real answer text from a built wheel — still covers **the semantic engine only**.
531
+
532
+ Line coverage measures how much of the intended behavior runs, not how much of reality it has met.
488
533
 
489
534
  **The honest one-paragraph version.** codeintel has been run on very few repositories its author did
490
535
  not write, and that is where its bugs have come from — every fix in `0.15.x` came from pointing it
491
536
  at an unfamiliar codebase. Its characteristic failure mode is **answering confidently from the
492
537
  wrong index rather than failing loudly**, which the never-raise contract makes harder to notice: a
493
538
  wrong answer and a right one are the same shape. Run `codeintel doctor` before trusting a repo-wide
494
- answer, treat `deadcode` as candidates for review, and if something looks off please
495
- [report it](#reporting-a-problem) — an issue from someone who is not the author is the single most
496
- useful thing this project can receive right now.
539
+ answer and `deadcode` in particular is retired rather than merely caveated (see above) — and if
540
+ something looks off please [report it](#reporting-a-problem) — an issue from someone who is not the
541
+ author is the single most useful thing this project can receive right now.
497
542
 
498
543
  **Engine coverage depends on external binaries.** Semantic search works out of the box. The graph
499
544
  engine needs `codebase-memory-mcp` and the LSP engine needs `uvx` on `PATH` — without them those
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codecortex
3
- Version: 0.15.4
3
+ Version: 0.16.0
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
@@ -95,39 +95,61 @@ It's one call: `code.query(op, target, engine="auto")`. In `auto` mode (the defa
95
95
  | Everything about one symbol | `context` | graph + lsp | both views merged |
96
96
  | **Impact of your uncommitted edits** | `changed` | graph | changed files → impacted symbols |
97
97
  | Refactor-risk hotspots | `hotspots` | graph | highest complexity / fan-in symbols |
98
- | Unreferenced (dead) code | `deadcode` | graph | non-test symbols with no callers, **verified against the source** — [treat as candidates, not instructions](#deadcode-is-a-candidate-list-not-a-delete-list) |
98
+ | Unreferenced (dead) code | `deadcode` | graph | **withdrawn and now retired** — a labelled corpus measured its precision at 25%; safe-nulls with `reason: "op-withdrawn"`, and no flag brings it back — [the measurement, and what to use instead](#deadcode-is-retired) |
99
99
 
100
100
  Pin one engine with `--engine graph│lsp│semantic`, or fan out with `--engine both` / `all` to merge results.
101
101
 
102
- #### `deadcode` is a candidate list, not a delete list
102
+ `callers`, `callees` and `impact` resolve the target by its **unqualified name**. When several
103
+ symbols share it, each matched symbol's rows are reported separately under its own heading and the
104
+ result says how many it found — narrow to one with a qualified target (`core.Group.invoke`) or a file
105
+ hint (`invoke@src/click/testing.py`); see
106
+ [when several symbols share a name](docs/graph.md#when-several-symbols-share-a-name).
103
107
 
104
- `deadcode` is the one op whose output invites a destructive action, so it gets an explicit caveat.
105
- Every hit is re-read and verified against the source before it is reported, which removes the
106
- common false positives — but **no reachability analysis sees every caller.** Dynamic dispatch,
107
- registries and decorators, `getattr` lookups, entry points declared in packaging metadata, plugin
108
- discovery, reflection, and calls from languages the graph does not parse are all invisible to it.
109
- Through `0.14.x` it was systematically wrong on callback-heavy code and confident about it; that
110
- class of defect is fixed, but the underlying limit is structural and permanent.
108
+ #### `deadcode` is retired
111
109
 
112
- **So: review each hit before deleting anything, and never wire `deadcode` into an agent that
113
- deletes without a human in the loop.** Used as a ranked list of *places worth looking*, it is
114
- genuinely useful. Used as a work order, it will eventually remove live code.
110
+ `deadcode` no longer exists. Asking for it returns a safe-null (`reason: "op-withdrawn"`) with a hint
111
+ naming what to use instead, and **no flag brings it back** the implementation has been deleted.
115
112
 
116
- **Example "who uses `safe_null_result`?"**
113
+ It was withdrawn pending one condition: *"it returns when a labelled corpus measures its precision
114
+ and recall — not before."* That corpus now exists, in
115
+ [`tests/test_corpus.py`](tests/test_corpus.py), and the measurement is what retired it.
117
116
 
118
- ```jsonc
119
- // request
120
- { "op": "callers", "target": "safe_null_result", "engine": "auto" }
117
+ **How it was measured.** Two pinned real Python repositories (`pallets/click`, `psf/requests`), with
118
+ every function and method collected from the **AST** — 2,425 definitions, `async def` and class
119
+ methods included, because a verification whose population comes from a pattern like `^\s*def ` cannot
120
+ see half of them. Each is labelled live or dead with the reference behind the label recorded beside
121
+ it. The oracle errs toward *live*: a decorator, a dunder, an override of an external interface, a
122
+ string-dispatch mention, or public-API status is each enough to call a symbol live, so "dead" is only
123
+ what survives all of them. That biases the numbers against the op, which is the correct direction for
124
+ a check whose output is an instruction to delete code. Known-answer canaries are planted in both trees
125
+ so recall has a denominator at all.
121
126
 
122
- // response — always this exact envelope; `result` is ready-to-read markdown
123
- {
124
- "ok": true, "op": "callers", "target": "safe_null_result",
125
- "engine": "graph", "cached": false,
126
- "result": "## Callers of safe_null_result (7)\n- …gateway [USAGE] (src/codeintel/gateway.py)\n- …providers.graph [USAGE] (src/codeintel/providers/graph.py)\n- …server [USAGE] (src/codeintel/server.py)\n- … (4 more)"
127
- }
128
- ```
127
+ **The numbers.**
128
+
129
+ | | precision | recall |
130
+ |---|---|---|
131
+ | as shipped | **25%** (6 of 24) | 60% (6 of 10) |
132
+ | with the two repairs this codebase already contains elsewhere | 89% (8 of 9) | 80% (8 of 10) |
133
+
134
+ And the measurement that decided it — **real code only, canaries removed**: the op as shipped named
135
+ **18 candidates across those two repositories, and every one of them was live.** All 18 were Makefile
136
+ targets, which the graph backend indexes as `Function` nodes. Repaired, it names exactly one, and
137
+ that one is `MockRequest.get_type` in requests — a method `http.cookiejar` calls by duck-typed
138
+ convention, whose name appears once in the source.
139
+
140
+ **Why it was not repaired further.** The verification was a name-frequency scan over the source, so it
141
+ fails on exactly one condition: a symbol whose name appears once and is called by a convention
142
+ outside the source. Two repositories produced three distinct instances of that condition — non-code
143
+ nodes labelled `Function`, interpreter-called dunders, and stdlib duck-typed protocol methods — and
144
+ the earlier TypeScript evidence adds a rollup plugin hook and object-literal properties. The set is
145
+ not enumerable: no specification lists `get_type`. Every repository added revealed a new member of it.
146
+
147
+ Weighed against that: in 2,425 real definitions across two maintained repositories there was **not
148
+ one** dead private symbol to find. An op whose measured yield on real code is zero true positives has
149
+ no benefit to set against that error rate.
129
150
 
130
- The agent hands `result` straight to the model. If the graph backend isn't installed, the identical call returns `"result": null, "reason": "engine-unavailable"` — no exception, and the agent just falls back to its own search.
151
+ **Use `callers` on a specific symbol instead.** "Does anything call this?" is exactly the question
152
+ `deadcode` was trying to answer in bulk, and `callers` answers it accurately, one symbol at a time.
131
153
 
132
154
  ## What makes it good
133
155
 
@@ -175,6 +197,21 @@ codeintel install # registers with the agents you actually have insta
175
197
  codeintel query --op search --target "authentication middleware"
176
198
  ```
177
199
 
200
+ ### Or: have your agent set it up
201
+
202
+ Prefer to let your coding agent run the steps? Generate a paste-ready prompt, tailored to this
203
+ machine and agent:
204
+
205
+ ```bash
206
+ codeintel prompt # this repo — probes health, emits only the steps still outstanding
207
+ codeintel prompt --fresh | pbcopy # the full sequence from `pip install`, to send a friend
208
+ ```
209
+
210
+ It runs a `doctor` probe and prints a block you copy into Claude Code / Codex / Gemini / Zed: the
211
+ exact remaining commands (or "just restart me" when everything is already healthy and registered),
212
+ a `doctor --deep` verification, and the reminder to restart the agent so the MCP tools load. The
213
+ prompt goes to stdout (so `| pbcopy` grabs exactly it); the "paste this" note goes to stderr.
214
+
178
215
  ### Enable native Codex integration
179
216
 
180
217
  `codeintel` is an MCP server, so Codex can call its tools directly rather than invoking the CLI.
@@ -358,6 +395,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
358
395
  | `codeintel help` | Every command grouped by task, with descriptions and examples (also the bare `codeintel`). A mistyped command suggests what you meant. |
359
396
  | `codeintel install [--agent auto\|claude\|codex\|gemini\|zed\|all] [--no-verify] [--relative-command]` | Register codeintel with the agents installed on this machine (`auto`, the default), then prove it by completing a real MCP handshake against the registered command |
360
397
  | `codeintel setup [project_root] [--all] [--index] [--warm] [--install-uv] [--install-deps] [--json]` | Prepare backends + index this repo (`--all` = one command: do everything automatable, idempotent); ends with a health report + **Next:** steps |
398
+ | `codeintel prompt [project_root] [--agent auto\|claude\|codex\|gemini\|zed] [--fresh] [--deep]` | Print a paste-to-your-agent setup prompt; probes health and emits only the outstanding steps (or "just restart me" when already healthy). `--fresh` = the full sequence from `pip install`, to send a friend |
361
399
  | `codeintel index [project_root]` | Index a project for semantic search |
362
400
  | `codeintel serve` | Start the MCP server (stdio transport) |
363
401
  | `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) |
@@ -511,26 +549,33 @@ back to grep rather than crashing.
511
549
 
512
550
  | Area | Why |
513
551
  |---|---|
514
- | `deadcode` | It suggests deletions and cannot see every caller — [read the caveat](#deadcode-is-a-candidate-list-not-a-delete-list). |
552
+ | `deadcode` | Withdrawn, then **retired** (`reason: "op-withdrawn"`) a labelled corpus measured 25% precision. Use `callers` on a specific symbol instead — [the measurement](#deadcode-is-retired). |
515
553
  | Non-loopback serving | `serve-http` is stdlib `http.server`. It binds loopback by default for a reason; front it with a reverse proxy and see [docs/deploy.md](docs/deploy.md). |
516
554
  | RBAC between **untrusting** tenants | It separates privilege levels among callers you already trust. It is not a wall against an adversary with write access to their own root — see the warning in [docs/deploy.md](docs/deploy.md). |
517
555
  | Unattended automation | Anything that acts on a result without a human reading it deserves a pilot first. |
518
556
 
519
557
  **On the test numbers.** The suite is large and the coverage floor is enforced, but read the figure
520
- with its caveat: the graph and LSP backends are external binaries that are **not installed in CI**,
521
- so those two engines are exercised against hand-authored mocks rather than the real wire contract,
522
- and the release canary which does assert on real answer text against a built wheel — currently
523
- covers the semantic engine only. Line coverage measures how much of the intended behavior runs, not
524
- how much of reality it has met.
558
+ with its caveat. In the **main test job** the graph and LSP backends are absent, so their live tests
559
+ skip and those engines run against hand-authored mocks rather than the real wire contract. Separate
560
+ jobs cover the contract itself: `graph-contract` installs the pinned `codebase-memory-mcp` and runs
561
+ the live graph tests and **fails if they skipped**, because a silently-skipped contract test is
562
+ how a total backend outage stayed green here once — while the nightly corpus job runs that same
563
+ real backend against pinned third-party repositories. `lsp-contract` runs the live serena tests but
564
+ is **`continue-on-error`**: serena is fetched from an upstream git HEAD this project does not
565
+ control, so a breakage there must be visible without blocking an unrelated release. Read that as
566
+ the LSP wire contract being *watched* rather than *gated*. The release canary — the only check that
567
+ asserts on real answer text from a built wheel — still covers **the semantic engine only**.
568
+
569
+ Line coverage measures how much of the intended behavior runs, not how much of reality it has met.
525
570
 
526
571
  **The honest one-paragraph version.** codeintel has been run on very few repositories its author did
527
572
  not write, and that is where its bugs have come from — every fix in `0.15.x` came from pointing it
528
573
  at an unfamiliar codebase. Its characteristic failure mode is **answering confidently from the
529
574
  wrong index rather than failing loudly**, which the never-raise contract makes harder to notice: a
530
575
  wrong answer and a right one are the same shape. Run `codeintel doctor` before trusting a repo-wide
531
- answer, treat `deadcode` as candidates for review, and if something looks off please
532
- [report it](#reporting-a-problem) — an issue from someone who is not the author is the single most
533
- useful thing this project can receive right now.
576
+ answer and `deadcode` in particular is retired rather than merely caveated (see above) — and if
577
+ something looks off please [report it](#reporting-a-problem) — an issue from someone who is not the
578
+ author is the single most useful thing this project can receive right now.
534
579
 
535
580
  **Engine coverage depends on external binaries.** Semantic search works out of the box. The graph
536
581
  engine needs `codebase-memory-mcp` and the LSP engine needs `uvx` on `PATH` — without them those
@@ -9,12 +9,16 @@ src/codecortex.egg-info/requires.txt
9
9
  src/codecortex.egg-info/top_level.txt
10
10
  src/codeintel/__init__.py
11
11
  src/codeintel/__main__.py
12
+ src/codeintel/agent_prompt.py
12
13
  src/codeintel/auth.py
13
14
  src/codeintel/cache.py
14
15
  src/codeintel/config.py
15
16
  src/codeintel/containment.py
16
17
  src/codeintel/doctor.py
17
18
  src/codeintel/gateway.py
19
+ src/codeintel/graph_backend.py
20
+ src/codeintel/graph_render.py
21
+ src/codeintel/graph_resolution.py
18
22
  src/codeintel/grapher.py
19
23
  src/codeintel/http_server.py
20
24
  src/codeintel/indexer.py
@@ -46,6 +50,7 @@ src/codeintel/commands/graph.py
46
50
  src/codeintel/commands/index.py
47
51
  src/codeintel/commands/install.py
48
52
  src/codeintel/commands/map.py
53
+ src/codeintel/commands/prompt.py
49
54
  src/codeintel/commands/query.py
50
55
  src/codeintel/commands/reset.py
51
56
  src/codeintel/commands/serve.py
@@ -59,6 +64,8 @@ src/codeintel/providers/none.py
59
64
  src/codeintel/providers/semantic.py
60
65
  src/codeintel/viewer/__init__.py
61
66
  src/codeintel/viewer/graph_template.html
67
+ tests/test_agent_prompt.py
68
+ tests/test_backend_reaper.py
62
69
  tests/test_cache.py
63
70
  tests/test_chunking.py
64
71
  tests/test_cli_commands.py
@@ -66,6 +73,8 @@ tests/test_cli_help.py
66
73
  tests/test_cold_process.py
67
74
  tests/test_config.py
68
75
  tests/test_corpus.py
76
+ tests/test_docs_ci_claims.py
77
+ tests/test_docs_deadcode_withdrawal.py
69
78
  tests/test_doctor.py
70
79
  tests/test_e2e.py
71
80
  tests/test_engine_adoption.py
@@ -100,4 +109,5 @@ tests/test_source_kind.py
100
109
  tests/test_term.py
101
110
  tests/test_treesitter.py
102
111
  tests/test_verify.py
103
- tests/test_verify_call.py
112
+ tests/test_verify_call.py
113
+ tests/test_version_skew.py
@@ -0,0 +1 @@
1
+ __version__ = "0.16.0"
@@ -18,6 +18,7 @@ _COMMAND_GROUPS: list[tuple[str, list[tuple[str, str]]]] = [
18
18
  ("setup", "Prepare backends + index this repo (--all does everything automatable)"),
19
19
  ("index", "Index a project for semantic search"),
20
20
  ("install", "Register codeintel with the AI agents installed on this machine"),
21
+ ("prompt", "Print a paste-to-your-agent setup prompt, tailored to this machine"),
21
22
  ]),
22
23
  ("Check health", [
23
24
  ("doctor", "Per-engine health + index status, with the fix for each gap"),
@@ -44,6 +45,7 @@ _MODULES = {
44
45
  "setup": "setup",
45
46
  "index": "index",
46
47
  "install": "install",
48
+ "prompt": "prompt",
47
49
  "doctor": "doctor",
48
50
  "status": "status",
49
51
  "reset": "reset",
@@ -236,6 +238,18 @@ def main() -> None:
236
238
  setup_parser.add_argument("--warm", action="store_true", help="Boot serena now (first run pulls it via uvx; slow)")
237
239
  setup_parser.add_argument("--json", action="store_true", help="Emit the structured JSON report")
238
240
 
241
+ # prompt subcommand
242
+ prompt_parser = subparsers.add_parser("prompt", parents=[color_parent],
243
+ help="Print a paste-to-your-agent setup prompt for this repo")
244
+ prompt_parser.add_argument("project_root", nargs="?", default=None, help="Project root (default: cwd)")
245
+ prompt_parser.add_argument("--agent", default="auto",
246
+ help="Agent the prompt targets: claude|codex|gemini|zed|auto (default: auto)")
247
+ prompt_parser.add_argument("--fresh", action="store_true",
248
+ help="Emit the full sequence from `pip install`, ignoring local state "
249
+ "(a template to paste to a friend on a clean machine)")
250
+ prompt_parser.add_argument("--deep", action="store_true",
251
+ help="Boot-check serena while probing (slower; sharper 'already set up' result)")
252
+
239
253
  # reset subcommand
240
254
  reset_parser = subparsers.add_parser("reset", parents=[color_parent],
241
255
  help="Clear the semantic index (recover from a corrupt/stale DB)")