codingest 0.1.7__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codingest-0.1.7 → codingest-0.2.0}/Cargo.lock +44 -38
- codingest-0.2.0/Cargo.toml +83 -0
- {codingest-0.1.7 → codingest-0.2.0}/PKG-INFO +5 -5
- {codingest-0.1.7 → codingest-0.2.0}/README.md +3 -3
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/Cargo.toml +4 -4
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/bin/codingest_bench.rs +161 -29
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/bin/codingest_stats.rs +10 -8
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/call_edges.rs +259 -34
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/js_workspace.rs +1 -6
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/load/edge_frames.rs +26 -10
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/mod.rs +514 -57
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/other_edges.rs +312 -1
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/routes/django.rs +3 -3
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/routes/fastapi.rs +3 -3
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/routes/flask.rs +1 -1
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/routes/mod.rs +152 -11
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/cross_lang.rs +88 -2
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/docs/mod.rs +375 -42
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/lib.rs +12 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/manifest/mod.rs +45 -3
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/models.rs +16 -1
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/agc.rs +14 -11
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/mod.rs +32 -11
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/registry.rs +62 -7
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/typescript.rs +12 -12
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/rev.rs +110 -30
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/tests/goldens/README.md +105 -0
- codingest-0.2.0/crates/codingest/tests/goldens/agc_basic.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/cross_ts_py.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/docs_ext_collide.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/docs_mdx.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/dup_minified_assets.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/html_js_lang_group.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/py_basic.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/py_inheritance.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/py_nested_defs.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/py_routes_dup.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/ts_callback.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/ts_closure_scope.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/ts_hof_binding.sha256 +1 -0
- codingest-0.2.0/crates/codingest/tests/goldens/ts_monorepo.sha256 +1 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/tests/parity.rs +38 -2
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/Cargo.toml +7 -5
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/skills/codingest-code-review/SKILL.md +29 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/code_tree_cli.rs +280 -22
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/tests/exit_codes.rs +155 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-mcp/Cargo.toml +2 -2
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-py/Cargo.toml +4 -4
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-py/src/lib.rs +1 -1
- {codingest-0.1.7 → codingest-0.2.0}/pyproject.toml +17 -2
- codingest-0.1.7/Cargo.toml +0 -46
- codingest-0.1.7/crates/codingest/tests/goldens/agc_basic.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/cross_ts_py.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/docs_mdx.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/dup_minified_assets.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/py_basic.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/py_inheritance.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/py_nested_defs.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/ts_callback.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/ts_closure_scope.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/ts_hof_binding.sha256 +0 -1
- codingest-0.1.7/crates/codingest/tests/goldens/ts_monorepo.sha256 +0 -1
- {codingest-0.1.7 → codingest-0.2.0}/LICENSE +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/codingest/__init__.py +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/codingest/__init__.pyi +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/codingest/cli.py +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/codingest/mcp_server.py +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/load/entity_frames.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/load.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/semantic_edges.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/builder/type_edges.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/docs/rst.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/cpp.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/csharp.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/css.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/dart.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/go.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/html.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/java.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/php.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/python.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/rust_lang.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/shared.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/parsers/swift.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/src/repo.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/tests/agc_apollo.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest/tests/goldens/rust_xfile.sha256 +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/skills/codingest-code-review/references/mcp-upgrade.md +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/skills/codingest-code-review/references/public-repositories.md +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/skills/codingest-code-review/references/queries.md +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/lib.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/main.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/query.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/skill.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-cli/src/skill_assets.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-mcp/src/lib.rs +0 -0
- {codingest-0.1.7 → codingest-0.2.0}/crates/codingest-mcp/src/main.rs +0 -0
|
@@ -124,17 +124,6 @@ dependencies = [
|
|
|
124
124
|
"stable_deref_trait",
|
|
125
125
|
]
|
|
126
126
|
|
|
127
|
-
[[package]]
|
|
128
|
-
name = "async-trait"
|
|
129
|
-
version = "0.1.91"
|
|
130
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
131
|
-
checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec"
|
|
132
|
-
dependencies = [
|
|
133
|
-
"proc-macro2",
|
|
134
|
-
"quote",
|
|
135
|
-
"syn 3.0.3",
|
|
136
|
-
]
|
|
137
|
-
|
|
138
127
|
[[package]]
|
|
139
128
|
name = "atomic-polyfill"
|
|
140
129
|
version = "1.0.3"
|
|
@@ -162,6 +151,12 @@ version = "0.22.1"
|
|
|
162
151
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
163
152
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
164
153
|
|
|
154
|
+
[[package]]
|
|
155
|
+
name = "base64"
|
|
156
|
+
version = "0.23.1"
|
|
157
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
158
|
+
checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
|
|
159
|
+
|
|
165
160
|
[[package]]
|
|
166
161
|
name = "bit-set"
|
|
167
162
|
version = "0.8.0"
|
|
@@ -313,10 +308,10 @@ dependencies = [
|
|
|
313
308
|
|
|
314
309
|
[[package]]
|
|
315
310
|
name = "codingest"
|
|
316
|
-
version = "0.
|
|
311
|
+
version = "0.2.0"
|
|
317
312
|
dependencies = [
|
|
318
313
|
"aho-corasick",
|
|
319
|
-
"base64",
|
|
314
|
+
"base64 0.22.1",
|
|
320
315
|
"kglite",
|
|
321
316
|
"rayon",
|
|
322
317
|
"regex",
|
|
@@ -345,7 +340,7 @@ dependencies = [
|
|
|
345
340
|
|
|
346
341
|
[[package]]
|
|
347
342
|
name = "codingest-cli"
|
|
348
|
-
version = "0.
|
|
343
|
+
version = "0.2.0"
|
|
349
344
|
dependencies = [
|
|
350
345
|
"anyhow",
|
|
351
346
|
"clap",
|
|
@@ -357,7 +352,7 @@ dependencies = [
|
|
|
357
352
|
|
|
358
353
|
[[package]]
|
|
359
354
|
name = "codingest-mcp"
|
|
360
|
-
version = "0.
|
|
355
|
+
version = "0.2.0"
|
|
361
356
|
dependencies = [
|
|
362
357
|
"anyhow",
|
|
363
358
|
"codingest",
|
|
@@ -366,7 +361,7 @@ dependencies = [
|
|
|
366
361
|
|
|
367
362
|
[[package]]
|
|
368
363
|
name = "codingest-py"
|
|
369
|
-
version = "0.
|
|
364
|
+
version = "0.2.0"
|
|
370
365
|
dependencies = [
|
|
371
366
|
"codingest",
|
|
372
367
|
"codingest-cli",
|
|
@@ -475,9 +470,9 @@ dependencies = [
|
|
|
475
470
|
|
|
476
471
|
[[package]]
|
|
477
472
|
name = "darling"
|
|
478
|
-
version = "0.
|
|
473
|
+
version = "0.24.0"
|
|
479
474
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
480
|
-
checksum = "
|
|
475
|
+
checksum = "88490bf1b990d87eaaa7ac8aa887f629a08e7359765b4911faf63c3763347d23"
|
|
481
476
|
dependencies = [
|
|
482
477
|
"darling_core",
|
|
483
478
|
"darling_macro",
|
|
@@ -485,26 +480,26 @@ dependencies = [
|
|
|
485
480
|
|
|
486
481
|
[[package]]
|
|
487
482
|
name = "darling_core"
|
|
488
|
-
version = "0.
|
|
483
|
+
version = "0.24.0"
|
|
489
484
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
490
|
-
checksum = "
|
|
485
|
+
checksum = "084e274f91c482280130e1e34e0b8d6e66776a060d7b6de7b84289ca778868c4"
|
|
491
486
|
dependencies = [
|
|
492
487
|
"ident_case",
|
|
493
488
|
"proc-macro2",
|
|
494
489
|
"quote",
|
|
495
490
|
"strsim",
|
|
496
|
-
"syn
|
|
491
|
+
"syn 3.0.3",
|
|
497
492
|
]
|
|
498
493
|
|
|
499
494
|
[[package]]
|
|
500
495
|
name = "darling_macro"
|
|
501
|
-
version = "0.
|
|
496
|
+
version = "0.24.0"
|
|
502
497
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
503
|
-
checksum = "
|
|
498
|
+
checksum = "68f5792fa0d41cd2325ce0ffa64f0a340eaebd4971a3a0c5e1ffd2cc488a355e"
|
|
504
499
|
dependencies = [
|
|
505
500
|
"darling_core",
|
|
506
501
|
"quote",
|
|
507
|
-
"syn
|
|
502
|
+
"syn 3.0.3",
|
|
508
503
|
]
|
|
509
504
|
|
|
510
505
|
[[package]]
|
|
@@ -1393,9 +1388,9 @@ dependencies = [
|
|
|
1393
1388
|
|
|
1394
1389
|
[[package]]
|
|
1395
1390
|
name = "kglite"
|
|
1396
|
-
version = "0.15.
|
|
1391
|
+
version = "0.15.11"
|
|
1397
1392
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1398
|
-
checksum = "
|
|
1393
|
+
checksum = "ab3210d1c2855536403c7e86725fe673ed4fce3b950bef81832324523b5d0357"
|
|
1399
1394
|
dependencies = [
|
|
1400
1395
|
"bzip2",
|
|
1401
1396
|
"chrono",
|
|
@@ -1428,9 +1423,9 @@ dependencies = [
|
|
|
1428
1423
|
|
|
1429
1424
|
[[package]]
|
|
1430
1425
|
name = "kglite-mcp-server"
|
|
1431
|
-
version = "0.15.
|
|
1426
|
+
version = "0.15.11"
|
|
1432
1427
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1433
|
-
checksum = "
|
|
1428
|
+
checksum = "920fed2716305e6be2663153782183c150330b643c06bf349dfaaf764fef54fe"
|
|
1434
1429
|
dependencies = [
|
|
1435
1430
|
"anyhow",
|
|
1436
1431
|
"bytes",
|
|
@@ -1532,9 +1527,9 @@ dependencies = [
|
|
|
1532
1527
|
|
|
1533
1528
|
[[package]]
|
|
1534
1529
|
name = "mcp-methods"
|
|
1535
|
-
version = "0.4.
|
|
1530
|
+
version = "0.4.4"
|
|
1536
1531
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1537
|
-
checksum = "
|
|
1532
|
+
checksum = "d6d41f37fa137ea40a0cd505729e41ae1156ed119dcf8f240210579889c5ba29"
|
|
1538
1533
|
dependencies = [
|
|
1539
1534
|
"anyhow",
|
|
1540
1535
|
"clap",
|
|
@@ -1945,12 +1940,11 @@ dependencies = [
|
|
|
1945
1940
|
|
|
1946
1941
|
[[package]]
|
|
1947
1942
|
name = "rmcp"
|
|
1948
|
-
version = "
|
|
1943
|
+
version = "3.1.1"
|
|
1949
1944
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1950
|
-
checksum = "
|
|
1945
|
+
checksum = "094c075f6698deef5a657cf4df6b684dff65157d255978b92b552ec22503f17a"
|
|
1951
1946
|
dependencies = [
|
|
1952
|
-
"
|
|
1953
|
-
"base64",
|
|
1947
|
+
"base64 0.23.1",
|
|
1954
1948
|
"chrono",
|
|
1955
1949
|
"futures",
|
|
1956
1950
|
"pastey",
|
|
@@ -1963,19 +1957,20 @@ dependencies = [
|
|
|
1963
1957
|
"tokio",
|
|
1964
1958
|
"tokio-util",
|
|
1965
1959
|
"tracing",
|
|
1960
|
+
"uuid",
|
|
1966
1961
|
]
|
|
1967
1962
|
|
|
1968
1963
|
[[package]]
|
|
1969
1964
|
name = "rmcp-macros"
|
|
1970
|
-
version = "
|
|
1965
|
+
version = "3.1.1"
|
|
1971
1966
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1972
|
-
checksum = "
|
|
1967
|
+
checksum = "737d947bcfd946fae6a179a4ef6487be6dcf25c930c2393856b820f1386e52a6"
|
|
1973
1968
|
dependencies = [
|
|
1974
1969
|
"darling",
|
|
1975
1970
|
"proc-macro2",
|
|
1976
1971
|
"quote",
|
|
1977
1972
|
"serde_json",
|
|
1978
|
-
"syn
|
|
1973
|
+
"syn 3.0.3",
|
|
1979
1974
|
]
|
|
1980
1975
|
|
|
1981
1976
|
[[package]]
|
|
@@ -2830,7 +2825,7 @@ version = "2.12.1"
|
|
|
2830
2825
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2831
2826
|
checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d"
|
|
2832
2827
|
dependencies = [
|
|
2833
|
-
"base64",
|
|
2828
|
+
"base64 0.22.1",
|
|
2834
2829
|
"flate2",
|
|
2835
2830
|
"log",
|
|
2836
2831
|
"once_cell",
|
|
@@ -2866,6 +2861,17 @@ version = "0.2.2"
|
|
|
2866
2861
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2867
2862
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|
2868
2863
|
|
|
2864
|
+
[[package]]
|
|
2865
|
+
name = "uuid"
|
|
2866
|
+
version = "1.24.0"
|
|
2867
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2868
|
+
checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
|
|
2869
|
+
dependencies = [
|
|
2870
|
+
"getrandom 0.4.3",
|
|
2871
|
+
"js-sys",
|
|
2872
|
+
"wasm-bindgen",
|
|
2873
|
+
]
|
|
2874
|
+
|
|
2869
2875
|
[[package]]
|
|
2870
2876
|
name = "valuable"
|
|
2871
2877
|
version = "0.1.1"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[workspace]
|
|
2
|
+
members = ["crates/codingest", "crates/codingest-cli", "crates/codingest-mcp", "crates/codingest-py"]
|
|
3
|
+
resolver = "2"
|
|
4
|
+
|
|
5
|
+
[workspace.package]
|
|
6
|
+
version = "0.2.0"
|
|
7
|
+
edition = "2021"
|
|
8
|
+
rust-version = "1.88"
|
|
9
|
+
license = "MIT"
|
|
10
|
+
repository = "https://github.com/kkollsga/codingest"
|
|
11
|
+
|
|
12
|
+
[workspace.dependencies]
|
|
13
|
+
base64 = "0.22"
|
|
14
|
+
sha2 = "0.11"
|
|
15
|
+
# kglite engine + MCP server — imported as crates.io libraries. The 0.15.11
|
|
16
|
+
# floor brings three things, only one of which changes what we run:
|
|
17
|
+
# * 0.15.10's `add_connections` resolves its edge-property columns once per
|
|
18
|
+
# call instead of once per cell — upstream measured 66.7ms -> 30.4ms
|
|
19
|
+
# (-54%) on 60k edges x 10 property columns. That is exactly the shape of
|
|
20
|
+
# our `control_edges_df` handoff, so it lands on the `calls` stage.
|
|
21
|
+
# * The `NodeData` -> `NodeView` API break from 0.15.9, made migratable in
|
|
22
|
+
# 0.15.11. 0.15.9 deleted `NodeData`'s inherent property accessors and
|
|
23
|
+
# 0.15.11 finally shipped reachable replacements: reads go through
|
|
24
|
+
# `DirGraph::node_view(idx)`, and by-index writes through the inherent
|
|
25
|
+
# `DirGraph::set_node_property(idx, "key", value)`. We migrated 21 read
|
|
26
|
+
# sites and the 2 `revs`/`rev_fp` write sites in `rev.rs` for this floor.
|
|
27
|
+
# It is a compile-time break only — the storage path behind both spellings
|
|
28
|
+
# is the one the removed methods already called, so it is NOT
|
|
29
|
+
# output-affecting.
|
|
30
|
+
# NOTE: do NOT reach the write side via `GraphWrite::set_node_property`
|
|
31
|
+
# with an `InternedKey::from_str` key. That key is never registered: it
|
|
32
|
+
# reads back within the session but breaks property enumeration and is
|
|
33
|
+
# silently dropped by `save_graph`. The inherent string-keyed calls
|
|
34
|
+
# register the name; use them.
|
|
35
|
+
# * 0.15.11's `kglite::api::embeddings` ingest API and `text_score()` query-
|
|
36
|
+
# vector arguments — codingest consumes neither.
|
|
37
|
+
# Per the 0.15.9-0.15.11 changelogs, graph output, property encoding and
|
|
38
|
+
# `.kgl` serialization are unchanged; the frozen parity goldens are what
|
|
39
|
+
# proves it, and they must not move across this bump.
|
|
40
|
+
#
|
|
41
|
+
# Floor history. The 0.15.8
|
|
42
|
+
# floor added recorded storage modes, `--storage` conversion on an existing
|
|
43
|
+
# graph, and boot-validated Cypher recipe catalogs — none of which codingest
|
|
44
|
+
# consumes — plus two changes that do reach us: workspace-graph producers now
|
|
45
|
+
# receive deduplicated changed-path hints alongside full-build requests (our
|
|
46
|
+
# `with_workspace_graph` producer lives in codingest-mcp), and the optimized-
|
|
47
|
+
# plan cache no longer lets a write loop evict other graphs' cached read plans.
|
|
48
|
+
# `OpenGraphResult` gained a `converted_from` field — a documented struct-
|
|
49
|
+
# literal break we are not exposed to, as codingest constructs no
|
|
50
|
+
# `OpenGraphResult`. 0.15.7 aligned the embedded server on mcp-methods 0.4.4
|
|
51
|
+
# and rmcp 3.1.1; dynamic handlers use rmcp's response envelope while
|
|
52
|
+
# preserving their payloads and MCP behavior. The 0.15.6 engine fixes
|
|
53
|
+
# mixed-selection vector dispatch, mixed-metric exact search,
|
|
54
|
+
# community-detection modularity scoring, sampled-centrality validation, and
|
|
55
|
+
# persisted HNSW validation, while adding the bulk node-degree primitive and
|
|
56
|
+
# graph-algorithm/vector-search performance improvements. It builds on the two
|
|
57
|
+
# workspace controls codingest asked upstream for in 0.15.5:
|
|
58
|
+
# `workspace.sandbox_root`, a real containment boundary that confines
|
|
59
|
+
# `set_root_dir` to a subtree instead of trusting the caller's path, and
|
|
60
|
+
# `workspace.adopt_client_roots`. Both land on top of the generic
|
|
61
|
+
# workspace-graph hooks, tri-state `durable` levels, typed
|
|
62
|
+
# constraint/conflict exceptions carrying a stable `.code`, and the
|
|
63
|
+
# deterministic Postcard persistence stack inherited from 0.14.5/0.15.0-0.15.3.
|
|
64
|
+
# 0.15.4 is deliberately skipped: it was WAL/durability and mapped-graph work
|
|
65
|
+
# we consume none of — codingest uses no `durable=` level, no `MappedGraph`,
|
|
66
|
+
# and no disk storage. Neither 0.15.7 nor 0.15.8 changes the `kglite::api` we
|
|
67
|
+
# call, graph output, property encoding, or `.kgl` serialization.
|
|
68
|
+
# Keep both libraries aligned so the graph and server share one engine release.
|
|
69
|
+
kglite = { version = "0.15.11", default-features = false }
|
|
70
|
+
kglite-mcp-server = { version = "0.15.11", default-features = false }
|
|
71
|
+
|
|
72
|
+
# Mirror KGLite's release codegen so the standalone builder has
|
|
73
|
+
# performance parity with the in-tree component (see KGLite
|
|
74
|
+
# workspace Cargo.toml).
|
|
75
|
+
[profile.release]
|
|
76
|
+
lto = "thin"
|
|
77
|
+
codegen-units = 1
|
|
78
|
+
strip = "symbols"
|
|
79
|
+
|
|
80
|
+
[profile.profiling]
|
|
81
|
+
inherits = "release"
|
|
82
|
+
debug = "line-tables-only"
|
|
83
|
+
strip = "none"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codingest
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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.15.
|
|
15
|
+
Requires-Dist: kglite>=0.15.11,<0.16
|
|
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
|
|
@@ -191,7 +191,7 @@ codingest skill install # code-review Agent Skill
|
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
194
|
-
commands. KGLite ≥0.15.
|
|
194
|
+
commands. KGLite ≥0.15.11 is installed automatically as the query/storage
|
|
195
195
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
196
196
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
197
197
|
|
|
@@ -204,7 +204,7 @@ Python prerequisites.
|
|
|
204
204
|
```toml
|
|
205
205
|
[dependencies]
|
|
206
206
|
codingest = "0.1"
|
|
207
|
-
kglite = "0.15.
|
|
207
|
+
kglite = "0.15.11"
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
```rust
|
|
@@ -276,7 +276,7 @@ diagnostic.
|
|
|
276
276
|
## Dependency policy
|
|
277
277
|
|
|
278
278
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
279
|
-
0.15.
|
|
279
|
+
0.15.11 minimum and a shared lockfile. This keeps the builder, persistence
|
|
280
280
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
281
281
|
|
|
282
282
|
## Parity with the (now-removed) in-tree component
|
|
@@ -164,7 +164,7 @@ codingest skill install # code-review Agent Skill
|
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
The wheel bundles every grammar plus the `codingest` and `codingest-mcp`
|
|
167
|
-
commands. KGLite ≥0.15.
|
|
167
|
+
commands. KGLite ≥0.15.11 is installed automatically as the query/storage
|
|
168
168
|
engine; its MCP server and the transitive `mcp-methods` framework power the
|
|
169
169
|
builder-aware Codingest server. Nothing else needs to be installed.
|
|
170
170
|
|
|
@@ -177,7 +177,7 @@ Python prerequisites.
|
|
|
177
177
|
```toml
|
|
178
178
|
[dependencies]
|
|
179
179
|
codingest = "0.1"
|
|
180
|
-
kglite = "0.15.
|
|
180
|
+
kglite = "0.15.11"
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
```rust
|
|
@@ -249,7 +249,7 @@ diagnostic.
|
|
|
249
249
|
## Dependency policy
|
|
250
250
|
|
|
251
251
|
`kglite` and `kglite-mcp-server` use matching crates.io requirements with a
|
|
252
|
-
0.15.
|
|
252
|
+
0.15.11 minimum and a shared lockfile. This keeps the builder, persistence
|
|
253
253
|
handoff, and embedded MCP server on one compatible engine patch line.
|
|
254
254
|
|
|
255
255
|
## 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 0.15 patch floor (0.15.
|
|
13
|
+
# workspace pins the current 0.15 patch floor (0.15.11).
|
|
14
14
|
|
|
15
15
|
[lib]
|
|
16
16
|
name = "codingest"
|
|
@@ -46,7 +46,7 @@ sha2 = { workspace = true }
|
|
|
46
46
|
|
|
47
47
|
serde = { version = "1.0.229", features = ["derive"] }
|
|
48
48
|
serde_json = "1.0.151"
|
|
49
|
-
regex = "1"
|
|
49
|
+
regex = "1.13.1"
|
|
50
50
|
rayon = "1.12"
|
|
51
51
|
tree-sitter = "0.26.11"
|
|
52
52
|
tree-sitter-python = "0.25.0"
|
|
@@ -65,8 +65,8 @@ tree-sitter-css = "0.25.0"
|
|
|
65
65
|
tree-sitter-dart = "0.2.0"
|
|
66
66
|
toml = "1.1.3"
|
|
67
67
|
walkdir = "2.5.0"
|
|
68
|
-
tempfile = "3"
|
|
68
|
+
tempfile = "3.27.0"
|
|
69
69
|
aho-corasick = "1.1.4"
|
|
70
70
|
|
|
71
71
|
[dev-dependencies]
|
|
72
|
-
tempfile = "3"
|
|
72
|
+
tempfile = "3.27.0"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
//! cargo run -p codingest --bin codingest_bench --release -- <path>
|
|
43
43
|
//! cargo run -p codingest --bin codingest_bench --release -- <path> --json
|
|
44
44
|
//! cargo run -p codingest --bin codingest_bench --release -- <path> --include-untracked
|
|
45
|
+
//! cargo run -p codingest --bin codingest_bench --release -- <path> --no-docs
|
|
45
46
|
|
|
46
47
|
use kglite::api::session::{execute_read, ExecuteOptions, ExecuteOutcome};
|
|
47
48
|
use kglite::api::{DirGraph, GraphRead, Value};
|
|
@@ -264,6 +265,69 @@ fn resolve_corpus(target: &Path, include_untracked: bool) -> Corpus {
|
|
|
264
265
|
}
|
|
265
266
|
}
|
|
266
267
|
|
|
268
|
+
// ── command line ─────────────────────────────────────────────────────────
|
|
269
|
+
|
|
270
|
+
const USAGE: &str = "usage: codingest_bench <path> [--json] [--include-untracked] [--no-docs]";
|
|
271
|
+
|
|
272
|
+
/// Everything the command line can say after `<path>`, parsed once so the
|
|
273
|
+
/// configuration a run was taken under is a value that can be echoed and
|
|
274
|
+
/// tested rather than a scatter of `any(|a| a == …)` predicates — the shape
|
|
275
|
+
/// `codingest_stats` already uses.
|
|
276
|
+
#[derive(Debug, PartialEq, Eq)]
|
|
277
|
+
struct Options {
|
|
278
|
+
json: bool,
|
|
279
|
+
include_untracked: bool,
|
|
280
|
+
/// DECISION (2026-08-10): this default points the OPPOSITE way to
|
|
281
|
+
/// `codingest_stats`' `--include-docs`, deliberately.
|
|
282
|
+
///
|
|
283
|
+
/// Both binaries obey the same rule — a binary's default must reproduce
|
|
284
|
+
/// that binary's own historical rows, or old and new numbers silently stop
|
|
285
|
+
/// being comparable — and they have mirror-image histories. Every
|
|
286
|
+
/// `codingest_stats` row predating its flag was captured docs-OFF, so it
|
|
287
|
+
/// defaults off and opts in. This harness hardcoded docs-ON from the day it
|
|
288
|
+
/// was written, so every bench row ever filed (`BENCHMARKS.md`, the ad-hoc
|
|
289
|
+
/// results log) is a docs-ON measurement: it keeps docs-ON as the default
|
|
290
|
+
/// and gains an explicit `--no-docs` opt-OUT.
|
|
291
|
+
///
|
|
292
|
+
/// The asymmetry is therefore not an inconsistency to be tidied away; it is
|
|
293
|
+
/// what keeps each binary's own series continuous. Neither default is
|
|
294
|
+
/// self-describing, which is why the effective value is echoed in the JSON
|
|
295
|
+
/// (`include_docs`) and in the human header either way — no row can be
|
|
296
|
+
/// filed without stating the mode it was taken under.
|
|
297
|
+
include_docs: bool,
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
impl Default for Options {
|
|
301
|
+
fn default() -> Self {
|
|
302
|
+
Self {
|
|
303
|
+
json: false,
|
|
304
|
+
include_untracked: false,
|
|
305
|
+
include_docs: true,
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// Parse the arguments after `<path>`.
|
|
311
|
+
///
|
|
312
|
+
/// Rejects anything unrecognised rather than silently ignoring it: a typo'd
|
|
313
|
+
/// `--include-untraked` or `--nodocs` would otherwise change nothing and the
|
|
314
|
+
/// run would be reported as a measurement taken under a mode it never ran in.
|
|
315
|
+
/// That includes `--include-docs`: it is `codingest_stats`' spelling, it is not
|
|
316
|
+
/// this binary's, and accepting it as a no-op would teach the wrong muscle
|
|
317
|
+
/// memory for the one flag whose two binaries disagree.
|
|
318
|
+
fn parse_options(args: &[String]) -> Result<Options, String> {
|
|
319
|
+
let mut out = Options::default();
|
|
320
|
+
for arg in args {
|
|
321
|
+
match arg.as_str() {
|
|
322
|
+
"--json" => out.json = true,
|
|
323
|
+
"--include-untracked" => out.include_untracked = true,
|
|
324
|
+
"--no-docs" => out.include_docs = false,
|
|
325
|
+
other => return Err(format!("unknown argument `{other}`")),
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
Ok(out)
|
|
329
|
+
}
|
|
330
|
+
|
|
267
331
|
struct QueryResult {
|
|
268
332
|
name: String,
|
|
269
333
|
rows: usize,
|
|
@@ -280,24 +344,20 @@ fn main() {
|
|
|
280
344
|
let path = match args.next() {
|
|
281
345
|
Some(p) => p,
|
|
282
346
|
None => {
|
|
283
|
-
eprintln!("
|
|
347
|
+
eprintln!("{USAGE}");
|
|
284
348
|
std::process::exit(2);
|
|
285
349
|
}
|
|
286
350
|
};
|
|
287
351
|
let rest: Vec<String> = args.collect();
|
|
288
|
-
let
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
.find(|a| !matches!(a.as_str(), "--json" | "--include-untracked"))
|
|
296
|
-
{
|
|
297
|
-
eprintln!("unknown argument `{bad}`");
|
|
298
|
-
eprintln!("usage: codingest_bench <path> [--json] [--include-untracked]");
|
|
352
|
+
let Options {
|
|
353
|
+
json,
|
|
354
|
+
include_untracked,
|
|
355
|
+
include_docs,
|
|
356
|
+
} = parse_options(&rest).unwrap_or_else(|e| {
|
|
357
|
+
eprintln!("{e}");
|
|
358
|
+
eprintln!("{USAGE}");
|
|
299
359
|
std::process::exit(2);
|
|
300
|
-
}
|
|
360
|
+
});
|
|
301
361
|
let target = Path::new(&path);
|
|
302
362
|
|
|
303
363
|
// Resolve the corpus BEFORE any timing: by default this copies the
|
|
@@ -306,22 +366,27 @@ fn main() {
|
|
|
306
366
|
let corpus = resolve_corpus(target, include_untracked);
|
|
307
367
|
let build_dir = corpus.build_dir.as_path();
|
|
308
368
|
|
|
309
|
-
// Two independent codingest builds with identical arguments:
|
|
310
|
-
//
|
|
369
|
+
// Two independent codingest builds with identical arguments: verbose=false,
|
|
370
|
+
// include_tests=false, save_to=None, max_loc=None, docs=`include_docs`
|
|
371
|
+
// (ON unless `--no-docs`). Both sides MUST take the same value — the A/B
|
|
372
|
+
// comparison is a determinism check, so a configuration difference between
|
|
373
|
+
// them would surface as a MISMATCH and be read as a builder regression.
|
|
311
374
|
let t = Instant::now();
|
|
312
|
-
let graph_a =
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
375
|
+
let graph_a =
|
|
376
|
+
codingest::builder::run_with_options(build_dir, false, false, None, None, include_docs)
|
|
377
|
+
.unwrap_or_else(|e| {
|
|
378
|
+
eprintln!("build A failed: {e}");
|
|
379
|
+
std::process::exit(1);
|
|
380
|
+
});
|
|
317
381
|
let build_a_secs = t.elapsed().as_secs_f64();
|
|
318
382
|
|
|
319
383
|
let t = Instant::now();
|
|
320
|
-
let graph_b =
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
384
|
+
let graph_b =
|
|
385
|
+
codingest::builder::run_with_options(build_dir, false, false, None, None, include_docs)
|
|
386
|
+
.unwrap_or_else(|e| {
|
|
387
|
+
eprintln!("build B failed: {e}");
|
|
388
|
+
std::process::exit(1);
|
|
389
|
+
});
|
|
325
390
|
let build_b_secs = t.elapsed().as_secs_f64();
|
|
326
391
|
|
|
327
392
|
let a: &DirGraph = &graph_a;
|
|
@@ -486,11 +551,15 @@ fn main() {
|
|
|
486
551
|
"corpus_files": corpus.sha256.as_ref().map(|_| corpus.files),
|
|
487
552
|
"corpus_bytes": corpus.sha256.as_ref().map(|_| corpus.bytes),
|
|
488
553
|
"corpus_sha256": corpus.sha256,
|
|
489
|
-
//
|
|
490
|
-
//
|
|
491
|
-
//
|
|
554
|
+
// Build configuration, echoed so a recorded row states it rather
|
|
555
|
+
// than inheriting it from whoever reads the row. `include_docs` is
|
|
556
|
+
// the EFFECTIVE value, not the default: docs are ON unless
|
|
557
|
+
// `--no-docs` was passed, and when they are on the docs pass is in
|
|
558
|
+
// these build times and node counts. Every historical bench row was
|
|
559
|
+
// taken docs-ON — see `Options::include_docs` for why that is this
|
|
560
|
+
// binary's default and the opposite of codingest_stats'.
|
|
492
561
|
"include_tests": false,
|
|
493
|
-
"include_docs":
|
|
562
|
+
"include_docs": include_docs,
|
|
494
563
|
"nodes": nodes,
|
|
495
564
|
"edges": edges,
|
|
496
565
|
"build_a_secs": (build_a_secs * 1000.0).round() / 1000.0,
|
|
@@ -532,6 +601,9 @@ fn main() {
|
|
|
532
601
|
corpus.reason,
|
|
533
602
|
),
|
|
534
603
|
}
|
|
604
|
+
// The effective build configuration, printed for the same reason the JSON
|
|
605
|
+
// echoes it: a pasted bench table must carry the mode it was taken under.
|
|
606
|
+
println!("config : include_tests=false include_docs={include_docs}");
|
|
535
607
|
println!("graph : {nodes} nodes / {edges} edges (identical across both builds)");
|
|
536
608
|
println!("build : A {build_a_secs:.3}s | B {build_b_secs:.3}s (one-off, context)");
|
|
537
609
|
println!("anchor : in-hub = {hot_in}");
|
|
@@ -568,3 +640,63 @@ fn main() {
|
|
|
568
640
|
mismatches
|
|
569
641
|
);
|
|
570
642
|
}
|
|
643
|
+
|
|
644
|
+
#[cfg(test)]
|
|
645
|
+
mod tests {
|
|
646
|
+
use super::*;
|
|
647
|
+
|
|
648
|
+
fn opts(args: &[&str]) -> Result<Options, String> {
|
|
649
|
+
parse_options(&args.iter().map(|a| a.to_string()).collect::<Vec<_>>())
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
#[test]
|
|
653
|
+
fn parse_options_defaults_to_the_historical_docs_on_configuration() {
|
|
654
|
+
// Every bench row ever filed was measured docs-ON, because this harness
|
|
655
|
+
// hardcoded docs-ON before the flag existed. The default must stay that
|
|
656
|
+
// way or old and new rows silently stop being comparable. This is the
|
|
657
|
+
// MIRROR of codingest_stats' equivalent test, which asserts docs-OFF —
|
|
658
|
+
// same rule, opposite history. See `Options::include_docs`.
|
|
659
|
+
let parsed = opts(&[]).expect("empty argv parses");
|
|
660
|
+
assert_eq!(parsed, Options::default());
|
|
661
|
+
assert!(parsed.include_docs, "bench must default to docs-ON");
|
|
662
|
+
assert!(!parsed.json);
|
|
663
|
+
assert!(!parsed.include_untracked);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
#[test]
|
|
667
|
+
fn parse_options_reads_every_flag() {
|
|
668
|
+
let parsed =
|
|
669
|
+
opts(&["--json", "--include-untracked", "--no-docs"]).expect("all flags parse");
|
|
670
|
+
assert!(parsed.json);
|
|
671
|
+
assert!(parsed.include_untracked);
|
|
672
|
+
assert!(!parsed.include_docs);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
#[test]
|
|
676
|
+
fn no_docs_turns_docs_off_on_its_own() {
|
|
677
|
+
// The one flag whose absence is not the interesting case: assert it
|
|
678
|
+
// flips the value rather than merely parsing.
|
|
679
|
+
assert!(!opts(&["--no-docs"]).expect("parses").include_docs);
|
|
680
|
+
assert!(opts(&["--json"]).expect("parses").include_docs);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
#[test]
|
|
684
|
+
fn parse_options_rejects_an_unknown_flag() {
|
|
685
|
+
// A silently-ignored typo would report a measurement taken under a mode
|
|
686
|
+
// the run never used — the reason this parser is strict at all.
|
|
687
|
+
let err = opts(&["--include-untraked"]).expect_err("typo must not parse");
|
|
688
|
+
assert!(err.contains("--include-untraked"), "unhelpful error: {err}");
|
|
689
|
+
assert!(opts(&["--nodocs"]).is_err(), "`--nodocs` must not parse");
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
#[test]
|
|
693
|
+
fn parse_options_rejects_the_stats_spelling_of_the_docs_flag() {
|
|
694
|
+
// `--include-docs` is codingest_stats' flag. Accepting it here as a
|
|
695
|
+
// harmless no-op (docs are already on) would teach that the two
|
|
696
|
+
// binaries share a spelling for the one flag on which they disagree —
|
|
697
|
+
// and would then silently accept `--include-docs` from a user who meant
|
|
698
|
+
// to CHANGE the mode. Rejecting it is what makes the asymmetry visible
|
|
699
|
+
// at the moment it matters.
|
|
700
|
+
assert!(opts(&["--include-docs"]).is_err());
|
|
701
|
+
}
|
|
702
|
+
}
|