mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-19 05:40:03 +08:00
Adds three changes that landed together in PR #257, with a JSON-escape hardening on the new File node properties so unusual file extensions can't produce malformed output. Mode A — search_graph results expose node properties_json --------------------------------------------------------- emit_search_results in src/mcp/mcp.c now calls enrich_node_properties for each result and parks the parsed yyjson_doc* in an out-array. The two exit paths in handle_search_graph (success and sq_type_error) walk that array and yyjson_doc_free each entry after yy_doc_to_str runs, so zero-copy strings stay alive until serialization completes. Callers no longer have to round-trip through get_code_snippet just to inspect a node's properties. Mode B — Cypher bare edge return surfaces full properties JSON -------------------------------------------------------------- binding_get_virtual in src/cypher/cypher.c returns e->properties_json (or "{}" if absent) when prop is NULL, instead of "". `RETURN r` on an edge variable is now actually useful for inspecting timestamps, weights, etc. without naming each property up front. Temporal data on FILE_CHANGES_WITH edges and File nodes ------------------------------------------------------- cbm_change_coupling_t gains last_co_change. cbm_commit_files_t and the internal commit_t gain a timestamp field. Both git-log paths (libgit2 and popen --pretty=format:COMMIT:%H:%ct) populate it. cbm_compute_change_coupling carries a parallel pair_timestamps hash table and writes the max timestamp to last_co_change. The edge properties JSON now includes "last_co_change":<unix-epoch>. cbm_pipeline_githistory_compute additionally aggregates per-file change_count and last_modified into a new cbm_file_temporal_t array exposed via result->file_temporal. cbm_pipeline_githistory_apply upserts those values onto matching File nodes so callers can run hotspot queries (most-changed, recently-changed) directly. Both the sequential cbm_pipeline_pass_githistory and the parallel run_githistory in pipeline.c free file_temporal and trigger apply when either couplings or temporal entries are present. The extension stored on the File node properties is now JSON-escaped via cbm_json_escape before snprintf'ing into the props blob. The original PR concatenated the raw extension; a hypothetical path with a quote or backslash in the extension would have produced malformed JSON. Practical risk was tiny (real extensions never contain those characters) but the escape is cheap and correct. Tests ----- - githistory_coupling_carries_last_co_change pins last_co_change as the max of the per-pair commit timestamps even when an unrelated pair sits between them in the input order. - cypher_bare_edge_return_exposes_properties_json regresses Mode B by asserting `RETURN r` on an HTTP_CALLS edge surfaces its url_path in the response. - tool_search_graph_includes_node_properties regresses Mode A by asserting search_graph's response contains the signature/return_type/ is_exported keys from a HandleRequest node's properties_json. Existing githistory tests had their cbm_commit_files_t initializers extended with a zero timestamp (backward-compatible — last_co_change falls back to 0 for callers that don't supply timestamps). Cherry-picked from #257; renamed the timestamp field types to long long for portability across 32-/64-bit time_t platforms, used the existing cbm_json_escape utility instead of raw concatenation for the extension, and added explicit tests for all three changes. Closes #257. Co-authored-by: Adam Schulte <adamschulte148@gmail.com>