Try to handle a subcommand (cli/install/uninstall/update/config/--version/--help). * Returns -1 if no subcommand matched, otherwise the exit code. */ `allow-root [--approve-sensitive] ` — record an indexing root. * * Enrollment lives here, in a command a person types, and deliberately nowhere * else: the whole point of the grant store is that neither an indexed repository * nor a tool c
| 942 | * the MCP surface would be answered by the same agent that may have been |
| 943 | * influenced, so it would not be a human decision at all. */ |
| 944 | static int main_run_allow_root(int argc, char **argv) { |
| 945 | const char *path = NULL; |
| 946 | bool approve_sensitive = false; |
| 947 | bool list_only = false; |
| 948 | bool approve_manifest = false; |
| 949 | for (int i = 0; i < argc; i++) { |
| 950 | if (strcmp(argv[i], "--approve-sensitive") == 0) { |
| 951 | approve_sensitive = true; |
| 952 | } else if (strcmp(argv[i], "--list") == 0) { |
| 953 | list_only = true; |
| 954 | } else if (strcmp(argv[i], "--approve-manifest") == 0) { |
| 955 | approve_manifest = true; |
| 956 | } else if (argv[i][0] == '-') { |
| 957 | (void)fprintf(stderr, "error: unknown option: %s\n", argv[i]); |
| 958 | return EXIT_FAILURE; |
| 959 | } else if (!path) { |
| 960 | path = argv[i]; |
| 961 | } else { |
| 962 | (void)fprintf(stderr, "error: only one path may be given\n"); |
| 963 | return EXIT_FAILURE; |
| 964 | } |
| 965 | } |
| 966 | |
| 967 | const char *cache_dir = cbm_workspace_cache_dir(); |
| 968 | if (!cache_dir || !cache_dir[0]) { |
| 969 | (void)fprintf(stderr, "error: cache directory could not be resolved\n"); |
| 970 | return EXIT_FAILURE; |
| 971 | } |
| 972 | |
| 973 | if (list_only || !path) { |
| 974 | char listing[CBM_SZ_8K]; |
| 975 | if (cbm_workspace_grant_list(cache_dir, listing, sizeof(listing))) { |
| 976 | printf("allowed roots:\n%s", listing); |
| 977 | } else { |
| 978 | printf("no allowed roots recorded — indexing is unconfined apart from the " |
| 979 | "always-refused roots (see docs/CONFIGURATION.md)\n"); |
| 980 | } |
| 981 | if (!path && !list_only) { |
| 982 | (void)fprintf(stderr, |
| 983 | "usage: codebase-memory-mcp allow-root [--approve-sensitive] <path>\n" |
| 984 | " codebase-memory-mcp allow-root --approve-manifest <project>\n" |
| 985 | " codebase-memory-mcp allow-root --list\n"); |
| 986 | return EXIT_FAILURE; |
| 987 | } |
| 988 | return 0; |
| 989 | } |
| 990 | |
| 991 | if (approve_manifest) { |
| 992 | /* Approve the manifest a project ships, keyed to its current content. The |
| 993 | * file only ever requests; this is the human action that grants. */ |
| 994 | char canonical_project[CBM_PATH_MAX]; |
| 995 | if (!cbm_canonical_path(path, canonical_project, sizeof(canonical_project))) { |
| 996 | (void)fprintf(stderr, "error: cannot resolve path: %s\n", path); |
| 997 | return EXIT_FAILURE; |
| 998 | } |
| 999 | char merr[CBM_SZ_1K]; |
| 1000 | if (!cbm_workspace_manifest_approve(cache_dir, cbm_workspace_home_dir(), canonical_project, |
| 1001 | merr, sizeof(merr))) { |
no test coverage detected