mcpick 0.0.25 → 0.0.26

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 (36) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/{add-7mhUpbrt.js → add-DwUPxD5U.js} +4 -5
  3. package/dist/{add-json-BMM2L4hv.js → add-json-Dk3C8QSR.js} +4 -4
  4. package/dist/atomic-write-9pfXia-x.js +22 -0
  5. package/dist/{backup-C-YJmgps.js → backup-Ber7st-_.js} +4 -5
  6. package/dist/{cache-BOYZhUF6.js → cache-BVNAOxqk.js} +3 -3
  7. package/dist/{cli-sOeHH4CK.js → cli-Dfein2li.js} +22 -22
  8. package/dist/{clients-D5KAuQ5U.js → clients-C1mWlnsn.js} +3 -3
  9. package/dist/{clone-BRJA55js.js → clone-BE904ik7.js} +3 -6
  10. package/dist/{dev-B-WlQSqY.js → dev-BW_2JDPM.js} +5 -6
  11. package/dist/{disable-Br0aVG3u.js → disable-CVwuJLhT.js} +4 -4
  12. package/dist/{enable-DUolKCEH.js → enable-BEi8TUd1.js} +4 -4
  13. package/dist/{get-D-6Cl_CO.js → get-eDOm6sRK.js} +3 -3
  14. package/dist/{hooks-BKPmZViU.js → hooks-DzGBYYId.js} +4 -3
  15. package/dist/index.js +306 -265
  16. package/dist/{list-DMcaHDfM.js → list-CvpW_mNZ.js} +3 -5
  17. package/dist/{marketplace-DTW7Ys8k.js → marketplace-BKGJ3UGr.js} +4 -4
  18. package/dist/{mutation-ukRPw3qM.js → mutation-BBMIFB8H.js} +2 -2
  19. package/dist/{output-BS1TMOWt.js → output-DGPi2IWN.js} +2 -2
  20. package/dist/{plugin-cache-Dw1I2YuO.js → plugin-cache-Dj-lS1mA.js} +169 -21
  21. package/dist/{plugins-BzLD4og0.js → plugins-elIQYM38.js} +4 -4
  22. package/dist/{profile-CmIWUJH_.js → profile-NVbTnJKI.js} +4 -4
  23. package/dist/{reload-Di28s_rY.js → reload-BkVtWaf0.js} +2 -2
  24. package/dist/{remove-B32EuYRC.js → remove-BC2vomi_.js} +4 -4
  25. package/dist/{reset-project-choices-DX4TnZ2i.js → reset-project-choices-DhJsWQx2.js} +3 -3
  26. package/dist/{restore-ByS4xi0y.js → restore-CeYSOFt8.js} +3 -5
  27. package/dist/{rollback-DdDJrA8y.js → rollback-g-WX6b3o.js} +3 -3
  28. package/dist/safe-apply-B5flt8QC.js +185 -0
  29. package/dist/{skills-pvyQ17XU.js → skills-zuQ5kCL1.js} +2 -2
  30. package/package.json +6 -6
  31. package/pnpm-workspace.yaml +1 -0
  32. package/dist/config-Bzh374VP.js +0 -167
  33. package/dist/paths-BPISiJi4.js +0 -124
  34. package/dist/redact-wBMtzbno.js +0 -88
  35. package/dist/rolldown-runtime-CiIaOW0V.js +0 -13
  36. package/dist/validation-CfPAjPJ5.js +0 -63
