|
21 | 21 | #include <foundation/constants.h> |
22 | 22 | #include <foundation/platform.h> |
23 | 23 | #include <mcp/mcp.h> |
| 24 | +#include <pipeline/pipeline.h> |
24 | 25 | #include <foundation/yaml.h> |
25 | 26 | #include <store/store.h> |
26 | 27 | #include <yyjson/yyjson.h> |
@@ -8791,6 +8792,44 @@ TEST(cli_hook_augment_context_tracks_search_json_shape) { |
8791 | 8792 | PASS(); |
8792 | 8793 | } |
8793 | 8794 |
|
| 8795 | +/* Exercise the real PreToolUse + Bash route instead of calling only the |
| 8796 | + * tokenizer seam. This pins the event guard and the graph lookup path together. |
| 8797 | + */ |
| 8798 | +TEST(cli_hook_augment_bash_pretooluse_reaches_augmenter) { |
| 8799 | + cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL); |
| 8800 | + ASSERT_NOT_NULL(srv); |
| 8801 | + cbm_store_t *st = cbm_mcp_server_store(srv); |
| 8802 | + ASSERT_NOT_NULL(st); |
| 8803 | + char *project = cbm_project_name_from_path("/tmp/hookproj"); |
| 8804 | + ASSERT_NOT_NULL(project); |
| 8805 | + cbm_mcp_server_set_project(srv, project); |
| 8806 | + cbm_store_upsert_project(st, project, "/tmp/hookproj"); |
| 8807 | + char qualified_name[256]; |
| 8808 | + snprintf(qualified_name, sizeof(qualified_name), "%s.mod.someIndexedSymbol", project); |
| 8809 | + cbm_node_t node = {.project = project, |
| 8810 | + .label = "Function", |
| 8811 | + .name = "someIndexedSymbol", |
| 8812 | + .qualified_name = qualified_name, |
| 8813 | + .file_path = "mod.py", |
| 8814 | + .start_line = 1, |
| 8815 | + .end_line = 4}; |
| 8816 | + ASSERT_GT(cbm_store_upsert_node(st, &node), 0); |
| 8817 | + |
| 8818 | + const char *input = "{\"hook_event_name\":\"PreToolUse\",\"tool_name\":\"Bash\"," |
| 8819 | + "\"cwd\":\"/tmp/hookproj\",\"tool_input\":{" |
| 8820 | + "\"command\":\"rg -n someIndexedSymbol .\"}}"; |
| 8821 | + char *output = cbm_hook_augment_process(srv, input); |
| 8822 | + bool reached = output && strstr(output, "hookSpecificOutput") && |
| 8823 | + strstr(output, "someIndexedSymbol") && strstr(output, "mod.py"); |
| 8824 | + free(output); |
| 8825 | + cbm_mcp_server_free(srv); |
| 8826 | + free(project); |
| 8827 | + |
| 8828 | + if (!reached) |
| 8829 | + FAIL("PreToolUse Bash must reach graph search augmentation"); |
| 8830 | + PASS(); |
| 8831 | +} |
| 8832 | + |
8794 | 8833 | TEST(cli_hook_augment_bash_pattern_extractor) { |
8795 | 8834 | char out[256]; |
8796 | 8835 |
|
@@ -10439,7 +10478,7 @@ TEST(cli_upsert_claude_hook_fresh) { |
10439 | 10478 | ASSERT_NOT_NULL(data); |
10440 | 10479 | ASSERT(strstr(data, "PreToolUse") != NULL); |
10441 | 10480 | ASSERT(strstr(data, "PostToolUse") != NULL); |
10442 | | - ASSERT(strstr(data, "\"Grep|Glob\"") != NULL); |
| 10481 | + ASSERT(strstr(data, "\"Grep|Glob|Bash\"") != NULL); |
10443 | 10482 | ASSERT(strstr(data, "\"Read\"") != NULL); |
10444 | 10483 | ASSERT(strstr(data, "\"Grep|Glob|Read\"") == NULL); |
10445 | 10484 | ASSERT_EQ(test_count_substring(data, "cbm-code-discovery-gate"), 2U); |
@@ -10953,7 +10992,7 @@ TEST(cli_upsert_claude_hook_existing) { |
10953 | 10992 |
|
10954 | 10993 | const char *data = read_test_file(settingspath); |
10955 | 10994 | ASSERT_NOT_NULL(data); |
10956 | | - ASSERT(strstr(data, "\"Grep|Glob\"") != NULL); |
| 10995 | + ASSERT(strstr(data, "\"Grep|Glob|Bash\"") != NULL); |
10957 | 10996 | ASSERT(strstr(data, "PostToolUse") != NULL); |
10958 | 10997 | ASSERT(strstr(data, "\"Read\"") != NULL); |
10959 | 10998 | /* Existing hook preserved */ |
@@ -11034,7 +11073,8 @@ TEST(cli_upsert_claude_hook_replace) { |
11034 | 11073 | const char *data = read_test_file(settingspath); |
11035 | 11074 | ASSERT_NOT_NULL(data); |
11036 | 11075 | ASSERT(strstr(data, "\"Grep|Glob|Read\"") == NULL); |
11037 | | - ASSERT(strstr(data, "\"Grep|Glob\"") != NULL); |
| 11076 | + ASSERT(strstr(data, "\"Grep|Glob|Bash\"") != NULL); |
| 11077 | + ASSERT(strstr(data, "\"Grep|Glob\"") == NULL); |
11038 | 11078 | ASSERT(strstr(data, "PostToolUse") != NULL); |
11039 | 11079 | ASSERT_EQ(test_count_substring(data, "cbm-code-discovery-gate"), 2U); |
11040 | 11080 |
|
@@ -11086,7 +11126,8 @@ TEST(cli_remove_claude_hooks) { |
11086 | 11126 |
|
11087 | 11127 | const char *data = read_test_file(settingspath); |
11088 | 11128 | ASSERT_NOT_NULL(data); |
11089 | | - ASSERT(strstr(data, "Grep|Glob|Read") == NULL); |
| 11129 | + ASSERT(strstr(data, "\"Grep|Glob|Bash\"") == NULL); |
| 11130 | + ASSERT(strstr(data, "\"Grep|Glob\"") == NULL); |
11090 | 11131 | ASSERT(strstr(data, "cbm-code-discovery-gate") == NULL); |
11091 | 11132 |
|
11092 | 11133 | test_rmdir_r(tmpdir); |
@@ -12039,6 +12080,7 @@ SUITE(cli) { |
12039 | 12080 | RUN_TEST(cli_claude_hook_commands_shell_quote_custom_config_dir); |
12040 | 12081 | RUN_TEST(cli_codex_migrates_to_single_hook_representation); |
12041 | 12082 | RUN_TEST(cli_hook_augment_context_tracks_search_json_shape); |
| 12083 | + RUN_TEST(cli_hook_augment_bash_pretooluse_reaches_augmenter); |
12042 | 12084 | RUN_TEST(cli_hook_augment_bash_pattern_extractor); |
12043 | 12085 | RUN_TEST(cli_hook_augment_lifecycle_output_contract); |
12044 | 12086 | RUN_TEST(cli_hook_augment_subagent_tier_router_contract); |
|
0 commit comments