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

Function attach_result_source

src/mcp/mcp.c:8906–8966  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

8904
8905/* Attach source or context lines to a search result JSON item. */
8906static void attach_result_source(yyjson_mut_doc *doc, yyjson_mut_val *item, search_result_t *r,
8907 int mode, int context_lines, const char *root_path) {
8908 enum { MODE_FULL = 1 };
8909 if (r->start_line <= 0 || r->end_line <= 0) {
8910 return;
8911 }
8912 char abs_path[CBM_SZ_1K];
8913 snprintf(abs_path, sizeof(abs_path), "%s/%s", root_path, r->file);
8914
8915 /* Containment: a search result whose indexed path resolves outside the
8916 * project root (a `..` segment, or a symlink/junction that discovery
8917 * followed) must not be read back into the response. Same guard the
8918 * snippet path already uses. */
8919 if (!cbm_path_within_root(root_path, abs_path)) {
8920 return;
8921 }
8922
8923 if (mode == MODE_FULL) {
8924 /* Cap each hit's source at a match-anchored window: uncapped
8925 * whole-symbol dumps ran to 5.7KB × N hits (142KB responses). The
8926 * complete symbol stays one get_code_snippet call away;
8927 * source_start/source_truncated make the cut explicit. */
8928 enum { SC_FULL_MAX_LINES = 60, SC_FULL_LEAD = 5 };
8929 int s = r->start_line;
8930 int e = r->end_line;
8931 bool truncated = false;
8932 if (e - s + 1 > SC_FULL_MAX_LINES) {
8933 if (r->match_count > 0 && r->match_lines[0] - SC_FULL_LEAD > s) {
8934 s = r->match_lines[0] - SC_FULL_LEAD;
8935 }
8936 e = s + SC_FULL_MAX_LINES - 1;
8937 if (e > r->end_line) {
8938 e = r->end_line;
8939 }
8940 truncated = true;
8941 }
8942 char *source = read_file_lines(abs_path, s, e);
8943 if (source) {
8944 sanitize_ascii(source);
8945 yyjson_mut_obj_add_strcpy(doc, item, "source", source);
8946 free(source);
8947 if (truncated) {
8948 yyjson_mut_obj_add_int(doc, item, "source_start", s);
8949 yyjson_mut_obj_add_bool(doc, item, "source_truncated", true);
8950 }
8951 }
8952 } else if (context_lines > 0 && r->match_count > 0) {
8953 int ctx_start = r->match_lines[0] - context_lines;
8954 int ctx_end = r->match_lines[r->match_count - SKIP_ONE] + context_lines;
8955 if (ctx_start < SKIP_ONE) {
8956 ctx_start = SKIP_ONE;
8957 }
8958 char *ctx = read_file_lines(abs_path, ctx_start, ctx_end);
8959 if (ctx) {
8960 sanitize_ascii(ctx);
8961 yyjson_mut_obj_add_strcpy(doc, item, "context", ctx);
8962 yyjson_mut_obj_add_int(doc, item, "context_start", ctx_start);
8963 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