mcpick 0.0.24 → 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.
- package/CHANGELOG.md +28 -0
- package/README.md +8 -2
- package/dist/{add-Qzd8i-5k.js → add-DwUPxD5U.js} +21 -35
- package/dist/{add-json-DGmsjB0O.js → add-json-Dk3C8QSR.js} +18 -34
- package/dist/atomic-write-9pfXia-x.js +22 -0
- package/dist/{backup-C7fvikFw.js → backup-Ber7st-_.js} +4 -5
- package/dist/{cache-D3jjh5dD.js → cache-BVNAOxqk.js} +4 -3
- package/dist/{cli-CZOlaqoZ.js → cli-Dfein2li.js} +22 -22
- package/dist/{clients-Bh93TGP4.js → clients-C1mWlnsn.js} +3 -3
- package/dist/{clone-MI8jJhTz.js → clone-BE904ik7.js} +3 -6
- package/dist/{dev-51esdZG9.js → dev-BW_2JDPM.js} +5 -6
- package/dist/{disable-csYAn2Vk.js → disable-CVwuJLhT.js} +18 -37
- package/dist/{enable-B5GbmhL-.js → enable-BEi8TUd1.js} +18 -37
- package/dist/{get-DacRZmwv.js → get-eDOm6sRK.js} +3 -3
- package/dist/{hooks-C_x49qap.js → hooks-DzGBYYId.js} +4 -3
- package/dist/index.js +752 -645
- package/dist/{list-BeBtsiae.js → list-CvpW_mNZ.js} +3 -5
- package/dist/{marketplace-BDC2YtvT.js → marketplace-BKGJ3UGr.js} +4 -4
- package/dist/mutation-BBMIFB8H.js +19 -0
- package/dist/{output-HtT5HCof.js → output-DGPi2IWN.js} +2 -2
- package/dist/{plugin-cache-DmLbh89d.js → plugin-cache-Dj-lS1mA.js} +177 -22
- package/dist/{plugins-Bkw-SKkZ.js → plugins-elIQYM38.js} +4 -4
- package/dist/profile-NVbTnJKI.js +163 -0
- package/dist/{reload-Bl1mYK1I.js → reload-BkVtWaf0.js} +2 -2
- package/dist/{remove-BSHgva79.js → remove-BC2vomi_.js} +18 -33
- package/dist/{reset-project-choices-BNLus9J9.js → reset-project-choices-DhJsWQx2.js} +3 -3
- package/dist/{restore-YisgARhc.js → restore-CeYSOFt8.js} +3 -5
- package/dist/{rollback-GR1RkpXW.js → rollback-g-WX6b3o.js} +3 -3
- package/dist/safe-apply-B5flt8QC.js +185 -0
- package/dist/{skills-rDTDqqZA.js → skills-zuQ5kCL1.js} +3 -3
- package/package.json +6 -6
- package/pnpm-workspace.yaml +1 -0
- package/dist/config-DE58Fik_.js +0 -176
- package/dist/dry-run-XQ32fxPT.js +0 -20
- package/dist/paths-BPISiJi4.js +0 -124
- package/dist/profile-DwJTVXiz.js +0 -161
- package/dist/redact-wBMtzbno.js +0 -88
- package/dist/rolldown-runtime-CiIaOW0V.js +0 -13
- package/dist/validation-xMlbgGCF.js +0 -44
package/dist/profile-DwJTVXiz.js
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { a as get_claude_settings_path, g as get_profile_path, i as get_claude_config_path } from "./paths-BPISiJi4.js";
|
|
2
|
-
import { s as read_claude_config } from "./config-DE58Fik_.js";
|
|
3
|
-
import { K as build_json_change_preview, Z as read_claude_settings, i as save_current_claude_profile, n as list_profiles, r as load_profile, t as apply_profile_to_claude } from "./index.js";
|
|
4
|
-
import { n as output, t as error } from "./output-HtT5HCof.js";
|
|
5
|
-
import { t as print_dry_run } from "./dry-run-XQ32fxPT.js";
|
|
6
|
-
import { defineCommand } from "citty";
|
|
7
|
-
var profile_default = defineCommand({
|
|
8
|
-
meta: {
|
|
9
|
-
name: "profile",
|
|
10
|
-
description: "Manage profiles (MCP servers + plugins)"
|
|
11
|
-
},
|
|
12
|
-
subCommands: {
|
|
13
|
-
list: defineCommand({
|
|
14
|
-
meta: {
|
|
15
|
-
name: "list",
|
|
16
|
-
description: "List all saved profiles"
|
|
17
|
-
},
|
|
18
|
-
args: { json: {
|
|
19
|
-
type: "boolean",
|
|
20
|
-
description: "Output as JSON",
|
|
21
|
-
default: false
|
|
22
|
-
} },
|
|
23
|
-
async run({ args }) {
|
|
24
|
-
const profiles = await list_profiles();
|
|
25
|
-
if (args.json) output(profiles, true);
|
|
26
|
-
else {
|
|
27
|
-
if (profiles.length === 0) {
|
|
28
|
-
console.log("No profiles found.");
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
for (const p of profiles) {
|
|
32
|
-
const parts = [`${p.serverCount} servers`];
|
|
33
|
-
if (p.pluginCount > 0) parts.push(`${p.pluginCount} plugins`);
|
|
34
|
-
console.log(`${p.name} (${parts.join(", ")})`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}),
|
|
39
|
-
load: defineCommand({
|
|
40
|
-
meta: {
|
|
41
|
-
name: "load",
|
|
42
|
-
description: "Load and apply a saved profile"
|
|
43
|
-
},
|
|
44
|
-
args: {
|
|
45
|
-
name: {
|
|
46
|
-
type: "positional",
|
|
47
|
-
description: "Profile name",
|
|
48
|
-
required: true
|
|
49
|
-
},
|
|
50
|
-
dryRun: {
|
|
51
|
-
type: "boolean",
|
|
52
|
-
description: "Preview changes without writing",
|
|
53
|
-
default: false
|
|
54
|
-
},
|
|
55
|
-
json: {
|
|
56
|
-
type: "boolean",
|
|
57
|
-
description: "Output as JSON",
|
|
58
|
-
default: false
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
async run({ args }) {
|
|
62
|
-
try {
|
|
63
|
-
if (args.dryRun) {
|
|
64
|
-
const profile = await load_profile(args.name);
|
|
65
|
-
const previews = [build_json_change_preview({
|
|
66
|
-
operation: "profile-load",
|
|
67
|
-
client: "claude-code",
|
|
68
|
-
scope: "user",
|
|
69
|
-
location: get_claude_config_path(),
|
|
70
|
-
before: await read_claude_config(),
|
|
71
|
-
after: profile.config
|
|
72
|
-
})];
|
|
73
|
-
if (profile.enabledPlugins) previews.push(build_json_change_preview({
|
|
74
|
-
operation: "profile-load-plugins",
|
|
75
|
-
client: "claude-code",
|
|
76
|
-
scope: "user",
|
|
77
|
-
location: get_claude_settings_path(),
|
|
78
|
-
before: await read_claude_settings(),
|
|
79
|
-
after: { enabledPlugins: profile.enabledPlugins }
|
|
80
|
-
}));
|
|
81
|
-
if (args.json) output(previews, true);
|
|
82
|
-
else for (const preview of previews) print_dry_run(preview, false);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const result = await apply_profile_to_claude(args.name);
|
|
86
|
-
if (args.json) output({
|
|
87
|
-
profile: result.profile,
|
|
88
|
-
servers: result.serverCount,
|
|
89
|
-
plugins: result.pluginCount
|
|
90
|
-
}, true);
|
|
91
|
-
else {
|
|
92
|
-
const parts = [`${result.serverCount} servers`];
|
|
93
|
-
if (result.pluginCount > 0) parts.push(`${result.pluginCount} plugins`);
|
|
94
|
-
console.log(`Profile '${result.profile}' applied (${parts.join(", ")})`);
|
|
95
|
-
}
|
|
96
|
-
} catch (err) {
|
|
97
|
-
error(err instanceof Error ? err.message : "Failed to load profile");
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}),
|
|
101
|
-
save: defineCommand({
|
|
102
|
-
meta: {
|
|
103
|
-
name: "save",
|
|
104
|
-
description: "Save current config as a profile"
|
|
105
|
-
},
|
|
106
|
-
args: {
|
|
107
|
-
name: {
|
|
108
|
-
type: "positional",
|
|
109
|
-
description: "Profile name",
|
|
110
|
-
required: true
|
|
111
|
-
},
|
|
112
|
-
dryRun: {
|
|
113
|
-
type: "boolean",
|
|
114
|
-
description: "Preview changes without writing",
|
|
115
|
-
default: false
|
|
116
|
-
},
|
|
117
|
-
json: {
|
|
118
|
-
type: "boolean",
|
|
119
|
-
description: "Output as JSON",
|
|
120
|
-
default: false
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
async run({ args }) {
|
|
124
|
-
try {
|
|
125
|
-
if (args.dryRun) {
|
|
126
|
-
const config = await read_claude_config();
|
|
127
|
-
const settings = await read_claude_settings();
|
|
128
|
-
const profile_data = { mcpServers: config.mcpServers || {} };
|
|
129
|
-
if (settings.enabledPlugins) profile_data.enabledPlugins = settings.enabledPlugins;
|
|
130
|
-
print_dry_run(build_json_change_preview({
|
|
131
|
-
operation: "profile-save",
|
|
132
|
-
client: "claude-code",
|
|
133
|
-
scope: "user",
|
|
134
|
-
location: get_profile_path(args.name),
|
|
135
|
-
before: {},
|
|
136
|
-
after: profile_data
|
|
137
|
-
}), args.json);
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const result = await save_current_claude_profile(args.name);
|
|
141
|
-
if (args.json) output({
|
|
142
|
-
profile: result.profile,
|
|
143
|
-
servers: result.serverCount,
|
|
144
|
-
plugins: result.pluginCount
|
|
145
|
-
}, true);
|
|
146
|
-
else {
|
|
147
|
-
const parts = [`${result.serverCount} servers`];
|
|
148
|
-
if (result.pluginCount > 0) parts.push(`${result.pluginCount} plugins`);
|
|
149
|
-
console.log(`Profile '${result.profile}' saved (${parts.join(", ")})`);
|
|
150
|
-
}
|
|
151
|
-
} catch (err) {
|
|
152
|
-
error(err instanceof Error ? err.message : "Failed to save profile");
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
//#endregion
|
|
159
|
-
export { profile_default as default };
|
|
160
|
-
|
|
161
|
-
//# sourceMappingURL=profile-DwJTVXiz.js.map
|
package/dist/redact-wBMtzbno.js
DELETED
|
@@ -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,44 +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 server_registry_schema = v.object({ servers: v.array(mcp_server_schema) });
|
|
32
|
-
function validate_mcp_server(data) {
|
|
33
|
-
return v.parse(mcp_server_schema, data);
|
|
34
|
-
}
|
|
35
|
-
function validate_claude_config(data) {
|
|
36
|
-
return v.parse(claude_config_schema, data);
|
|
37
|
-
}
|
|
38
|
-
function validate_server_registry(data) {
|
|
39
|
-
return v.parse(server_registry_schema, data);
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { validate_mcp_server as n, validate_server_registry as r, validate_claude_config as t };
|
|
43
|
-
|
|
44
|
-
//# sourceMappingURL=validation-xMlbgGCF.js.map
|