| 11009 | } |
| 11010 | |
| 11011 | int cbm_cmd_uninstall(int argc, char **argv) { |
| 11012 | parse_auto_answer(argc, argv); |
| 11013 | bool dry_run = false; |
| 11014 | /* An install into a custom --dir must be removable from that same dir: |
| 11015 | * without this, anyone who installed outside ~/.local/bin has no supported |
| 11016 | * uninstall path at all. Mirrors cbm_cmd_install's parsing. */ |
| 11017 | const char *requested_bin_dir = NULL; |
| 11018 | for (int i = 0; i < argc; i++) { |
| 11019 | /* The public command dispatcher passes option-only argv, while the |
| 11020 | * long-standing direct API/tests include the subcommand at argv[0]. */ |
| 11021 | if (i == 0 && strcmp(argv[i], "uninstall") == 0) { |
| 11022 | continue; |
| 11023 | } |
| 11024 | if (strcmp(argv[i], "--dry-run") == 0) { |
| 11025 | dry_run = true; |
| 11026 | } else if (strncmp(argv[i], "--dir=", SLEN("--dir=")) == 0) { |
| 11027 | requested_bin_dir = argv[i] + SLEN("--dir="); |
| 11028 | if (!requested_bin_dir[0]) { |
| 11029 | (void)fprintf(stderr, "error: --dir requires a non-empty path\n"); |
| 11030 | return CLI_TRUE; |
| 11031 | } |
| 11032 | } else if (strcmp(argv[i], "--dir") == 0) { |
| 11033 | if (i + 1 >= argc || !argv[i + 1] || !argv[i + 1][0] || argv[i + 1][0] == '-') { |
| 11034 | (void)fprintf(stderr, "error: --dir requires a non-empty path\n"); |
| 11035 | return CLI_TRUE; |
| 11036 | } |
| 11037 | requested_bin_dir = argv[++i]; |
| 11038 | } else if (strcmp(argv[i], "-y") != 0 && strcmp(argv[i], "--yes") != 0 && |
| 11039 | strcmp(argv[i], "-n") != 0 && strcmp(argv[i], "--no") != 0) { |
| 11040 | (void)fprintf(stderr, "error: unknown uninstall option: %s\n", argv[i]); |
| 11041 | return CLI_TRUE; |
| 11042 | } |
| 11043 | } |
| 11044 | |
| 11045 | const char *home = cbm_get_home_dir(); |
| 11046 | if (!home) { |
| 11047 | (void)fprintf(stderr, "error: HOME not set (use USERPROFILE on Windows)\n"); |
| 11048 | return CLI_TRUE; |
| 11049 | } |
| 11050 | |
| 11051 | printf("codebase-memory-mcp uninstall\n\n"); |
| 11052 | |
| 11053 | g_agent_uninstall_errors = 0; |
| 11054 | cbm_detected_agents_t agents = cbm_detect_agents(home); |
| 11055 | |
| 11056 | /* Confirm index removal outside the startup lock, but defer the mutation |
| 11057 | * until the final guarded activation. Dry-run never removes indexes. */ |
| 11058 | bool delete_indexes = false; |
| 11059 | int index_count = count_db_indexes(home); |
| 11060 | if (index_count > 0) { |
| 11061 | printf("\nFound %d index(es):\n", index_count); |
| 11062 | cbm_list_indexes(home); |
| 11063 | if (prompt_yn("Delete these indexes?")) { |
| 11064 | if (dry_run) { |
| 11065 | printf("(dry-run — indexes would be deleted)\n"); |
| 11066 | } else { |
| 11067 | delete_indexes = true; |
| 11068 | } |
no test coverage detected