MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / attach_result_source

Function attach_result_source

src/mcp/mcp.c:8857–8917  ·  view source on GitHub ↗

Attach source or context lines to a search result JSON item. */

Source from the content-addressed store, hash-verified

8855
8856/* Attach source or context lines to a search result JSON item. */
8857static void attach_result_source(yyjson_mut_doc *doc, yyjson_mut_val *item, search_result_t *r,
8858 int mode, int context_lines, const char *root_path) {
8859 enum { MODE_FULL = 1 };
8860 if (r->start_line <= 0 || r->end_line <= 0) {
8861 return;
8862 }
8863 char abs_path[CBM_SZ_1K];
8864 snprintf(abs_path, sizeof(abs_path), "%s/%s", root_path, r->file);
8865
8866 /* Containment: a search result whose indexed path resolves outside the
8867 * project root (a `..` segment, or a symlink/junction that discovery
8868 * followed) must not be read back into the response. Same guard the
8869 * snippet path already uses. */
8870 if (!cbm_path_within_root(root_path, abs_path)) {
8871 return;
8872 }
8873
8874 if (mode == MODE_FULL) {
8875 /* Cap each hit's source at a match-anchored window: uncapped
8876 * whole-symbol dumps ran to 5.7KB × N hits (142KB responses). The
8877 * complete symbol stays one get_code_snippet call away;
8878 * source_start/source_truncated make the cut explicit. */
8879 enum { SC_FULL_MAX_LINES = 60, SC_FULL_LEAD = 5 };
8880 int s = r->start_line;
8881 int e = r->end_line;
8882 bool truncated = false;
8883 if (e - s + 1 > SC_FULL_MAX_LINES) {
8884 if (r->match_count > 0 && r->match_lines[0] - SC_FULL_LEAD > s) {
8885 s = r->match_lines[0] - SC_FULL_LEAD;
8886 }
8887 e = s + SC_FULL_MAX_LINES - 1;
8888 if (e > r->end_line) {
8889 e = r->end_line;
8890 }
8891 truncated = true;
8892 }
8893 char *source = read_file_lines(abs_path, s, e);
8894 if (source) {
8895 sanitize_ascii(source);
8896 yyjson_mut_obj_add_strcpy(doc, item, "source", source);
8897 free(source);
8898 if (truncated) {
8899 yyjson_mut_obj_add_int(doc, item, "source_start", s);
8900 yyjson_mut_obj_add_bool(doc, item, "source_truncated", true);
8901 }
8902 }
8903 } else if (context_lines > 0 && r->match_count > 0) {
8904 int ctx_start = r->match_lines[0] - context_lines;
8905 int ctx_end = r->match_lines[r->match_count - SKIP_ONE] + context_lines;
8906 if (ctx_start < SKIP_ONE) {
8907 ctx_start = SKIP_ONE;
8908 }
8909 char *ctx = read_file_lines(abs_path, ctx_start, ctx_end);
8910 if (ctx) {
8911 sanitize_ascii(ctx);
8912 yyjson_mut_obj_add_strcpy(doc, item, "context", ctx);
8913 yyjson_mut_obj_add_int(doc, item, "context_start", ctx_start);
8914 free(ctx);

Callers 1

assemble_search_outputFunction · 0.85

Calls 3

cbm_path_within_rootFunction · 0.85
read_file_linesFunction · 0.85
sanitize_asciiFunction · 0.85

Tested by

no test coverage detected