@@ -1,167 +0,0 @@
1
- import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { i as get_claude_config_path, o as get_current_project_path, v as get_project_mcp_json_path } from "./paths-BPISiJi4.js";
3
- import { t as validate_claude_config } from "./validation-CfPAjPJ5.js";
4
- import { K as atomic_json_write } from "./index.js";
5
- import { access, readFile } from "node:fs/promises";
6
- //#region src/core/config.ts
7
- var config_exports = /* @__PURE__ */ __exportAll({
8
- detect_server_scope: () => detect_server_scope,
9
- find_server_in_scope: () => find_server_in_scope,
10
- get_enabled_servers: () => get_enabled_servers,
11
- get_enabled_servers_for_scope: () => get_enabled_servers_for_scope,
12
- read_claude_config: () => read_claude_config,
13
- write_claude_config: () => write_claude_config
14
- });
15
- async function read_claude_config() {
16
- const config_path = get_claude_config_path();
17
- try {
18
- await access(config_path);
19
- const config_content = await readFile(config_path, "utf-8");
20
- return validate_claude_config(JSON.parse(config_content));
21
- } catch (error) {
22
- if (error instanceof Error && "code" in error && error.code === "ENOENT") return { mcpServers: {} };
23
- throw error;
24
- }
25
- }
26
- async function write_claude_config(config) {
27
- await atomic_json_write(get_claude_config_path(), (existing) => {
28
- existing.mcpServers = config.mcpServers;
29
- return existing;
30
- });
31
- }
32
- function get_enabled_servers(config) {
33
- if (!config.mcpServers) return [];
34
- return Object.entries(config.mcpServers).map(([name, server]) => ({
35
- ...server,
36
- name
37
- }));
38
- }
39
- /**
40
- * Find a server's full config in a specific scope.
41
- */
42
- async function find_server_in_scope(name, scope) {
43
- if (scope === "user" || scope === "local") {
44
- const config_path = get_claude_config_path();
45
- try {
46
- await access(config_path);
47
- const content = await readFile(config_path, "utf-8");
48
- const parsed = JSON.parse(content);
49
- if (scope === "user") {
50
- const server = parsed.mcpServers?.[name];
51
- if (server) return {
52
- server,
53
- scope: "user"
54
- };
55
- } else {
56
- const cwd = get_current_project_path();
57
- const server = parsed.projects?.[cwd]?.mcpServers?.[name];
58
- if (server) return {
59
- server,
60
- scope: "local"
61
- };
62
- }
63
- } catch {}
64
- } else if (scope === "project") {
65
- const mcp_path = get_project_mcp_json_path();
66
- try {
67
- await access(mcp_path);
68
- const content = await readFile(mcp_path, "utf-8");
69
- const server = JSON.parse(content).mcpServers?.[name];
70
- if (server) return {
71
- server,
72
- scope: "project"
73
- };
74
- } catch {}
75
- }
76
- return null;
77
- }
78
- /**
79
- * Auto-detect which scope a server lives in.
80
- * Searches local → project → user.
81
- */
82
- async function detect_server_scope(name) {
83
- for (const scope of [
84
- "local",
85
- "project",
86
- "user"
87
- ]) {
88
- const result = await find_server_in_scope(name, scope);
89
- if (result) return result;
90
- }
91
- return null;
92
- }
93
- /**
94
- * Read full Claude config including projects section
95
- */
96
- async function read_claude_config_full() {
97
- const config_path = get_claude_config_path();
98
- try {
99
- await access(config_path);
100
- const config_content = await readFile(config_path, "utf-8");
101
- return JSON.parse(config_content);
102
- } catch {
103
- return {
104
- mcpServers: {},
105
- projects: {}
106
- };
107
- }
108
- }
109
- /**
110
- * Read MCP servers for local scope (current project)
111
- * Stored in ~/.claude.json -> projects[cwd].mcpServers
112
- * Also searches parent directories since Claude CLI may store config at parent level
113
- */
114
- async function read_local_mcp_servers() {
115
- const { dirname } = await import("node:path");
116
- const { homedir } = await import("node:os");
117
- const full_config = await read_claude_config_full();
118
- const home = homedir();
119
- let current_dir = get_current_project_path();
120
- while (current_dir && current_dir !== "/" && current_dir.length >= home.length) {
121
- const project_config = full_config.projects?.[current_dir];
122
- if (project_config?.mcpServers && Object.keys(project_config.mcpServers).length > 0) return Object.keys(project_config.mcpServers);
123
- current_dir = dirname(current_dir);
124
- }
125
- return [];
126
- }
127
- /**
128
- * Read MCP servers from ~/.claude.json -> mcpServers (user scope)
129
- */
130
- async function read_user_mcp_servers() {
131
- const config = await read_claude_config();
132
- return Object.keys(config.mcpServers || {});
133
- }
134
- /**
135
- * Read MCP servers from .mcp.json files (project scope)
136
- * Searches current directory and parents for .mcp.json
137
- */
138
- async function find_and_read_project_mcp_json() {
139
- const { dirname } = await import("node:path");
140
- let current_dir = get_current_project_path();
141
- const home = (await import("node:os")).homedir();
142
- while (current_dir && current_dir !== "/" && current_dir.length >= home.length) {
143
- const mcp_path = `${current_dir}/.mcp.json`;
144
- try {
145
- await access(mcp_path);
146
- const content = await readFile(mcp_path, "utf-8");
147
- const servers = JSON.parse(content).mcpServers || {};
148
- return Object.keys(servers);
149
- } catch {}
150
- current_dir = dirname(current_dir);
151
- }
152
- return [];
153
- }
154
- /**
155
- * Get currently enabled server names for a specific scope
156
- */
157
- async function get_enabled_servers_for_scope(scope) {
158
- switch (scope) {
159
- case "local": return read_local_mcp_servers();
160
- case "project": return find_and_read_project_mcp_json();
161
- case "user": return read_user_mcp_servers();
162
- }
163
- }
164
- //#endregion
165
- export { get_enabled_servers_for_scope as a, get_enabled_servers as i, detect_server_scope as n, read_claude_config as o, find_server_in_scope as r, write_claude_config as s, config_exports as t };
166
-
167
- //# sourceMappingURL=config-Bzh374VP.js.map
@@ -1,124 +0,0 @@
1
- import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { access, mkdir } from "node:fs/promises";
3
- import { dirname, join } from "node:path";
4
- import { existsSync } from "node:fs";
5
- import { homedir } from "node:os";
6
- //#region src/utils/paths.ts
7
- var paths_exports = /* @__PURE__ */ __exportAll({
8
- ensure_directory_exists: () => ensure_directory_exists,
9
- get_backup_filename: () => get_backup_filename,
10
- get_backups_dir: () => get_backups_dir,
11
- get_base_dir: () => get_base_dir,
12
- get_claude_config_path: () => get_claude_config_path,
13
- get_claude_settings_path: () => get_claude_settings_path,
14
- get_current_project_path: () => get_current_project_path,
15
- get_dev_overrides_path: () => get_dev_overrides_path,
16
- get_disabled_hooks_path: () => get_disabled_hooks_path,
17
- get_installed_plugins_path: () => get_installed_plugins_path,
18
- get_known_marketplaces_path: () => get_known_marketplaces_path,
19
- get_marketplace_manifest_path: () => get_marketplace_manifest_path,
20
- get_marketplaces_dir: () => get_marketplaces_dir,
21
- get_mcpick_dir: () => get_mcpick_dir,
22
- get_plugin_backup_filename: () => get_plugin_backup_filename,
23
- get_plugin_cache_dir: () => get_plugin_cache_dir,
24
- get_plugins_dir: () => get_plugins_dir,
25
- get_profile_path: () => get_profile_path,
26
- get_profiles_dir: () => get_profiles_dir,
27
- get_project_mcp_json_path: () => get_project_mcp_json_path,
28
- get_server_registry_path: () => get_server_registry_path
29
- });
30
- function get_base_dir() {
31
- const configDir = process.env.CLAUDE_CONFIG_DIR;
32
- if (configDir && configDir.length > 0 && existsSync(configDir)) return {
33
- baseDir: configDir,
34
- parentDir: dirname(configDir),
35
- coLocatedConfig: true
36
- };
37
- const defaultDir = join(homedir(), ".claude");
38
- return {
39
- baseDir: defaultDir,
40
- parentDir: dirname(defaultDir),
41
- coLocatedConfig: false
42
- };
43
- }
44
- function get_claude_config_path() {
45
- const { baseDir, parentDir, coLocatedConfig } = get_base_dir();
46
- if (coLocatedConfig) return join(baseDir, ".claude.json");
47
- return join(parentDir, ".claude.json");
48
- }
49
- function get_claude_settings_path() {
50
- return join(get_base_dir().baseDir, "settings.json");
51
- }
52
- function get_mcpick_dir() {
53
- return join(get_base_dir().baseDir, "mcpick");
54
- }
55
- function get_dev_overrides_path() {
56
- return join(get_mcpick_dir(), "dev-overrides.json");
57
- }
58
- function get_server_registry_path() {
59
- return join(get_mcpick_dir(), "servers.json");
60
- }
61
- function get_backups_dir() {
62
- return join(get_mcpick_dir(), "backups");
63
- }
64
- function get_profiles_dir() {
65
- return join(get_mcpick_dir(), "profiles");
66
- }
67
- function get_profile_path(name) {
68
- const filename = name.endsWith(".json") ? name : `${name}.json`;
69
- return join(get_profiles_dir(), filename);
70
- }
71
- function format_backup_timestamp() {
72
- const now = /* @__PURE__ */ new Date();
73
- return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}-${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}${String(now.getSeconds()).padStart(2, "0")}`;
74
- }
75
- function get_backup_filename() {
76
- return `mcp-servers-${format_backup_timestamp()}.json`;
77
- }
78
- function get_plugin_backup_filename() {
79
- return `plugins-${format_backup_timestamp()}.json`;
80
- }
81
- async function ensure_directory_exists(dir_path) {
82
- try {
83
- await access(dir_path);
84
- } catch {
85
- await mkdir(dir_path, { recursive: true });
86
- }
87
- }
88
- /**
89
- * Get the current working directory (project path)
90
- */
91
- function get_current_project_path() {
92
- return process.cwd();
93
- }
94
- /**
95
- * Get the path to .mcp.json in the current project directory (project scope)
96
- */
97
- function get_project_mcp_json_path() {
98
- return join(get_current_project_path(), ".mcp.json");
99
- }
100
- function get_plugins_dir() {
101
- return join(get_base_dir().baseDir, "plugins");
102
- }
103
- function get_installed_plugins_path() {
104
- return join(get_plugins_dir(), "installed_plugins.json");
105
- }
106
- function get_known_marketplaces_path() {
107
- return join(get_plugins_dir(), "known_marketplaces.json");
108
- }
109
- function get_plugin_cache_dir() {
110
- return join(get_plugins_dir(), "cache");
111
- }
112
- function get_marketplaces_dir() {
113
- return join(get_plugins_dir(), "marketplaces");
114
- }
115
- function get_disabled_hooks_path() {
116
- return join(get_mcpick_dir(), "disabled-hooks.json");
117
- }
118
- function get_marketplace_manifest_path(name) {
119
- return join(get_marketplaces_dir(), name, ".claude-plugin", "marketplace.json");
120
- }
121
- //#endregion
122
- export { get_profiles_dir as _, get_claude_settings_path as a, paths_exports as b, get_disabled_hooks_path as c, get_marketplace_manifest_path as d, get_marketplaces_dir as f, get_profile_path as g, get_plugin_cache_dir as h, get_claude_config_path as i, get_installed_plugins_path as l, get_plugin_backup_filename as m, get_backup_filename as n, get_current_project_path as o, get_mcpick_dir as p, get_backups_dir as r, get_dev_overrides_path as s, ensure_directory_exists as t, get_known_marketplaces_path as u, get_project_mcp_json_path as v, get_server_registry_path as y };
123
-
124
- //# sourceMappingURL=paths-BPISiJi4.js.map
@@ -1,88 +0,0 @@
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,13 +0,0 @@
1
- //#region \0rolldown/runtime.js
2
- var __defProp = Object.defineProperty;
3
- var __exportAll = (all, no_symbols) => {
4
- let target = {};
5
- for (var name in all) __defProp(target, name, {
6
- get: all[name],
7
- enumerable: true
8
- });
9
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
- return target;
11
- };
12
- //#endregion
13
- export { __exportAll as t };
@@ -1,63 +0,0 @@
1
- import * as v from "valibot";
2
- //#region src/core/validation.ts
3
- const mcp_server_schema_stdio = v.object({
4
- type: v.optional(v.literal("stdio")),
5
- command: v.pipe(v.string(), v.minLength(1)),
6
- args: v.optional(v.array(v.string())),
7
- env: v.optional(v.record(v.string(), v.string())),
8
- description: v.optional(v.string())
9
- });
10
- const mcp_server_schema_sse = v.object({
11
- type: v.literal("sse"),
12
- env: v.optional(v.record(v.string(), v.string())),
13
- url: v.pipe(v.string(), v.minLength(1)),
14
- headers: v.optional(v.record(v.string(), v.string())),
15
- description: v.optional(v.string())
16
- });
17
- const mcp_server_schema_http = v.object({
18
- type: v.literal("http"),
19
- env: v.optional(v.record(v.string(), v.string())),
20
- url: v.pipe(v.string(), v.minLength(1)),
21
- headers: v.optional(v.record(v.string(), v.string())),
22
- description: v.optional(v.string())
23
- });
24
- const mcp_server_schema_base = v.union([
25
- mcp_server_schema_stdio,
26
- mcp_server_schema_sse,
27
- mcp_server_schema_http
28
- ]);
29
- const mcp_server_schema = v.intersect([v.object({ name: v.pipe(v.string(), v.minLength(1)) }), mcp_server_schema_base]);
30
- const claude_config_schema = v.object({ mcpServers: v.optional(v.record(v.string(), mcp_server_schema_base)) });
31
- const portable_mcp_server_schema = v.object({
32
- name: v.pipe(v.string(), v.minLength(1)),
33
- transport: v.union([
34
- v.literal("stdio"),
35
- v.literal("http"),
36
- v.literal("sse")
37
- ]),
38
- command: v.optional(v.string()),
39
- args: v.optional(v.array(v.string())),
40
- url: v.optional(v.string()),
41
- env: v.optional(v.record(v.string(), v.string())),
42
- headers: v.optional(v.record(v.string(), v.string())),
43
- description: v.optional(v.string()),
44
- disabled: v.optional(v.boolean()),
45
- client_options: v.optional(v.record(v.string(), v.unknown()))
46
- });
47
- const server_registry_schema = v.object({
48
- version: v.literal(3),
49
- servers: v.array(portable_mcp_server_schema)
50
- });
51
- function validate_mcp_server(data) {
52
- return v.parse(mcp_server_schema, data);
53
- }
54
- function validate_claude_config(data) {
55
- return v.parse(claude_config_schema, data);
56
- }
57
- function validate_server_registry(data) {
58
- return v.parse(server_registry_schema, data);
59
- }
60
- //#endregion
61
- export { validate_mcp_server as n, validate_server_registry as r, validate_claude_config as t };
62
-
63
- //# sourceMappingURL=validation-CfPAjPJ5.js.map