codingest 0.2.22__tar.gz → 0.2.24__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.22 → codingest-0.2.24}/Cargo.lock +29 -10
- {codingest-0.2.22 → codingest-0.2.24}/Cargo.toml +66 -6
- {codingest-0.2.22 → codingest-0.2.24}/PKG-INFO +9 -7
- {codingest-0.2.22 → codingest-0.2.24}/README.md +7 -5
- {codingest-0.2.22 → codingest-0.2.24}/codingest/__init__.pyi +7 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/Cargo.toml +1 -1
- codingest-0.2.24/crates/codingest/assets/code_review/recipes.json +97 -0
- codingest-0.2.24/crates/codingest/assets/code_review/skill.md +70 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/docs/mod.rs +13 -4
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/lib.rs +1 -0
- codingest-0.2.24/crates/codingest/src/methodology.rs +243 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/Cargo.toml +1 -1
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/skills/codingest-code-review/SKILL.md +1 -1
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/skills/codingest-code-review/references/mcp-upgrade.md +1 -1
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/code_tree_cli.rs +23 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/query.rs +1 -0
- codingest-0.2.24/crates/codingest-cli/tests/embed_skills.rs +127 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/tests/skill_recipes.rs +116 -2
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-mcp/Cargo.toml +1 -1
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-mcp/src/lib.rs +20 -5
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-mcp/tests/response_contract.rs +123 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-py/Cargo.toml +3 -3
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-py/src/lib.rs +19 -4
- {codingest-0.2.22 → codingest-0.2.24}/pyproject.toml +2 -2
- {codingest-0.2.22 → codingest-0.2.24}/LICENSE +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/codingest/__init__.py +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/codingest/cli.py +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/codingest/mcp_server.py +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/bin/codingest_bench.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/bin/codingest_stats.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/call_edges.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/js_workspace.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/load/edge_frames.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/load/entity_frames.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/load.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/mod.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/other_edges.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/routes/django.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/routes/fastapi.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/routes/flask.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/routes/mod.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/semantic_edges.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/builder/type_edges.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/cross_lang.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/docs/rst.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/manifest/mod.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/models.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/agc.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/cpp.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/csharp.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/css.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/dart.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/go.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/html.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/java.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/julia.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/mod.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/php.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/python.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/r.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/registry.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/rust_lang.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/shared.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/swift.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/parsers/typescript.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/repo.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/src/rev.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/agc_apollo.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/README.md +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/agc_basic.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/cpp_extern_c.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/cpp_include.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/cross_ts_py.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/csharp_using_alias.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/dart_import.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/dart_part_of.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/docs_ext_collide.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/docs_mdx.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/dup_minified_assets.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/go_interface.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/html_js_lang_group.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/java_javadoc.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/julia_basic.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/php_group_use.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_basic.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_import.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_inheritance.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_nested_defs.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_routes_dup.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/py_src_layout.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/r_basic.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/rust_import.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/rust_inline_mod.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/rust_xfile.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/swift_basic.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/ts_callback.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/ts_closure_scope.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/ts_hof_binding.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/ts_monorepo.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/goldens/web_served_root.sha256 +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/grammar_kinds.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/parity.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest/tests/traversal_semantics.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/skills/codingest-code-review/references/public-repositories.md +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/skills/codingest-code-review/references/queries.md +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/lib.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/main.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/skill.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/src/skill_assets.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/crates/codingest-cli/tests/exit_codes.rs +0 -0
- {codingest-0.2.22 → codingest-0.2.24}/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.24"
|
|
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.24"
|
|
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.24"
|
|
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.24"
|
|
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.9"
|
|
1372
1372
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1373
|
-
checksum = "
|
|
1373
|
+
checksum = "84cc52c7ac2e3901aaf1b23311ee329b7509c9dd483cc6e59ed70b079ec9c78e"
|
|
1374
1374
|
dependencies = [
|
|
1375
1375
|
"bzip2",
|
|
1376
1376
|
"chrono",
|
|
@@ -1386,6 +1386,7 @@ dependencies = [
|
|
|
1386
1386
|
"memmap2",
|
|
1387
1387
|
"petgraph",
|
|
1388
1388
|
"postcard",
|
|
1389
|
+
"pulldown-cmark",
|
|
1389
1390
|
"rayon",
|
|
1390
1391
|
"regex",
|
|
1391
1392
|
"rstar 0.13.0",
|
|
@@ -1404,11 +1405,12 @@ dependencies = [
|
|
|
1404
1405
|
|
|
1405
1406
|
[[package]]
|
|
1406
1407
|
name = "kglite-mcp-server"
|
|
1407
|
-
version = "0.17.
|
|
1408
|
+
version = "0.17.9"
|
|
1408
1409
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1409
|
-
checksum = "
|
|
1410
|
+
checksum = "ffd62a6af8cb4f07b89375612a04c4a71adf525d5054597c466824586a49360a"
|
|
1410
1411
|
dependencies = [
|
|
1411
1412
|
"anyhow",
|
|
1413
|
+
"base64 0.22.1",
|
|
1412
1414
|
"bytes",
|
|
1413
1415
|
"chrono",
|
|
1414
1416
|
"clap",
|
|
@@ -1510,9 +1512,9 @@ dependencies = [
|
|
|
1510
1512
|
|
|
1511
1513
|
[[package]]
|
|
1512
1514
|
name = "mcp-methods"
|
|
1513
|
-
version = "0.4.
|
|
1515
|
+
version = "0.4.12"
|
|
1514
1516
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1515
|
-
checksum = "
|
|
1517
|
+
checksum = "5bcc5fdac2ffd82893fbc640b569785bdc63ead7f3c6c3d695685b692ddf2d1a"
|
|
1516
1518
|
dependencies = [
|
|
1517
1519
|
"anyhow",
|
|
1518
1520
|
"clap",
|
|
@@ -1742,6 +1744,17 @@ dependencies = [
|
|
|
1742
1744
|
"cc",
|
|
1743
1745
|
]
|
|
1744
1746
|
|
|
1747
|
+
[[package]]
|
|
1748
|
+
name = "pulldown-cmark"
|
|
1749
|
+
version = "0.13.4"
|
|
1750
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1751
|
+
checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
|
|
1752
|
+
dependencies = [
|
|
1753
|
+
"bitflags",
|
|
1754
|
+
"memchr",
|
|
1755
|
+
"unicase",
|
|
1756
|
+
]
|
|
1757
|
+
|
|
1745
1758
|
[[package]]
|
|
1746
1759
|
name = "pyo3"
|
|
1747
1760
|
version = "0.29.0"
|
|
@@ -2792,6 +2805,12 @@ version = "1.20.1"
|
|
|
2792
2805
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2793
2806
|
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
|
2794
2807
|
|
|
2808
|
+
[[package]]
|
|
2809
|
+
name = "unicase"
|
|
2810
|
+
version = "2.9.0"
|
|
2811
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2812
|
+
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
|
2813
|
+
|
|
2795
2814
|
[[package]]
|
|
2796
2815
|
name = "unicode-ident"
|
|
2797
2816
|
version = "1.0.24"
|
|
@@ -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.24"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
rust-version = "1.88"
|
|
9
9
|
license = "MIT"
|
|
@@ -12,12 +12,72 @@ 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.9
|
|
16
|
+
# floor covers two same-day releases, 0.17.8 (the Obsidian vault format) and
|
|
17
|
+
# 0.17.9 (the vault structure profile). Both land almost entirely on
|
|
18
|
+
# `dialect="obsidian"`, which codingest never selects — but they rebuilt the
|
|
19
|
+
# `kglite::okf` *type* surface underneath our docs pass, so this is the first
|
|
20
|
+
# kglite bump since 0.16.x that needs a source change:
|
|
21
|
+
# * `okf::BuildOptions` gained `profile` (a `Profile` the parser reads for
|
|
22
|
+
# its conventions) and lost `embed` (a field the loader never read — it
|
|
23
|
+
# embedded nothing in any dialect, so removing it changes no behaviour),
|
|
24
|
+
# and `okf::walk::DiscoveredFile` gained `size` / `mtime`. Our docs pass
|
|
25
|
+
# built both as exhaustive struct literals. `BuildOptions` is now
|
|
26
|
+
# constructed through `BuildOptions::for_dialect(Dialect::Okf)` with only
|
|
27
|
+
# the two fields we deliberately differ on overridden — a `Profile` cannot
|
|
28
|
+
# be a struct literal outside kglite any more, and `for_dialect` is the
|
|
29
|
+
# constructor that keeps a future field at its dialect default instead of
|
|
30
|
+
# failing the build a third time. `size`/`mtime` are `0`/`None`: they feed
|
|
31
|
+
# only `okf::fingerprint` and the vault's attachment nodes, and
|
|
32
|
+
# `parse_concepts` — the one entry point we call — reads neither.
|
|
33
|
+
# * The rest of the breaking set does not reach us: `okf::build` now returns
|
|
34
|
+
# `BuildOutput { graph, report }`, `links::extract_links` and
|
|
35
|
+
# `walk::discover` take the options/profile instead of a `Dialect` /
|
|
36
|
+
# `skip_dirs` slice, `Dialect` gained `Obsidian`, `Link` lost
|
|
37
|
+
# `is_wikilink`, and `ExportOptions` / `ExportReport` gained
|
|
38
|
+
# `edge_tables` / `warnings`. codingest calls none of them (grep: zero
|
|
39
|
+
# hits outside `docs/mod.rs`) — we use `okf::parse_concepts` and nothing
|
|
40
|
+
# else, and we read only `concept_id` / `file_path` / `title` / `body` /
|
|
41
|
+
# `props` off each `ConceptDoc`, never its links.
|
|
42
|
+
# * Behaviour under `Dialect::Okf` is the old behaviour by construction:
|
|
43
|
+
# `Profile::default()` is the OKF-bundle profile with every vault feature
|
|
44
|
+
# (wikilinks, embeds, inline tags, frontmatter edges, aliases, folder
|
|
45
|
+
# notes, attachments, `structure:`) off, which is what the parser hardcoded
|
|
46
|
+
# before. The one 0.17.8 parser fix that is dialect-independent and lands
|
|
47
|
+
# on a value we store is the heading rule: a line starting with `#` is a
|
|
48
|
+
# heading only when one to six `#` are followed by a space, a tab, or the
|
|
49
|
+
# line end, so an inline-tag line like `#project see …` is no longer read
|
|
50
|
+
# as an `# H1`. That feeds our `:Doc` title fallback. The 31 frozen
|
|
51
|
+
# goldens are the gate on it, and they are byte-identical across this move.
|
|
52
|
+
# * kglite-mcp-server: `--vault` mode and the vault-authoring skill are new
|
|
53
|
+
# surface we do not register, and the bundled skill set is now gated by
|
|
54
|
+
# graph shape — the four code-graph skills bundle only where the graph
|
|
55
|
+
# carries `Function` / `Class`, which is exactly a codingest graph, so the
|
|
56
|
+
# skills an agent reaches through `codingest-mcp` are unchanged while a
|
|
57
|
+
# document deployment stops paying for ours. Our producer layer
|
|
58
|
+
# (`ServerExtensions::with_skills` / `with_recipes`) is untouched.
|
|
59
|
+
# The preceding 0.17.7
|
|
60
|
+
# floor adds the producer-level methodology hook codingest asked for on
|
|
61
|
+
# 2026-09-16: `ServerExtensions::with_skills` / `with_recipes` let the binary
|
|
62
|
+
# embedding the server register its own skill layer and Cypher recipe
|
|
63
|
+
# catalogue once, applying to every graph it serves in EVERY mode — including
|
|
64
|
+
# codingest-mcp's manifest-less workspace boot, where graph-carried records
|
|
65
|
+
# are never read. Precedence `bundled < producer < graph < operator`; with no
|
|
66
|
+
# manifest, or one that never mentions `skills:`, the server serves the
|
|
67
|
+
# bundled set plus the producer layer, and an explicit `skills: false`
|
|
68
|
+
# silences both. A producer record that fails validation fails the boot
|
|
69
|
+
# naming itself. 0.17.7 also revives the bundled predicate-gated code-graph
|
|
70
|
+
# skills, which were dead in every workspace deployment (no graph at boot,
|
|
71
|
+
# never re-evaluated): they now activate on the first `set_root_dir`.
|
|
72
|
+
# codingest-mcp registers the code-review skill and recipe corpus through
|
|
73
|
+
# these builders (`crates/codingest-mcp/src/lib.rs`).
|
|
74
|
+
# The preceding 0.17.6
|
|
16
75
|
# floor is the graph-carried skills and recipes release. `kglite::api::skills`
|
|
17
|
-
# and `kglite::api::recipes`
|
|
76
|
+
# and `kglite::api::recipes` arrived here: their `KgliteSkill` /
|
|
18
77
|
# `KgliteRecipe` records are system labels, hidden from every type enumeration,
|
|
19
78
|
# so a codingest graph reports the same `node_types()` / `describe()` as before
|
|
20
|
-
# and every golden digest is unchanged
|
|
79
|
+
# and every golden digest is unchanged (codingest writes them only behind the
|
|
80
|
+
# opt-in `codingest build --embed-skills`). What reaches users is in the embedded
|
|
21
81
|
# `codingest-mcp` server, and only when an operator manifest turns `skills:`
|
|
22
82
|
# on: methodology skills are now delivered lazily (mcp-methods 0.4.11 — a
|
|
23
83
|
# skill contributes its when-to-use paragraph to the tools it references and
|
|
@@ -530,8 +590,8 @@ sha2 = "0.11"
|
|
|
530
590
|
# and no disk storage. Neither 0.15.7 nor 0.15.8 changes the `kglite::api` we
|
|
531
591
|
# call, graph output, property encoding, or `.kgl` serialization.
|
|
532
592
|
# Keep both libraries aligned so the graph and server share one engine release.
|
|
533
|
-
kglite = { version = "0.17.
|
|
534
|
-
kglite-mcp-server = { version = "0.17.
|
|
593
|
+
kglite = { version = "0.17.9", default-features = false }
|
|
594
|
+
kglite-mcp-server = { version = "0.17.9", default-features = false }
|
|
535
595
|
|
|
536
596
|
# Dependency debuginfo capped at line tables (kglite coordination, 2026-08-31,
|
|
537
597
|
# 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.24
|
|
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.9,<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.9 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.9"
|
|
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.9 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.9 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.9"
|
|
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.9 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.9).
|
|
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.
|
|
@@ -249,20 +249,29 @@ fn discover_and_parse(root: &Path) -> Result<Vec<DocEntry>, String> {
|
|
|
249
249
|
// computes titles from frontmatter / first heading, honors `kg_skip`,
|
|
250
250
|
// flattens frontmatter). We bypass `okf::walk` so `.rst` shares one traversal and so
|
|
251
251
|
// `index.md` is kept (the docs pass builds no Folder hierarchy).
|
|
252
|
+
// `for_dialect` rather than a struct literal: it carries the dialect's
|
|
253
|
+
// `Profile` (the conventions the parser reads — id scheme, reserved keys,
|
|
254
|
+
// wikilinks, collection encoding), which a literal cannot construct from
|
|
255
|
+
// outside kglite and which a bare `dialect:` assignment would leave at the
|
|
256
|
+
// wrong dialect's defaults. Only the two fields the docs pass deliberately
|
|
257
|
+
// differs on are overridden: every `.md` is admitted (a repo's docs carry
|
|
258
|
+
// no frontmatter) and the body is stored (the `:Doc` node's prose).
|
|
252
259
|
let md_opts = okf::BuildOptions {
|
|
253
|
-
dialect: okf::Dialect::Okf,
|
|
254
260
|
require_frontmatter: false,
|
|
255
|
-
respect_skip: true,
|
|
256
|
-
skip_dirs: Vec::new(),
|
|
257
261
|
with_body: true,
|
|
258
|
-
|
|
262
|
+
..okf::BuildOptions::for_dialect(okf::Dialect::Okf)
|
|
259
263
|
};
|
|
264
|
+
// `size` / `mtime` feed only `okf::fingerprint` and the attachment nodes,
|
|
265
|
+
// neither of which the docs pass reaches — `parse_concepts` reads nothing
|
|
266
|
+
// but the two paths — so the walk does not stat a second time to fill them.
|
|
260
267
|
let md_files: Vec<okf::walk::DiscoveredFile> = found
|
|
261
268
|
.iter()
|
|
262
269
|
.filter(|d| d.format == DocFormat::Markdown)
|
|
263
270
|
.map(|d| okf::walk::DiscoveredFile {
|
|
264
271
|
rel_path: d.rel_path.clone(),
|
|
265
272
|
abs_path: d.abs_path.clone(),
|
|
273
|
+
size: 0,
|
|
274
|
+
mtime: None,
|
|
266
275
|
})
|
|
267
276
|
.collect();
|
|
268
277
|
let mut docs: Vec<DocEntry> = okf::parse_concepts(&md_files, &md_opts)
|