Repository navigation
Implement to support with claude desktop - #4
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (11)
WalkthroughThe MCP crate now uses rmcp transports and session-bound workspace operations. The CLI supports asynchronous ChangesMCP session and CLI lifecycle
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant serve_stdio
participant CodegraphServer
participant Session
MCPClient->>serve_stdio: Send MCP tool request
serve_stdio->>CodegraphServer: Forward rmcp call
CodegraphServer->>Session: Apply session operation
Session-->>CodegraphServer: Return state or tool data
CodegraphServer-->>serve_stdio: Return rmcp result
serve_stdio-->>MCPClient: Send MCP response
Possibly related PRs
Suggested reviewers: Poem
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eaning magic features (#51) * Implement dynamic dispatch flag + fan-out * Enrich Go semantics: method-set matching, function values, imports, concurrency markers - Method-set matching cho implicit interface: receiver_fn hook lưu receiver base type vào Symbol.type_name (`func (f *File) Write` → "File"); khai báo method trong interface body là node `method_elem` (không phải method_declaration) — giờ được extract với scope đúng vào interface symbol. build_go_method_sets tính structural typing: T implements I ⟺ method names(I) ⊆ method names(T); w.Write() fan-out chỉ tới các type thỏa thay vì naive CHA (fallback giữ nguyên khi method-set chưa đủ dữ liệu). - Function value tracking: go_fn_ptr_assign bắt `handler := process` / `handler = process` → PointerAssign fan-out (dùng chung machinery C). - Package/import: FileDeps { package, imports } mới trong ParseResult; go_file_deps đọc package_clause + import_spec (alias→path); alias_qualified_name resolve `orders.Get` qua import alias cho in-repo packages (match segment cuối path). - Concurrency markers: MARKER_GO/MARKER_DEFER (Marker::Go/Defer) vào chain cho `go f()`/`defer f()`; select_statement wired vào switch machinery (communication_case); EffectType::Panic cho panic/log.Fatal/os.Exit. Tests: 5 extractor (receiver type, interface method scope, fn value, file deps, markers) + 2 e2e graph (method-set precision, import alias). Clippy sạch, fmt xong. * Go method-set: match signature, không chỉ tên + gom LangSpec thành nhóm - Symbol.sig_key: signature key chuẩn hóa `(param_types)(result_types)` (bỏ tên param) qua sig_key_fn hook; go_signature_key dùng chung cho method_declaration/method_elem/function_declaration. build_go_method_sets thỏa interface ⟺ (name, sig_key) khớp — `Wrong.Read(string) string` không còn bị coi là implement `Reader.Read([]byte) (int, error)`. Thiếu key nào → fallback name-only (lenient); interface 0 method → skip. - LangSpec refactor: gom 3 nhóm base / hooks (HookSpec — các Option<fn>, HookSpec::none()) / markers (MarkerSpec — control-flow kinds + field names, MarkerSpec::dflt()); LangSpec::dflt() const + FRU hợp lệ trong static. 14 language spec chỉ khai field KHÁC default — thêm hook mới không còn phải sửa 14 file. * Rust semantic enrichment: field/param typing, use indexing, cross-file impl linking, sig_key - decls += field_declaration/parameter/let_declaration: struct field, tham số và local giờ là symbol có type_name (từ field `type`) — tie-break field_declared_type resolve `db.query()` theo type của `db`. Parameter lấy tên từ field `pattern` TRƯỚC name_type_fallback (tránh lấy nhầm tên kiểu). - rust_file_deps: extract `use` (alias = `as` alias hoặc segment cuối); import_alias_candidates hỗ trợ `Type::method` — `use crate::storage::Database` + `Database::new()` resolve về method của class Database (Alias). - link_impls_globally: impl linking chuyển lên global ingest — `impl Worker` khác file với `struct Worker` vẫn nối (type_ref → def, re-parent methods). - rust_signature_key: `(params)(return)` cho method/fn (self → "self") — nguyên liệu trait matching theo signature. * Python semantic enrichment + persist dynamic indexes qua reopen Python (theo review gaps): - param_container_kinds: `parameters` container → Parameter symbols (identifier / typed_parameter / default_parameter, type từ type hint) — field/param typing cho tie-break resolution. - field_from_self_attr: `self.attr = Database()` → Field symbol scope vào class, type từ callee text — instance-attr typing. - py_file_deps: import/import-as/from-import → FileDeps (alias→path), ăn vào import_alias_candidates sẵn có. - py_superclasses: `class File(Writer)` → impl_trait "Writer" — inheritance fan-out qua machinery impl_index (giống C++ base class). Persistence (fix: dynamic indexes chỉ ở RAM, MCP restart là mất): - Storage trait + sqlite (sg_file_deps/sg_fn_ptr_assigns) + in_memory: persist ĐẦU VÀO thô FileDeps + FnPtrAssigns theo file path. - rebuild() khi open: rebuild file_imports/fn_ptr_index từ blob + link_impls_globally/impl_index/go_impls từ sg_symbols — resolution quality giữ nguyên sau restart. E2e: dynamic_indexes_survive_reopen. * Rust config review fixes: trait-declared methods + macro invocations Review bằng fixture "thật" (trait + impl + macro + closure + async) phát hiện: - function_signature_item (method KHAI BÁO trong trait) không được extract — không có symbol scope vào Interface nên fan-out Rust không bao giờ fire trên code thật (các test trước dùng synthetic symbols). Thêm vào decls → trigger Interface như Go method_elem. - macro_invocation không phải call (println!/vec! mất hoàn toàn) — thêm CallRule với rust_macro_call_name (`println!`). - E2E extraction thật: trait Repo{ping} + 2 impl → r.ping() fan-out cả hai (HierarchyFanOut) — chứng minh path thật chạy, không chỉ synthetic. - Cập nhật chain expectation test cũ: cg_t!/cg_d! giờ là call thật. Còn lại (defer): closure/callable tracking (cb()), generic instantiation, associated type semantics, UFCS. * Persist file_deps/fn_ptr_assigns cho MỌI storage backend Trước đó chỉ sqlite + in_memory implement — lmdb/postgres/mysql/redis rơi về no-op default = mất dynamic indexes khi reopen trên các backend đó. - lmdb: 2 named DBI (sg_file_deps/sg_fn_ptr_assigns) + set/all (cursor iter) + clear_entities. - postgres/mysql: bảng sg_file_deps/sg_fn_ptr_assigns (repo_id, path) PK, CREATE TABLE IF NOT EXISTS idempotent khi mở repo (không cần migration tay); mysql dùng ON DUPLICATE KEY UPDATE; clear_entities thêm 2 bảng. - redis: 2 hash keys (filedeps/fnptpassigns) + DEL trong clear_entities. - cached.rs: forward 4 methods xuống inner storage (trước đây rơi về default no-op → bypass backend thật!). - Test roundtrip in_memory (set/all/clear); build + test --all-features. * callers()/impact xuyên dyn-trait: fan-out fire theo receiver_text + dyn_callers index Review qua MCP index thật (codegraph-rs tự index chính nó) phát hiện: - `callers(set_file_deps)` trả rỗng dù ingest_with_progress gọi nó qua `dyn Storage` — call qua trait object bị resolve Single vì is_method_dispatch check `call_name.contains('.')` nhưng extractor đã rút call_name còn bare, trong khi receiver_text vẫn giữ receiver. - Fix 1: is_method_dispatch = receiver_text.is_some() || call_name.contains('.') → fan-out fire cho dyn-trait call. - Fix 2: dyn_callers (callee → callers) build từ call_meta khi ingest, scan call records khi rebuild; callers_resumable merge vào pending (dedup qua visited) → callers()/impact() thấy caller xuyên dyn-trait/interface/fn-ptr. - E2E: callers() của từng impl method thấy dyn caller (trước đây rỗng). Note vận hành: MCP server đang chạy bị MDB_BAD_RSLOT sau re-index in-process — reader locktable stale, cần restart MCP server (issue riêng, chưa xử lý). * Java + JavaScript/TypeScript semantic enrichment Review setup vs machinery Go/Rust/Python đã có — lấp các gap: Java (typing đã tốt nhất: field/param/local + annotations + implements): - java_supers: gộp extends (superclass) + implements vào impl_trait — inheritance fan-out qua machinery C++-base (superclass đứng trước). - java_signature_key: (params)(return) — tên param bỏ. - java_file_deps: import (bỏ static/wildcard) → FileDeps; strip keyword "extends" khỏi superclass text. JavaScript/TypeScript: - param_container_kinds formal_parameters: js identifier/rest_pattern, ts required/optional_parameter (name từ field pattern, type từ type_annotation — strip ':' + '?'). Trước đây params KHÔNG được extract. - js_file_deps (share TS): import default/named-as/namespace → FileDeps. Bug kèm theo: class_type_name cũ không bao giờ match JS thuần (class_heritage không có extends_clause — chỉ TS có); js_extends xử lý cả 2 grammar. - js_extends → impl_trait: inheritance fan-out cho class extends. - js_fn_value_assign: `handler = process` / `const h = process` (identifier thuần) → PointerAssign machinery. Tests: 3 fixture mới (java supers/sig/imports; js params/imports/extends/ fn-value; ts typed params + interface method scope). 20/21 suite (Redis env). * PHP/Ruby/Lua/Scala semantic enrichment — hoàn thiện fan-out toàn ngôn ngữ PHP (typing đã tốt: params/property/variable): - php_supers: base_clause (extends) + class_interface_clause (implements) — LÀ NODE KIND không phải field name (child_by_field_name trả None!) — inheritance fan-out. - php_signature_key + php_use_deps (namespace_use_declaration, bỏ function/const/wildcard). Ruby (mỏng nhất — params chưa từng extract): - param_container_kinds method_parameters: identifier/optional_parameter/ keyword_parameter/splat_parameter. - ruby_superclass → impl_trait (bỏ dynamic superclass `< Struct.new(..)`). - ruby_require_deps: require/require_relative → FileDeps. Lua: - param_container_kinds "parameters" (kind thật, không phải parameter_list). - lua_require_deps: `local mod = require('mod')` ghép variable_list với expression_list theo vị trí. - lua_fn_value_assign: `handler = process` → PointerAssign. Scala: - scala_supers: field "extend" (extends_clause là node kind, field tên "extend") — extends B with T → "B,T". - scala_signature_key + scala_file_deps (import_declaration, selector `.{a, b => c}`); token keyword "import" có cùng kind — guard child_count. Bài học chung: field name vs node kind khác nhau từng grammar — luôn dump AST trước khi wire hook. * Swift/C# semantic enrichment — đủ 14/14 ngôn ngữ Swift (trước đây gần trống — không hooks): - decls += protocol_function_declaration: method KHAI BÁO trong protocol scope vào Interface → fan-out (đúng bug Rust từng mắc). - swift_supers: inheritance_specifier (`class FileRepo: BaseRepo, Repo`) → impl_trait — protocol conformance đi cùng cơ chế fan-out. - swift_signature_key: Swift dùng TRÙNG tên field "name" cho tên param VÀ type (lấy field "name" cuối); match cả protocol_function_declaration; return = user_type sau token "->". - swift_import_deps: import_declaration → FileDeps. C# (typing/annotations sẵn tốt): - csharp_bases: base_list (node kind, unnamed child) → impl_trait (base class + interfaces, strip generic). - csharp_signature_key: return field là "returns" (không phải "type"). - csharp_using_deps: `using App.Repos` + alias form `using Db = App.Data`. Tests: 2 fixture mới (swift protocol/supers/sig/imports; csharp bases/sig/ using). 25/25 dynamic_dispatch, 20/21 workspace (Redis env-only). * FunctionValue + member assignment + MARKER_AWAIT (priority 1/3/6) A. FunctionValue cho 4 ngôn ngữ còn thiếu: - Python: `handler = process` (identifier=identifier) + `self.handler = process` (member, var = "self.handler"). - Ruby: CHỈ `handler = method(:process)` — plain `x = process` là LỜI GỌI trong Ruby, không track. - Java: `Runnable r = this::run` — method_reference, target = identifier cuối (không phụ thuộc field name grammar). - C#: `Action handler = Process` — value là identifier UNNAMED (không có field "value") — lấy identifier con cuối khác name. B. Member fn assignment `obj.handler = fn`: - Mở guard fn_ptr_index (bỏ `!contains('.')`) — lookup theo call_name bare lẫn dotted. - js/ts: member_expression left → key full dotted text (`Foo.prototype.run`). - lua: text chứa '.' → full text; bracket `handlers["read"]` skip. - python: self.attr. C. MARKER_AWAIT (Marker::Await = 27): MarkerSpec.await_kinds — python "await", js/ts/csharp/swift "await_expression" (dump AST xác nhận); walk_chain push AWAIT trước call như GO/DEFER → edge mang ngữ cảnh async boundary. E2E: member_fn_assignment_resolves_dotted_call — `obj.handler = process` + `obj.handler()` → PointerAssign (trước đây guard chặn). 25/25 dynamic_dispatch (2 test mới), 20/21 workspace (Redis env-only). * C/C++ enrichment batch 1-4: include graph, fn-ptr mở rộng, sig_key, virtual precision 1. c_include_deps: #include "foo.h" / <openssl/ssl.h> → FileDeps (path nguyên văn, alias = tên file không extension) — include graph qua machinery file_imports; C + C++ share. 2. c_fn_ptr_assign mở rộng: LHS field_expression (`obj.handler` — dotted key, ăn guard fn_ptr_index mới) + pointer_expression (`*handler` → "handler"); RHS `&f` address-of + `&ns::cb` qualified. 3. cpp_signature_key: params từ function_declarator (function_definition 1 tầng declarator; method inline field_declaration cũng 1 tầng — dump mới thấy, không phải 2); return field "type". 4. Virtual precision trong collect_fanout (C++ path): nếu CÓ candidate mang keyword virtual/override (signature chứa — extractor lưu dòng khai báo) → chỉ giữ virtual candidates + base decl; không keyword nào → giữ hết (soundness fallback). Loại non-virtual cùng tên trong hierarchy. E2E: cpp_virtual_filter_prefers_override_candidates (D2 non-virtual bị loại). Tests: 26/26 dynamic_dispatch (2 mới), 121/121 graph lib, 20/21 workspace (Redis env-only). * Web UI: dynamic-dispatch badges, Call sites/Pattern/Trace tabs, search pagination + annotation Explore UI (SvelteKit + GraphQL) lộ đầy đủ query surface mới: - Flow tab: mỗi call hiện badge resolvedVia ([dyn]/[fn-ptr]/[unresolved]/…) + candidate chips click-to-navigate (searchExact). GraphQL enum là SCREAMING_SNAKE_CASE — smoke query bắt được bug casing lowercase ban đầu. - Tab Call sites (references): tìm callers theo call name — thấy cả unresolved/library + dynamic calls; prefill theo symbol name. - Tab Pattern (searchFlow): tìm hàm theo chain pattern (markers/tên/id). - Tab Trace (traceFullFlow — targetId arg): debug-style paths caller → target, indent theo stackDepth, icon theo action (CALL/RETURN/THROW/BRANCH/LOOP), màu theo PathEnding; chọn caller depth. - SymbolSearch: Load more (offset pagination), "continue" khi timed_out (resumable cursor), source by name | by annotation (graphcodeSearchByAnnotation). Smoke qua server thật: flow(ingest_with_progress) có 11 HIERARCHY_FAN_OUT calls với 7 candidates (dyn Storage backends), trace 3 paths, annotation "derive" 196 kết quả, references set_file_deps 2 callers. svelte-check 0 errors, build-web assets embed, workspace tests 20/21 (Redis env-only). * C/C++ batch #6 + #8: declaration–definition linking + namespace-qualified call #6 link_cpp_decl_def (global, chạy cả ingest lẫn rebuild): - `void Service::run() {}` trong .cpp (definition, có chain) nối với method khai báo trong .hpp (declaration, không chain): cùng tên + cùng sig_key (khi cả hai có) + khác file → def re-parent về scope của decl (class/ namespace) + reclassify theo kind của decl; decl.type_ref → def. - Hiệu ứng: fan-out/hierarchy thấy definition (có body/flow), class_info theo type_ref tới nơi có chain. #8 qualified call `orders::run()`: - Short-name fallback split cả '::' (rsplit ['.', ':'] bỏ segment rỗng) — trước đây "::" không split → qualified call unresolved hoàn toàn. - Namespace preference: prefix trước '::' lọc candidate theo tổ tiên Module (namespace) cùng tên hoặc file chứa prefix — `foo::run` không còn nhầm `bar::run`; không subset khớp → giữ tất cả (soundness). E2E: cpp_decl_def_linked_across_files (link đúng, pick_best ưu tiên def has-chain); cpp_qualified_call_prefers_namespace (orders::run chọn đúng namespace, không chọn bar). 123/123 graph lib, 20/21 workspace (Redis env). * C/C++ batch cuối: lambda có tên (#5), macro theo thiết kế ghi-nhận (#9-lite), typedef signature (#4-lite) #5 C++ lambda thành Function symbol: - decls/func_kinds += lambda_expression → chain riêng cho calls trong lambda body (attribution chính xác, không gộp vào enclosing fn). - anonymous_name_fn cpp_lambda_name: `auto f = [](){}` mượn tên biến — LƯU Ý init_declarator đặt tên ở field `declarator`, không phải `name` như JS variable_declarator (grammar khác nhau). #9-lite macro THEO THIẾT KẾ GHI-NHẬN (không resolve): - preproc_function_def + preproc_def → Constant symbol, signature = định nghĩa nguyên văn (`CALL(x) x()`, `MAX 10`) — macro KHÔNG phải function, invocation giữ raw call → usage tra qua call-name index (references). - Hành vi semantic do config khai báo ("LLM tự định nghĩa"): `[[effect_rules]]` trong .codegraph/config.toml (matcher + EffectType, xét trước bảng default) — test chứng minh rule Contains "CALL" → Panic (exception-like). - Không làm (đúng defer): macro expansion, conditional compilation. #4-lite typedef signature: - HookSpec thêm typedef_sig_fn; c_typedef_sig (C + C++ share): typedef + macro → signature = text định nghĩa (strip typedef/#define + ;). Hook ƯU TIÊN extract_signature (nó trả full text trước khiến hook không chạy). - fn-ptr typedef giờ giữ underlying type: `int (*handler_t)(int)` thay vì chỉ `int` từ field type. Tests: cpp_lambda_macro_typedef_batch (lambda symbol + chain + calls, macro Constant + signature + raw invocation + effect-rule config, typedef sig). 20/21 workspace (Redis env-only), clippy sạch. * MCP + GraphQL tool cấu hình effect rules runtime (LLM tự định nghĩa macro semantics) Trước đây `[[effect_rules]]` chỉ đọc được từ .codegraph/config.toml — LLM phải sửa file ngoài band rồi re-index. Giờ có tool chính tắc: - config.rs CRUD API: list_effect_rules (raw — kể cả rule lỗi) / add_effect_rule (validate matcher + EffectType, toml_edit preserve mọi section khác) / remove_effect_rule (theo index). Sau ghi: install_current cho thread hiện tại; orchestrator reload config mỗi index nên rule áp dụng từ lần re-index kế tiếp (re-classify call records). - MCP tool `codegraph_config_effects`: op list|add|remove; mô tả tool kèm ví dụ macro exception-like (contains CHECK → panic) + ghi chú áp dụng. - GraphQL mutation `configEffects(op, matcher, text, effect, index)` mirror cho web UI. Test: effect_rule_crud_roundtrip — add 2 rules → list đúng, classifier load từ file classify CHECK_OK → Panic / db.Query → SqlQuery, effect sai bị chặn (file không đổi), remove theo index, section khác (storage) nguyên vẹn. Fix bug bắt được bởi test: or_insert tạo ArrayOfTables với table rỗng dummy → rule rỗng đầu danh sách. * Bump version to v2.2.11 * Dọn debug eprintln sót (DBG by_name/DBG/DBG3/PHPDBG/SCALADBG) sau các batch debug
Summary by CodeRabbit
New Features
init,deinit, andserve --mcp.Documentation