codingest 0.2.34__tar.gz → 0.2.35__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.34 → codingest-0.2.35}/Cargo.lock +8 -8
- {codingest-0.2.34 → codingest-0.2.35}/Cargo.toml +9 -5
- {codingest-0.2.34 → codingest-0.2.35}/PKG-INFO +5 -5
- {codingest-0.2.34 → codingest-0.2.35}/README.md +3 -3
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/Cargo.toml +1 -1
- codingest-0.2.35/crates/codingest/assets/code_review/skill.md +60 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/other_edges.rs +5 -5
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/methodology.rs +17 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/registry.rs +5 -2
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/typescript.rs +99 -7
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/README.md +22 -0
- codingest-0.2.35/crates/codingest/tests/goldens/js_module_exts.sha256 +1 -0
- codingest-0.2.35/crates/codingest/tests/goldens/ts_hof_binding.sha256 +1 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/parity.rs +10 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/Cargo.toml +1 -1
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/skills/codingest-code-review/SKILL.md +1 -1
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/skills/codingest-code-review/references/mcp-upgrade.md +1 -1
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-mcp/Cargo.toml +1 -1
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-py/Cargo.toml +3 -3
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-py/src/lib.rs +1 -1
- {codingest-0.2.34 → codingest-0.2.35}/pyproject.toml +2 -2
- codingest-0.2.34/crates/codingest/assets/code_review/skill.md +0 -70
- codingest-0.2.34/crates/codingest/tests/goldens/ts_hof_binding.sha256 +0 -1
- {codingest-0.2.34 → codingest-0.2.35}/LICENSE +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/codingest/__init__.py +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/codingest/__init__.pyi +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/codingest/cli.py +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/codingest/mcp_server.py +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/assets/code_review/recipes.json +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/bin/codingest_bench.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/bin/codingest_stats.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/call_edges.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/js_workspace.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/load/edge_frames.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/load/entity_frames.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/load.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/mod.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/routes/django.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/routes/fastapi.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/routes/flask.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/routes/mod.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/semantic_edges.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/builder/type_edges.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/cross_lang.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/docs/mod.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/docs/rst.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/lib.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/manifest/mod.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/models.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/agc.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/cpp.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/csharp.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/css.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/dart.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/go.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/html.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/java.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/julia.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/mod.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/php.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/python.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/r.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/rust_lang.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/shared.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/parsers/swift.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/repo.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/src/rev.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/agc_apollo.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/agc_basic.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/cpp_extern_c.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/cpp_include.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/cross_ts_py.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/csharp_using_alias.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/dart_import.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/dart_part_of.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/docs_ext_collide.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/docs_mdx.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/dup_minified_assets.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/go_interface.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/html_js_lang_group.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/java_javadoc.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/julia_basic.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/php_group_use.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_basic.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_import.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_inheritance.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_nested_defs.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_routes_dup.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/py_src_layout.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/r_basic.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/rust_import.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/rust_inline_mod.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/rust_xfile.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/swift_basic.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/ts_callback.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/ts_closure_scope.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/ts_monorepo.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/web_served_root.sha256 +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/grammar_kinds.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/traversal_semantics.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/skills/codingest-code-review/references/public-repositories.md +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/skills/codingest-code-review/references/queries.md +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/code_tree_cli.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/lib.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/main.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/query.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/skill.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/src/skill_assets.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/tests/embed_skills.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/tests/exit_codes.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/tests/skill_recipes.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-mcp/src/lib.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-mcp/src/main.rs +0 -0
- {codingest-0.2.34 → codingest-0.2.35}/crates/codingest-mcp/tests/response_contract.rs +0 -0
|
@@ -306,7 +306,7 @@ dependencies = [
|
|
|
306
306
|
|
|
307
307
|
[[package]]
|
|
308
308
|
name = "codingest"
|
|
309
|
-
version = "0.2.
|
|
309
|
+
version = "0.2.35"
|
|
310
310
|
dependencies = [
|
|
311
311
|
"aho-corasick",
|
|
312
312
|
"base64",
|
|
@@ -342,7 +342,7 @@ dependencies = [
|
|
|
342
342
|
|
|
343
343
|
[[package]]
|
|
344
344
|
name = "codingest-cli"
|
|
345
|
-
version = "0.2.
|
|
345
|
+
version = "0.2.35"
|
|
346
346
|
dependencies = [
|
|
347
347
|
"anyhow",
|
|
348
348
|
"clap",
|
|
@@ -354,7 +354,7 @@ dependencies = [
|
|
|
354
354
|
|
|
355
355
|
[[package]]
|
|
356
356
|
name = "codingest-mcp"
|
|
357
|
-
version = "0.2.
|
|
357
|
+
version = "0.2.35"
|
|
358
358
|
dependencies = [
|
|
359
359
|
"anyhow",
|
|
360
360
|
"codingest",
|
|
@@ -365,7 +365,7 @@ dependencies = [
|
|
|
365
365
|
|
|
366
366
|
[[package]]
|
|
367
367
|
name = "codingest-py"
|
|
368
|
-
version = "0.2.
|
|
368
|
+
version = "0.2.35"
|
|
369
369
|
dependencies = [
|
|
370
370
|
"codingest",
|
|
371
371
|
"codingest-cli",
|
|
@@ -1421,9 +1421,9 @@ dependencies = [
|
|
|
1421
1421
|
|
|
1422
1422
|
[[package]]
|
|
1423
1423
|
name = "kglite"
|
|
1424
|
-
version = "0.21.
|
|
1424
|
+
version = "0.21.5"
|
|
1425
1425
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1426
|
-
checksum = "
|
|
1426
|
+
checksum = "68f04fd73825dfbf10f9da22f85a2bdb084fd642b36a9b99400719f1df33c7ed"
|
|
1427
1427
|
dependencies = [
|
|
1428
1428
|
"bzip2",
|
|
1429
1429
|
"chrono",
|
|
@@ -1461,9 +1461,9 @@ dependencies = [
|
|
|
1461
1461
|
|
|
1462
1462
|
[[package]]
|
|
1463
1463
|
name = "kglite-mcp-server"
|
|
1464
|
-
version = "0.21.
|
|
1464
|
+
version = "0.21.5"
|
|
1465
1465
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1466
|
-
checksum = "
|
|
1466
|
+
checksum = "867346f8685bc1c76c698049a347583ebdef43907b22335d5b62d0aea7f29b6f"
|
|
1467
1467
|
dependencies = [
|
|
1468
1468
|
"anyhow",
|
|
1469
1469
|
"base64",
|
|
@@ -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.35"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
rust-version = "1.88"
|
|
9
9
|
license = "MIT"
|
|
@@ -12,8 +12,12 @@ repository = "https://github.com/kkollsga/codingest"
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
13
|
base64 = "0.23.1"
|
|
14
14
|
sha2 = "0.11"
|
|
15
|
-
# kglite engine + MCP server — imported as crates.io libraries. The 0.21.
|
|
16
|
-
# floor is a patch step within 0.21 (0.21.
|
|
15
|
+
# kglite engine + MCP server — imported as crates.io libraries. The 0.21.5
|
|
16
|
+
# floor is a patch step within 0.21 (0.21.4 -> 0.21.5): a query-path speedup
|
|
17
|
+
# only — a fused columnar kernel for single-label filtered `count`/`sum`/`avg`/
|
|
18
|
+
# `min`/`max` and negative-literal pushdown, results identical. It changes no
|
|
19
|
+
# `kglite::api` codingest calls and nothing the builder writes. The 0.21.4
|
|
20
|
+
# floor was a patch step within 0.21 (0.21.2 -> 0.21.4: MCP clients that never
|
|
17
21
|
# send `initialize`, Python 3.12+ wheel, `with_identity` `--help` fix and the
|
|
18
22
|
# embedder `serverInfo.name`); it changes no `kglite::api` codingest calls. The 0.21.1
|
|
19
23
|
# floor is an engine minor (0.20.0 -> 0.21.1, taking 0.21.0 with it): graphs of
|
|
@@ -660,8 +664,8 @@ sha2 = "0.11"
|
|
|
660
664
|
# and no disk storage. Neither 0.15.7 nor 0.15.8 changes the `kglite::api` we
|
|
661
665
|
# call, graph output, property encoding, or `.kgl` serialization.
|
|
662
666
|
# Keep both libraries aligned so the graph and server share one engine release.
|
|
663
|
-
kglite = { version = "0.21.
|
|
664
|
-
kglite-mcp-server = { version = "0.21.
|
|
667
|
+
kglite = { version = "0.21.5", default-features = false }
|
|
668
|
+
kglite-mcp-server = { version = "0.21.5", default-features = false }
|
|
665
669
|
|
|
666
670
|
# Dependency debuginfo capped at line tables (kglite coordination, 2026-08-31,
|
|
667
671
|
# 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.35
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3.15
|
|
|
11
11
|
Classifier: Programming Language :: Rust
|
|
12
12
|
Classifier: Topic :: Software Development
|
|
13
13
|
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
-
Requires-Dist: kglite>=0.21.
|
|
14
|
+
Requires-Dist: kglite>=0.21.5,<0.22
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Summary: Build fast, queryable code graphs for AI agents, MCP code review, and local or GitHub repository analysis.
|
|
17
17
|
Keywords: ai-agents,mcp,code-review,knowledge-graph,code-analysis,github,tree-sitter,cypher
|
|
@@ -193,7 +193,7 @@ codingest skill install # code-review Agent Skill
|
|
|
193
193
|
```
|
|
194
194
|
|
|
195
195
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
196
|
-
commands. KGLite ≥0.21.
|
|
196
|
+
commands. KGLite ≥0.21.5 is installed automatically as the query/storage
|
|
197
197
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
198
198
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
199
199
|
|
|
@@ -206,7 +206,7 @@ Python prerequisites.
|
|
|
206
206
|
```toml
|
|
207
207
|
[dependencies]
|
|
208
208
|
codingest = "0.2"
|
|
209
|
-
kglite = "0.21.
|
|
209
|
+
kglite = "0.21.5"
|
|
210
210
|
```
|
|
211
211
|
|
|
212
212
|
```rust
|
|
@@ -278,7 +278,7 @@ diagnostic.
|
|
|
278
278
|
## Dependency policy
|
|
279
279
|
|
|
280
280
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
281
|
-
0.21.
|
|
281
|
+
0.21.5 minimum and a shared lockfile. This keeps the builder, persistence
|
|
282
282
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
283
283
|
|
|
284
284
|
## Parity with the (now-removed) in-tree component
|
|
@@ -167,7 +167,7 @@ codingest skill install # code-review Agent Skill
|
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
170
|
-
commands. KGLite ≥0.21.
|
|
170
|
+
commands. KGLite ≥0.21.5 is installed automatically as the query/storage
|
|
171
171
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
172
172
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
173
173
|
|
|
@@ -180,7 +180,7 @@ Python prerequisites.
|
|
|
180
180
|
```toml
|
|
181
181
|
[dependencies]
|
|
182
182
|
codingest = "0.2"
|
|
183
|
-
kglite = "0.21.
|
|
183
|
+
kglite = "0.21.5"
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
```rust
|
|
@@ -252,7 +252,7 @@ diagnostic.
|
|
|
252
252
|
## Dependency policy
|
|
253
253
|
|
|
254
254
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
255
|
-
0.21.
|
|
255
|
+
0.21.5 minimum and a shared lockfile. This keeps the builder, persistence
|
|
256
256
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
257
257
|
|
|
258
258
|
## Parity with the (now-removed) in-tree component
|
|
@@ -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.21.
|
|
13
|
+
# workspace pins the current engine floor (0.21.5).
|
|
14
14
|
|
|
15
15
|
[lib]
|
|
16
16
|
name = "codingest"
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
Use the graph only as far as the question requires.
|
|
9
|
+
|
|
10
|
+
## Sequence
|
|
11
|
+
|
|
12
|
+
Recipe `code_review/<name>` runs as `run_recipe_query("code_review", "<name>", {…})`.
|
|
13
|
+
|
|
14
|
+
1. **Resolve targets first** with `code_review/target_coverage`
|
|
15
|
+
(`{"requested": [...]}`). A null `target` means the name is not in this
|
|
16
|
+
graph (typo, macro-generated, other revision); `callers` of zero for an
|
|
17
|
+
existing target is a real absence. Never read an empty result as an absence
|
|
18
|
+
until the target has resolved.
|
|
19
|
+
2. **Count before paging.** `code_review/caller_coverage` splits one target's
|
|
20
|
+
callers into production and test counts. One target per call: a shared page
|
|
21
|
+
can fill with one target and hide another.
|
|
22
|
+
3. **Page callers by kind.** `code_review/callers_page` with `is_test: false`
|
|
23
|
+
gives the production callers, `is_test: true` the tests that would notice,
|
|
24
|
+
25 at a time with file and line. Each row carries the `CALLS` edge's
|
|
25
|
+
evidence: `resolution`, `candidates` (>1 = the call site fanned out),
|
|
26
|
+
`import_backed` (false is unconfirmed, not refuted) and `call_lines`.
|
|
27
|
+
4. **Walk the other way** with `code_review/direct_callees`, same evidence
|
|
28
|
+
columns. An unresolved source call has no `CALLS` edge at all, so read the
|
|
29
|
+
source before concluding a call is absent.
|
|
30
|
+
5. **Witness reachability, do not explore it.** `code_review/bounded_call_path`
|
|
31
|
+
returns up to ten paths of at most four hops between two resolved functions.
|
|
32
|
+
6. **Type and trait impact.** `code_review/type_consumers` lists functions
|
|
33
|
+
taking a struct as an explicit parameter; `code_review/trait_implementations`
|
|
34
|
+
lists structs with an `IMPLEMENTS` edge to a trait. Macro-generated or
|
|
35
|
+
heuristic structure may be missing — a reason to read source.
|
|
36
|
+
7. **Read the selected source** with `read_code_source` (qualified name) or
|
|
37
|
+
`read_source` (path), bounded by `start_line` / `end_line`.
|
|
38
|
+
8. **Use `cypher_query` only for a question no recipe shapes** — imports,
|
|
39
|
+
module structure, docs links, `CALL rev_diff({from, to})` on a multi-rev
|
|
40
|
+
graph — and check the shape with `graph_overview` first.
|
|
41
|
+
|
|
42
|
+
For a diff-scoped review, start from the functions whose `file_path` the diff
|
|
43
|
+
touched, resolve them, then run steps 2 to 4 on each.
|
|
44
|
+
|
|
45
|
+
## Reading results
|
|
46
|
+
|
|
47
|
+
A page is complete only up to its literal size (25 rows, 10 paths); a full page
|
|
48
|
+
proves nothing about other targets. Expansion cannot recover rows a `LIMIT`
|
|
49
|
+
excluded — narrow the target instead. A warning about an unknown property or
|
|
50
|
+
reversed relationship means the query shape is wrong, not that the result is
|
|
51
|
+
empty.
|
|
52
|
+
|
|
53
|
+
## Findings and honesty
|
|
54
|
+
|
|
55
|
+
A finding names a concrete failure — the input or state and the wrong outcome
|
|
56
|
+
— verified against exact source lines at the reviewed revision. "No findings"
|
|
57
|
+
is a valid review; design preferences are not findings, and an edge showing
|
|
58
|
+
coupling is a fact, not a defect. Never invent labels, properties, edge types
|
|
59
|
+
or recipe names; a missing edge is absence of evidence, not proof of absence;
|
|
60
|
+
never build or execute a repository's code merely to review it.
|
|
@@ -228,11 +228,11 @@ fn path_import_candidates(file: &FileInfo, raw: &str) -> Vec<String> {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
/// Module-path suffixes a TS/JS specifier may carry. Stripped before matching,
|
|
231
|
-
///
|
|
232
|
-
///
|
|
233
|
-
/// their *emitted* name (`import "./util.js"` resolving to
|
|
234
|
-
|
|
235
|
-
|
|
231
|
+
/// with the same list `JstsParser::file_to_module_path` strips. The JS
|
|
232
|
+
/// suffixes matter for TS too: NodeNext resolution has source files import
|
|
233
|
+
/// each other by their *emitted* name (`import "./util.js"` resolving to
|
|
234
|
+
/// `util.ts`).
|
|
235
|
+
const MODULE_PATH_EXTENSIONS: &[&str] = crate::parsers::typescript::JSTS_MODULE_SUFFIXES;
|
|
236
236
|
|
|
237
237
|
/// Candidate module paths for one TS/JS import specifier, in fixed priority
|
|
238
238
|
/// order — first match wins, and the order IS the documented tie-break.
|
|
@@ -228,6 +228,23 @@ mod tests {
|
|
|
228
228
|
assert_eq!(record.references_tools, REFERENCES_TOOLS);
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
/// mcp-methods warns on every server boot and `--selftest` when a skill
|
|
232
|
+
/// exceeds its soft limit (`SOFT_SIZE_LIMIT_BYTES`, 4 KiB in 0.6.2), and it
|
|
233
|
+
/// measures the skill as served: the frontmatter kglite renders from the
|
|
234
|
+
/// record fields plus the body. A body sized against the limit alone
|
|
235
|
+
/// (4,093 bytes) rendered to 4,709 and warned on every boot.
|
|
236
|
+
#[test]
|
|
237
|
+
fn rendered_skill_fits_the_mcp_soft_size_limit() {
|
|
238
|
+
const MCP_SOFT_SIZE_LIMIT_BYTES: usize = 4 * 1024;
|
|
239
|
+
let rendered = skills::render_markdown(&skill_record());
|
|
240
|
+
assert!(
|
|
241
|
+
rendered.len() <= MCP_SOFT_SIZE_LIMIT_BYTES,
|
|
242
|
+
"rendered skill is {} bytes (body {}), soft limit is {MCP_SOFT_SIZE_LIMIT_BYTES}",
|
|
243
|
+
rendered.len(),
|
|
244
|
+
SKILL_BODY.len()
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
231
248
|
#[test]
|
|
232
249
|
fn skill_body_names_every_recipe_and_the_description_loads_it_before_cypher() {
|
|
233
250
|
for record in recipe_records() {
|
|
@@ -192,7 +192,7 @@ language_registry! {
|
|
|
192
192
|
make_parser: python_parser,
|
|
193
193
|
},
|
|
194
194
|
"typescript" => {
|
|
195
|
-
extensions: ["ts", "tsx"],
|
|
195
|
+
extensions: ["ts", "tsx", "mts", "cts"],
|
|
196
196
|
module_sep: "/",
|
|
197
197
|
edge_sep: "/",
|
|
198
198
|
group: LangGroup::GoTsJs,
|
|
@@ -200,7 +200,7 @@ language_registry! {
|
|
|
200
200
|
make_parser: typescript_parser,
|
|
201
201
|
},
|
|
202
202
|
"javascript" => {
|
|
203
|
-
extensions: ["js", "jsx", "mjs"],
|
|
203
|
+
extensions: ["js", "jsx", "mjs", "cjs"],
|
|
204
204
|
module_sep: "/",
|
|
205
205
|
edge_sep: "/",
|
|
206
206
|
group: LangGroup::GoTsJs,
|
|
@@ -411,9 +411,12 @@ mod tests {
|
|
|
411
411
|
("pyi", "python"),
|
|
412
412
|
("ts", "typescript"),
|
|
413
413
|
("tsx", "typescript"),
|
|
414
|
+
("mts", "typescript"),
|
|
415
|
+
("cts", "typescript"),
|
|
414
416
|
("js", "javascript"),
|
|
415
417
|
("jsx", "javascript"),
|
|
416
418
|
("mjs", "javascript"),
|
|
419
|
+
("cjs", "javascript"),
|
|
417
420
|
("go", "go"),
|
|
418
421
|
("java", "java"),
|
|
419
422
|
("cs", "csharp"),
|
|
@@ -142,18 +142,26 @@ thread_local! {
|
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/// File-name suffixes stripped to form a TS/JS module path, shared by
|
|
146
|
+
/// `file_to_module_path` and the import resolver in `builder::other_edges` so
|
|
147
|
+
/// the two agree on module identity. Every extension the `typescript` and
|
|
148
|
+
/// `javascript` registry entries claim must be here, or its files get a
|
|
149
|
+
/// module path that still carries the extension and no import can reach them.
|
|
150
|
+
pub(crate) const JSTS_MODULE_SUFFIXES: &[&str] =
|
|
151
|
+
&[".tsx", ".ts", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".js"];
|
|
152
|
+
|
|
145
153
|
impl JstsParser {
|
|
146
154
|
pub fn typescript() -> Self {
|
|
147
155
|
JstsParser {
|
|
148
156
|
lang_name: "typescript",
|
|
149
|
-
extensions: &["ts", "tsx"],
|
|
157
|
+
extensions: &["ts", "tsx", "mts", "cts"],
|
|
150
158
|
}
|
|
151
159
|
}
|
|
152
160
|
|
|
153
161
|
pub fn javascript() -> Self {
|
|
154
162
|
JstsParser {
|
|
155
163
|
lang_name: "javascript",
|
|
156
|
-
extensions: &["js", "jsx", "mjs"],
|
|
164
|
+
extensions: &["js", "jsx", "mjs", "cjs"],
|
|
157
165
|
}
|
|
158
166
|
}
|
|
159
167
|
|
|
@@ -1095,7 +1103,7 @@ impl JstsParser {
|
|
|
1095
1103
|
.filter_map(|c| c.as_os_str().to_str().map(str::to_string))
|
|
1096
1104
|
.collect();
|
|
1097
1105
|
if let Some(last) = parts.last_mut() {
|
|
1098
|
-
for ext in
|
|
1106
|
+
for ext in JSTS_MODULE_SUFFIXES {
|
|
1099
1107
|
if let Some(stem) = last.strip_suffix(ext) {
|
|
1100
1108
|
*last = stem.to_string();
|
|
1101
1109
|
break;
|
|
@@ -1248,7 +1256,19 @@ impl JstsParser {
|
|
|
1248
1256
|
None => module_path.to_string(),
|
|
1249
1257
|
};
|
|
1250
1258
|
let qualified_name = format!("{}.{}", prefix, name);
|
|
1251
|
-
|
|
1259
|
+
// A concise arrow (`x => expr`) has no `{ … }` block; its expression IS
|
|
1260
|
+
// the body. Without this fallback such a function had null metrics and
|
|
1261
|
+
// dropped every call it made (`const run = c => execSync(c)` had no
|
|
1262
|
+
// CALLS edge at all).
|
|
1263
|
+
let body = Self::get_block(node).or_else(|| {
|
|
1264
|
+
(node.kind() == "arrow_function")
|
|
1265
|
+
.then(|| node.child_by_field_name("body"))
|
|
1266
|
+
.flatten()
|
|
1267
|
+
});
|
|
1268
|
+
// A concise body that is itself a nested scope (`a => b => f()`) stays
|
|
1269
|
+
// behind the boundary a `{ return b => f(); }` block puts it behind:
|
|
1270
|
+
// measured as empty, its calls not folded into this function.
|
|
1271
|
+
let block = body.filter(|b| !NESTED_SCOPES.contains(&b.kind()));
|
|
1252
1272
|
|
|
1253
1273
|
let mut metadata = crate::models::MetadataMap::new();
|
|
1254
1274
|
let mut cursor = node.walk();
|
|
@@ -1269,12 +1289,13 @@ impl JstsParser {
|
|
|
1269
1289
|
.filter(|p| p.kind != ParameterKind::Receiver)
|
|
1270
1290
|
.count() as u32,
|
|
1271
1291
|
);
|
|
1272
|
-
let (branch_count, max_nesting) = match block {
|
|
1273
|
-
Some(b) => {
|
|
1292
|
+
let (branch_count, max_nesting) = match (block, body) {
|
|
1293
|
+
(Some(b), _) => {
|
|
1274
1294
|
let (c, n) = compute_complexity(b, BRANCH_KINDS_TS, NESTED_SCOPES);
|
|
1275
1295
|
(Some(c), Some(n))
|
|
1276
1296
|
}
|
|
1277
|
-
None => (
|
|
1297
|
+
(None, Some(_)) => (Some(0), Some(0)),
|
|
1298
|
+
(None, None) => (None, None),
|
|
1278
1299
|
};
|
|
1279
1300
|
let is_recursive = Some(calls.iter().any(|(n, _)| n == &name));
|
|
1280
1301
|
let docstring = Self::get_docstring(node, source);
|
|
@@ -1865,6 +1886,12 @@ impl LanguageParser for JstsParser {
|
|
|
1865
1886
|
".spec.jsx",
|
|
1866
1887
|
".test.mjs",
|
|
1867
1888
|
".spec.mjs",
|
|
1889
|
+
".test.cjs",
|
|
1890
|
+
".spec.cjs",
|
|
1891
|
+
".test.mts",
|
|
1892
|
+
".spec.mts",
|
|
1893
|
+
".test.cts",
|
|
1894
|
+
".spec.cts",
|
|
1868
1895
|
];
|
|
1869
1896
|
let is_test = crate::parsers::shared::is_test_path(&rel_path, &filename, &test_suffixes);
|
|
1870
1897
|
|
|
@@ -2759,3 +2786,68 @@ export function outer(items: string[]) {
|
|
|
2759
2786
|
assert_eq!(calls_of(src, "a.outer"), vec!["items.forEach", "transform"]);
|
|
2760
2787
|
}
|
|
2761
2788
|
}
|
|
2789
|
+
|
|
2790
|
+
#[cfg(test)]
|
|
2791
|
+
mod concise_arrow_tests {
|
|
2792
|
+
use super::*;
|
|
2793
|
+
use crate::parsers::LanguageParser;
|
|
2794
|
+
|
|
2795
|
+
/// `(branch_count, max_nesting, call names)` for the Function named `name`.
|
|
2796
|
+
fn measured(src: &str, name: &str) -> (Option<u32>, Option<u32>, Vec<String>) {
|
|
2797
|
+
let dir = tempfile::tempdir().expect("tempdir");
|
|
2798
|
+
let path = dir.path().join("a.ts");
|
|
2799
|
+
std::fs::write(&path, src).expect("write fixture");
|
|
2800
|
+
let result = JstsParser::typescript().parse_file(&path, dir.path());
|
|
2801
|
+
let f = result
|
|
2802
|
+
.functions
|
|
2803
|
+
.iter()
|
|
2804
|
+
.find(|f| f.name == name)
|
|
2805
|
+
.unwrap_or_else(|| panic!("no Function named {name}"));
|
|
2806
|
+
let calls = f.calls.iter().map(|(c, _)| c.clone()).collect();
|
|
2807
|
+
(f.branch_count, f.max_nesting, calls)
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
/// The regression: an arrow whose body is an expression rather than a
|
|
2811
|
+
/// `{ … }` block had null metrics and no calls at all.
|
|
2812
|
+
#[test]
|
|
2813
|
+
fn concise_arrow_is_measured_and_keeps_its_calls() {
|
|
2814
|
+
let src = "const run = (cmd: string) => execSync(cmd, { stdio: \"inherit\" });\n";
|
|
2815
|
+
assert_eq!(
|
|
2816
|
+
measured(src, "run"),
|
|
2817
|
+
(Some(0), Some(0), vec!["execSync".to_string()])
|
|
2818
|
+
);
|
|
2819
|
+
let src = "const pick = (x: number) => x > 0 ? up(x) : down(x);\n";
|
|
2820
|
+
assert_eq!(
|
|
2821
|
+
measured(src, "pick"),
|
|
2822
|
+
(Some(1), Some(1), vec!["up".to_string(), "down".to_string()])
|
|
2823
|
+
);
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
/// A concise body that is itself an arrow reads the same as its
|
|
2827
|
+
/// block-bodied twin: the inner scope stays behind the nested-scope
|
|
2828
|
+
/// boundary in both spellings.
|
|
2829
|
+
#[test]
|
|
2830
|
+
fn curried_concise_arrow_matches_its_block_twin() {
|
|
2831
|
+
let concise = "const f = (a: number) => (b: number) => g(a ? b : 0);\n";
|
|
2832
|
+
let block = "const f = (a: number) => { return (b: number) => g(a ? b : 0); };\n";
|
|
2833
|
+
assert_eq!(measured(concise, "f"), (Some(0), Some(0), Vec::new()));
|
|
2834
|
+
assert_eq!(measured(concise, "f"), measured(block, "f"));
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
/// Every extension the registry routes to this parser must be stripped
|
|
2838
|
+
/// to form a module path; one left out makes its files unreachable by
|
|
2839
|
+
/// any import.
|
|
2840
|
+
#[test]
|
|
2841
|
+
fn module_suffixes_cover_every_registered_extension() {
|
|
2842
|
+
for language in ["typescript", "javascript"] {
|
|
2843
|
+
let spec = crate::parsers::registry::spec(language).expect("registered");
|
|
2844
|
+
for ext in spec.extensions {
|
|
2845
|
+
let suffix = format!(".{ext}");
|
|
2846
|
+
assert!(
|
|
2847
|
+
JSTS_MODULE_SUFFIXES.contains(&suffix.as_str()),
|
|
2848
|
+
"{language} extension {suffix} is parsed but not stripped from module paths"
|
|
2849
|
+
);
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
@@ -389,6 +389,28 @@ what shows the change is pure identity and not behaviour. Verified the strict
|
|
|
389
389
|
way: `capture_goldens` rewrote every file, and afterwards `git status` reported
|
|
390
390
|
exactly those two digests as modified.
|
|
391
391
|
|
|
392
|
+
The additive `js_module_exts` digest was captured on 2026-11-01 with the
|
|
393
|
+
corpus itself. The parser registry listed `js`/`jsx`/`mjs` and `ts`/`tsx` only,
|
|
394
|
+
so every `.cjs`, `.mts` and `.cts` file was skipped without a diagnostic — and
|
|
395
|
+
no corpus contained one, so the gap had no golden to move. The corpus pins all
|
|
396
|
+
three extensions and a `.d.mts` declaration file, the `.test.cts` test flag,
|
|
397
|
+
and import resolution onto a `.mts` module both by its emitted name
|
|
398
|
+
(`./util.mjs`, NodeNext) and by its own (`./util.mts`). Verified additive the
|
|
399
|
+
strict way: `capture_goldens` rewrote every file, and afterwards `git status`
|
|
400
|
+
reported only `js_module_exts.sha256` as new. Every pre-existing corpus is a
|
|
401
|
+
control and does not move.
|
|
402
|
+
|
|
403
|
+
**`ts_hof_binding` regenerated 2026-11-01 (concise-arrow bodies).** A
|
|
404
|
+
TS/JS arrow whose body is an expression rather than a `{ … }` block was never
|
|
405
|
+
measured and never walked for calls: `branch_count`/`max_nesting` were null and
|
|
406
|
+
`const run = c => execSync(c)` had no CALLS edge. The parser now treats the
|
|
407
|
+
expression as the body. The digest movement is the record: `ts_hof_binding` is
|
|
408
|
+
the only corpus with a concise-bodied Function node, and its one such node
|
|
409
|
+
(`createMemo(() => 1 + 2)`'s binding, no calls) gained `branch_count=0` and
|
|
410
|
+
`max_nesting=0` — two added properties, nothing else. Verified by dumping every
|
|
411
|
+
corpus with and without the fix (`dump_canonical`); only that file differed.
|
|
412
|
+
The calls half is pinned by `concise_arrow_tests` in the parser.
|
|
413
|
+
|
|
392
414
|
## The 2026-08-10 bulk regeneration (13 of 14 digests)
|
|
393
415
|
|
|
394
416
|
**This is the first bulk regeneration since the extraction**, and the only one
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ecba2b7d126857eab60248df7d88753f68fcf00e5774ba1308b4c27260411a8e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
804888ec5bbf3e6b76f5d17a4f31f8bf62b4fd3bd422507ede01f45adc327863
|
|
@@ -351,6 +351,16 @@ const CORPORA: &[&str] = &[
|
|
|
351
351
|
// root is still tried first. Its golden is captured additively (see
|
|
352
352
|
// `tests/goldens/README.md`).
|
|
353
353
|
"web_served_root",
|
|
354
|
+
// Added 2026-11-01. No other corpus contains a `.cjs`, `.mts` or `.cts`
|
|
355
|
+
// file — the parser registry did not list those extensions at all, so the
|
|
356
|
+
// builder skipped them without a word (an Electron app's whole
|
|
357
|
+
// `electron/*.cjs` main process was absent from its graph). It pins all
|
|
358
|
+
// three extensions plus a `.d.mts` declaration file, the `.test.cts` test
|
|
359
|
+
// flag, and import resolution onto a `.mts` module both by its emitted
|
|
360
|
+
// name (`./util.mjs`, NodeNext) and by its own (`./util.mts`). Its golden
|
|
361
|
+
// is captured additively (see
|
|
362
|
+
// `tests/goldens/README.md`).
|
|
363
|
+
"js_module_exts",
|
|
354
364
|
];
|
|
355
365
|
|
|
356
366
|
/// Independent builds of each corpus per `golden_parity` run.
|
|
@@ -14,7 +14,7 @@ name = "codingest"
|
|
|
14
14
|
path = "src/main.rs"
|
|
15
15
|
|
|
16
16
|
[dependencies]
|
|
17
|
-
codingest = { version = "0.2.
|
|
17
|
+
codingest = { version = "0.2.35", path = "../codingest" }
|
|
18
18
|
kglite = { workspace = true }
|
|
19
19
|
anyhow = "1.0.104"
|
|
20
20
|
clap = { version = "4.6.7", features = ["derive"] }
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest-cli/skills/codingest-code-review/SKILL.md
RENAMED
|
@@ -14,7 +14,7 @@ git diff, source reading, and literal-text search; it does not replace them.
|
|
|
14
14
|
> codingest` also provides the builder-aware `codingest-mcp` server and a
|
|
15
15
|
> compatible graph engine. Rust-only environments can alternatively use Cargo.
|
|
16
16
|
> Examples that invoke the external `kglite` CLI require a compatible
|
|
17
|
-
> `kglite>=0.21.
|
|
17
|
+
> `kglite>=0.21.5,<0.22`; verify `kglite --version` before using its
|
|
18
18
|
> agent-response features.
|
|
19
19
|
|
|
20
20
|
Inspect the diff and repository guidance first. Identify changed symbols and
|
|
@@ -42,7 +42,7 @@ doctest = false
|
|
|
42
42
|
pyo3 = { version = "0.30" }
|
|
43
43
|
# The engine-free builder (parsers, call/type/route edges, rev merge, repo
|
|
44
44
|
# clone, manifest reader). Docs pass gated by this crate's `docs` feature.
|
|
45
|
-
codingest = { version = "0.2.
|
|
45
|
+
codingest = { version = "0.2.35", path = "../codingest", default-features = false }
|
|
46
46
|
# `.kgl` persistence (`kglite::api::io::save_graph`) for the serialize half of
|
|
47
47
|
# the build-then-load handoff, plus the `DirGraph` type the builder returns.
|
|
48
48
|
kglite = { workspace = true }
|
|
@@ -53,9 +53,9 @@ tempfile = "3.27.0"
|
|
|
53
53
|
# through `_run_cli`, so `pip install codingest` also installs the `codingest`
|
|
54
54
|
# command without a second wheel or a duplicated builder build. Mirrors
|
|
55
55
|
# kglite-py's `kglite-cli` bundling.
|
|
56
|
-
codingest-cli = { version = "0.2.
|
|
56
|
+
codingest-cli = { version = "0.2.35", path = "../codingest-cli" }
|
|
57
57
|
# Source-building MCP composition. The graph server and generic MCP lifecycle
|
|
58
58
|
# remain owned by its existing kglite-mcp-server -> mcp-methods Rust dependency
|
|
59
59
|
# chain; linking this thin library into the extension gives pip users the same
|
|
60
60
|
# builder-aware server as the standalone `codingest-mcp` binary.
|
|
61
|
-
codingest-mcp = { version = "0.2.
|
|
61
|
+
codingest-mcp = { version = "0.2.35", path = "../codingest-mcp" }
|
|
@@ -86,7 +86,7 @@ fn load_via_kglite(py: Python<'_>, path: &Path) -> PyResult<Py<PyAny>> {
|
|
|
86
86
|
PyRuntimeError::new_err(format!(
|
|
87
87
|
"codingest.build() returns a kglite.KnowledgeGraph, but importing \
|
|
88
88
|
`kglite` failed ({e}). Install it: `pip install \
|
|
89
|
-
'kglite>=0.21.
|
|
89
|
+
'kglite>=0.21.5,<0.22'`."
|
|
90
90
|
))
|
|
91
91
|
})?;
|
|
92
92
|
let graph = kglite.call_method1("load", (path.to_string_lossy().as_ref(),))?;
|
|
@@ -41,9 +41,9 @@ dynamic = ["version"]
|
|
|
41
41
|
# minor releases (e.g. the v3->v4 break, which refuses old files outright), so
|
|
42
42
|
# pip must never be free to pair our writer with a reader from a different
|
|
43
43
|
# minor. This range therefore mirrors the Cargo semver range for the pin above
|
|
44
|
-
# (`version = "0.21.
|
|
44
|
+
# (`version = "0.21.5"` == `>=0.21.5,<0.22.0`) exactly — bump both together.
|
|
45
45
|
dependencies = [
|
|
46
|
-
"kglite>=0.21.
|
|
46
|
+
"kglite>=0.21.5,<0.22",
|
|
47
47
|
]
|
|
48
48
|
|
|
49
49
|
[project.urls]
|
|
@@ -1,70 +0,0 @@
|
|
|
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.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
68ea85e83b5135a8030d282475490e453fb4afd2f98779e05e5cd5992f3e5585
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/csharp_using_alias.sha256
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/docs_ext_collide.sha256
RENAMED
|
File without changes
|
|
File without changes
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/dup_minified_assets.sha256
RENAMED
|
File without changes
|
|
File without changes
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/html_js_lang_group.sha256
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codingest-0.2.34 → codingest-0.2.35}/crates/codingest/tests/goldens/ts_closure_scope.sha256
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|