codecortex 0.18.0__tar.gz → 0.19.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.
- {codecortex-0.18.0/src/codecortex.egg-info → codecortex-0.19.0}/PKG-INFO +3 -2
- {codecortex-0.18.0 → codecortex-0.19.0}/README.md +2 -1
- {codecortex-0.18.0 → codecortex-0.19.0/src/codecortex.egg-info}/PKG-INFO +3 -2
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codecortex.egg-info/SOURCES.txt +5 -0
- codecortex-0.19.0/src/codeintel/__init__.py +1 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/__main__.py +206 -20
- codecortex-0.19.0/src/codeintel/c4.py +829 -0
- codecortex-0.19.0/src/codeintel/commands/c4.py +182 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/http_server.py +16 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/mapper.py +62 -13
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/providers/graph.py +69 -4
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/server.py +163 -37
- codecortex-0.19.0/tests/test_c4.py +356 -0
- codecortex-0.19.0/tests/test_c4_model.py +127 -0
- codecortex-0.19.0/tests/test_c4_output.py +401 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_cli_commands.py +2 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_cli_help.py +92 -5
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_graph_provider.py +60 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_mapper.py +58 -2
- codecortex-0.19.0/tests/test_mcp_server.py +190 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_never_raise.py +30 -4
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_rbac.py +43 -0
- codecortex-0.18.0/src/codeintel/__init__.py +0 -1
- codecortex-0.18.0/tests/test_mcp_server.py +0 -78
- {codecortex-0.18.0 → codecortex-0.19.0}/LICENSE +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/pyproject.toml +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/setup.cfg +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codecortex.egg-info/dependency_links.txt +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codecortex.egg-info/entry_points.txt +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codecortex.egg-info/requires.txt +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codecortex.egg-info/top_level.txt +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/agent_prompt.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/auth.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/cache.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/__init__.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/_common.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/doctor.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/gen_token.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/graph.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/index.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/install.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/map.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/prompt.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/query.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/reset.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/serve.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/serve_http.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/setup.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/commands/status.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/config.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/containment.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/doctor.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/gateway.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/graph_backend.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/graph_render.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/graph_resolution.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/grapher.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/indexer.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/injector.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/installer.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/loc.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/logconfig.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/metrics.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/onboarding.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/outcome.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/paths.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/policy.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/progress.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/provider.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/providers/__init__.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/providers/lsp.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/providers/none.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/providers/semantic.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/py.typed +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/redact.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/reindexer.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/reset.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/searcher.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/semantic_db.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/source_kind.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/term.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/verify.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/viewer/__init__.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/src/codeintel/viewer/graph_template.html +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_agent_prompt.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_backend_reaper.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_cache.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_chunking.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_cold_process.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_config.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_corpus.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_docs_ci_claims.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_docs_deadcode_withdrawal.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_doctor.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_e2e.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_engine_adoption.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_enterprise.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_gateway.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_graph_failure_population.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_graph_real.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_graph_stdin.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_grapher.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_hardening.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_http_auth.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_http_server.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_incompleteness.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_index_progress.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_indexer_binary.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_installer.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_integration.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_loc_census.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_lsp_provider.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_lsp_real.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_mcp_handshake.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_model_dimension.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_onboarding.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_redaction_boundary.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_reindexer.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_rerank.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_reset.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_semantic_provider.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_source_kind.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_staleness.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_symbol_context.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_term.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_treesitter.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_verify.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_verify_call.py +0 -0
- {codecortex-0.18.0 → codecortex-0.19.0}/tests/test_version_skew.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecortex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19.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
|
|
@@ -279,7 +279,7 @@ Then it launches the exact command it registered and drives a real MCP handshake
|
|
|
279
279
|
```text
|
|
280
280
|
v claude: registered at /Users/you/.claude.json
|
|
281
281
|
|
|
282
|
-
v verified: codeintel 0.
|
|
282
|
+
v verified: codeintel 0.19.0 — 4 tools (code.query, code.status, code.doctor, code.map)
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
If the command is not on `PATH`, or the server fails to start, install says so and exits non-zero
|
|
@@ -404,6 +404,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
404
404
|
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
405
405
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
406
406
|
| `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) |
|
|
407
|
+
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--json]` | Write a LikeC4 architecture model (`.c4`) of the repo's file/directory structure and its import graph — committable, diffable, hand-editable source rather than a rendered picture. Indexes the repo first if it has no graph index. See [docs/c4.md](docs/c4.md) |
|
|
407
408
|
| `codeintel reset [project_root] [--all] [--yes] [--json]` | Clear this repo's index — **both** semantic and graph — so it's as if never indexed; `--all` wipes every repo. Recovers from a corrupt/stale DB |
|
|
408
409
|
| `codeintel gen-token` | Print a secure random bearer token (for `serve-http` / RBAC `auth.toml`) |
|
|
409
410
|
|
|
@@ -242,7 +242,7 @@ Then it launches the exact command it registered and drives a real MCP handshake
|
|
|
242
242
|
```text
|
|
243
243
|
v claude: registered at /Users/you/.claude.json
|
|
244
244
|
|
|
245
|
-
v verified: codeintel 0.
|
|
245
|
+
v verified: codeintel 0.19.0 — 4 tools (code.query, code.status, code.doctor, code.map)
|
|
246
246
|
```
|
|
247
247
|
|
|
248
248
|
If the command is not on `PATH`, or the server fails to start, install says so and exits non-zero
|
|
@@ -367,6 +367,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
367
367
|
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
368
368
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
369
369
|
| `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) |
|
|
370
|
+
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--json]` | Write a LikeC4 architecture model (`.c4`) of the repo's file/directory structure and its import graph — committable, diffable, hand-editable source rather than a rendered picture. Indexes the repo first if it has no graph index. See [docs/c4.md](docs/c4.md) |
|
|
370
371
|
| `codeintel reset [project_root] [--all] [--yes] [--json]` | Clear this repo's index — **both** semantic and graph — so it's as if never indexed; `--all` wipes every repo. Recovers from a corrupt/stale DB |
|
|
371
372
|
| `codeintel gen-token` | Print a secure random bearer token (for `serve-http` / RBAC `auth.toml`) |
|
|
372
373
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codecortex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19.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
|
|
@@ -279,7 +279,7 @@ Then it launches the exact command it registered and drives a real MCP handshake
|
|
|
279
279
|
```text
|
|
280
280
|
v claude: registered at /Users/you/.claude.json
|
|
281
281
|
|
|
282
|
-
v verified: codeintel 0.
|
|
282
|
+
v verified: codeintel 0.19.0 — 4 tools (code.query, code.status, code.doctor, code.map)
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
If the command is not on `PATH`, or the server fails to start, install says so and exits non-zero
|
|
@@ -404,6 +404,7 @@ Full system docs live in [`docs/`](docs/) — start with the index:
|
|
|
404
404
|
| `codeintel doctor [project_root] [--deep] [--json]` | Diagnose per-engine health + repo index status, with a fix for each gap |
|
|
405
405
|
| `codeintel map [project_root]` | Generate the `CODE_INTEL.md` orientation file |
|
|
406
406
|
| `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) |
|
|
407
|
+
| `codeintel c4 [project_root] [--out DIR] [--depth N] [--scope PATH] [--include-tests] [--no-index] [--json]` | Write a LikeC4 architecture model (`.c4`) of the repo's file/directory structure and its import graph — committable, diffable, hand-editable source rather than a rendered picture. Indexes the repo first if it has no graph index. See [docs/c4.md](docs/c4.md) |
|
|
407
408
|
| `codeintel reset [project_root] [--all] [--yes] [--json]` | Clear this repo's index — **both** semantic and graph — so it's as if never indexed; `--all` wipes every repo. Recovers from a corrupt/stale DB |
|
|
408
409
|
| `codeintel gen-token` | Print a secure random bearer token (for `serve-http` / RBAC `auth.toml`) |
|
|
409
410
|
|
|
@@ -11,6 +11,7 @@ src/codeintel/__init__.py
|
|
|
11
11
|
src/codeintel/__main__.py
|
|
12
12
|
src/codeintel/agent_prompt.py
|
|
13
13
|
src/codeintel/auth.py
|
|
14
|
+
src/codeintel/c4.py
|
|
14
15
|
src/codeintel/cache.py
|
|
15
16
|
src/codeintel/config.py
|
|
16
17
|
src/codeintel/containment.py
|
|
@@ -46,6 +47,7 @@ src/codeintel/term.py
|
|
|
46
47
|
src/codeintel/verify.py
|
|
47
48
|
src/codeintel/commands/__init__.py
|
|
48
49
|
src/codeintel/commands/_common.py
|
|
50
|
+
src/codeintel/commands/c4.py
|
|
49
51
|
src/codeintel/commands/doctor.py
|
|
50
52
|
src/codeintel/commands/gen_token.py
|
|
51
53
|
src/codeintel/commands/graph.py
|
|
@@ -68,6 +70,9 @@ src/codeintel/viewer/__init__.py
|
|
|
68
70
|
src/codeintel/viewer/graph_template.html
|
|
69
71
|
tests/test_agent_prompt.py
|
|
70
72
|
tests/test_backend_reaper.py
|
|
73
|
+
tests/test_c4.py
|
|
74
|
+
tests/test_c4_model.py
|
|
75
|
+
tests/test_c4_output.py
|
|
71
76
|
tests/test_cache.py
|
|
72
77
|
tests/test_chunking.py
|
|
73
78
|
tests/test_cli_commands.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.19.0"
|
|
@@ -10,15 +10,16 @@ from codeintel import __version__
|
|
|
10
10
|
# wanted. Each entry is (command, one-line description).
|
|
11
11
|
_COMMAND_GROUPS: list[tuple[str, list[tuple[str, str]]]] = [
|
|
12
12
|
("Understand your code", [
|
|
13
|
-
("query", "Ask one question —
|
|
13
|
+
("query", "Ask one question — changed, impact, callers, chain, search"),
|
|
14
14
|
("map", "Write CODE_INTEL.md — a committable architecture overview"),
|
|
15
|
-
("graph", "
|
|
15
|
+
("graph", "Call graph of functions — self-contained HTML, no install"),
|
|
16
|
+
("c4", "Architecture map of files/folders — LikeC4 source, needs Node"),
|
|
16
17
|
]),
|
|
17
18
|
("Set up", [
|
|
18
|
-
("setup", "Prepare backends + index this repo (--all does
|
|
19
|
-
("index", "
|
|
20
|
-
("install", "Register codeintel with the AI agents
|
|
21
|
-
("prompt", "Print a paste-to-your-agent setup prompt
|
|
19
|
+
("setup", "Prepare backends + index this repo (--all does it all)"),
|
|
20
|
+
("index", "Build the index every other command reads (semantic + graph)"),
|
|
21
|
+
("install", "Register codeintel with the AI agents on this machine"),
|
|
22
|
+
("prompt", "Print a paste-to-your-agent setup prompt for this machine"),
|
|
22
23
|
]),
|
|
23
24
|
("Check health", [
|
|
24
25
|
("doctor", "Per-engine health + index status, with the fix for each gap"),
|
|
@@ -42,6 +43,7 @@ _MODULES = {
|
|
|
42
43
|
"query": "query",
|
|
43
44
|
"map": "map",
|
|
44
45
|
"graph": "graph",
|
|
46
|
+
"c4": "c4",
|
|
45
47
|
"setup": "setup",
|
|
46
48
|
"index": "index",
|
|
47
49
|
"install": "install",
|
|
@@ -54,13 +56,30 @@ _MODULES = {
|
|
|
54
56
|
"gen-token": "gen_token",
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
# Deliberately NOT a second setup path. `_START_HERE` owns onboarding; these show what the tool is
|
|
60
|
+
# FOR once it works. The two blocks used to disagree — one said `index` first, the other
|
|
61
|
+
# `setup --all` — and neither of the numbered steps mentioned `install`, so following the "New
|
|
62
|
+
# here?" list end to end produced a working CLI and an agent that still greps. README's quickstart
|
|
63
|
+
# is `setup --all` -> `install` -> `query`; `_START_HERE` now matches it.
|
|
57
64
|
_EXAMPLES = [
|
|
58
|
-
(
|
|
59
|
-
("codeintel
|
|
60
|
-
("codeintel
|
|
61
|
-
("codeintel doctor", "why is a query
|
|
65
|
+
('codeintel query --op changed --target ""', "what do my edits break?"),
|
|
66
|
+
("codeintel query --op callers --target foo", "who calls it?"),
|
|
67
|
+
("codeintel graph . --html", "open the call graph"),
|
|
68
|
+
("codeintel doctor", "why is a query empty?"),
|
|
62
69
|
]
|
|
63
70
|
|
|
71
|
+
# The ordered path out of an empty state. A first-time user's problem is not "which of 15 commands"
|
|
72
|
+
# but "what do I run first" — the command list answers the former and silently assumes the latter.
|
|
73
|
+
_START_HERE = [
|
|
74
|
+
("codeintel setup --all .", "backends + index this repo"),
|
|
75
|
+
("codeintel install", "connect it to your AI agent"),
|
|
76
|
+
("codeintel doctor", "confirm it works"),
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
HELP_WIDTH = 78 # the width every rendered help line must fit inside
|
|
81
|
+
HELP_GUTTER_CAP = 44 # ceiling on the derived comment column (see `gutter` below)
|
|
82
|
+
|
|
64
83
|
|
|
65
84
|
def render_help() -> str:
|
|
66
85
|
"""The `codeintel` / `codeintel help` screen: grouped, colored, with real examples.
|
|
@@ -72,10 +91,31 @@ def render_help() -> str:
|
|
|
72
91
|
width = max(len(name) for name in _COMMANDS)
|
|
73
92
|
out = [
|
|
74
93
|
c.bold("codeintel") + c.dim(f" {__version__}")
|
|
75
|
-
+ c.dim(" — code intelligence for AI agents: graph
|
|
94
|
+
+ c.dim(" — code intelligence for AI agents: graph, LSP, semantic"),
|
|
76
95
|
"",
|
|
77
96
|
c.dim("usage: ") + "codeintel <command> [options]",
|
|
78
97
|
]
|
|
98
|
+
|
|
99
|
+
# ONE comment column across both blocks, derived from the widest entry in either. Two blocks
|
|
100
|
+
# each self-aligning would ragged the screen into two gutters; the numbered prefix ("1. ") is
|
|
101
|
+
# part of the measured width so the two blocks' comments still line up.
|
|
102
|
+
# Capped. Derived-from-content is right, but an unbounded max lets ONE long invocation set the
|
|
103
|
+
# column for every short row: `codeintel doctor` was paying 38 blank columns and the line
|
|
104
|
+
# reached 96 chars, so an 80-column terminal wrapped the comment onto its own ragged row —
|
|
105
|
+
# losing the alignment the gutter exists to create. Past the cap a row keeps its comment one
|
|
106
|
+
# space away rather than aligned; a ragged row beats a wrapped screen.
|
|
107
|
+
gutter = min(max(max(len(cmd) + 3 for cmd, _why in _START_HERE),
|
|
108
|
+
max(len(cmd) for cmd, _why in _EXAMPLES)) + 2, HELP_GUTTER_CAP)
|
|
109
|
+
out.append("")
|
|
110
|
+
# A rule, not a new colour: cyan already means "this is a command name" on this screen, and
|
|
111
|
+
# diluting that costs more than it buys. The block needed separating from the four command
|
|
112
|
+
# groups below it — it was bold at the same weight and indent as every group heading, so the
|
|
113
|
+
# one block a first-time user needs looked like part of the reference list.
|
|
114
|
+
out.append(" " + c.rule(40))
|
|
115
|
+
out.append(" " + c.bold("New here?"))
|
|
116
|
+
for i, (cmd, why) in enumerate(_START_HERE, 1):
|
|
117
|
+
out.append(" " + f"{i}. {cmd}".ljust(gutter) + c.dim("# " + why))
|
|
118
|
+
|
|
79
119
|
for group, items in _COMMAND_GROUPS:
|
|
80
120
|
out.append("")
|
|
81
121
|
out.append(" " + c.bold(group))
|
|
@@ -84,11 +124,11 @@ def render_help() -> str:
|
|
|
84
124
|
|
|
85
125
|
out.append("")
|
|
86
126
|
out.append(" " + c.bold("Examples"))
|
|
87
|
-
#
|
|
88
|
-
# one example grows past it, and ljust() will not
|
|
89
|
-
|
|
127
|
+
# Same `gutter` as the New here? block above — width from the content, not a guess. A hardcoded
|
|
128
|
+
# column silently loses its gutter the moment one example grows past it, and ljust() will not
|
|
129
|
+
# pad below the string's own length.
|
|
90
130
|
for cmd, why in _EXAMPLES:
|
|
91
|
-
out.append(" " + cmd.ljust(
|
|
131
|
+
out.append(" " + cmd.ljust(gutter) + c.dim("# " + why))
|
|
92
132
|
|
|
93
133
|
out.append("")
|
|
94
134
|
out.append(" " + c.dim("codeintel <command> --help") + " full options for one command")
|
|
@@ -118,7 +158,111 @@ def _unknown_command(name: str) -> int:
|
|
|
118
158
|
return 2
|
|
119
159
|
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
# `epilog` text for each subcommand: WHEN to reach for it, and one real invocation. The top-level
|
|
162
|
+
# screen (`render_help`) has grouped output, colour and examples; every `codeintel <cmd> --help`
|
|
163
|
+
# one level down was still stock argparse — flags listed, purpose unexplained, no example. A flag
|
|
164
|
+
# list answers "what can I pass"; it never answers "should I be running this at all".
|
|
165
|
+
#
|
|
166
|
+
# Kept as a table rather than inline `epilog=` kwargs so the wording of every screen is reviewable
|
|
167
|
+
# in one place, and so a command added without an entry degrades to today's behaviour (no epilog)
|
|
168
|
+
# rather than breaking.
|
|
169
|
+
_EPILOGS: dict[str, str] = {
|
|
170
|
+
"index": """examples:
|
|
171
|
+
codeintel index . index this repo (semantic + graph)
|
|
172
|
+
codeintel index ~/src/other-repo index a repo elsewhere
|
|
173
|
+
|
|
174
|
+
Run this first, and again after big changes. `codeintel status` shows index
|
|
175
|
+
age.""",
|
|
176
|
+
"query": """examples:
|
|
177
|
+
codeintel query --op changed
|
|
178
|
+
codeintel query --op search
|
|
179
|
+
codeintel query --op impact
|
|
180
|
+
codeintel query --op callers
|
|
181
|
+
codeintel query --op chain
|
|
182
|
+
codeintel query --op overview --target ""
|
|
183
|
+
|
|
184
|
+
`overview`, `changed` and `hotspots` ignore --target. Prefer this over grep:
|
|
185
|
+
results are ranked by graph importance, not by match order.""",
|
|
186
|
+
"map": """examples:
|
|
187
|
+
codeintel map . write CODE_INTEL.md
|
|
188
|
+
codeintel map . --inject also point CLAUDE.md / AGENTS.md at it
|
|
189
|
+
|
|
190
|
+
A committable, readable architecture overview — for agents that do not speak
|
|
191
|
+
MCP, and for reading before grepping. Re-run after `codeintel index`.""",
|
|
192
|
+
"graph": """examples:
|
|
193
|
+
codeintel graph . --html
|
|
194
|
+
codeintel graph . > graph.json the graph as {nodes,edges} JSON
|
|
195
|
+
|
|
196
|
+
Function-level "what calls what", with nothing to install. For file-level
|
|
197
|
+
architecture instead, see `codeintel c4`.""",
|
|
198
|
+
"c4": """examples:
|
|
199
|
+
codeintel c4 . write codeintel-c4/model.c4
|
|
200
|
+
codeintel c4 . --scope src model only src/
|
|
201
|
+
codeintel c4 . --depth 2 coarser: fewer, larger boxes
|
|
202
|
+
codeintel c4 . --json inspect the payload, write nothing
|
|
203
|
+
|
|
204
|
+
File/directory-level "what depends on what". Emits LikeC4 source you can
|
|
205
|
+
commit, diff and hand-edit — viewing it needs Node (`npx likec4 start
|
|
206
|
+
codeintel-c4`). For function-level calls, or if you have no Node, use
|
|
207
|
+
`codeintel graph --html` instead. Indexes the repo first if needed.""",
|
|
208
|
+
"status": """examples:
|
|
209
|
+
codeintel status
|
|
210
|
+
|
|
211
|
+
Shows which of the three engines are ready. If one is not, `codeintel doctor`
|
|
212
|
+
says how to fix it.""",
|
|
213
|
+
"doctor": """examples:
|
|
214
|
+
codeintel doctor
|
|
215
|
+
codeintel doctor --deep
|
|
216
|
+
|
|
217
|
+
Run this when a query comes back empty — it separates "not indexed" from
|
|
218
|
+
"engine missing" from "nothing to find".""",
|
|
219
|
+
"setup": """examples:
|
|
220
|
+
codeintel setup --all
|
|
221
|
+
codeintel setup
|
|
222
|
+
|
|
223
|
+
The one-shot path on a new machine.""",
|
|
224
|
+
"install": """examples:
|
|
225
|
+
codeintel install
|
|
226
|
+
codeintel install --dry-run show what would change, write nothing
|
|
227
|
+
|
|
228
|
+
Writes the MCP server config so an agent can call codeintel. Then restart the
|
|
229
|
+
agent (or start a new session) — a running host does not reload its MCP
|
|
230
|
+
config. `codeintel doctor` lists what got registered where.""",
|
|
231
|
+
"prompt": """examples:
|
|
232
|
+
codeintel prompt
|
|
233
|
+
|
|
234
|
+
For agents that cannot read an MCP config: paste the output into the
|
|
235
|
+
conversation.""",
|
|
236
|
+
"reset": """examples:
|
|
237
|
+
codeintel reset .
|
|
238
|
+
codeintel reset --all --yes wipe every repo, no prompt
|
|
239
|
+
|
|
240
|
+
Recovers from a corrupt or stale index. Re-index afterwards.""",
|
|
241
|
+
"serve": """examples:
|
|
242
|
+
codeintel serve start the MCP server on stdio
|
|
243
|
+
|
|
244
|
+
This is what an AI agent launches; you rarely run it by hand. `codeintel
|
|
245
|
+
install` wires it up.""",
|
|
246
|
+
"serve-http": """examples:
|
|
247
|
+
codeintel serve-http loopback only, no auth
|
|
248
|
+
codeintel serve-http --token "$(codeintel gen-token)"
|
|
249
|
+
|
|
250
|
+
Loopback-only unless --allow-remote. Use --token whenever the port is
|
|
251
|
+
reachable by anything else.""",
|
|
252
|
+
"gen-token": """examples:
|
|
253
|
+
codeintel gen-token print a random bearer token
|
|
254
|
+
|
|
255
|
+
For `serve-http --token`, or an RBAC auth.toml.""",
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
260
|
+
"""Construct the full argparse surface.
|
|
261
|
+
|
|
262
|
+
Split out of `main()` so the registered subcommands can be introspected directly. `--help` is
|
|
263
|
+
routed to `render_help()`, so argparse's own listing is no longer reachable from the CLI — and
|
|
264
|
+
that listing was how the help-honesty test proved every advertised command is really wired up.
|
|
265
|
+
Reading the parser is a stronger source of truth than scraping either screen's text."""
|
|
122
266
|
parser = argparse.ArgumentParser(prog="codeintel")
|
|
123
267
|
parser.add_argument("--version", action="version", version=f"codeintel {__version__}")
|
|
124
268
|
subparsers = parser.add_subparsers(dest="command")
|
|
@@ -133,7 +277,7 @@ def main() -> None:
|
|
|
133
277
|
# index subcommand
|
|
134
278
|
index_parser = subparsers.add_parser(
|
|
135
279
|
"index", parents=[color_parent],
|
|
136
|
-
help="
|
|
280
|
+
help="Build the index every other command reads (semantic + graph)")
|
|
137
281
|
index_parser.add_argument(
|
|
138
282
|
"project_root",
|
|
139
283
|
nargs="?",
|
|
@@ -205,7 +349,8 @@ def main() -> None:
|
|
|
205
349
|
|
|
206
350
|
# map subcommand
|
|
207
351
|
map_parser = subparsers.add_parser("map", help="Generate CODE_INTEL.md orientation file")
|
|
208
|
-
map_parser.add_argument("project_root", nargs="?", default=None
|
|
352
|
+
map_parser.add_argument("project_root", nargs="?", default=None,
|
|
353
|
+
help="Project root (default: cwd)")
|
|
209
354
|
map_parser.add_argument("--inject", action="store_true", help="Inject reference block into CLAUDE.md/AGENTS.md")
|
|
210
355
|
map_parser.add_argument("--budget", type=int, default=32768, help="Byte budget for CODE_INTEL.md (default: 32768)")
|
|
211
356
|
|
|
@@ -219,6 +364,27 @@ def main() -> None:
|
|
|
219
364
|
graph_parser.add_argument("--out", default=None, help="Output path for --html (default: codeintel-graph.html)")
|
|
220
365
|
graph_parser.add_argument("--limit", type=int, default=220, help="Max call edges to include (default: 220)")
|
|
221
366
|
|
|
367
|
+
# c4 subcommand — a LikeC4 model of the Folder/File + IMPORTS slice
|
|
368
|
+
c4_parser = subparsers.add_parser(
|
|
369
|
+
"c4", help="Generate a LikeC4 architecture model (.c4) from the import graph")
|
|
370
|
+
c4_parser.add_argument("project_root", nargs="?", default=None, help="Project root (default: cwd)")
|
|
371
|
+
c4_parser.add_argument("--out", default=None,
|
|
372
|
+
help="Output DIRECTORY (default: codeintel-c4/). LikeC4 merges every "
|
|
373
|
+
".c4 in a directory into one project, so the model gets its own.")
|
|
374
|
+
c4_parser.add_argument("--depth", type=int, default=None,
|
|
375
|
+
help="Directory roll-up depth for elements (default: auto-fit to the "
|
|
376
|
+
"100-element view cap; the chosen depth is always reported)")
|
|
377
|
+
c4_parser.add_argument("--scope", action="append", default=None,
|
|
378
|
+
help="Limit the model to this path prefix; repeatable. A scope matching "
|
|
379
|
+
"no indexed file is an error, not a silent empty model.")
|
|
380
|
+
c4_parser.add_argument("--include-tests", action="store_true",
|
|
381
|
+
help="Model test directories too (excluded by default — they are not "
|
|
382
|
+
"architecture and outnumber source in some repos)")
|
|
383
|
+
c4_parser.add_argument("--no-index", action="store_true",
|
|
384
|
+
help="Fail instead of indexing an un-indexed repo (default: index it "
|
|
385
|
+
"first, so one command always produces a model)")
|
|
386
|
+
c4_parser.add_argument("--json", action="store_true", help="Print the payload; write nothing")
|
|
387
|
+
|
|
222
388
|
# doctor subcommand
|
|
223
389
|
doctor_parser = subparsers.add_parser("doctor", parents=[color_parent],
|
|
224
390
|
help="Diagnose engine health + index status for a repo")
|
|
@@ -268,13 +434,33 @@ def main() -> None:
|
|
|
268
434
|
subparsers.add_parser("gen-token", help="Print a secure random bearer token (for serve-http / RBAC auth.toml)")
|
|
269
435
|
subparsers.add_parser("help", help="Show every command, grouped, with examples")
|
|
270
436
|
|
|
437
|
+
# Applied in one pass over the built parser rather than at each `add_parser` call site: an
|
|
438
|
+
# epilog is presentation, and threading two extra kwargs through fourteen construction sites
|
|
439
|
+
# would bury the flags that actually define each command. RawDescriptionHelpFormatter goes with
|
|
440
|
+
# it — argparse otherwise re-wraps the epilog and destroys the aligned example columns.
|
|
441
|
+
for _name, _sub in (subparsers.choices or {}).items():
|
|
442
|
+
_epilog = _EPILOGS.get(_name)
|
|
443
|
+
if _epilog:
|
|
444
|
+
_sub.epilog = _epilog
|
|
445
|
+
_sub.formatter_class = argparse.RawDescriptionHelpFormatter
|
|
446
|
+
|
|
447
|
+
return parser
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def main() -> None:
|
|
451
|
+
parser = build_parser()
|
|
452
|
+
|
|
271
453
|
# Intercept an unrecognized command BEFORE argparse, whose error prints the full choice list and
|
|
272
454
|
# stops — a dead end for a one-character typo. Only a bare word is claimed here; anything
|
|
273
|
-
# starting with `-` (--version
|
|
455
|
+
# starting with `-` (--version) still goes to argparse.
|
|
274
456
|
argv = sys.argv[1:]
|
|
275
457
|
if argv and not argv[0].startswith("-") and argv[0] not in [*_COMMANDS, "help"]:
|
|
276
458
|
sys.exit(_unknown_command(argv[0]))
|
|
277
|
-
|
|
459
|
+
# `-h`/`--help` only counts as top-level when it is the FIRST token: `codeintel query --help`
|
|
460
|
+
# has argv[0] == "query", so it still falls through to argparse and gets that command's own
|
|
461
|
+
# screen. Without this, the command a new user actually types was the ONE path that missed
|
|
462
|
+
# render_help() and fell back to stock argparse.
|
|
463
|
+
if not argv or argv[0] in ("help", "-h", "--help"):
|
|
278
464
|
from codeintel import term
|
|
279
465
|
term.configure(no_color=False, ascii_mode=None)
|
|
280
466
|
print(render_help())
|