mcpick 0.0.21 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +30 -5
  2. package/README.md +150 -127
  3. package/dist/add-LJQa2my2.js +164 -0
  4. package/dist/add-json-TEdYweZ5.js +95 -0
  5. package/dist/{backup-DSDhHI5f.js → backup-kyS5IVIr.js} +4 -4
  6. package/dist/{cache-D6kd7qE8.js → cache-DTfzTsEE.js} +3 -3
  7. package/dist/cli-By-0nYNQ.js +112 -0
  8. package/dist/clients-qMozizys.js +30 -0
  9. package/dist/{clone-DYKPEsar.js → clone-BVhYjRGO.js} +5 -6
  10. package/dist/{config-DijVdEFn.js → config-DzMmTJYL.js} +2 -2
  11. package/dist/{dev-DRJRNp7y.js → dev-Cst8WkQ-.js} +5 -5
  12. package/dist/disable-BaOs9lrm.js +83 -0
  13. package/dist/enable--3mjSmTq.js +84 -0
  14. package/dist/{get-Bb1eOOIZ.js → get-CjhNWyRj.js} +3 -3
  15. package/dist/{hooks-Bmn7pUZa.js → hooks-DFmxgD0t.js} +3 -4
  16. package/dist/index.js +1929 -297
  17. package/dist/list-D5CkCXpP.js +100 -0
  18. package/dist/{marketplace-DcKk5dc1.js → marketplace-C3EGyIG0.js} +4 -5
  19. package/dist/output-HtT5HCof.js +17 -0
  20. package/dist/{plugin-cache-Bby9Dxm9.js → plugin-cache-BSgB42wa.js} +34 -15
  21. package/dist/{plugins-Dc7DN6R_.js → plugins-Dn2mPFKm.js} +4 -5
  22. package/dist/{profile-CX97sMGp.js → profile-Dq3ORPil.js} +4 -5
  23. package/dist/redact-wBMtzbno.js +88 -0
  24. package/dist/{reload-CYDhkCVZ.js → reload-257iU7Z7.js} +2 -2
  25. package/dist/remove-26XFzkPd.js +87 -0
  26. package/dist/{reset-project-choices-BfRSNN3m.js → reset-project-choices-D2F04LfC.js} +3 -3
  27. package/dist/{restore-DdMfUljI.js → restore-BYYsoNqF.js} +4 -5
  28. package/dist/rollback-CPdaME91.js +55 -0
  29. package/dist/skills-DfWk9mpk.js +216 -0
  30. package/package.json +22 -8
  31. package/.github/copilot-instructions.md +0 -32
  32. package/.github/workflows/ci.yml +0 -26
  33. package/.vscode/settings.json +0 -5
  34. package/dist/add-BDyaBew0.js +0 -113
  35. package/dist/add-json-BjgzdeG-.js +0 -58
  36. package/dist/atomic-write-BqEykHp9.js +0 -26
  37. package/dist/claude-cli-DnmBJrjg.js +0 -445
  38. package/dist/cli-CsFfnWBo.js +0 -84
  39. package/dist/disable-xJXZfUR_.js +0 -39
  40. package/dist/enable-RrpcN6la.js +0 -40
  41. package/dist/hook-state-Di8lUsPr.js +0 -171
  42. package/dist/list-B8YeDWt6.js +0 -64
  43. package/dist/output-BchYq0mR.js +0 -15
  44. package/dist/profile-DkY_lBEm.js +0 -70
  45. package/dist/redact-O35tjnRD.js +0 -26
  46. package/dist/registry-CfUKT7_C.js +0 -92
  47. package/dist/remove-D1owHLhG.js +0 -31
  48. package/dist/settings-DEcWtzLE.js +0 -201
