codingest 0.2.21__tar.gz → 0.2.23__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.
- {codingest-0.2.21 → codingest-0.2.23}/Cargo.lock +10 -10
- {codingest-0.2.21 → codingest-0.2.23}/Cargo.toml +32 -4
- {codingest-0.2.21 → codingest-0.2.23}/PKG-INFO +9 -7
- {codingest-0.2.21 → codingest-0.2.23}/README.md +7 -5
- {codingest-0.2.21 → codingest-0.2.23}/codingest/__init__.pyi +7 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/Cargo.toml +1 -1
- codingest-0.2.23/crates/codingest/assets/code_review/recipes.json +97 -0
- codingest-0.2.23/crates/codingest/assets/code_review/skill.md +70 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/lib.rs +1 -0
- codingest-0.2.23/crates/codingest/src/methodology.rs +243 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/Cargo.toml +1 -1
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/skills/codingest-code-review/SKILL.md +1 -1
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/skills/codingest-code-review/references/mcp-upgrade.md +1 -1
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/code_tree_cli.rs +23 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/query.rs +1 -0
- codingest-0.2.23/crates/codingest-cli/tests/embed_skills.rs +127 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/tests/skill_recipes.rs +116 -2
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-mcp/Cargo.toml +1 -1
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-mcp/src/lib.rs +20 -5
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-mcp/tests/response_contract.rs +123 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-py/Cargo.toml +3 -3
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-py/src/lib.rs +19 -4
- {codingest-0.2.21 → codingest-0.2.23}/pyproject.toml +2 -2
- {codingest-0.2.21 → codingest-0.2.23}/LICENSE +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/codingest/__init__.py +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/codingest/cli.py +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/codingest/mcp_server.py +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/bin/codingest_bench.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/bin/codingest_stats.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/call_edges.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/js_workspace.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/load/edge_frames.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/load/entity_frames.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/load.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/mod.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/other_edges.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/routes/django.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/routes/fastapi.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/routes/flask.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/routes/mod.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/semantic_edges.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/builder/type_edges.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/cross_lang.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/docs/mod.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/docs/rst.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/manifest/mod.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/models.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/agc.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/cpp.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/csharp.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/css.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/dart.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/go.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/html.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/java.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/julia.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/mod.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/php.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/python.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/r.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/registry.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/rust_lang.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/shared.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/swift.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/parsers/typescript.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/repo.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/src/rev.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/agc_apollo.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/README.md +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/agc_basic.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/cpp_extern_c.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/cpp_include.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/cross_ts_py.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/csharp_using_alias.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/dart_import.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/dart_part_of.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/docs_ext_collide.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/docs_mdx.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/dup_minified_assets.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/go_interface.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/html_js_lang_group.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/java_javadoc.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/julia_basic.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/php_group_use.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_basic.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_import.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_inheritance.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_nested_defs.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_routes_dup.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/py_src_layout.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/r_basic.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/rust_import.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/rust_inline_mod.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/rust_xfile.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/swift_basic.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/ts_callback.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/ts_closure_scope.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/ts_hof_binding.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/ts_monorepo.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/goldens/web_served_root.sha256 +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/grammar_kinds.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/parity.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest/tests/traversal_semantics.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/skills/codingest-code-review/references/public-repositories.md +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/skills/codingest-code-review/references/queries.md +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/lib.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/main.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/skill.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/src/skill_assets.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-cli/tests/exit_codes.rs +0 -0
- {codingest-0.2.21 → codingest-0.2.23}/crates/codingest-mcp/src/main.rs +0 -0
|
@@ -302,7 +302,7 @@ dependencies = [
|
|
|
302
302
|
|
|
303
303
|
[[package]]
|
|
304
304
|
name = "codingest"
|
|
305
|
-
version = "0.2.
|
|
305
|
+
version = "0.2.23"
|
|
306
306
|
dependencies = [
|
|
307
307
|
"aho-corasick",
|
|
308
308
|
"base64 0.22.1",
|
|
@@ -338,7 +338,7 @@ dependencies = [
|
|
|
338
338
|
|
|
339
339
|
[[package]]
|
|
340
340
|
name = "codingest-cli"
|
|
341
|
-
version = "0.2.
|
|
341
|
+
version = "0.2.23"
|
|
342
342
|
dependencies = [
|
|
343
343
|
"anyhow",
|
|
344
344
|
"clap",
|
|
@@ -350,7 +350,7 @@ dependencies = [
|
|
|
350
350
|
|
|
351
351
|
[[package]]
|
|
352
352
|
name = "codingest-mcp"
|
|
353
|
-
version = "0.2.
|
|
353
|
+
version = "0.2.23"
|
|
354
354
|
dependencies = [
|
|
355
355
|
"anyhow",
|
|
356
356
|
"codingest",
|
|
@@ -361,7 +361,7 @@ dependencies = [
|
|
|
361
361
|
|
|
362
362
|
[[package]]
|
|
363
363
|
name = "codingest-py"
|
|
364
|
-
version = "0.2.
|
|
364
|
+
version = "0.2.23"
|
|
365
365
|
dependencies = [
|
|
366
366
|
"codingest",
|
|
367
367
|
"codingest-cli",
|
|
@@ -1368,9 +1368,9 @@ dependencies = [
|
|
|
1368
1368
|
|
|
1369
1369
|
[[package]]
|
|
1370
1370
|
name = "kglite"
|
|
1371
|
-
version = "0.17.
|
|
1371
|
+
version = "0.17.7"
|
|
1372
1372
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1373
|
-
checksum = "
|
|
1373
|
+
checksum = "e59bdace8eb48e7db04cdc5c066956f494bbcc6fdddb661b4f09764a49428c4e"
|
|
1374
1374
|
dependencies = [
|
|
1375
1375
|
"bzip2",
|
|
1376
1376
|
"chrono",
|
|
@@ -1404,9 +1404,9 @@ dependencies = [
|
|
|
1404
1404
|
|
|
1405
1405
|
[[package]]
|
|
1406
1406
|
name = "kglite-mcp-server"
|
|
1407
|
-
version = "0.17.
|
|
1407
|
+
version = "0.17.7"
|
|
1408
1408
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1409
|
-
checksum = "
|
|
1409
|
+
checksum = "57a37838e2d50d16363c4dc28d7d9a791d9f7edd374660ddbece6578f5c7601b"
|
|
1410
1410
|
dependencies = [
|
|
1411
1411
|
"anyhow",
|
|
1412
1412
|
"bytes",
|
|
@@ -1510,9 +1510,9 @@ dependencies = [
|
|
|
1510
1510
|
|
|
1511
1511
|
[[package]]
|
|
1512
1512
|
name = "mcp-methods"
|
|
1513
|
-
version = "0.4.
|
|
1513
|
+
version = "0.4.11"
|
|
1514
1514
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1515
|
-
checksum = "
|
|
1515
|
+
checksum = "31c5a17334897b67053e843235be8c66610d0c6684c845bea30e70ecff9dd204"
|
|
1516
1516
|
dependencies = [
|
|
1517
1517
|
"anyhow",
|
|
1518
1518
|
"clap",
|
|
@@ -3,7 +3,7 @@ members = ["crates/codingest", "crates/codingest-cli", "crates/codingest-mcp", "
|
|
|
3
3
|
resolver = "2"
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.23"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
rust-version = "1.88"
|
|
9
9
|
license = "MIT"
|
|
@@ -12,7 +12,35 @@ repository = "https://github.com/kkollsga/codingest"
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
13
|
base64 = "0.22"
|
|
14
14
|
sha2 = "0.11"
|
|
15
|
-
# kglite engine + MCP server — imported as crates.io libraries. The 0.17.
|
|
15
|
+
# kglite engine + MCP server — imported as crates.io libraries. The 0.17.7
|
|
16
|
+
# floor adds the producer-level methodology hook codingest asked for on
|
|
17
|
+
# 2026-09-16: `ServerExtensions::with_skills` / `with_recipes` let the binary
|
|
18
|
+
# embedding the server register its own skill layer and Cypher recipe
|
|
19
|
+
# catalogue once, applying to every graph it serves in EVERY mode — including
|
|
20
|
+
# codingest-mcp's manifest-less workspace boot, where graph-carried records
|
|
21
|
+
# are never read. Precedence `bundled < producer < graph < operator`; with no
|
|
22
|
+
# manifest, or one that never mentions `skills:`, the server serves the
|
|
23
|
+
# bundled set plus the producer layer, and an explicit `skills: false`
|
|
24
|
+
# silences both. A producer record that fails validation fails the boot
|
|
25
|
+
# naming itself. 0.17.7 also revives the bundled predicate-gated code-graph
|
|
26
|
+
# skills, which were dead in every workspace deployment (no graph at boot,
|
|
27
|
+
# never re-evaluated): they now activate on the first `set_root_dir`.
|
|
28
|
+
# codingest-mcp registers the code-review skill and recipe corpus through
|
|
29
|
+
# these builders (`crates/codingest-mcp/src/lib.rs`).
|
|
30
|
+
# The preceding 0.17.6
|
|
31
|
+
# floor is the graph-carried skills and recipes release. `kglite::api::skills`
|
|
32
|
+
# and `kglite::api::recipes` arrived here: their `KgliteSkill` /
|
|
33
|
+
# `KgliteRecipe` records are system labels, hidden from every type enumeration,
|
|
34
|
+
# so a codingest graph reports the same `node_types()` / `describe()` as before
|
|
35
|
+
# and every golden digest is unchanged (codingest writes them only behind the
|
|
36
|
+
# opt-in `codingest build --embed-skills`). What reaches users is in the embedded
|
|
37
|
+
# `codingest-mcp` server, and only when an operator manifest turns `skills:`
|
|
38
|
+
# on: methodology skills are now delivered lazily (mcp-methods 0.4.11 — a
|
|
39
|
+
# skill contributes its when-to-use paragraph to the tools it references and
|
|
40
|
+
# the body arrives on `skill(name)`), a served `.kgl`'s own skills and recipes
|
|
41
|
+
# load as a layer under the operator's, and `graph_has_node_type` answers
|
|
42
|
+
# false for the two system labels. Nothing in codingest's builder source moved.
|
|
43
|
+
# The preceding 0.17.5
|
|
16
44
|
# floor fixes two MCP workspace faults that reach users through the embedded
|
|
17
45
|
# `codingest-mcp` server. A relative sandbox path in a manifest now resolves
|
|
18
46
|
# from the manifest's own directory instead of the process working directory,
|
|
@@ -518,8 +546,8 @@ sha2 = "0.11"
|
|
|
518
546
|
# and no disk storage. Neither 0.15.7 nor 0.15.8 changes the `kglite::api` we
|
|
519
547
|
# call, graph output, property encoding, or `.kgl` serialization.
|
|
520
548
|
# Keep both libraries aligned so the graph and server share one engine release.
|
|
521
|
-
kglite = { version = "0.17.
|
|
522
|
-
kglite-mcp-server = { version = "0.17.
|
|
549
|
+
kglite = { version = "0.17.7", default-features = false }
|
|
550
|
+
kglite-mcp-server = { version = "0.17.7", default-features = false }
|
|
523
551
|
|
|
524
552
|
# Dependency debuginfo capped at line tables (kglite coordination, 2026-08-31,
|
|
525
553
|
# after unbounded debug trees filled the build-cache disk to zero): a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codingest
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.23
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
12
12
|
Classifier: Programming Language :: Rust
|
|
13
13
|
Classifier: Topic :: Software Development
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
-
Requires-Dist: kglite>=0.17.
|
|
15
|
+
Requires-Dist: kglite>=0.17.7,<0.18
|
|
16
16
|
License-File: LICENSE
|
|
17
17
|
Summary: Build fast, queryable code graphs for AI agents, MCP code review, and local or GitHub repository analysis.
|
|
18
18
|
Keywords: ai-agents,mcp,code-review,knowledge-graph,code-analysis,github,tree-sitter,cypher
|
|
@@ -59,7 +59,9 @@ a real `kglite.KnowledgeGraph`, ready for Cypher queries.
|
|
|
59
59
|
## Built for agents and code analysis
|
|
60
60
|
|
|
61
61
|
- **Agent-ready MCP:** give an MCP client `graph_overview`, `cypher_query`,
|
|
62
|
-
`read_code_source`, repository switching,
|
|
62
|
+
`read_code_source`, repository switching, automatic graph refresh, and the
|
|
63
|
+
code-review methodology itself — a `code_review` skill and a catalogue of
|
|
64
|
+
parameter-checked review recipes (`run_recipe_query`) served for every graph.
|
|
63
65
|
[opencode is set up and verified end to end](https://codingest.readthedocs.io/en/latest/mcp.html#using-codingest-mcp-with-opencode)
|
|
64
66
|
— including a config that needs no absolute paths — and `codingest skill
|
|
65
67
|
install` packages the review skill for Claude Code and Codex, which opencode
|
|
@@ -192,7 +194,7 @@ codingest skill install # code-review Agent Skill
|
|
|
192
194
|
```
|
|
193
195
|
|
|
194
196
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
195
|
-
commands. KGLite ≥0.17.
|
|
197
|
+
commands. KGLite ≥0.17.7 is installed automatically as the query/storage
|
|
196
198
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
197
199
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
198
200
|
|
|
@@ -205,7 +207,7 @@ Python prerequisites.
|
|
|
205
207
|
```toml
|
|
206
208
|
[dependencies]
|
|
207
209
|
codingest = "0.2"
|
|
208
|
-
kglite = "0.17.
|
|
210
|
+
kglite = "0.17.7"
|
|
209
211
|
```
|
|
210
212
|
|
|
211
213
|
```rust
|
|
@@ -237,7 +239,7 @@ Documentation: **[codingest.readthedocs.io](https://codingest.readthedocs.io)**
|
|
|
237
239
|
|---|---|
|
|
238
240
|
| `crates/codingest` | The component library (`codingest`): builder, parsers, manifest reader, docs pass, multi-rev merge, cross-language edges. Extracted from the former `KGLite/crates/kglite/src/code_tree/` (removed upstream 2026-07-16) and re-targeted at the public `kglite::api` facade. Ships the `codingest_stats` + `codingest_bench` binaries. |
|
|
239
241
|
| `crates/codingest-cli` | `codingest` binary — `build` a checkout or git revision(s) into a `.kgl` graph, `status` to check staleness, and `skill` to install Codingest's code-review Agent Skill. |
|
|
240
|
-
| `crates/codingest-mcp` | `codingest-mcp` binary — the full MCP tool surface imported from the `kglite-mcp-server` library, with the codingest builder injected. |
|
|
242
|
+
| `crates/codingest-mcp` | `codingest-mcp` binary — the full MCP tool surface imported from the `kglite-mcp-server` library, with the codingest builder injected and codingest's `code_review` skill + recipe catalogue registered as the producer's methodology. |
|
|
241
243
|
| `crates/codingest-py` | PyO3 wrapper built by maturin into the `codingest` wheel (`pip install codingest`). Python package source is `codingest/`; `pyproject.toml` drives the maturin build. Not published to crates.io (`publish = false`). |
|
|
242
244
|
|
|
243
245
|
## CI-equivalent local gate
|
|
@@ -277,7 +279,7 @@ diagnostic.
|
|
|
277
279
|
## Dependency policy
|
|
278
280
|
|
|
279
281
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
280
|
-
0.17.
|
|
282
|
+
0.17.7 minimum and a shared lockfile. This keeps the builder, persistence
|
|
281
283
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
282
284
|
|
|
283
285
|
## Parity with the (now-removed) in-tree component
|
|
@@ -32,7 +32,9 @@ a real `kglite.KnowledgeGraph`, ready for Cypher queries.
|
|
|
32
32
|
## Built for agents and code analysis
|
|
33
33
|
|
|
34
34
|
- **Agent-ready MCP:** give an MCP client `graph_overview`, `cypher_query`,
|
|
35
|
-
`read_code_source`, repository switching,
|
|
35
|
+
`read_code_source`, repository switching, automatic graph refresh, and the
|
|
36
|
+
code-review methodology itself — a `code_review` skill and a catalogue of
|
|
37
|
+
parameter-checked review recipes (`run_recipe_query`) served for every graph.
|
|
36
38
|
[opencode is set up and verified end to end](https://codingest.readthedocs.io/en/latest/mcp.html#using-codingest-mcp-with-opencode)
|
|
37
39
|
— including a config that needs no absolute paths — and `codingest skill
|
|
38
40
|
install` packages the review skill for Claude Code and Codex, which opencode
|
|
@@ -165,7 +167,7 @@ codingest skill install # code-review Agent Skill
|
|
|
165
167
|
```
|
|
166
168
|
|
|
167
169
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
168
|
-
commands. KGLite ≥0.17.
|
|
170
|
+
commands. KGLite ≥0.17.7 is installed automatically as the query/storage
|
|
169
171
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
170
172
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
171
173
|
|
|
@@ -178,7 +180,7 @@ Python prerequisites.
|
|
|
178
180
|
```toml
|
|
179
181
|
[dependencies]
|
|
180
182
|
codingest = "0.2"
|
|
181
|
-
kglite = "0.17.
|
|
183
|
+
kglite = "0.17.7"
|
|
182
184
|
```
|
|
183
185
|
|
|
184
186
|
```rust
|
|
@@ -210,7 +212,7 @@ Documentation: **[codingest.readthedocs.io](https://codingest.readthedocs.io)**
|
|
|
210
212
|
|---|---|
|
|
211
213
|
| `crates/codingest` | The component library (`codingest`): builder, parsers, manifest reader, docs pass, multi-rev merge, cross-language edges. Extracted from the former `KGLite/crates/kglite/src/code_tree/` (removed upstream 2026-07-16) and re-targeted at the public `kglite::api` facade. Ships the `codingest_stats` + `codingest_bench` binaries. |
|
|
212
214
|
| `crates/codingest-cli` | `codingest` binary — `build` a checkout or git revision(s) into a `.kgl` graph, `status` to check staleness, and `skill` to install Codingest's code-review Agent Skill. |
|
|
213
|
-
| `crates/codingest-mcp` | `codingest-mcp` binary — the full MCP tool surface imported from the `kglite-mcp-server` library, with the codingest builder injected. |
|
|
215
|
+
| `crates/codingest-mcp` | `codingest-mcp` binary — the full MCP tool surface imported from the `kglite-mcp-server` library, with the codingest builder injected and codingest's `code_review` skill + recipe catalogue registered as the producer's methodology. |
|
|
214
216
|
| `crates/codingest-py` | PyO3 wrapper built by maturin into the `codingest` wheel (`pip install codingest`). Python package source is `codingest/`; `pyproject.toml` drives the maturin build. Not published to crates.io (`publish = false`). |
|
|
215
217
|
|
|
216
218
|
## CI-equivalent local gate
|
|
@@ -250,7 +252,7 @@ diagnostic.
|
|
|
250
252
|
## Dependency policy
|
|
251
253
|
|
|
252
254
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
253
|
-
0.17.
|
|
255
|
+
0.17.7 minimum and a shared lockfile. This keeps the builder, persistence
|
|
254
256
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
255
257
|
|
|
256
258
|
## Parity with the (now-removed) in-tree component
|
|
@@ -23,6 +23,7 @@ def build(
|
|
|
23
23
|
rev: Optional[str] = None,
|
|
24
24
|
revs: Optional[list[str]] = None,
|
|
25
25
|
repo_root: Optional[str] = None,
|
|
26
|
+
embed_skills: bool = False,
|
|
26
27
|
) -> KnowledgeGraph:
|
|
27
28
|
"""Parse a codebase at ``src_dir`` into a :class:`kglite.KnowledgeGraph`.
|
|
28
29
|
|
|
@@ -70,6 +71,12 @@ def build(
|
|
|
70
71
|
include_tests: Include test files/dirs in the graph (default True).
|
|
71
72
|
max_loc_per_file: Skip files longer than this many lines (None = no cap).
|
|
72
73
|
include_docs: Ingest markdown as ``:Doc`` nodes (see above).
|
|
74
|
+
embed_skills: Also write codingest's ``code_review`` skill and its
|
|
75
|
+
recipe catalogue into the graph as graph-carried records
|
|
76
|
+
(``KgliteSkill`` / ``KgliteRecipe``), for a ``.kgl`` served by a
|
|
77
|
+
plain ``kglite-mcp-server --graph``. Off by default: the default
|
|
78
|
+
graph is byte-identical to earlier releases, and ``codingest-mcp``
|
|
79
|
+
serves the methodology by itself. ``repo_tree`` never embeds.
|
|
73
80
|
rev: A single git revspec to build (mutually exclusive with ``revs``).
|
|
74
81
|
revs: A list of git revspecs to merge into a multi-rev graph.
|
|
75
82
|
repo_root: Override the auto-resolved git root for ``rev``/``revs``.
|
|
@@ -10,7 +10,7 @@ keywords = ["knowledge-graph", "code-analysis", "tree-sitter", "cypher", "kglite
|
|
|
10
10
|
categories = ["development-tools", "parser-implementations"]
|
|
11
11
|
|
|
12
12
|
# Requires the kglite 0.15 engine API (`kglite::api::code_entities`); the
|
|
13
|
-
# workspace pins the current engine floor (0.17.
|
|
13
|
+
# workspace pins the current engine floor (0.17.7).
|
|
14
14
|
|
|
15
15
|
[lib]
|
|
16
16
|
name = "codingest"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code_review": {
|
|
3
|
+
"description": "Exact, parameter-checked operations for reviewing a change to a codingest code graph: resolve targets, count and page callers, walk callees, witness bounded call paths, and find type consumers and trait implementors.",
|
|
4
|
+
"queries": {
|
|
5
|
+
"target_coverage": {
|
|
6
|
+
"description": "For each requested qualified name: whether the Function exists (target is null when missing) and how many Functions call it (callers is zero for an existing target with no callers). Run this before reading any empty result as an absence.",
|
|
7
|
+
"parameters": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"requested": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": { "type": "string" },
|
|
13
|
+
"description": "Exact Function qualified names to resolve."
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": ["requested"],
|
|
17
|
+
"additionalProperties": false
|
|
18
|
+
},
|
|
19
|
+
"cypher": "UNWIND $requested AS requested OPTIONAL MATCH (target:Function {qualified_name: requested}) OPTIONAL MATCH (caller:Function)-[:CALLS]->(target) RETURN requested, target.qualified_name AS target, count(caller) AS callers ORDER BY requested"
|
|
20
|
+
},
|
|
21
|
+
"caller_coverage": {
|
|
22
|
+
"description": "Caller counts of one Function split by whether the caller is a test (is_test), so production and test pages can be requested separately with callers_page.",
|
|
23
|
+
"parameters": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"properties": {
|
|
26
|
+
"qualified_name": { "type": "string", "description": "Exact Function qualified name." }
|
|
27
|
+
},
|
|
28
|
+
"required": ["qualified_name"],
|
|
29
|
+
"additionalProperties": false
|
|
30
|
+
},
|
|
31
|
+
"cypher": "MATCH (caller:Function)-[:CALLS]->(target:Function) WHERE target.qualified_name = $qualified_name RETURN target.qualified_name AS target, caller.is_test AS is_test, count(caller) AS callers ORDER BY is_test"
|
|
32
|
+
},
|
|
33
|
+
"callers_page": {
|
|
34
|
+
"description": "One page (25 rows) of direct callers of a Function, production (is_test false) or test (is_test true), with each caller's location and the evidence behind the CALLS edge: resolution, candidates (>1 means the call site fanned out), import_backed (false is unconfirmed, not refuted) and call_lines.",
|
|
35
|
+
"parameters": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"properties": {
|
|
38
|
+
"qualified_name": { "type": "string", "description": "Exact Function qualified name of the callee." },
|
|
39
|
+
"is_test": { "type": "boolean", "description": "true for test callers, false for production callers." }
|
|
40
|
+
},
|
|
41
|
+
"required": ["is_test", "qualified_name"],
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
},
|
|
44
|
+
"cypher": "MATCH (caller:Function)-[rel:CALLS]->(target:Function) WHERE target.qualified_name = $qualified_name AND caller.is_test = $is_test RETURN target.qualified_name AS target, caller.qualified_name AS caller, caller.file_path AS file, caller.line_number AS line, rel.resolution AS resolution, rel.candidates AS candidates, rel.import_backed AS import_backed, rel.call_lines AS call_lines ORDER BY caller, file, line LIMIT 25"
|
|
45
|
+
},
|
|
46
|
+
"direct_callees": {
|
|
47
|
+
"description": "Up to 25 Functions a Function calls directly, with both locations and the CALLS edge evidence (resolution, candidates, import_backed, call_lines). An unresolved source call has no CALLS edge; inspect the source before concluding a call is absent.",
|
|
48
|
+
"parameters": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"properties": {
|
|
51
|
+
"qualified_name": { "type": "string", "description": "Exact Function qualified name of the caller." }
|
|
52
|
+
},
|
|
53
|
+
"required": ["qualified_name"],
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
},
|
|
56
|
+
"cypher": "MATCH (caller:Function)-[rel:CALLS]->(callee:Function) WHERE caller.qualified_name = $qualified_name RETURN caller.qualified_name AS caller, callee.qualified_name AS callee, caller.file_path AS caller_file, caller.line_number AS caller_line, callee.file_path AS callee_file, callee.line_number AS callee_line, rel.resolution AS resolution, rel.candidates AS candidates, rel.import_backed AS import_backed, rel.call_lines AS call_lines ORDER BY callee, callee_file, callee_line LIMIT 25"
|
|
57
|
+
},
|
|
58
|
+
"bounded_call_path": {
|
|
59
|
+
"description": "Up to ten CALLS paths of one to four hops from one Function to another, shortest first: bounded path witnesses instead of an unbounded neighbourhood.",
|
|
60
|
+
"parameters": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"properties": {
|
|
63
|
+
"start": { "type": "string", "description": "Exact qualified name of the starting Function." },
|
|
64
|
+
"finish": { "type": "string", "description": "Exact qualified name of the Function to reach." }
|
|
65
|
+
},
|
|
66
|
+
"required": ["finish", "start"],
|
|
67
|
+
"additionalProperties": false
|
|
68
|
+
},
|
|
69
|
+
"cypher": "MATCH path = (start:Function)-[:CALLS*1..4]->(finish:Function) WHERE start.qualified_name = $start AND finish.qualified_name = $finish RETURN [step IN nodes(path) | step.qualified_name] AS functions, length(path) AS hops ORDER BY hops, functions LIMIT 10"
|
|
70
|
+
},
|
|
71
|
+
"type_consumers": {
|
|
72
|
+
"description": "Up to 25 Functions that take a Struct as an explicit parameter (position parameter or both, since one USES_TYPE edge aggregates a type used as both parameter and return value), with each consumer's location.",
|
|
73
|
+
"parameters": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"properties": {
|
|
76
|
+
"qualified_name": { "type": "string", "description": "Exact Struct qualified name." }
|
|
77
|
+
},
|
|
78
|
+
"required": ["qualified_name"],
|
|
79
|
+
"additionalProperties": false
|
|
80
|
+
},
|
|
81
|
+
"cypher": "MATCH (consumer:Function)-[use:USES_TYPE]->(used:Struct) WHERE used.qualified_name = $qualified_name AND use.position IN ['parameter', 'both'] RETURN used.qualified_name AS used_type, consumer.qualified_name AS consumer, consumer.file_path AS file, consumer.line_number AS line, use.position AS position ORDER BY consumer, file, line LIMIT 25"
|
|
82
|
+
},
|
|
83
|
+
"trait_implementations": {
|
|
84
|
+
"description": "Up to 25 Structs with an IMPLEMENTS edge to a Trait, with each implementor's location. Macro-generated or heuristic structure may be absent from the graph: a missing edge is a reason to inspect source, not proof of no implementation.",
|
|
85
|
+
"parameters": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"qualified_name": { "type": "string", "description": "Exact Trait qualified name." }
|
|
89
|
+
},
|
|
90
|
+
"required": ["qualified_name"],
|
|
91
|
+
"additionalProperties": false
|
|
92
|
+
},
|
|
93
|
+
"cypher": "MATCH (implementor:Struct)-[:IMPLEMENTS]->(implemented:Trait) WHERE implemented.qualified_name = $qualified_name RETURN implemented.qualified_name AS trait, implementor.qualified_name AS implementor, implementor.file_path AS file, implementor.line_number AS line ORDER BY implementor, file, line LIMIT 25"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Reviewing a codingest code graph
|
|
2
|
+
|
|
3
|
+
codingest built every graph this server serves, so the shapes are fixed:
|
|
4
|
+
`Function`, `Struct`, `Class`, `Trait`, `Interface`, `Protocol`, `Enum`,
|
|
5
|
+
`Module`, `File`, `Doc` nodes keyed by `qualified_name`; `CALLS`,
|
|
6
|
+
`USES_TYPE`, `IMPLEMENTS`, `EXTENDS`, `HAS_METHOD`, `IMPORTS`, `DEFINES`,
|
|
7
|
+
`HAS_FILE` edges. Functions carry `file_path`, `line_number`, `is_test`.
|
|
8
|
+
The graph is structural evidence beside the diff and the source; use it
|
|
9
|
+
only as far as the question requires.
|
|
10
|
+
|
|
11
|
+
## Sequence
|
|
12
|
+
|
|
13
|
+
1. **Resolve targets first** with `run_recipe_query("code_review",
|
|
14
|
+
"target_coverage", {"requested": [...]})`. A null `target` means the name is
|
|
15
|
+
not in this graph (typo, macro-generated, other revision); `callers` of zero
|
|
16
|
+
for an existing target is a real absence. Never read an empty result as an
|
|
17
|
+
absence until the target has resolved.
|
|
18
|
+
2. **Count before paging.** `caller_coverage` splits one target's callers into
|
|
19
|
+
production and test counts. One target per call: a shared page can fill
|
|
20
|
+
with one target and hide another.
|
|
21
|
+
3. **Page callers by kind.** `callers_page` with `is_test: false` gives the
|
|
22
|
+
production callers, `is_test: true` the tests that would notice, 25 at a
|
|
23
|
+
time with file and line. Each row carries the `CALLS` edge's evidence:
|
|
24
|
+
`resolution`, `candidates` (>1 = the call site fanned out), `import_backed`
|
|
25
|
+
(false is unconfirmed, not refuted) and `call_lines`.
|
|
26
|
+
4. **Walk the other way** with `direct_callees`, same evidence columns. An
|
|
27
|
+
unresolved source call has no `CALLS` edge at all, so read the source before
|
|
28
|
+
concluding a call is absent.
|
|
29
|
+
5. **Witness reachability, do not explore it.** `bounded_call_path` returns up
|
|
30
|
+
to ten paths of at most four hops between two resolved functions.
|
|
31
|
+
6. **Type and trait impact.** `type_consumers` lists functions taking a struct
|
|
32
|
+
as an explicit parameter; `trait_implementations` lists structs with an
|
|
33
|
+
`IMPLEMENTS` edge to a trait. Macro-generated or heuristic structure may be
|
|
34
|
+
missing, so a missing edge is a reason to read source.
|
|
35
|
+
7. **Read the selected source** with `read_code_source` (qualified name) or
|
|
36
|
+
`read_source` (path), bounded by `start_line` / `end_line`.
|
|
37
|
+
8. **Use `cypher_query` only for a question no recipe shapes** — imports,
|
|
38
|
+
module structure, docs links, `CALL rev_diff({from, to})` on a multi-rev
|
|
39
|
+
graph — and check the shape with `graph_overview` first.
|
|
40
|
+
|
|
41
|
+
## Recipes served for this graph
|
|
42
|
+
|
|
43
|
+
- `code_review/target_coverage` — existence plus caller count, for a list of names.
|
|
44
|
+
- `code_review/caller_coverage` — production versus test caller counts for one target.
|
|
45
|
+
- `code_review/callers_page` — direct callers of one kind, 25 at a time, with edge evidence.
|
|
46
|
+
- `code_review/direct_callees` — what one function calls, 25 at a time, with edge evidence.
|
|
47
|
+
- `code_review/bounded_call_path` — up to ten paths of at most four hops between two functions.
|
|
48
|
+
- `code_review/type_consumers` — functions taking a struct as an explicit parameter.
|
|
49
|
+
- `code_review/trait_implementations` — structs implementing a trait.
|
|
50
|
+
|
|
51
|
+
For a diff-scoped review, start from the functions whose `file_path` the
|
|
52
|
+
diff touched, resolve them, then run steps 2 to 4 on each.
|
|
53
|
+
|
|
54
|
+
## Reading results
|
|
55
|
+
|
|
56
|
+
A page is complete only up to its literal size (25 rows, 10 paths); a full
|
|
57
|
+
page proves nothing about other targets or edges the builder never emitted.
|
|
58
|
+
Follow a retained result's advertised expansion; expansion cannot recover
|
|
59
|
+
rows a `LIMIT` excluded — narrow the target instead. A warning about an
|
|
60
|
+
unknown property or reversed relationship means the query shape is wrong, not
|
|
61
|
+
that the result is empty.
|
|
62
|
+
|
|
63
|
+
## Findings and honesty
|
|
64
|
+
|
|
65
|
+
A finding names a concrete failure — the input or state and the wrong outcome
|
|
66
|
+
— verified against exact source lines at the reviewed revision. "No findings"
|
|
67
|
+
is a valid review; design preferences are not findings, and an edge showing
|
|
68
|
+
coupling is a fact, not a defect. Never invent labels, properties, edge types
|
|
69
|
+
or recipe names; a missing edge is absence of evidence, not proof of absence;
|
|
70
|
+
never build or execute a repository's code merely to review it.
|