coderadar-rs 0.9.3__tar.gz → 0.9.4__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.
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/Cargo.lock +3 -3
- coderadar_rs-0.9.4/Cargo.toml +10 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/PKG-INFO +19 -10
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/README.md +15 -9
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/Cargo.toml +3 -1
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/cold_start.rs +3 -3
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/persistence.rs +8 -17
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/persistence_tests.rs +23 -3
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/lib.rs +107 -25
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/storage.rs +285 -12
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/__init__.py +1 -1
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/cli.py +10 -1
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/pyproject.toml +5 -1
- coderadar_rs-0.9.3/Cargo.toml +0 -8
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/LICENSE +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/bash.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/c.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/clojure.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/cmake.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/cpp.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/csharp.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/dart.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/dockerfile.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/elisp.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/elixir.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/erlang.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/fsharp.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/go.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/graphql.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/groovy.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/haskell.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/hcl.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/java.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/javascript.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/julia.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/kotlin.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/lua.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/nix.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/objc.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/ocaml.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/perl.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/php.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/powershell.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/protobuf.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/python.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/r.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/ruby.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/rust.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/scala.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/shell.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/sql.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/swift.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/systemverilog.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/typescript.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/verilog.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/queries/zig.scm +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/clones/apted.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/clones/lsh_index.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/clones/minhash.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/clones/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/clones/tokens.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/decorators.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/docstring.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/single_pass.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/spans.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/tagger.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/extract/walker.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/fs/git.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/fs/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/fs/watcher.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/call_graph.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/centrality.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/cfg.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/config.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/deadcode/entry_points.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/deadcode/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/deadcode/reachability.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/embeddings.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/import_graph.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/indexing.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/inheritance.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/module_resolution.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/mro.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/projection_ops.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/resolve_calls.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/rta_lite.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/call_graph_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/embedding_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/import_graph_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/indexing_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/inheritance_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/mro_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/projection_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/query_compile_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/tests/traversal_tests.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/graph/traversal.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/mutation/edit.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/mutation/indent.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/mutation/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/mutation/write_guard.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/query/exec.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/query/grammar.pest +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/query/grammar.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/query/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/resolve/cache.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/resolve/import_graph.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/resolve/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/resolve/orchestrator.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/resolve/signature.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/scaffold/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/scaffold/secrets.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/scoring/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/const_eval.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/engine.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/metrics.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/profile.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rule.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/brain_method.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/data_class.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/dead_branch.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/dead_code.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/deep_nesting.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/excessive_returns.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/god_class.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/high_cyclomatic_complexity.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/intra_dead_statements.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/long_method.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/long_parameter_list.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/mod.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/rules/too_many_fields.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/smells/types.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/types.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/core_indexer/src/update/wal.rs +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/agent/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/agent/graphrag.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/coldstart.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/config.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/embedding/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/embedding/dedup.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/excludes.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/lsp/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/lsp/pool.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/lazy.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/lifecycle.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/roots.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/server.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mcp/startup.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mutation/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/mutation/tool_router.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/project_state.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/query/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/query/cache.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/query/executor.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/query/planner.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/actix.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/aspnet.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/base.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/django.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/exports.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/express.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/fastapi.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/flask.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/go.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/laravel.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/nestjs.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/rails.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/reactrouter.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/resolution.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/springboot.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/resolvers/vuerouter.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/visualizers/__init__.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/visualizers/call_graph.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/visualizers/graphviz_viz.py +0 -0
- {coderadar_rs-0.9.3 → coderadar_rs-0.9.4}/py_agent/src/coderadar/visualizers/mermaid.py +0 -0
|
@@ -445,7 +445,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|
|
445
445
|
|
|
446
446
|
[[package]]
|
|
447
447
|
name = "core_indexer"
|
|
448
|
-
version = "0.9.
|
|
448
|
+
version = "0.9.4"
|
|
449
449
|
dependencies = [
|
|
450
450
|
"crossbeam-channel",
|
|
451
451
|
"dashmap",
|
|
@@ -1640,9 +1640,9 @@ dependencies = [
|
|
|
1640
1640
|
|
|
1641
1641
|
[[package]]
|
|
1642
1642
|
name = "macrame-db"
|
|
1643
|
-
version = "0.
|
|
1643
|
+
version = "0.18.0"
|
|
1644
1644
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1645
|
-
checksum = "
|
|
1645
|
+
checksum = "6c07608eae01b1acf1fa71f739e92e9cc4c5ab90c8ebadc82b36eee500fd8a1d"
|
|
1646
1646
|
dependencies = [
|
|
1647
1647
|
"bincode",
|
|
1648
1648
|
"libsql",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coderadar-rs
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.4
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -27,12 +27,15 @@ Provides-Extra: dev
|
|
|
27
27
|
Provides-Extra: visualizers
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
Summary: Live semantic graph of your codebase — incremental, queryable, LLM-writable
|
|
30
|
+
Home-Page: https://github.com/opticsWolf/coderadar
|
|
30
31
|
Author: CodeRadar Team
|
|
31
32
|
License: MIT
|
|
32
33
|
Requires-Python: >=3.10
|
|
33
34
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
35
|
+
Project-URL: Homepage, https://github.com/opticsWolf/coderadar
|
|
36
|
+
Project-URL: Repository, https://github.com/opticsWolf/coderadar
|
|
34
37
|
|
|
35
|
-
# CodeRadar v0.9.
|
|
38
|
+
# CodeRadar v0.9.4
|
|
36
39
|
|
|
37
40
|
[](https://github.com/opticsWolf/coderadar/actions/workflows/ci.yml)
|
|
38
41
|
[](https://pypi.org/project/coderadar-rs/)
|
|
@@ -41,6 +44,8 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
41
44
|
[](LICENSE)
|
|
42
45
|
[]()
|
|
43
46
|
|
|
47
|
+
[Homepage](https://github.com/opticsWolf/coderadar) · [Repository](https://github.com/opticsWolf/coderadar)
|
|
48
|
+
|
|
44
49
|
**Live semantic graph of your codebase — incremental, queryable, LLM-writable.**
|
|
45
50
|
|
|
46
51
|
CodeRadar maintains an incrementally updatable graph of your code's logical structure, enabling LLMs and developer tools to both **query** and **safely rewrite** code through a unified pipeline.
|
|
@@ -89,7 +94,7 @@ Rust Core (ProjectedGraph, Tree-sitter 41-lang, Parallel Extraction,
|
|
|
89
94
|
| Metric | Value |
|
|
90
95
|
|--------|-------|
|
|
91
96
|
| **Languages indexed** | 41 (12 Tier 1, 29 Tier 2, 330+ Tier 3) |
|
|
92
|
-
| **Tests** |
|
|
97
|
+
| **Tests** | 1139 passing (372 Rust + 767 Python; 1 Python skipped) |
|
|
93
98
|
| **MCP Tools** | 22 — 17 `codegraph_*` (explore, search, node, affected, query, search_similar, compute_embeddings, module_children, as_of, traverse, get_smells, dead_code, find_clones, find_scaffolding, reindex, update_file, set_project) + 5 `coderadar_*` (resolve, replace_body, update_signature, rename, create_entity) |
|
|
94
99
|
| **Query surface** | Pest structural + Macrame agent traversals + vector search |
|
|
95
100
|
| **Frameworks** | Django, Flask, FastAPI, Go, Actix, Express, Spring Boot, Laravel, ASP.NET, Rails, NestJS, Vue Router, React Router |
|
|
@@ -335,13 +340,17 @@ cold-start design in [`docs/v0.8-p1-cold-start-design.md`](docs/v0.8-p1-cold-sta
|
|
|
335
340
|
- **Shell-friendly entity IDs (E7).** Stored IDs keep OS-native separators (FK stability);
|
|
336
341
|
display renders forward slashes with the redundant `./` dropped, and every pasted variant
|
|
337
342
|
resolves back to the stored key.
|
|
338
|
-
- **macrame-db 0.
|
|
339
|
-
`
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
343
|
+
- **macrame-db 0.18 (schema v21, auto-rungs v15→v21 on open).** CodeRadar stores
|
|
344
|
+
compact namespaced metadata (`kind`, `file_path`, `content_hash`) in
|
|
345
|
+
`concepts.extra`, indexes the file path for precise stale-row cleanup, and
|
|
346
|
+
gives framework edges stable namespaced kinds such as
|
|
347
|
+
`synthetic:django:handles` instead of flattening their types. This is a
|
|
348
|
+
forward-only database upgrade: a 0.17 binary cannot open v21 or fold a
|
|
349
|
+
concept written by 0.18. Existing 0.17 concept content remains canonical and
|
|
350
|
+
is rewritten with `extra` on the next analyze. Existing no-op-write filtering
|
|
351
|
+
and the `MAX(seq_id)` ledger-revision stamp remain in place; see the
|
|
352
|
+
[integration notes](docs/macrame-0.18-integration.md) for the adopted fields
|
|
353
|
+
and the KV deferral.
|
|
345
354
|
|
|
346
355
|
## v0.8.1–v0.8.14 Highlights — the dogfood batch
|
|
347
356
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# CodeRadar v0.9.
|
|
1
|
+
# CodeRadar v0.9.4
|
|
2
2
|
|
|
3
3
|
[](https://github.com/opticsWolf/coderadar/actions/workflows/ci.yml)
|
|
4
4
|
[](https://pypi.org/project/coderadar-rs/)
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[]()
|
|
9
9
|
|
|
10
|
+
[Homepage](https://github.com/opticsWolf/coderadar) · [Repository](https://github.com/opticsWolf/coderadar)
|
|
11
|
+
|
|
10
12
|
**Live semantic graph of your codebase — incremental, queryable, LLM-writable.**
|
|
11
13
|
|
|
12
14
|
CodeRadar maintains an incrementally updatable graph of your code's logical structure, enabling LLMs and developer tools to both **query** and **safely rewrite** code through a unified pipeline.
|
|
@@ -55,7 +57,7 @@ Rust Core (ProjectedGraph, Tree-sitter 41-lang, Parallel Extraction,
|
|
|
55
57
|
| Metric | Value |
|
|
56
58
|
|--------|-------|
|
|
57
59
|
| **Languages indexed** | 41 (12 Tier 1, 29 Tier 2, 330+ Tier 3) |
|
|
58
|
-
| **Tests** |
|
|
60
|
+
| **Tests** | 1139 passing (372 Rust + 767 Python; 1 Python skipped) |
|
|
59
61
|
| **MCP Tools** | 22 — 17 `codegraph_*` (explore, search, node, affected, query, search_similar, compute_embeddings, module_children, as_of, traverse, get_smells, dead_code, find_clones, find_scaffolding, reindex, update_file, set_project) + 5 `coderadar_*` (resolve, replace_body, update_signature, rename, create_entity) |
|
|
60
62
|
| **Query surface** | Pest structural + Macrame agent traversals + vector search |
|
|
61
63
|
| **Frameworks** | Django, Flask, FastAPI, Go, Actix, Express, Spring Boot, Laravel, ASP.NET, Rails, NestJS, Vue Router, React Router |
|
|
@@ -301,13 +303,17 @@ cold-start design in [`docs/v0.8-p1-cold-start-design.md`](docs/v0.8-p1-cold-sta
|
|
|
301
303
|
- **Shell-friendly entity IDs (E7).** Stored IDs keep OS-native separators (FK stability);
|
|
302
304
|
display renders forward slashes with the redundant `./` dropped, and every pasted variant
|
|
303
305
|
resolves back to the stored key.
|
|
304
|
-
- **macrame-db 0.
|
|
305
|
-
`
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
306
|
+
- **macrame-db 0.18 (schema v21, auto-rungs v15→v21 on open).** CodeRadar stores
|
|
307
|
+
compact namespaced metadata (`kind`, `file_path`, `content_hash`) in
|
|
308
|
+
`concepts.extra`, indexes the file path for precise stale-row cleanup, and
|
|
309
|
+
gives framework edges stable namespaced kinds such as
|
|
310
|
+
`synthetic:django:handles` instead of flattening their types. This is a
|
|
311
|
+
forward-only database upgrade: a 0.17 binary cannot open v21 or fold a
|
|
312
|
+
concept written by 0.18. Existing 0.17 concept content remains canonical and
|
|
313
|
+
is rewritten with `extra` on the next analyze. Existing no-op-write filtering
|
|
314
|
+
and the `MAX(seq_id)` ledger-revision stamp remain in place; see the
|
|
315
|
+
[integration notes](docs/macrame-0.18-integration.md) for the adopted fields
|
|
316
|
+
and the KV deferral.
|
|
311
317
|
|
|
312
318
|
## v0.8.1–v0.8.14 Highlights — the dogfood batch
|
|
313
319
|
|
|
@@ -3,6 +3,8 @@ name = "core_indexer"
|
|
|
3
3
|
version.workspace = true
|
|
4
4
|
edition.workspace = true
|
|
5
5
|
license.workspace = true
|
|
6
|
+
homepage.workspace = true
|
|
7
|
+
repository.workspace = true
|
|
6
8
|
|
|
7
9
|
[lib]
|
|
8
10
|
name = "core_indexer"
|
|
@@ -23,7 +25,7 @@ xxhash-rust = { version = "0.8", features = ["xxh3"] }
|
|
|
23
25
|
git2 = { version = "0.21" }
|
|
24
26
|
zstd = "0.13"
|
|
25
27
|
# slotmap and arc-swap removed in v3.5 — replaced by HashMap<String, Arc<T>> + RwLock
|
|
26
|
-
macrame-db = "0.
|
|
28
|
+
macrame-db = "0.18"
|
|
27
29
|
tokio = { version = "1", features = ["rt-multi-thread"] }
|
|
28
30
|
pest = "2.7"
|
|
29
31
|
pest_derive = "2.7"
|
|
@@ -208,7 +208,7 @@ fn restore_synthetic_edges(
|
|
|
208
208
|
state: &MaterializedState,
|
|
209
209
|
stats: &mut ColdStartStats,
|
|
210
210
|
) {
|
|
211
|
-
// Defensive (source, target, kind) triple dedup. macrame 0.15 enforces
|
|
211
|
+
// Defensive (source, target, kind) triple dedup. macrame 0.15+ enforces
|
|
212
212
|
// a single open interval per triple, so duplicates are impossible in
|
|
213
213
|
// practice; the guard stays cheap in case legacy rows ever appear.
|
|
214
214
|
let mut seen: HashSet<(String, String, String)> = HashSet::new();
|
|
@@ -428,12 +428,12 @@ mod tests {
|
|
|
428
428
|
for c in &concepts {
|
|
429
429
|
map.insert(
|
|
430
430
|
c.id.clone(),
|
|
431
|
-
// macrame 0.17
|
|
431
|
+
// macrame 0.17+: NodeAttributes is #[non_exhaustive]
|
|
432
432
|
// (embedding_model defaults None, as before).
|
|
433
433
|
NodeAttributes::new(c.id.clone(), c.title.clone(), c.content.clone()),
|
|
434
434
|
);
|
|
435
435
|
}
|
|
436
|
-
// macrame 0.17
|
|
436
|
+
// macrame 0.17+: MaterializedState is #[non_exhaustive] —
|
|
437
437
|
// assemble from empty(); fields stay pub and assignable.
|
|
438
438
|
let mut state = MaterializedState::empty("2026-02-08T00:00:00.000000Z");
|
|
439
439
|
state.seq_anchor = 42;
|
|
@@ -316,19 +316,11 @@ impl CodeGraph {
|
|
|
316
316
|
// Persist to Macrame if store attached. Re-registering a synthetic
|
|
317
317
|
// edge that is already open is skipped (same fact), otherwise the
|
|
318
318
|
// re-run would abort on the single-open guard and the error would be
|
|
319
|
-
// silently dropped below.
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
// all-or-nothing batch and lose every edge in it. The underscore
|
|
325
|
-
// is stripped at this boundary; the in-memory indices are
|
|
326
|
-
// kind-agnostic, so nothing else changes.
|
|
327
|
-
// * `links` has FKs to `concepts` on both endpoints, so edges whose
|
|
328
|
-
// endpoints are not persisted concepts (e.g. `django:route:...`
|
|
329
|
-
// route nodes) cannot be asserted; the batch drops the failing
|
|
330
|
-
// write rather than failing the registration (best-effort, as
|
|
331
|
-
// before).
|
|
319
|
+
// silently dropped below. Macrame 0.18 accepts namespaced kinds, so
|
|
320
|
+
// preserve the caller's semantic edge type rather than flattening it.
|
|
321
|
+
// `links` still has FKs to `concepts` on both endpoints, so edges whose
|
|
322
|
+
// endpoints are not persisted concepts (e.g. `django:route:...` route
|
|
323
|
+
// nodes) cannot be asserted; the batch drops those best-effort.
|
|
332
324
|
if let Some(store) = self.store.as_ref() {
|
|
333
325
|
let ts_now = crate::storage::now_iso8601();
|
|
334
326
|
// Unreadable ledger → assert everything (the pre-existing
|
|
@@ -341,13 +333,12 @@ impl CodeGraph {
|
|
|
341
333
|
.collect();
|
|
342
334
|
let batch: Vec<_> = edges
|
|
343
335
|
.iter()
|
|
344
|
-
.map(|(source_id, target_id, kind)| {
|
|
345
|
-
let kind = kind.replace('_', "");
|
|
346
|
-
(source_id.clone(), target_id.clone(), kind)
|
|
347
|
-
})
|
|
348
336
|
.filter(|(source_id, target_id, kind)| {
|
|
349
337
|
!open.contains(&edge_key(source_id, target_id, kind))
|
|
350
338
|
})
|
|
339
|
+
.map(|(source_id, target_id, kind)| {
|
|
340
|
+
(source_id.clone(), target_id.clone(), kind.clone())
|
|
341
|
+
})
|
|
351
342
|
.map(|(source_id, target_id, kind)| {
|
|
352
343
|
macrame::graph::EdgeAssertion::new(
|
|
353
344
|
source_id.as_str(),
|
|
@@ -528,10 +528,11 @@ fn synthetic_pairs_not_persisted_as_calls_and_stale_edges_retracted() {
|
|
|
528
528
|
.map(|(_, _, k)| k)
|
|
529
529
|
.collect()
|
|
530
530
|
};
|
|
531
|
-
//
|
|
531
|
+
// Macrame 0.18 preserves the caller's edge-kind spelling, including
|
|
532
|
+
// underscores, instead of collapsing distinct kinds at this boundary.
|
|
532
533
|
assert_eq!(
|
|
533
534
|
kinds_for(&run_id, &combine_id),
|
|
534
|
-
vec!["
|
|
535
|
+
vec!["DEPENDS_ON".to_string()]
|
|
535
536
|
);
|
|
536
537
|
assert_eq!(kinds_for(&main_id, &run_id), vec!["CALLS".to_string()]);
|
|
537
538
|
|
|
@@ -556,7 +557,26 @@ fn synthetic_pairs_not_persisted_as_calls_and_stale_edges_retracted() {
|
|
|
556
557
|
assert_eq!(retired, 1, "only the legacy synthetic-as-CALLS row closes");
|
|
557
558
|
assert_eq!(
|
|
558
559
|
kinds_for(&run_id, &combine_id),
|
|
559
|
-
vec!["
|
|
560
|
+
vec!["DEPENDS_ON".to_string()]
|
|
560
561
|
);
|
|
561
562
|
assert_eq!(kinds_for(&main_id, &run_id), vec!["CALLS".to_string()]);
|
|
562
563
|
}
|
|
564
|
+
|
|
565
|
+
#[test]
|
|
566
|
+
fn namespaced_synthetic_edge_kind_is_persisted_verbatim() {
|
|
567
|
+
let (graph, _dir) = graph_with_temp_store();
|
|
568
|
+
index_source(&graph, "def handler(): pass\n", "views.py");
|
|
569
|
+
let source = "views.py::module";
|
|
570
|
+
let target = "views.py::handler";
|
|
571
|
+
graph
|
|
572
|
+
.register_synthetic_edge(source, target, "synthetic:django:handles")
|
|
573
|
+
.expect("register namespaced kind");
|
|
574
|
+
|
|
575
|
+
let store = graph.store.as_ref().unwrap();
|
|
576
|
+
let open = store
|
|
577
|
+
.open_edge_triples(&crate::storage::now_iso8601())
|
|
578
|
+
.expect("read open edges");
|
|
579
|
+
assert!(open
|
|
580
|
+
.iter()
|
|
581
|
+
.any(|(s, t, kind)| { s == source && t == target && kind == "synthetic:django:handles" }));
|
|
582
|
+
}
|
|
@@ -845,7 +845,7 @@ fn analyze(
|
|
|
845
845
|
}
|
|
846
846
|
|
|
847
847
|
fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> AnalyzeOutcome {
|
|
848
|
-
use crate::types::Language;
|
|
848
|
+
use crate::types::{Language, ParseQuality};
|
|
849
849
|
use std::fs;
|
|
850
850
|
|
|
851
851
|
let config = active_config();
|
|
@@ -901,6 +901,10 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
901
901
|
// reported plain success.
|
|
902
902
|
let mut failures: Vec<String> = Vec::new();
|
|
903
903
|
let mut panicked_workers: usize = 0;
|
|
904
|
+
// Reconcile absent ledger concepts only after a complete, clean scan. A
|
|
905
|
+
// walk, file-read, extraction, worker, or recovered-parse failure must
|
|
906
|
+
// never make good concepts look stale merely because source was missed.
|
|
907
|
+
let mut reconciliation_safe = root_path.is_dir();
|
|
904
908
|
let mut all_concepts: Vec<macrame::ConceptUpsert> = Vec::new();
|
|
905
909
|
|
|
906
910
|
if root_path.is_dir() {
|
|
@@ -915,7 +919,14 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
915
919
|
for entry in project_walk(root, &config.project, extra_excludes) {
|
|
916
920
|
match entry {
|
|
917
921
|
Ok(entry) => {
|
|
918
|
-
|
|
922
|
+
let file_type = match entry.file_type() {
|
|
923
|
+
Some(file_type) => file_type,
|
|
924
|
+
None => {
|
|
925
|
+
reconciliation_safe = false;
|
|
926
|
+
continue;
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
if !file_type.is_file() {
|
|
919
930
|
continue;
|
|
920
931
|
}
|
|
921
932
|
let path = entry.path();
|
|
@@ -931,26 +942,11 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
931
942
|
if CodeGraph::ts_language(&language).is_none() {
|
|
932
943
|
continue;
|
|
933
944
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
&path.to_string_lossy(),
|
|
940
|
-
);
|
|
941
|
-
tasks.push(FileTask {
|
|
942
|
-
path: canon,
|
|
943
|
-
source,
|
|
944
|
-
language,
|
|
945
|
-
});
|
|
946
|
-
}
|
|
947
|
-
} else {
|
|
948
|
-
// Files without extension (Dockerfile, CMakeLists.txt)
|
|
949
|
-
let language = Language::from_filename(&path.to_string_lossy());
|
|
950
|
-
if language != Language::OtherTen
|
|
951
|
-
&& CodeGraph::ts_language(&language).is_some()
|
|
952
|
-
{
|
|
953
|
-
if let Ok(source) = fs::read_to_string(path) {
|
|
945
|
+
match fs::read_to_string(path) {
|
|
946
|
+
Ok(source) => {
|
|
947
|
+
// F14: mint the canonical id form at write time —
|
|
948
|
+
// the walk's spelling embeds the root used (`.`
|
|
949
|
+
// vs absolute), so it is normalized here.
|
|
954
950
|
let canon = crate::graph::module_resolution::canonical_file_form(
|
|
955
951
|
&path.to_string_lossy(),
|
|
956
952
|
);
|
|
@@ -960,10 +956,41 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
960
956
|
language,
|
|
961
957
|
});
|
|
962
958
|
}
|
|
959
|
+
Err(e) => {
|
|
960
|
+
reconciliation_safe = false;
|
|
961
|
+
failures.push(format!("{}: {e}", path.display()));
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
} else {
|
|
965
|
+
// Files without extension (Dockerfile, CMakeLists.txt)
|
|
966
|
+
let language = Language::from_filename(&path.to_string_lossy());
|
|
967
|
+
if language != Language::OtherTen
|
|
968
|
+
&& CodeGraph::ts_language(&language).is_some()
|
|
969
|
+
{
|
|
970
|
+
match fs::read_to_string(path) {
|
|
971
|
+
Ok(source) => {
|
|
972
|
+
let canon =
|
|
973
|
+
crate::graph::module_resolution::canonical_file_form(
|
|
974
|
+
&path.to_string_lossy(),
|
|
975
|
+
);
|
|
976
|
+
tasks.push(FileTask {
|
|
977
|
+
path: canon,
|
|
978
|
+
source,
|
|
979
|
+
language,
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
Err(e) => {
|
|
983
|
+
reconciliation_safe = false;
|
|
984
|
+
failures.push(format!("{}: {e}", path.display()));
|
|
985
|
+
}
|
|
986
|
+
}
|
|
963
987
|
}
|
|
964
988
|
}
|
|
965
989
|
}
|
|
966
|
-
Err(
|
|
990
|
+
Err(e) => {
|
|
991
|
+
reconciliation_safe = false;
|
|
992
|
+
failures.push(format!("project walk: {e}"));
|
|
993
|
+
}
|
|
967
994
|
}
|
|
968
995
|
}
|
|
969
996
|
|
|
@@ -1052,6 +1079,18 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
1052
1079
|
let mut proj = (*graph.snapshot()).clone();
|
|
1053
1080
|
for chunk_results in all_results {
|
|
1054
1081
|
for (fragment, concepts) in chunk_results {
|
|
1082
|
+
// Tree-sitter can recover a partial projection from
|
|
1083
|
+
// malformed source without returning an extraction
|
|
1084
|
+
// error. Keep old ledger concepts until every file is
|
|
1085
|
+
// cleanly parsed; absence from a recovered AST is not
|
|
1086
|
+
// reliable evidence of deletion.
|
|
1087
|
+
if fragment
|
|
1088
|
+
.modules
|
|
1089
|
+
.values()
|
|
1090
|
+
.any(|module| module.parse_quality != ParseQuality::Clean)
|
|
1091
|
+
{
|
|
1092
|
+
reconciliation_safe = false;
|
|
1093
|
+
}
|
|
1055
1094
|
let entity_count = fragment.functions.len()
|
|
1056
1095
|
+ fragment.classes.len()
|
|
1057
1096
|
+ fragment.imports.len()
|
|
@@ -1106,6 +1145,8 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
1106
1145
|
// building them).
|
|
1107
1146
|
{
|
|
1108
1147
|
let mut projection = (*graph.snapshot()).clone();
|
|
1148
|
+
let mut current_concept_ids = HashSet::new();
|
|
1149
|
+
let mut concept_flush_succeeded = true;
|
|
1109
1150
|
// Dotted-name resolution (resolve_imports, resolve_all_calls) is O(1)
|
|
1110
1151
|
// per lookup once this suffix index is built; without it the cascade
|
|
1111
1152
|
// scans every module per import (v0.8 P1: 8.3s of the 46s benchmark).
|
|
@@ -1119,7 +1160,11 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
1119
1160
|
// Concept JSON v2 flush — post-cascade, pre-edge (FK order).
|
|
1120
1161
|
if let Some(ref store) = graph.store {
|
|
1121
1162
|
let v2 = crate::storage::build_v2_concepts_all(&projection);
|
|
1122
|
-
|
|
1163
|
+
current_concept_ids = v2.iter().map(|concept| concept.id.clone()).collect();
|
|
1164
|
+
if let Err(e) = store.upsert_concepts_bulk(&v2) {
|
|
1165
|
+
concept_flush_succeeded = false;
|
|
1166
|
+
eprintln!("[diag] v2 concept flush failed: {e:?}");
|
|
1167
|
+
}
|
|
1123
1168
|
}
|
|
1124
1169
|
// Persist resolved edges to Macrame store
|
|
1125
1170
|
if let Err(e) = graph.persist_edges(&projection) {
|
|
@@ -1164,6 +1209,19 @@ fn analyze_inner(root: &str, create_store: bool, extra_excludes: &[String]) -> A
|
|
|
1164
1209
|
Ok(_) => {}
|
|
1165
1210
|
Err(e) => eprintln!("[diag] non-canonical retraction failed: {e:?}"),
|
|
1166
1211
|
}
|
|
1212
|
+
// Retire stale canonical rows (notably line-addressed imports)
|
|
1213
|
+
// only when every source was walked/read/extracted and the v2
|
|
1214
|
+
// projection flush succeeded. Otherwise missing data in this
|
|
1215
|
+
// run is not evidence that a ledger concept was deleted.
|
|
1216
|
+
if reconciliation_safe && failures.is_empty() && concept_flush_succeeded {
|
|
1217
|
+
match store.retire_stale_file_concepts(¤t_concept_ids) {
|
|
1218
|
+
Ok(n) if n > 0 => eprintln!(
|
|
1219
|
+
"[coderadar] retired {n} stale file concept(s) absent from the fresh index"
|
|
1220
|
+
),
|
|
1221
|
+
Ok(_) => {}
|
|
1222
|
+
Err(e) => eprintln!("[diag] stale concept retraction failed: {e:?}"),
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1167
1225
|
// R2-2: edge retraction. The persist above is assert-only
|
|
1168
1226
|
// and the concept retractions only close edges of removed
|
|
1169
1227
|
// entities, so an edge whose endpoints both survive but
|
|
@@ -1337,7 +1395,31 @@ fn remove_file(file_path: &str) -> PyResult<PyObject> {
|
|
|
1337
1395
|
// F14: remove by the canonical form or the walk-form entry is
|
|
1338
1396
|
// never found (forward-slash input vs `\` -joined stored ids).
|
|
1339
1397
|
let canonical = crate::graph::module_resolution::canonical_file_form(file_path);
|
|
1340
|
-
let removed = graph.remove_file(&canonical);
|
|
1398
|
+
let mut removed = graph.remove_file(&canonical);
|
|
1399
|
+
// The in-memory projection may have lost track of concepts written by
|
|
1400
|
+
// an interrupted or older indexer. Use the indexed `extra.file_path`
|
|
1401
|
+
// metadata to retire any such current rows as part of file deletion.
|
|
1402
|
+
if let Some(store) = graph.store.as_ref() {
|
|
1403
|
+
match store.live_concept_ids_for_file(&canonical) {
|
|
1404
|
+
Ok(ledger_ids) => {
|
|
1405
|
+
let known: std::collections::HashSet<&str> =
|
|
1406
|
+
removed.iter().map(String::as_str).collect();
|
|
1407
|
+
let stale: Vec<String> = ledger_ids
|
|
1408
|
+
.into_iter()
|
|
1409
|
+
.filter(|id| !known.contains(id.as_str()))
|
|
1410
|
+
.collect();
|
|
1411
|
+
if !stale.is_empty() {
|
|
1412
|
+
match store.retire_entities(&stale) {
|
|
1413
|
+
Ok(_) => removed.extend(stale),
|
|
1414
|
+
Err(e) => eprintln!(
|
|
1415
|
+
"[diag] failed to retire stale concepts for {canonical}: {e:?}"
|
|
1416
|
+
),
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
Err(e) => eprintln!("[diag] indexed concept lookup failed for {canonical}: {e:?}"),
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1341
1423
|
let dict = PyDict::new(py);
|
|
1342
1424
|
dict.set_item("entities_removed", removed.len())?;
|
|
1343
1425
|
dict.set_item("removed_ids", removed)?;
|