mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 08:13:37 +08:00
config: Set automatic dependency-source indexing disabled by default
Define CBM_DEFAULT_AUTO_INDEX_DEPS and use it in depindex, MCP request handling, hook guidance, and the config registry. Replace the two quality presets with four exact streamlined/classic presets that state whether automatic installed dependency-source indexing is enabled. Keep rank and optional-graph benchmark ablations on the dependency-disabled baseline. Document that index_dependencies remains available and disabling automation does not delete stored dependency projects. Verification: CBM_ONLY_SUITE=cli make -f Makefile.cbm test (243 passed); CBM_ONLY_SUITE=depindex make -f Makefile.cbm test (40 passed); CBM_ONLY_SUITE=input_validation make -f Makefile.cbm test (56 passed). Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
@@ -508,6 +508,8 @@ codebase-memory-mcp config set tool_mode streamlined # concise surface; reve
|
||||
codebase-memory-mcp config set auto_index_deps true # index installed dependency APIs
|
||||
codebase-memory-mcp config set auto_dep_limit 20 # import-ranked dependency package cap; 0=unlimited
|
||||
codebase-memory-mcp config preset list # list named capability/API configurations
|
||||
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
|
||||
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
|
||||
codebase-memory-mcp config set auto_watch false # don't register background git watcher (default: true)
|
||||
codebase-memory-mcp config set default_response_format json # full JSON objects instead of compact TOON tables
|
||||
codebase-memory-mcp config reset auto_index # reset to default
|
||||
@@ -520,7 +522,9 @@ indexing and first-response codebase context are automatic when configured. Use
|
||||
directly and uses `search_graph`, then `trace_path`, then `get_code_snippet` for
|
||||
structural discovery. Automatic repository indexing obeys
|
||||
`auto_index`/`auto_index_limit`; automatic dependency indexing obeys
|
||||
`auto_index_deps`/`auto_dep_limit`.
|
||||
`auto_index_deps`/`auto_dep_limit` and is disabled by default. Explicit
|
||||
`index_dependencies` calls remain available; disabling automation does not delete
|
||||
dependency projects that are already indexed.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
|
||||
+16
-10
@@ -86,7 +86,7 @@ for any registry key):
|
||||
| `tool_mode` | `streamlined` | MCP discovery surface: `streamlined` or `classic`. |
|
||||
| `context_injection` | `true` | Include codebase schema and stats automatically in the first `search_graph` response. |
|
||||
| `rank_enabled` | `true` | Compute PageRank, LinkRank, and degree views used by relevance ranking. |
|
||||
| `auto_index_deps` | `true` | Index installed dependency APIs for cross-package search and tracing. |
|
||||
| `auto_index_deps` | `false` | Automatically index installed dependency source for cross-package search and tracing. |
|
||||
| `auto_dep_limit` | `20` | Import-ranked automatic dependency package cap; `0` is unlimited. |
|
||||
| `similarity_enabled` | `true` | Create MinHash similarity edges in applicable index modes. |
|
||||
| `semantic_edges_enabled` | `true` | Create semantic-related edges in applicable index modes. |
|
||||
@@ -107,17 +107,23 @@ silently leak into a comparison:
|
||||
|
||||
```bash
|
||||
codebase-memory-mcp config preset list
|
||||
codebase-memory-mcp config preset apply streamlined-quality
|
||||
codebase-memory-mcp config preset apply classic-quality
|
||||
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
|
||||
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
|
||||
codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-disabled
|
||||
codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-enabled
|
||||
```
|
||||
|
||||
`streamlined-quality` is the recommended default surface with all measured quality
|
||||
capabilities enabled. `classic-quality` changes only the API discovery surface while
|
||||
retaining those capabilities. The `rank-disabled`, `dependency-disabled`,
|
||||
`optional-graph-disabled`, and `minimal-indexing` presets are explicit ablations;
|
||||
the CLI labels them as quality tradeoffs when applied. Environment variables remain
|
||||
higher priority than stored preset values, and the command returns nonzero with a
|
||||
warning when an active override prevents the requested effective configuration.
|
||||
The four product presets pair the `streamlined` or `classic` tool surface with an
|
||||
explicit automatic dependency-source indexing state. All four enable the same rank,
|
||||
similarity, semantic-edge, Git-history, and HTTP-link capabilities. The disabled
|
||||
variants bound default indexing latency, CPU, memory, and stored graph size; the
|
||||
enabled variants add installed dependency-source coverage up to `auto_dep_limit`.
|
||||
`index_dependencies` remains available for explicit packages. Disabling automation
|
||||
stops future automatic dependency indexing but does not delete dependency projects
|
||||
already indexed. `rank-disabled`, `optional-graph-disabled`, and `minimal-indexing`
|
||||
are benchmark ablations, and the CLI labels them accordingly. Environment variables
|
||||
remain higher priority than stored preset values, and preset application returns
|
||||
nonzero when an active override prevents the requested effective configuration.
|
||||
|
||||
## 3. UI Settings
|
||||
|
||||
|
||||
+52
-55
@@ -9978,80 +9978,75 @@ typedef struct {
|
||||
const char *description;
|
||||
const cbm_config_preset_value_t *values;
|
||||
size_t value_count;
|
||||
bool quality_tradeoff;
|
||||
bool benchmark_ablation;
|
||||
} cbm_config_preset_t;
|
||||
|
||||
#define PRESET_VALUE(key_, value_) {key_, value_}
|
||||
#define PRESET_COUNT(values_) (sizeof(values_) / sizeof((values_)[0]))
|
||||
#define PRESET_QUALITY_VALUES(auto_index_deps_, rank_, similarity_, semantic_, git_, http_) \
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, rank_), \
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, auto_index_deps_), \
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, similarity_), \
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, semantic_), \
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, git_), \
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, http_)
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_STREAMLINED_QUALITY[] = {
|
||||
static const cbm_config_preset_value_t PRESET_STREAMLINED_DEPS_DISABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_STREAMLINED),
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
|
||||
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "true", "true", "true",
|
||||
"true", "true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_CLASSIC_QUALITY[] = {
|
||||
static const cbm_config_preset_value_t PRESET_STREAMLINED_DEPS_ENABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_STREAMLINED),
|
||||
PRESET_QUALITY_VALUES("true", "true", "true", "true", "true", "true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_CLASSIC_DEPS_DISABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_CLASSIC),
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
|
||||
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "true", "true", "true",
|
||||
"true", "true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_CLASSIC_DEPS_ENABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_CLASSIC),
|
||||
PRESET_QUALITY_VALUES("true", "true", "true", "true", "true", "true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_RANK_DISABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_DEPENDENCY_DISABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
|
||||
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "true", "true", "true",
|
||||
"true"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_OPTIONAL_GRAPH_DISABLED[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "false"),
|
||||
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "false", "false", "false",
|
||||
"false"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_value_t PRESET_MINIMAL_INDEXING[] = {
|
||||
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "false"),
|
||||
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "false"),
|
||||
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "false", "false", "false",
|
||||
"false"),
|
||||
};
|
||||
|
||||
static const cbm_config_preset_t CBM_CONFIG_PRESETS[] = {
|
||||
{"streamlined-quality", "recommended streamlined API with all measured quality capabilities",
|
||||
PRESET_STREAMLINED_QUALITY, PRESET_COUNT(PRESET_STREAMLINED_QUALITY), false},
|
||||
{"classic-quality", "classic API with the same full-quality graph capabilities",
|
||||
PRESET_CLASSIC_QUALITY, PRESET_COUNT(PRESET_CLASSIC_QUALITY), false},
|
||||
{"streamlined-automatic-dependency-source-indexing-disabled",
|
||||
"streamlined API; automatic installed dependency-source indexing disabled",
|
||||
PRESET_STREAMLINED_DEPS_DISABLED, PRESET_COUNT(PRESET_STREAMLINED_DEPS_DISABLED), false},
|
||||
{"streamlined-automatic-dependency-source-indexing-enabled",
|
||||
"streamlined API; automatic installed dependency-source indexing enabled",
|
||||
PRESET_STREAMLINED_DEPS_ENABLED, PRESET_COUNT(PRESET_STREAMLINED_DEPS_ENABLED), false},
|
||||
{"classic-automatic-dependency-source-indexing-disabled",
|
||||
"classic API; automatic installed dependency-source indexing disabled",
|
||||
PRESET_CLASSIC_DEPS_DISABLED, PRESET_COUNT(PRESET_CLASSIC_DEPS_DISABLED), false},
|
||||
{"classic-automatic-dependency-source-indexing-enabled",
|
||||
"classic API; automatic installed dependency-source indexing enabled",
|
||||
PRESET_CLASSIC_DEPS_ENABLED, PRESET_COUNT(PRESET_CLASSIC_DEPS_ENABLED), false},
|
||||
{"rank-disabled", "exact PageRank/LinkRank ablation; lowers measured ranking quality",
|
||||
PRESET_RANK_DISABLED, PRESET_COUNT(PRESET_RANK_DISABLED), true},
|
||||
{"dependency-disabled", "exact dependency-indexing ablation; removes dependency API results",
|
||||
PRESET_DEPENDENCY_DISABLED, PRESET_COUNT(PRESET_DEPENDENCY_DISABLED), true},
|
||||
{"optional-graph-disabled", "disable optional graph passes but retain dependency indexing",
|
||||
{"optional-graph-disabled",
|
||||
"disable optional graph passes; dependency-source automation stays disabled",
|
||||
PRESET_OPTIONAL_GRAPH_DISABLED, PRESET_COUNT(PRESET_OPTIONAL_GRAPH_DISABLED), true},
|
||||
{"minimal-indexing", "lowest measured indexing cost; disables rank and dependency results",
|
||||
{"minimal-indexing", "disable optional graph passes and dependency-source automation",
|
||||
PRESET_MINIMAL_INDEXING, PRESET_COUNT(PRESET_MINIMAL_INDEXING), true},
|
||||
{NULL, NULL, NULL, 0, false},
|
||||
};
|
||||
@@ -10090,7 +10085,7 @@ static void cbm_config_print_presets(void) {
|
||||
printf("Named presets (applied atomically):\n");
|
||||
for (size_t i = 0; CBM_CONFIG_PRESETS[i].name; i++) {
|
||||
printf(" %-24s %s%s\n", CBM_CONFIG_PRESETS[i].name, CBM_CONFIG_PRESETS[i].description,
|
||||
CBM_CONFIG_PRESETS[i].quality_tradeoff ? " [quality tradeoff]" : "");
|
||||
CBM_CONFIG_PRESETS[i].benchmark_ablation ? " [benchmark ablation]" : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10534,11 +10529,13 @@ const cbm_config_entry_t CBM_CONFIG_REGISTRY[] = {
|
||||
"'unweighted' = raw connection count regardless of type. "
|
||||
"'calls_only' = only count direct function call connections — best for finding the most-called functions."},
|
||||
/* ── Dependencies ── */
|
||||
{"auto_index_deps", "true", NULL, "Dependencies",
|
||||
"Auto-index installed packages from package.json, Cargo.toml, go.mod, etc.",
|
||||
{CBM_CONFIG_AUTO_INDEX_DEPS, CBM_DEFAULT_AUTO_INDEX_DEPS_STR, NULL, "Dependencies",
|
||||
"Automatically index installed dependency source for cross-package search and tracing",
|
||||
"true|false",
|
||||
"Enable to trace calls into dependencies (e.g. find all callers of a library function). "
|
||||
"Disable for faster indexing when cross-package search is not needed."},
|
||||
"Disabled by default to bound indexing latency, CPU, memory, and stored graph size. Enable when "
|
||||
"automatic dependency-source coverage is worth that cost; auto_dep_limit bounds each discovery "
|
||||
"pass. index_dependencies remains available for explicit packages. Disabling this setting stops "
|
||||
"future automatic dependency indexing; it does not delete dependency projects already indexed."},
|
||||
{CBM_CONFIG_AUTO_DEP_LIMIT, CBM_STRINGIFY(CBM_DEFAULT_AUTO_DEP_LIMIT), NULL, "Dependencies",
|
||||
"Max number of packages to auto-index",
|
||||
"0-10000",
|
||||
|
||||
@@ -1158,7 +1158,7 @@ static ha_guidance_config_t ha_load_guidance_config(void) {
|
||||
.auto_index = true,
|
||||
.context_injection = true,
|
||||
.auto_watch = true,
|
||||
.auto_index_deps = true,
|
||||
.auto_index_deps = CBM_DEFAULT_AUTO_INDEX_DEPS,
|
||||
.auto_index_limit = CBM_DEFAULT_AUTO_INDEX_LIMIT,
|
||||
.auto_dep_limit = CBM_DEFAULT_AUTO_DEP_LIMIT,
|
||||
};
|
||||
@@ -1171,8 +1171,8 @@ static ha_guidance_config_t ha_load_guidance_config(void) {
|
||||
result.context_injection =
|
||||
cbm_config_get_effective_bool(cfg, CBM_CONFIG_CONTEXT_INJECTION, true);
|
||||
result.auto_watch = cbm_config_get_effective_bool(cfg, CBM_CONFIG_AUTO_WATCH, true);
|
||||
result.auto_index_deps =
|
||||
cbm_config_get_effective_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true);
|
||||
result.auto_index_deps = cbm_config_get_effective_bool(
|
||||
cfg, CBM_CONFIG_AUTO_INDEX_DEPS, CBM_DEFAULT_AUTO_INDEX_DEPS);
|
||||
result.auto_index_limit =
|
||||
cbm_config_get_effective_int(cfg, CBM_CONFIG_AUTO_INDEX_LIMIT,
|
||||
CBM_DEFAULT_AUTO_INDEX_LIMIT);
|
||||
|
||||
@@ -740,10 +740,8 @@ int cbm_discover_installed_deps(cbm_pkg_manager_t mgr, const char *project_root,
|
||||
/* ── Auto-Index ────────────────────────────────────────────────── */
|
||||
|
||||
int cbm_dep_auto_index_effective_limit(cbm_config_t *cfg, int default_limit) {
|
||||
if (!cfg) {
|
||||
return default_limit;
|
||||
}
|
||||
if (!cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true)) {
|
||||
if (!cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
|
||||
CBM_DEFAULT_AUTO_INDEX_DEPS)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ static const char *CBM_MANIFEST_FILES[] = {
|
||||
};
|
||||
|
||||
/* Default limits (convention: -1=unlimited, 0=disabled, >0=limit) */
|
||||
#define CBM_DEFAULT_AUTO_INDEX_DEPS false
|
||||
#define CBM_DEFAULT_AUTO_INDEX_DEPS_STR "false"
|
||||
#define CBM_DEFAULT_AUTO_DEP_LIMIT 20
|
||||
#define CBM_DEFAULT_DEP_MAX_FILES 1000
|
||||
|
||||
|
||||
+3
-1
@@ -2557,7 +2557,9 @@ static int cbm_mcp_overlay_compaction_max_generations(cbm_mcp_server_t *srv) {
|
||||
}
|
||||
|
||||
static int cbm_mcp_effective_auto_dep_limit(cbm_mcp_server_t *srv, const char *args_json) {
|
||||
bool enabled = cbm_config_get_bool(srv ? srv->config : NULL, CBM_CONFIG_AUTO_INDEX_DEPS, true);
|
||||
bool enabled = cbm_config_get_bool(srv ? srv->config : NULL,
|
||||
CBM_CONFIG_AUTO_INDEX_DEPS,
|
||||
CBM_DEFAULT_AUTO_INDEX_DEPS);
|
||||
if (cbm_mcp_has_arg(args_json, CBM_CONFIG_AUTO_INDEX_DEPS)) {
|
||||
enabled = cbm_mcp_get_bool_arg_default(args_json, CBM_CONFIG_AUTO_INDEX_DEPS, enabled);
|
||||
}
|
||||
|
||||
+103
-8
@@ -4171,6 +4171,39 @@ TEST(cli_hook_augment_subagent_no_project_guidance_is_read_only) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_hook_augment_guidance_uses_dependency_default) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-default-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cli_env_snapshot_t cache = {0};
|
||||
cli_env_snapshot_t auto_index_deps = {0};
|
||||
cli_env_snapshot_t auto_dep_limit = {0};
|
||||
ASSERT_TRUE(cli_env_snapshot(&cache, "CBM_CACHE_DIR"));
|
||||
ASSERT_TRUE(cli_env_snapshot(&auto_index_deps, "CBM_AUTO_INDEX_DEPS"));
|
||||
ASSERT_TRUE(cli_env_snapshot(&auto_dep_limit, "CBM_AUTO_DEP_LIMIT"));
|
||||
cbm_setenv("CBM_CACHE_DIR", tmpdir, 1);
|
||||
cbm_unsetenv("CBM_AUTO_INDEX_DEPS");
|
||||
cbm_unsetenv("CBM_AUTO_DEP_LIMIT");
|
||||
|
||||
const char *input =
|
||||
"{\"hook_event_name\":\"SessionStart\","
|
||||
"\"cwd\":\"/definitely-not-indexed/default-dependency-guidance\"}";
|
||||
char *output = cbm_hook_augment_lifecycle_json(input);
|
||||
ASSERT_NOT_NULL(output);
|
||||
ASSERT_NOT_NULL(strstr(output, "auto_index_deps=false"));
|
||||
ASSERT_NOT_NULL(strstr(output, "index_dependencies"));
|
||||
ASSERT_NULL(strstr(output, "Dependencies: automatic"));
|
||||
free(output);
|
||||
|
||||
cli_env_restore(&auto_dep_limit);
|
||||
cli_env_restore(&auto_index_deps);
|
||||
cli_env_restore(&cache);
|
||||
test_rmdir_r(tmpdir);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_hook_augment_guidance_tracks_tool_and_dependency_config) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-config-XXXXXX");
|
||||
@@ -6932,6 +6965,24 @@ TEST(cli_config_registry_auto_dep_limit_uses_shared_default) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_config_registry_auto_index_deps_defaults_disabled) {
|
||||
const cbm_config_entry_t *found = NULL;
|
||||
for (int i = 0; CBM_CONFIG_REGISTRY[i].key; i++) {
|
||||
if (strcmp(CBM_CONFIG_REGISTRY[i].key, CBM_CONFIG_AUTO_INDEX_DEPS) == 0) {
|
||||
found = &CBM_CONFIG_REGISTRY[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_NOT_NULL(found);
|
||||
ASSERT_STR_EQ(found->default_val, "false");
|
||||
ASSERT_STR_EQ(found->range, "true|false");
|
||||
ASSERT_NOT_NULL(strstr(found->description, "installed dependency source"));
|
||||
ASSERT_NOT_NULL(strstr(found->guidance, "index_dependencies"));
|
||||
ASSERT_NOT_NULL(strstr(found->guidance, "does not delete"));
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(cli_config_registry_reindex_startup_guidance_is_precise) {
|
||||
const cbm_config_entry_t *found = NULL;
|
||||
for (int i = 0; CBM_CONFIG_REGISTRY[i].key; i++) {
|
||||
@@ -7017,14 +7068,55 @@ TEST(cli_config_presets_apply_exact_capability_sets) {
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
|
||||
ASSERT_EQ(cbm_config_apply_preset(cfg, "streamlined-quality"), 0);
|
||||
ASSERT_STR_EQ(cbm_config_get(cfg, CBM_CONFIG_TOOL_MODE, ""), "streamlined");
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, false));
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *tool_mode;
|
||||
bool auto_index_deps;
|
||||
} cases[] = {
|
||||
{"streamlined-automatic-dependency-source-indexing-disabled", "streamlined", false},
|
||||
{"streamlined-automatic-dependency-source-indexing-enabled", "streamlined", true},
|
||||
{"classic-automatic-dependency-source-indexing-disabled", "classic", false},
|
||||
{"classic-automatic-dependency-source-indexing-enabled", "classic", true},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_RANK_ENABLED, "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
|
||||
cases[i].auto_index_deps ? "false" : "true"),
|
||||
0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_SIMILARITY_ENABLED, "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_GITHISTORY_ENABLED, "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, "false"), 0);
|
||||
|
||||
ASSERT_EQ(cbm_config_apply_preset(cfg, cases[i].name), 0);
|
||||
ASSERT_STR_EQ(cbm_config_get(cfg, CBM_CONFIG_TOOL_MODE, ""), cases[i].tool_mode);
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, false));
|
||||
ASSERT_EQ(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
|
||||
!cases[i].auto_index_deps),
|
||||
cases[i].auto_index_deps);
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, false));
|
||||
}
|
||||
|
||||
ASSERT_NEQ(cbm_config_apply_preset(cfg, "streamlined-quality"), 0);
|
||||
ASSERT_NEQ(cbm_config_apply_preset(cfg, "classic-quality"), 0);
|
||||
ASSERT_NEQ(cbm_config_apply_preset(cfg, "dependency-disabled"), 0);
|
||||
|
||||
ASSERT_EQ(cbm_config_apply_preset(cfg, "rank-disabled"), 0);
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, false));
|
||||
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, false));
|
||||
|
||||
ASSERT_EQ(cbm_config_apply_preset(cfg, "optional-graph-disabled"), 0);
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, true));
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, true));
|
||||
|
||||
ASSERT_EQ(cbm_config_apply_preset(cfg, "minimal-indexing"), 0);
|
||||
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
|
||||
@@ -7070,7 +7162,8 @@ TEST(cli_config_command_dispatches_presets) {
|
||||
/* Stored preset values remain deterministic, but an active environment
|
||||
* override must be reported through a nonzero command status. */
|
||||
cbm_setenv("CBM_TOOL_MODE", CBM_CONFIG_TOOL_MODE_CLASSIC, 1);
|
||||
char *overridden_args[] = {"preset", "apply", "streamlined-quality"};
|
||||
char *overridden_args[] = {
|
||||
"preset", "apply", "streamlined-automatic-dependency-source-indexing-disabled"};
|
||||
ASSERT_NEQ(cbm_cmd_config(3, overridden_args), 0);
|
||||
cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -7643,6 +7736,7 @@ SUITE(cli) {
|
||||
RUN_TEST(cli_hook_augment_lifecycle_output_contract);
|
||||
RUN_TEST(cli_hook_augment_subagent_tier_router_contract);
|
||||
RUN_TEST(cli_hook_augment_subagent_no_project_guidance_is_read_only);
|
||||
RUN_TEST(cli_hook_augment_guidance_uses_dependency_default);
|
||||
RUN_TEST(cli_hook_augment_guidance_tracks_tool_and_dependency_config);
|
||||
RUN_TEST(cli_hook_augment_post_read_event_and_path_contract);
|
||||
RUN_TEST(cli_hook_augment_hermes_dialect_contract);
|
||||
@@ -7755,6 +7849,7 @@ SUITE(cli) {
|
||||
RUN_TEST(cli_config_registry_includes_dep_ranking_toggle);
|
||||
RUN_TEST(cli_config_registry_includes_query_max_rows);
|
||||
RUN_TEST(cli_config_registry_auto_dep_limit_uses_shared_default);
|
||||
RUN_TEST(cli_config_registry_auto_index_deps_defaults_disabled);
|
||||
RUN_TEST(cli_config_registry_reindex_startup_guidance_is_precise);
|
||||
RUN_TEST(cli_configuration_doc_auto_index_default_matches_registry);
|
||||
RUN_TEST(cli_config_delete);
|
||||
|
||||
@@ -1081,8 +1081,8 @@ TEST(test_auto_index_deps_config_limit_policy) {
|
||||
cbm_config_t *cfg = cbm_config_open(cache_tmp);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
|
||||
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT),
|
||||
CBM_DEFAULT_AUTO_DEP_LIMIT);
|
||||
ASSERT_EQ(cbm_dep_auto_index_effective_limit(NULL, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
|
||||
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "false"), 0);
|
||||
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <mcp/mcp.h>
|
||||
#include <store/store.h>
|
||||
#include <cli/cli.h>
|
||||
#include <depindex/depindex.h>
|
||||
#include <yyjson/yyjson.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -1459,7 +1460,7 @@ TEST(path_project_autoindex_respects_file_limit) {
|
||||
|
||||
/* ══════════════════════════════════════════════════════════════════
|
||||
* Path-based auto-index must run dependency auto-indexing exactly like
|
||||
* the session-root branch: auto_index_deps (default true) triggers
|
||||
* the session-root branch: explicit auto_index_deps=true triggers
|
||||
* cbm_mcp_auto_index_deps after the project index; config can disable
|
||||
* it or cap it via auto_dep_limit. Analysis:
|
||||
* notes/2026-07-21-2332-path-autoindex-dependency-asymmetry-analysis.md
|
||||
@@ -1531,55 +1532,12 @@ TEST(path_project_autoindex_indexes_dependencies) {
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
|
||||
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
|
||||
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
ASSERT_NOT_NULL(srv);
|
||||
const char *old_auto_index = getenv("CBM_AUTO_INDEX");
|
||||
char *old_auto_index_copy = old_auto_index ? strdup(old_auto_index) : NULL;
|
||||
cbm_setenv("CBM_AUTO_INDEX", "true", 1);
|
||||
|
||||
bool project_indexed = false;
|
||||
char *dep_resp = NULL;
|
||||
run_path_dep_queries(srv, session_tmp, target_tmp, "path_dep_sentinel",
|
||||
&project_indexed, &dep_resp);
|
||||
bool dep_indexed = dep_resp && strstr(dep_resp, "path_dep_sentinel") != NULL;
|
||||
free(dep_resp);
|
||||
|
||||
cbm_mcp_server_free(srv);
|
||||
if (old_auto_index_copy) {
|
||||
cbm_setenv("CBM_AUTO_INDEX", old_auto_index_copy, 1);
|
||||
free(old_auto_index_copy);
|
||||
} else {
|
||||
cbm_unsetenv("CBM_AUTO_INDEX");
|
||||
}
|
||||
th_cleanup(target_tmp);
|
||||
th_cleanup(session_tmp);
|
||||
|
||||
ASSERT_TRUE(project_indexed);
|
||||
/* RED before the fix: the path branch never called
|
||||
* cbm_mcp_auto_index_deps, so the vendored dep was silently absent
|
||||
* even though auto_index_deps defaults to true. */
|
||||
ASSERT_TRUE(dep_indexed);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(path_project_autoindex_deps_disabled_by_config) {
|
||||
char session_tmp[256];
|
||||
snprintf(session_tmp, sizeof(session_tmp), "/tmp/cbm_path_depoff_sess_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(session_tmp));
|
||||
ASSERT_EQ(th_write_file(TH_PATH(session_tmp, "main.c"), "void session_dep_fn(void) {}\n"),
|
||||
0);
|
||||
|
||||
char target_tmp[256];
|
||||
snprintf(target_tmp, sizeof(target_tmp), "/tmp/cbm_path_depoff_tgt_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
|
||||
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
|
||||
|
||||
char cfg_tmp[256];
|
||||
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depoff_cfg_XXXXXX");
|
||||
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depon_cfg_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
|
||||
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
|
||||
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
ASSERT_NOT_NULL(srv);
|
||||
@@ -1608,7 +1566,58 @@ TEST(path_project_autoindex_deps_disabled_by_config) {
|
||||
th_cleanup(session_tmp);
|
||||
|
||||
ASSERT_TRUE(project_indexed);
|
||||
/* auto_index_deps=false must keep the path branch dep-free. */
|
||||
/* The enabled preset path must run the same dependency indexing helper as
|
||||
* session-root indexing. */
|
||||
ASSERT_TRUE(dep_indexed);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(path_project_autoindex_deps_disabled_by_default) {
|
||||
char session_tmp[256];
|
||||
snprintf(session_tmp, sizeof(session_tmp), "/tmp/cbm_path_depoff_sess_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(session_tmp));
|
||||
ASSERT_EQ(th_write_file(TH_PATH(session_tmp, "main.c"), "void session_dep_fn(void) {}\n"),
|
||||
0);
|
||||
|
||||
char target_tmp[256];
|
||||
snprintf(target_tmp, sizeof(target_tmp), "/tmp/cbm_path_depoff_tgt_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
|
||||
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
|
||||
|
||||
char cfg_tmp[256];
|
||||
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depoff_cfg_XXXXXX");
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
|
||||
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
ASSERT_NOT_NULL(srv);
|
||||
cbm_mcp_server_set_config(srv, cfg);
|
||||
const char *old_auto_index = getenv("CBM_AUTO_INDEX");
|
||||
char *old_auto_index_copy = old_auto_index ? strdup(old_auto_index) : NULL;
|
||||
cbm_setenv("CBM_AUTO_INDEX", "true", 1);
|
||||
|
||||
bool project_indexed = false;
|
||||
char *dep_resp = NULL;
|
||||
run_path_dep_queries(srv, session_tmp, target_tmp, "path_dep_sentinel",
|
||||
&project_indexed, &dep_resp);
|
||||
bool dep_indexed = dep_resp && strstr(dep_resp, "path_dep_sentinel") != NULL;
|
||||
free(dep_resp);
|
||||
|
||||
cbm_mcp_server_free(srv);
|
||||
cbm_config_close(cfg);
|
||||
if (old_auto_index_copy) {
|
||||
cbm_setenv("CBM_AUTO_INDEX", old_auto_index_copy, 1);
|
||||
free(old_auto_index_copy);
|
||||
} else {
|
||||
cbm_unsetenv("CBM_AUTO_INDEX");
|
||||
}
|
||||
th_cleanup(cfg_tmp);
|
||||
th_cleanup(target_tmp);
|
||||
th_cleanup(session_tmp);
|
||||
|
||||
ASSERT_TRUE(project_indexed);
|
||||
/* The product default must keep automatic path indexing dep-free. */
|
||||
ASSERT_FALSE(dep_indexed);
|
||||
PASS();
|
||||
}
|
||||
@@ -1645,7 +1654,7 @@ TEST(path_project_autoindex_honors_auto_dep_limit) {
|
||||
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
|
||||
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "true"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, "auto_dep_limit", "1"), 0);
|
||||
|
||||
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
|
||||
@@ -1697,7 +1706,7 @@ TEST(dep_search_hint_names_index_dependencies_when_deps_disabled) {
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmp);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "false"), 0);
|
||||
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "false"), 0);
|
||||
cbm_mcp_server_set_config(srv, cfg);
|
||||
|
||||
/* "deps" expands to "validation-test.dep" (prefix match, zero rows).
|
||||
@@ -1856,7 +1865,7 @@ void suite_input_validation(void) {
|
||||
RUN_TEST(path_project_auto_indexes_separate_directory);
|
||||
RUN_TEST(path_project_autoindex_respects_file_limit);
|
||||
RUN_TEST(path_project_autoindex_indexes_dependencies);
|
||||
RUN_TEST(path_project_autoindex_deps_disabled_by_config);
|
||||
RUN_TEST(path_project_autoindex_deps_disabled_by_default);
|
||||
RUN_TEST(path_project_autoindex_honors_auto_dep_limit);
|
||||
RUN_TEST(dep_search_hint_names_index_dependencies_when_deps_disabled);
|
||||
RUN_TEST(regression_trace_path_tool_name_still_works);
|
||||
|
||||
Reference in New Issue
Block a user