Merge branch 'main' into fix/relative-non-code-imports

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel committed 2026-10-20 03:51:07 +02:00
commit ad178b23e6
2 files changed
+57 -1

No files matched your search

+12 -1
View File
@@ -377,6 +377,13 @@ static char *ha_build_args(const char *project, const char *token) {
return out; /* caller frees */
}
/* Closes every search augmentation that found symbols: cbm's own statement,
* outside the untrusted data block, naming the graph tool for the likely next
* question at the moment the agent greps. Facts, not commands. */
static const char HA_SEARCH_FOLLOW_UP[] =
"\n[codebase-memory] For these symbols, trace_path lists callers and callees, "
"get_code_snippet returns the exact source, and search_graph finds related symbols by name.";
/* Parse the MCP envelope returned by cbm_mcp_handle_tool and, if it is a
* successful search_graph result with >=1 hit, format a compact
* additionalContext string. Returns malloc'd text or NULL.
@@ -432,7 +439,7 @@ static char *ha_format_context(const char *envelope, const char *token, bool *is
return NULL; /* valid project, just no matching symbols */
}
char *text = malloc(4096);
char *text = malloc(4096 + sizeof(HA_SEARCH_FOLLOW_UP));
if (!text) {
yyjson_doc_free(idoc);
yyjson_doc_free(edoc);
@@ -476,6 +483,10 @@ static char *ha_format_context(const char *envelope, const char *token, bool *is
safe_path, safe_label[0] ? " " : "", safe_label);
}
}
/* off can run past the list cap when a row is truncated, so append at the
* real end; the allocation reserves room for the whole follow-up line. */
size_t used = strlen(text);
snprintf(text + used, 4096 + sizeof(HA_SEARCH_FOLLOW_UP) - used, "%s", HA_SEARCH_FOLLOW_UP);
yyjson_doc_free(idoc);
yyjson_doc_free(edoc);
+45
View File
@@ -13498,6 +13498,50 @@ TEST(cli_hook_augment_context_tracks_search_json_shape) {
PASS();
}
/* A search that found symbols closes with cbm's own follow-up line, after the
* untrusted symbol list and on its own line, naming the graph tools for the
* next question; it carries no repository-derived value. */
TEST(cli_hook_augment_context_names_graph_follow_ups) {
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
ASSERT_NOT_NULL(srv);
cbm_store_t *st = cbm_mcp_server_store(srv);
const char *proj = "hookproj";
cbm_mcp_server_set_project(srv, proj);
cbm_store_upsert_project(st, proj, "/tmp/hookproj");
cbm_node_t n = {.project = proj,
.label = "Function",
.name = "someIndexedSymbol",
.qualified_name = "hookproj.mod.someIndexedSymbol",
.file_path = "mod.py",
.start_line = 1,
.end_line = 4};
ASSERT_GT(cbm_store_upsert_node(st, &n), 0);
char *envelope =
cbm_mcp_handle_tool(srv, "search_graph",
"{\"project\":\"hookproj\",\"name_pattern\":\".*someIndexedSymbol.*\","
"\"limit\":5,\"format\":\"json\"}");
ASSERT_NOT_NULL(envelope);
bool is_error = true;
char *ctx =
cbm_hook_augment_format_context_for_testing(envelope, "someIndexedSymbol", &is_error);
ASSERT_FALSE(is_error);
ASSERT_NOT_NULL(ctx);
const char *list = strstr(ctx, "\n- hookproj.mod.someIndexedSymbol");
const char *follow = strstr(ctx, "\n[codebase-memory] For these symbols, trace_path lists "
"callers and callees, get_code_snippet returns the exact "
"source, and search_graph finds related symbols by name.");
ASSERT_NOT_NULL(list);
ASSERT_NOT_NULL(follow);
ASSERT_TRUE(follow > list);
ASSERT_NULL(strstr(follow, "someIndexedSymbol"));
ASSERT_NULL(strstr(follow, "mod.py"));
free(ctx);
free(envelope);
cbm_mcp_server_free(srv);
PASS();
}
/* Exercise the real PreToolUse + Bash route instead of calling only the
* tokenizer seam. This pins the event guard and the graph lookup path together.
*/
@@ -18479,6 +18523,7 @@ SUITE(cli) {
RUN_TEST(cli_codex_preflight_reports_heading_and_reason);
#endif
RUN_TEST(cli_hook_augment_context_tracks_search_json_shape);
RUN_TEST(cli_hook_augment_context_names_graph_follow_ups);
RUN_TEST(cli_hook_augment_bash_pretooluse_reaches_augmenter);
RUN_TEST(cli_hook_augment_bash_pattern_extractor);
RUN_TEST(cli_hook_augment_coverage_requests_machine_json);