@@ -0,0 +1,100 @@
1
+ import { o as get_enabled_servers_for_scope } from "./config-DzMmTJYL.js";
2
+ import { a as redact_url, n as redact_server, t as redact_portable_server } from "./redact-wBMtzbno.js";
3
+ import { M as get_client_adapter, T as get_all_available_servers } from "./index.js";
4
+ import { n as output, t as error } from "./output-HtT5HCof.js";
5
+ import { defineCommand } from "citty";
6
+ //#region src/cli/commands/list.ts
7
+ var list_default = defineCommand({
8
+ meta: {
9
+ name: "list",
10
+ description: "List all MCP servers and their status"
11
+ },
12
+ args: {
13
+ client: {
14
+ type: "string",
15
+ description: "Client to read: claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi"
16
+ },
17
+ scope: {
18
+ type: "string",
19
+ description: "Scope to check: local, project, or user"
20
+ },
21
+ json: {
22
+ type: "boolean",
23
+ description: "Output as JSON",
24
+ default: false
25
+ }
26
+ },
27
+ async run({ args }) {
28
+ if (args.client && args.client !== "claude-code") {
29
+ await list_client_servers(args.client, args.scope, args.json);
30
+ return;
31
+ }
32
+ const scopes = args.scope ? [args.scope] : [
33
+ "local",
34
+ "project",
35
+ "user"
36
+ ];
37
+ if (args.scope && ![
38
+ "local",
39
+ "project",
40
+ "user"
41
+ ].includes(args.scope)) error(`Invalid scope: ${args.scope}. Use local, project, or user.`);
42
+ const all_servers = await get_all_available_servers();
43
+ const enabled_by_scope = {};
44
+ for (const scope of scopes) enabled_by_scope[scope] = await get_enabled_servers_for_scope(scope);
45
+ if (args.json) output(all_servers.map((server) => {
46
+ const status = {};
47
+ for (const scope of scopes) status[scope] = enabled_by_scope[scope].includes(server.name);
48
+ const { name, ...rest } = redact_server(server);
49
+ return {
50
+ name,
51
+ ...status,
52
+ ...rest
53
+ };
54
+ }), true);
55
+ else {
56
+ if (all_servers.length === 0) {
57
+ console.log("No servers in registry.");
58
+ return;
59
+ }
60
+ for (const server of all_servers) {
61
+ const statuses = scopes.map((scope) => {
62
+ return `${scope}:${enabled_by_scope[scope].includes(server.name) ? "on" : "off"}`;
63
+ }).join(" ");
64
+ console.log(`${server.name} ${statuses}`);
65
+ }
66
+ }
67
+ }
68
+ });
69
+ async function list_client_servers(client, scope, json) {
70
+ const adapter = get_client_adapter(client);
71
+ if (!adapter) error(`Invalid client: ${client}. Use claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi.`);
72
+ if (scope && ![
73
+ "local",
74
+ "project",
75
+ "user"
76
+ ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
77
+ const supported_scopes = new Set(adapter.locations().map((location) => location.scope));
78
+ if (scope && !supported_scopes.has(scope)) error(`${adapter.label} does not support ${scope} scope in MCPick yet.`);
79
+ const servers = await adapter.read(scope);
80
+ if (json) {
81
+ output({
82
+ client: adapter.id,
83
+ servers: servers.map(redact_portable_server)
84
+ }, true);
85
+ return;
86
+ }
87
+ if (servers.length === 0) {
88
+ console.log(`No MCP servers found for ${adapter.label}.`);
89
+ return;
90
+ }
91
+ for (const server of servers) {
92
+ const status = server.disabled ? "off" : "on";
93
+ const target = server.command || (server.url ? redact_url(server.url) : "(unknown)");
94
+ console.log(`${server.name} ${status} ${server.transport} ${target}`);
95
+ }
96
+ }
97
+ //#endregion
98
+ export { list_default as default };
99
+
100
+ //# sourceMappingURL=list-D5CkCXpP.js.map
@@ -1,7 +1,6 @@
1
- import { c as marketplace_remove_via_cli, l as marketplace_update_via_cli, o as marketplace_add_via_cli, s as marketplace_list_via_cli } from "./claude-cli-DnmBJrjg.js";
2
- import { u as read_marketplace_manifest } from "./plugin-cache-Bby9Dxm9.js";
3
- import { a as redisable_restored_hooks, t as check_restored_hooks } from "./hook-state-Di8lUsPr.js";
4
- import { n as output, t as error } from "./output-BchYq0mR.js";
1
+ import { u as read_marketplace_manifest } from "./plugin-cache-BSgB42wa.js";
2
+ import { g as marketplace_update_via_cli, h as marketplace_remove_via_cli, m as marketplace_list_via_cli, o as check_restored_hooks, p as marketplace_add_via_cli, u as redisable_restored_hooks } from "./index.js";
3
+ import { n as output, t as error } from "./output-HtT5HCof.js";
5
4
  import { defineCommand } from "citty";
6
5
  //#region src/cli/commands/marketplace.ts
7
6
  const list = defineCommand({
@@ -165,4 +164,4 @@ var marketplace_default = defineCommand({
165
164
  //#endregion
166
165
  export { marketplace_default as default };
167
166
 
168
- //# sourceMappingURL=marketplace-DcKk5dc1.js.map
167
+ //# sourceMappingURL=marketplace-C3EGyIG0.js.map
@@ -0,0 +1,17 @@
1
+ import { i as redact_text, o as redact_value } from "./redact-wBMtzbno.js";
2
+ //#region src/cli/output.ts
3
+ function output(data, json) {
4
+ const safe_data = redact_value(data);
5
+ if (json) console.log(JSON.stringify(safe_data, null, 2));
6
+ else if (typeof safe_data === "string") console.log(safe_data);
7
+ else if (Array.isArray(safe_data)) for (const item of safe_data) console.log(typeof item === "string" ? item : JSON.stringify(item));
8
+ else console.log(safe_data);
9
+ }
10
+ function error(message) {
11
+ console.error(`error: ${redact_text(message)}`);
12
+ process.exit(1);
13
+ }
14
+ //#endregion
15
+ export { output as n, error as t };
16
+
17
+ //# sourceMappingURL=output-HtT5HCof.js.map
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
2
  import { d as get_marketplace_manifest_path, h as get_plugin_cache_dir, l as get_installed_plugins_path, t as ensure_directory_exists, u as get_known_marketplaces_path } from "./paths-BPISiJi4.js";
3
- import { t as atomic_json_write } from "./atomic-write-BqEykHp9.js";
3
+ import { W as atomic_json_write } from "./index.js";
4
4
  import { lstat, readFile, readdir, readlink, rename, rm, symlink } from "node:fs/promises";
5
5
  import { join, resolve } from "node:path";
6
- import { exec } from "node:child_process";
6
+ import { execFile } from "node:child_process";
7
7
  import { promisify } from "node:util";
8
8
  //#region src/core/plugin-cache.ts
9
9
  var plugin_cache_exports = /* @__PURE__ */ __exportAll({
@@ -22,7 +22,14 @@ var plugin_cache_exports = /* @__PURE__ */ __exportAll({
22
22
  unlink_local_plugin: () => unlink_local_plugin,
23
23
  write_installed_plugins: () => write_installed_plugins
24
24
  });
25
- const execAsync = promisify(exec);
25
+ const execFileAsync = promisify(execFile);
26
+ function git(dir, args, timeout) {
27
+ return execFileAsync("git", [
28
+ "-C",
29
+ dir,
30
+ ...args
31
+ ], { timeout });
32
+ }
26
33
  const EMPTY_INSTALLED = {
27
34
  version: 2,
28
35
  plugins: {}
@@ -59,8 +66,8 @@ async function read_marketplace_manifest(name) {
59
66
  }
60
67
  async function get_marketplace_head_sha(marketplace_path) {
61
68
  try {
62
- const { stdout } = await execAsync(`git -C ${JSON.stringify(marketplace_path)} rev-parse HEAD`, { timeout: 1e4 });
63
- return stdout.trim() || null;
69
+ const { stdout } = await git(marketplace_path, ["rev-parse", "HEAD"], 1e4);
70
+ return String(stdout).trim() || null;
64
71
  } catch {
65
72
  return null;
66
73
  }
@@ -70,25 +77,37 @@ async function get_marketplace_head_sha(marketplace_path) {
70
77
  * Resets the fetch refspec, fetches all branches, and checks out the default branch.
71
78
  */
72
79
  async function recover_deleted_branch(dir) {
73
- const q = JSON.stringify(dir);
74
80
  try {
75
- await execAsync(`git -C ${q} remote set-branches origin '*'`, { timeout: 1e4 });
76
- await execAsync(`git -C ${q} fetch origin`, { timeout: 3e4 });
81
+ await git(dir, [
82
+ "remote",
83
+ "set-branches",
84
+ "origin",
85
+ "*"
86
+ ], 1e4);
87
+ await git(dir, ["fetch", "origin"], 3e4);
77
88
  let default_branch = "main";
78
89
  try {
79
- const { stdout } = await execAsync(`git -C ${q} symbolic-ref refs/remotes/origin/HEAD`, { timeout: 5e3 });
80
- const match = stdout.trim().match(/refs\/remotes\/origin\/(.+)/);
90
+ const { stdout } = await git(dir, ["symbolic-ref", "refs/remotes/origin/HEAD"], 5e3);
91
+ const match = String(stdout).trim().match(/refs\/remotes\/origin\/(.+)/);
81
92
  if (match) default_branch = match[1];
82
93
  } catch {
83
94
  try {
84
- await execAsync(`git -C ${q} rev-parse --verify origin/main`, { timeout: 5e3 });
95
+ await git(dir, [
96
+ "rev-parse",
97
+ "--verify",
98
+ "origin/main"
99
+ ], 5e3);
85
100
  default_branch = "main";
86
101
  } catch {
87
102
  default_branch = "master";
88
103
  }
89
104
  }
90
- await execAsync(`git -C ${q} checkout ${default_branch}`, { timeout: 1e4 });
91
- await execAsync(`git -C ${q} reset --hard origin/${default_branch}`, { timeout: 1e4 });
105
+ await git(dir, ["checkout", default_branch], 1e4);
106
+ await git(dir, [
107
+ "reset",
108
+ "--hard",
109
+ `origin/${default_branch}`
110
+ ], 1e4);
92
111
  return { recovered: true };
93
112
  } catch (err) {
94
113
  return {
@@ -100,7 +119,7 @@ async function recover_deleted_branch(dir) {
100
119
  async function refresh_marketplace(name, marketplace) {
101
120
  const dir = marketplace.installLocation;
102
121
  try {
103
- await execAsync(`git -C ${JSON.stringify(dir)} pull --ff-only`, { timeout: 3e4 });
122
+ await git(dir, ["pull", "--ff-only"], 3e4);
104
123
  return { success: true };
105
124
  } catch {
106
125
  const recovery = await recover_deleted_branch(dir);
@@ -402,4 +421,4 @@ async function list_linked_plugins() {
402
421
  //#endregion
403
422
  export { list_linked_plugins as a, read_installed_plugins as c, refresh_all_marketplaces as d, scan_all_cache_keys as f, link_local_plugin as i, read_known_marketplaces as l, clear_plugin_caches as n, parse_plugin_key as o, unlink_local_plugin as p, get_cached_plugins_info as r, plugin_cache_exports as s, clean_orphaned_versions as t, read_marketplace_manifest as u };
404
423
 
405
- //# sourceMappingURL=plugin-cache-Bby9Dxm9.js.map
424
+ //# sourceMappingURL=plugin-cache-BSgB42wa.js.map
@@ -1,7 +1,6 @@
1
- import { a as install_plugin_via_cli, g as validate_plugin_via_cli, h as update_plugin_via_cli, m as uninstall_plugin_via_cli } from "./claude-cli-DnmBJrjg.js";
2
- import { a as read_claude_settings, i as get_all_plugins, n as build_enabled_plugins, s as write_claude_settings } from "./settings-DEcWtzLE.js";
3
- import { l as read_known_marketplaces, o as parse_plugin_key } from "./plugin-cache-Bby9Dxm9.js";
4
- import { n as output, t as error } from "./output-BchYq0mR.js";
1
+ import { l as read_known_marketplaces, o as parse_plugin_key } from "./plugin-cache-BSgB42wa.js";
2
+ import { B as get_all_plugins, C as validate_plugin_via_cli, R as build_enabled_plugins, S as update_plugin_via_cli, U as write_claude_settings, V as read_claude_settings, f as install_plugin_via_cli, x as uninstall_plugin_via_cli } from "./index.js";
3
+ import { n as output, t as error } from "./output-HtT5HCof.js";
5
4
  import { defineCommand } from "citty";
6
5
  var plugins_default = defineCommand({
7
6
  meta: {
@@ -209,4 +208,4 @@ var plugins_default = defineCommand({
209
208
  //#endregion
210
209
  export { plugins_default as default };
211
210
 
212
- //# sourceMappingURL=plugins-Dc7DN6R_.js.map
211
+ //# sourceMappingURL=plugins-Dn2mPFKm.js.map
@@ -1,7 +1,6 @@
1
- import { c as write_claude_config } from "./config-DijVdEFn.js";
2
- import { s as write_claude_settings } from "./settings-DEcWtzLE.js";
3
- import { n as load_profile, r as save_profile, t as list_profiles } from "./profile-DkY_lBEm.js";
4
- import { n as output, t as error } from "./output-BchYq0mR.js";
1
+ import { c as write_claude_config } from "./config-DzMmTJYL.js";
2
+ import { U as write_claude_settings, n as load_profile, r as save_profile, t as list_profiles } from "./index.js";
3
+ import { n as output, t as error } from "./output-HtT5HCof.js";
5
4
  import { defineCommand } from "citty";
6
5
  var profile_default = defineCommand({
7
6
  meta: {
@@ -117,4 +116,4 @@ var profile_default = defineCommand({
117
116
  //#endregion
118
117
  export { profile_default as default };
119
118
 
120
- //# sourceMappingURL=profile-CX97sMGp.js.map
119
+ //# sourceMappingURL=profile-Dq3ORPil.js.map
@@ -0,0 +1,88 @@
1
+ //#region src/utils/redact.ts
2
+ const SENSITIVE_KEY_PATTERN = /(api[_-]?key|token|secret|password|passwd|authorization|client[_-]?secret|access[_-]?token|refresh[_-]?token|private[_-]?key)/i;
3
+ const ANSI_PATTERN = new RegExp(String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[a-zA-Z\d]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`, "g");
4
+ const TEXT_REDACTIONS = [
5
+ [/AKIA[A-Z0-9]{16}/g, "[REDACTED:AWS_ACCESS_KEY]"],
6
+ [/\bAIza[0-9A-Za-z_-]{35}\b/g, "[REDACTED:GOOGLE_API_KEY]"],
7
+ [/\bya29\.[0-9A-Za-z_-]{20,}\b/g, "[REDACTED:GOOGLE_OAUTH_TOKEN]"],
8
+ [/\bsk-(?:live|test)?_?[a-zA-Z0-9._-]{20,}\b/g, "[REDACTED:API_KEY]"],
9
+ [/\b(?:pk|rk)_(?:live|test)_[a-zA-Z0-9]{20,}\b/g, "[REDACTED:API_KEY]"],
10
+ [/\bBearer\s+[a-zA-Z0-9._~+/-]+=*/gi, "Bearer [REDACTED]"],
11
+ [/(:\/\/[^:\s/@]+):([^@\s]+)@/g, "$1:[REDACTED]@"],
12
+ [/([?&][^=&#\s]*(?:token|key|secret|password|passwd)[^=&#\s]*=)[^&#\s]*/gi, "$1[REDACTED]"],
13
+ [/\b(Authorization\s*:\s*)(?:Bearer\s+)?[^\s,}\]]+/gi, "$1[REDACTED]"],
14
+ [/\b((?:api[_-]?key|token|secret|password|passwd|client[_-]?secret|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?)[^"'\s,}\]]{8,}/gi, "$1[REDACTED]"],
15
+ [/\b((?:SecretAccessKey|aws_secret_access_key)\s*[:=]\s*)[A-Za-z0-9/+=]{20,}/gi, "$1[REDACTED]"],
16
+ [/-----BEGIN\s+[\w\s]*PRIVATE\s+KEY-----[\s\S]*?-----END\s+[\w\s]*PRIVATE\s+KEY-----/g, "[REDACTED:PRIVATE_KEY]"]
17
+ ];
18
+ /**
19
+ * Redact known secret patterns from arbitrary text. This is a safety net for
20
+ * CLI stdout/stderr; structured MCP config redaction should happen first.
21
+ */
22
+ function redact_text(text) {
23
+ let redacted = text;
24
+ for (const [pattern, replacement] of TEXT_REDACTIONS) redacted = redacted.replace(pattern, replacement);
25
+ return redacted.replace(ANSI_PATTERN, "");
26
+ }
27
+ function redact_value(value, key = "") {
28
+ if (typeof value === "string") return SENSITIVE_KEY_PATTERN.test(key) ? "***" : redact_text(value);
29
+ if (Array.isArray(value)) return value.map((item) => redact_value(item));
30
+ if (value && typeof value === "object") {
31
+ const redacted = {};
32
+ for (const [child_key, child_value] of Object.entries(value)) redacted[child_key] = child_key === "env" || child_key === "headers" ? redact_unknown_record(child_value) : SENSITIVE_KEY_PATTERN.test(child_key) ? "***" : redact_value(child_value, child_key);
33
+ return redacted;
34
+ }
35
+ return value;
36
+ }
37
+ /**
38
+ * Redact sensitive values from a server config.
39
+ * Shows env/header key names but replaces values with "***".
40
+ */
41
+ function redact_server_base(server) {
42
+ const redacted = redact_value(server);
43
+ if ("env" in redacted && redacted.env) redacted.env = redact_record(redacted.env);
44
+ if ("headers" in redacted && redacted.headers) redacted.headers = redact_record(redacted.headers);
45
+ if ("url" in redacted && redacted.url) redacted.url = redact_url(redacted.url);
46
+ return redacted;
47
+ }
48
+ function redact_server(server) {
49
+ return {
50
+ ...redact_server_base(server),
51
+ name: server.name
52
+ };
53
+ }
54
+ function redact_portable_server(server) {
55
+ return {
56
+ ...redact_value(server),
57
+ ...server.env ? { env: redact_record(server.env) } : {},
58
+ ...server.headers ? { headers: redact_record(server.headers) } : {},
59
+ ...server.url ? { url: redact_url(server.url) } : {}
60
+ };
61
+ }
62
+ function redact_url(url) {
63
+ try {
64
+ const parsed = new URL(url);
65
+ parsed.username = "";
66
+ parsed.password = "";
67
+ parsed.search = parsed.search ? "?redacted" : "";
68
+ parsed.hash = "";
69
+ return parsed.toString();
70
+ } catch {
71
+ return redact_text(url.replace(/[?#].*$/, "?redacted"));
72
+ }
73
+ }
74
+ function redact_unknown_record(value) {
75
+ if (!value || typeof value !== "object" || Array.isArray(value)) return redact_value(value);
76
+ const redacted = {};
77
+ for (const key of Object.keys(value)) redacted[key] = "***";
78
+ return redacted;
79
+ }
80
+ function redact_record(record) {
81
+ const redacted = {};
82
+ for (const key of Object.keys(record)) redacted[key] = "***";
83
+ return redacted;
84
+ }
85
+ //#endregion
86
+ export { redact_url as a, redact_text as i, redact_server as n, redact_value as o, redact_server_base as r, redact_portable_server as t };
87
+
88
+ //# sourceMappingURL=redact-wBMtzbno.js.map
@@ -1,4 +1,4 @@
1
- import { n as output } from "./output-BchYq0mR.js";
1
+ import { n as output } from "./output-HtT5HCof.js";
2
2
  import { defineCommand } from "citty";
3
3
  //#region src/cli/commands/reload.ts
4
4
  var reload_default = defineCommand({
@@ -28,4 +28,4 @@ var reload_default = defineCommand({
28
28
  //#endregion
29
29
  export { reload_default as default };
30
30
 
31
- //# sourceMappingURL=reload-CYDhkCVZ.js.map
31
+ //# sourceMappingURL=reload-257iU7Z7.js.map
@@ -0,0 +1,87 @@
1
+ import { F as resolve_client_location, M as get_client_adapter, O as read_server_registry, P as remove_client_server, T as get_all_available_servers, b as remove_mcp_via_cli, k as write_server_registry } from "./index.js";
2
+ import { n as output, t as error } from "./output-HtT5HCof.js";
3
+ import { defineCommand } from "citty";
4
+ //#region src/cli/commands/remove.ts
5
+ var remove_default = defineCommand({
6
+ meta: {
7
+ name: "remove",
8
+ description: "Remove an MCP server from the registry and disable it"
9
+ },
10
+ args: {
11
+ server: {
12
+ type: "positional",
13
+ description: "Server name to remove",
14
+ required: true
15
+ },
16
+ client: {
17
+ type: "string",
18
+ description: "Client to edit: claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi",
19
+ default: "claude-code"
20
+ },
21
+ scope: {
22
+ type: "string",
23
+ description: "Scope: local, project, or user"
24
+ },
25
+ location: {
26
+ type: "string",
27
+ description: "Exact config path when a client has multiple matching locations"
28
+ },
29
+ json: {
30
+ type: "boolean",
31
+ description: "Output as JSON",
32
+ default: false
33
+ }
34
+ },
35
+ async run({ args }) {
36
+ if (args.client && args.client !== "claude-code") {
37
+ await remove_from_client(args.client, args.server, args.scope, args.location, args.json);
38
+ return;
39
+ }
40
+ const scope = args.scope || "local";
41
+ if (![
42
+ "local",
43
+ "project",
44
+ "user"
45
+ ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
46
+ if (!(await get_all_available_servers()).find((s) => s.name === args.server)) error(`Server '${args.server}' not found. Run 'mcpick list' to see available servers.`);
47
+ const registry = await read_server_registry();
48
+ const index = registry.servers.findIndex((s) => s.name === args.server);
49
+ if (index >= 0) {
50
+ registry.servers.splice(index, 1);
51
+ await write_server_registry(registry);
52
+ }
53
+ await remove_mcp_via_cli(args.server, scope);
54
+ if (args.json) output({
55
+ removed: args.server,
56
+ client: "claude-code",
57
+ scope
58
+ }, true);
59
+ else console.log(`Removed '${args.server}'`);
60
+ }
61
+ });
62
+ async function remove_from_client(client, server, scope, location_path, json) {
63
+ const adapter = get_client_adapter(client);
64
+ if (!adapter) error(`Invalid client: ${client}. Use claude-code, gemini-cli, vscode, cursor, windsurf, opencode, or pi.`);
65
+ if (scope && ![
66
+ "local",
67
+ "project",
68
+ "user"
69
+ ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
70
+ try {
71
+ const location = resolve_client_location(adapter, scope, location_path);
72
+ await remove_client_server(adapter, location, server);
73
+ if (json) output({
74
+ removed: server,
75
+ client: adapter.id,
76
+ scope: location.scope,
77
+ location: location.path
78
+ }, true);
79
+ else console.log(`Removed '${server}' (${adapter.id}:${location.scope})`);
80
+ } catch (err) {
81
+ error(err instanceof Error ? err.message : "Failed to remove server");
82
+ }
83
+ }
84
+ //#endregion
85
+ export { remove_default as default };
86
+
87
+ //# sourceMappingURL=remove-26XFzkPd.js.map
@@ -1,5 +1,5 @@
1
- import { f as mcp_reset_project_choices_via_cli } from "./claude-cli-DnmBJrjg.js";
2
- import { n as output, t as error } from "./output-BchYq0mR.js";
1
+ import { y as mcp_reset_project_choices_via_cli } from "./index.js";
2
+ import { n as output, t as error } from "./output-HtT5HCof.js";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/cli/commands/reset-project-choices.ts
5
5
  var reset_project_choices_default = defineCommand({
@@ -25,4 +25,4 @@ var reset_project_choices_default = defineCommand({
25
25
  //#endregion
26
26
  export { reset_project_choices_default as default };
27
27
 
28
- //# sourceMappingURL=reset-project-choices-BfRSNN3m.js.map
28
+ //# sourceMappingURL=reset-project-choices-D2F04LfC.js.map
@@ -1,8 +1,7 @@
1
1
  import { t as validate_claude_config } from "./validation-xMlbgGCF.js";
2
- import { i as list_plugin_backups, r as list_backups } from "./registry-CfUKT7_C.js";
3
- import { c as write_claude_config } from "./config-DijVdEFn.js";
4
- import { s as write_claude_settings } from "./settings-DEcWtzLE.js";
5
- import { n as output, t as error } from "./output-BchYq0mR.js";
2
+ import { c as write_claude_config } from "./config-DzMmTJYL.js";
3
+ import { D as list_plugin_backups, E as list_backups, U as write_claude_settings } from "./index.js";
4
+ import { n as output, t as error } from "./output-HtT5HCof.js";
6
5
  import { readFile } from "node:fs/promises";
7
6
  import { defineCommand } from "citty";
8
7
  //#region src/cli/commands/restore.ts
@@ -81,4 +80,4 @@ var restore_default = defineCommand({
81
80
  //#endregion
82
81
  export { restore_default as default };
83
82
 
84
- //# sourceMappingURL=restore-DdMfUljI.js.map
83
+ //# sourceMappingURL=restore-BYYsoNqF.js.map
@@ -0,0 +1,55 @@
1
+ import { G as list_config_backups, K as restore_config_backup } from "./index.js";
2
+ import { n as output, t as error } from "./output-HtT5HCof.js";
3
+ import { defineCommand } from "citty";
4
+ //#region src/cli/commands/rollback.ts
5
+ var rollback_default = defineCommand({
6
+ meta: {
7
+ name: "rollback",
8
+ description: "List or restore automatic config backups created before safe writes"
9
+ },
10
+ args: {
11
+ file: {
12
+ type: "positional",
13
+ description: "Config backup filename or path. Defaults to latest backup.",
14
+ required: false
15
+ },
16
+ list: {
17
+ type: "boolean",
18
+ description: "List available config rollback backups",
19
+ default: false
20
+ },
21
+ json: {
22
+ type: "boolean",
23
+ description: "Output as JSON",
24
+ default: false
25
+ }
26
+ },
27
+ async run({ args }) {
28
+ try {
29
+ const backups = await list_config_backups();
30
+ if (args.list) {
31
+ if (args.json) {
32
+ output(backups, true);
33
+ return;
34
+ }
35
+ if (backups.length === 0) {
36
+ console.log("No config rollback backups found.");
37
+ return;
38
+ }
39
+ for (const backup of backups) console.log(`${backup.created_at} ${backup.path} -> ${backup.original_path}`);
40
+ return;
41
+ }
42
+ const backup_path = args.file || backups[0]?.path;
43
+ if (!backup_path) error("No config rollback backups found.");
44
+ const restored = await restore_config_backup(backup_path);
45
+ if (args.json) output({ restored }, true);
46
+ else console.log(`Restored ${restored.original_path} from ${restored.path}`);
47
+ } catch (err) {
48
+ error(err instanceof Error ? err.message : "Rollback failed");
49
+ }
50
+ }
51
+ });
52
+ //#endregion
53
+ export { rollback_default as default };
54
+
55
+ //# sourceMappingURL=rollback-CPdaME91.js.map