mcpick 0.0.17 → 0.0.19
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/.vscode/settings.json +5 -0
- package/CHANGELOG.md +15 -0
- package/dist/add-B9nVyh8T.js +113 -0
- package/dist/add-json-CXNDl3al.js +58 -0
- package/dist/atomic-write-BqEykHp9.js +26 -0
- package/dist/backup-DSDhHI5f.js +64 -0
- package/dist/cache-D6kd7qE8.js +226 -0
- package/dist/claude-cli-BeA-bmoW.js +394 -0
- package/dist/cli-DNNZjJYL.js +84 -0
- package/dist/clone-DLFLewBY.js +88 -0
- package/dist/config-DijVdEFn.js +176 -0
- package/dist/dev-DRJRNp7y.js +265 -0
- package/dist/disable-BA8tXPJN.js +39 -0
- package/dist/enable-Bdnnn_Cq.js +40 -0
- package/dist/get-BPjMXTMc.js +41 -0
- package/dist/hook-state-Di8lUsPr.js +171 -0
- package/dist/hooks-Bmn7pUZa.js +280 -0
- package/dist/index.js +1230 -303
- package/dist/list-B8YeDWt6.js +64 -0
- package/dist/marketplace-Br89Tg-Z.js +168 -0
- package/dist/output-BchYq0mR.js +15 -0
- package/dist/paths-BPISiJi4.js +124 -0
- package/dist/plugin-cache-Bby9Dxm9.js +405 -0
- package/dist/plugins-DHYJF5CP.js +212 -0
- package/dist/profile-CX97sMGp.js +120 -0
- package/dist/profile-DkY_lBEm.js +70 -0
- package/dist/redact-O35tjnRD.js +26 -0
- package/dist/registry-CfUKT7_C.js +92 -0
- package/dist/reload-CYDhkCVZ.js +31 -0
- package/dist/remove-DIPWYMpk.js +31 -0
- package/dist/reset-project-choices-DRM5KByw.js +28 -0
- package/dist/restore-DdMfUljI.js +84 -0
- package/dist/rolldown-runtime-CiIaOW0V.js +13 -0
- package/dist/settings-DEcWtzLE.js +201 -0
- package/dist/validation-xMlbgGCF.js +44 -0
- package/package.json +20 -19
- package/dist/cli/commands/add-json.js +0 -60
- package/dist/cli/commands/add.js +0 -135
- package/dist/cli/commands/backup.js +0 -83
- package/dist/cli/commands/cache.js +0 -296
- package/dist/cli/commands/dev.js +0 -161
- package/dist/cli/commands/disable.js +0 -36
- package/dist/cli/commands/enable.js +0 -39
- package/dist/cli/commands/get.js +0 -45
- package/dist/cli/commands/hooks.js +0 -314
- package/dist/cli/commands/list.js +0 -63
- package/dist/cli/commands/marketplace.js +0 -211
- package/dist/cli/commands/plugins.js +0 -265
- package/dist/cli/commands/profile.js +0 -134
- package/dist/cli/commands/reload.js +0 -36
- package/dist/cli/commands/remove.js +0 -35
- package/dist/cli/commands/reset-project-choices.js +0 -32
- package/dist/cli/commands/restore.js +0 -105
- package/dist/cli/index.js +0 -28
- package/dist/cli/output.js +0 -21
- package/dist/commands/add-server.js +0 -310
- package/dist/commands/backup.js +0 -60
- package/dist/commands/edit-config.js +0 -109
- package/dist/commands/edit-plugins.js +0 -201
- package/dist/commands/manage-cache.js +0 -155
- package/dist/commands/manage-hooks.js +0 -99
- package/dist/commands/manage-marketplace.js +0 -293
- package/dist/commands/restore.js +0 -118
- package/dist/core/config.js +0 -146
- package/dist/core/dev-override.js +0 -210
- package/dist/core/hook-state.js +0 -220
- package/dist/core/plugin-cache.js +0 -506
- package/dist/core/profile.js +0 -94
- package/dist/core/registry.js +0 -121
- package/dist/core/settings.js +0 -243
- package/dist/core/validation.js +0 -49
- package/dist/types.js +0 -2
- package/dist/utils/atomic-write.js +0 -27
- package/dist/utils/claude-cli.js +0 -483
- package/dist/utils/paths.js +0 -114
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
|
|
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";
|
|
4
|
+
import { lstat, readFile, readdir, readlink, rename, rm, symlink } from "node:fs/promises";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
6
|
+
import { exec } from "node:child_process";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
//#region src/core/plugin-cache.ts
|
|
9
|
+
var plugin_cache_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
clean_orphaned_versions: () => clean_orphaned_versions,
|
|
11
|
+
clear_plugin_caches: () => clear_plugin_caches,
|
|
12
|
+
get_cached_plugins_info: () => get_cached_plugins_info,
|
|
13
|
+
link_local_plugin: () => link_local_plugin,
|
|
14
|
+
list_linked_plugins: () => list_linked_plugins,
|
|
15
|
+
parse_plugin_key: () => parse_plugin_key,
|
|
16
|
+
read_installed_plugins: () => read_installed_plugins,
|
|
17
|
+
read_known_marketplaces: () => read_known_marketplaces,
|
|
18
|
+
read_marketplace_manifest: () => read_marketplace_manifest,
|
|
19
|
+
refresh_all_marketplaces: () => refresh_all_marketplaces,
|
|
20
|
+
refresh_marketplace: () => refresh_marketplace,
|
|
21
|
+
scan_all_cache_keys: () => scan_all_cache_keys,
|
|
22
|
+
unlink_local_plugin: () => unlink_local_plugin,
|
|
23
|
+
write_installed_plugins: () => write_installed_plugins
|
|
24
|
+
});
|
|
25
|
+
const execAsync = promisify(exec);
|
|
26
|
+
const EMPTY_INSTALLED = {
|
|
27
|
+
version: 2,
|
|
28
|
+
plugins: {}
|
|
29
|
+
};
|
|
30
|
+
async function read_installed_plugins() {
|
|
31
|
+
try {
|
|
32
|
+
const content = await readFile(get_installed_plugins_path(), "utf-8");
|
|
33
|
+
return JSON.parse(content);
|
|
34
|
+
} catch {
|
|
35
|
+
return {
|
|
36
|
+
...EMPTY_INSTALLED,
|
|
37
|
+
plugins: {}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function write_installed_plugins(data) {
|
|
42
|
+
await atomic_json_write(get_installed_plugins_path(), () => data);
|
|
43
|
+
}
|
|
44
|
+
async function read_known_marketplaces() {
|
|
45
|
+
try {
|
|
46
|
+
const content = await readFile(get_known_marketplaces_path(), "utf-8");
|
|
47
|
+
return JSON.parse(content);
|
|
48
|
+
} catch {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function read_marketplace_manifest(name) {
|
|
53
|
+
try {
|
|
54
|
+
const content = await readFile(get_marketplace_manifest_path(name), "utf-8");
|
|
55
|
+
return JSON.parse(content);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function get_marketplace_head_sha(marketplace_path) {
|
|
61
|
+
try {
|
|
62
|
+
const { stdout } = await execAsync(`git -C ${JSON.stringify(marketplace_path)} rev-parse HEAD`, { timeout: 1e4 });
|
|
63
|
+
return stdout.trim() || null;
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Recover a marketplace clone stuck on a deleted branch.
|
|
70
|
+
* Resets the fetch refspec, fetches all branches, and checks out the default branch.
|
|
71
|
+
*/
|
|
72
|
+
async function recover_deleted_branch(dir) {
|
|
73
|
+
const q = JSON.stringify(dir);
|
|
74
|
+
try {
|
|
75
|
+
await execAsync(`git -C ${q} remote set-branches origin '*'`, { timeout: 1e4 });
|
|
76
|
+
await execAsync(`git -C ${q} fetch origin`, { timeout: 3e4 });
|
|
77
|
+
let default_branch = "main";
|
|
78
|
+
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\/(.+)/);
|
|
81
|
+
if (match) default_branch = match[1];
|
|
82
|
+
} catch {
|
|
83
|
+
try {
|
|
84
|
+
await execAsync(`git -C ${q} rev-parse --verify origin/main`, { timeout: 5e3 });
|
|
85
|
+
default_branch = "main";
|
|
86
|
+
} catch {
|
|
87
|
+
default_branch = "master";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
await execAsync(`git -C ${q} checkout ${default_branch}`, { timeout: 1e4 });
|
|
91
|
+
await execAsync(`git -C ${q} reset --hard origin/${default_branch}`, { timeout: 1e4 });
|
|
92
|
+
return { recovered: true };
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return {
|
|
95
|
+
recovered: false,
|
|
96
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function refresh_marketplace(name, marketplace) {
|
|
101
|
+
const dir = marketplace.installLocation;
|
|
102
|
+
try {
|
|
103
|
+
await execAsync(`git -C ${JSON.stringify(dir)} pull --ff-only`, { timeout: 3e4 });
|
|
104
|
+
return { success: true };
|
|
105
|
+
} catch {
|
|
106
|
+
const recovery = await recover_deleted_branch(dir);
|
|
107
|
+
if (recovery.recovered) return { success: true };
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: `${name}: recovery failed: ${recovery.error}`
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function refresh_all_marketplaces() {
|
|
115
|
+
const marketplaces = await read_known_marketplaces();
|
|
116
|
+
const results = /* @__PURE__ */ new Map();
|
|
117
|
+
for (const [name, info] of Object.entries(marketplaces)) results.set(name, await refresh_marketplace(name, info));
|
|
118
|
+
return results;
|
|
119
|
+
}
|
|
120
|
+
async function find_orphaned_versions(marketplace, plugin_name) {
|
|
121
|
+
const plugin_dir = join(get_plugin_cache_dir(), marketplace, plugin_name);
|
|
122
|
+
const orphaned = [];
|
|
123
|
+
try {
|
|
124
|
+
const versions = await readdir(plugin_dir, { withFileTypes: true });
|
|
125
|
+
for (const entry of versions) {
|
|
126
|
+
if (!entry.isDirectory()) continue;
|
|
127
|
+
try {
|
|
128
|
+
await readFile(join(plugin_dir, entry.name, ".orphaned_at"));
|
|
129
|
+
orphaned.push(entry.name);
|
|
130
|
+
} catch {}
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
133
|
+
return orphaned;
|
|
134
|
+
}
|
|
135
|
+
function parse_plugin_key(key) {
|
|
136
|
+
const at_index = key.lastIndexOf("@");
|
|
137
|
+
return {
|
|
138
|
+
name: at_index > 0 ? key.substring(0, at_index) : key,
|
|
139
|
+
marketplace: at_index > 0 ? key.substring(at_index + 1) : "unknown"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
async function get_cached_plugins_info() {
|
|
143
|
+
const installed = await read_installed_plugins();
|
|
144
|
+
const marketplaces = await read_known_marketplaces();
|
|
145
|
+
const manifests = /* @__PURE__ */ new Map();
|
|
146
|
+
for (const name of Object.keys(marketplaces)) {
|
|
147
|
+
const manifest = await read_marketplace_manifest(name);
|
|
148
|
+
if (manifest) manifests.set(name, manifest);
|
|
149
|
+
}
|
|
150
|
+
const sha_cache = /* @__PURE__ */ new Map();
|
|
151
|
+
for (const [name, info] of Object.entries(marketplaces)) sha_cache.set(name, await get_marketplace_head_sha(info.installLocation));
|
|
152
|
+
const results = [];
|
|
153
|
+
for (const [key, entries] of Object.entries(installed.plugins)) {
|
|
154
|
+
const entry = entries[0];
|
|
155
|
+
if (!entry) continue;
|
|
156
|
+
const { name, marketplace } = parse_plugin_key(key);
|
|
157
|
+
const latest_version = (manifests.get(marketplace)?.plugins.find((p) => p.name === name))?.version ?? null;
|
|
158
|
+
const is_version_stale = latest_version !== null && latest_version !== entry.version;
|
|
159
|
+
const remote_sha = sha_cache.get(marketplace) ?? null;
|
|
160
|
+
const is_sha_stale = remote_sha !== null && entry.gitCommitSha !== "" && remote_sha !== entry.gitCommitSha;
|
|
161
|
+
const orphaned = await find_orphaned_versions(marketplace, name);
|
|
162
|
+
results.push({
|
|
163
|
+
key,
|
|
164
|
+
name,
|
|
165
|
+
marketplace,
|
|
166
|
+
installedVersion: entry.version,
|
|
167
|
+
latestVersion: latest_version,
|
|
168
|
+
installedSha: entry.gitCommitSha,
|
|
169
|
+
remoteSha: remote_sha,
|
|
170
|
+
isVersionStale: is_version_stale,
|
|
171
|
+
isShaStale: is_sha_stale,
|
|
172
|
+
orphanedVersions: orphaned,
|
|
173
|
+
installPath: entry.installPath
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return results;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Scan the cache directory on disk to find all plugin keys,
|
|
180
|
+
* including marketplace-sourced plugins not tracked in installed_plugins.json.
|
|
181
|
+
*/
|
|
182
|
+
async function scan_all_cache_keys() {
|
|
183
|
+
const cache_dir = get_plugin_cache_dir();
|
|
184
|
+
const keys = [];
|
|
185
|
+
try {
|
|
186
|
+
const marketplaces = await readdir(cache_dir, { withFileTypes: true });
|
|
187
|
+
for (const mkt of marketplaces) {
|
|
188
|
+
if (!mkt.isDirectory() && !mkt.isSymbolicLink()) continue;
|
|
189
|
+
const mkt_path = join(cache_dir, mkt.name);
|
|
190
|
+
try {
|
|
191
|
+
const plugins = await readdir(mkt_path, { withFileTypes: true });
|
|
192
|
+
for (const plugin of plugins) {
|
|
193
|
+
if (!plugin.isDirectory() && !plugin.isSymbolicLink()) continue;
|
|
194
|
+
keys.push(`${plugin.name}@${mkt.name}`);
|
|
195
|
+
}
|
|
196
|
+
} catch {}
|
|
197
|
+
}
|
|
198
|
+
} catch {}
|
|
199
|
+
return keys;
|
|
200
|
+
}
|
|
201
|
+
function is_safe_cache_path(path) {
|
|
202
|
+
const cache_dir = resolve(get_plugin_cache_dir());
|
|
203
|
+
return resolve(path).startsWith(cache_dir + "/");
|
|
204
|
+
}
|
|
205
|
+
async function clear_plugin_caches(keys) {
|
|
206
|
+
const installed = await read_installed_plugins();
|
|
207
|
+
const marketplaces = await read_known_marketplaces();
|
|
208
|
+
const cleared = [];
|
|
209
|
+
const errors = [];
|
|
210
|
+
const marketplace_names = /* @__PURE__ */ new Set();
|
|
211
|
+
for (const key of keys) {
|
|
212
|
+
const { marketplace } = parse_plugin_key(key);
|
|
213
|
+
marketplace_names.add(marketplace);
|
|
214
|
+
}
|
|
215
|
+
for (const mkt_name of marketplace_names) {
|
|
216
|
+
const mkt_info = marketplaces[mkt_name];
|
|
217
|
+
if (mkt_info) {
|
|
218
|
+
const result = await refresh_marketplace(mkt_name, mkt_info);
|
|
219
|
+
if (!result.success) errors.push(`Marketplace refresh failed: ${result.error}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const cache_dir = get_plugin_cache_dir();
|
|
223
|
+
for (const key of keys) {
|
|
224
|
+
const { name, marketplace } = parse_plugin_key(key);
|
|
225
|
+
const plugin_cache_path = join(cache_dir, marketplace, name);
|
|
226
|
+
if (!is_safe_cache_path(plugin_cache_path)) {
|
|
227
|
+
errors.push(`Unsafe path, skipped: ${plugin_cache_path}`);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
await rm(plugin_cache_path, {
|
|
232
|
+
recursive: true,
|
|
233
|
+
force: true
|
|
234
|
+
});
|
|
235
|
+
delete installed.plugins[key];
|
|
236
|
+
cleared.push(key);
|
|
237
|
+
} catch (err) {
|
|
238
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
239
|
+
errors.push(`Failed to clear ${key}: ${msg}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
await write_installed_plugins(installed);
|
|
243
|
+
return {
|
|
244
|
+
cleared,
|
|
245
|
+
errors
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
async function clean_orphaned_versions() {
|
|
249
|
+
const cache_dir = get_plugin_cache_dir();
|
|
250
|
+
const cleaned_paths = [];
|
|
251
|
+
try {
|
|
252
|
+
const marketplaces = await readdir(cache_dir, { withFileTypes: true });
|
|
253
|
+
for (const mkt of marketplaces) {
|
|
254
|
+
if (!mkt.isDirectory()) continue;
|
|
255
|
+
const mkt_path = join(cache_dir, mkt.name);
|
|
256
|
+
const plugins = await readdir(mkt_path, { withFileTypes: true });
|
|
257
|
+
for (const plugin of plugins) {
|
|
258
|
+
if (!plugin.isDirectory()) continue;
|
|
259
|
+
const plugin_path = join(mkt_path, plugin.name);
|
|
260
|
+
const versions = await readdir(plugin_path, { withFileTypes: true });
|
|
261
|
+
for (const version of versions) {
|
|
262
|
+
if (!version.isDirectory()) continue;
|
|
263
|
+
const version_path = join(plugin_path, version.name);
|
|
264
|
+
try {
|
|
265
|
+
await readFile(join(version_path, ".orphaned_at"));
|
|
266
|
+
if (is_safe_cache_path(version_path)) {
|
|
267
|
+
await rm(version_path, {
|
|
268
|
+
recursive: true,
|
|
269
|
+
force: true
|
|
270
|
+
});
|
|
271
|
+
cleaned_paths.push(`${mkt.name}/${plugin.name}/${version.name}`);
|
|
272
|
+
}
|
|
273
|
+
} catch {}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
} catch {}
|
|
278
|
+
return {
|
|
279
|
+
cleaned: cleaned_paths.length,
|
|
280
|
+
paths: cleaned_paths
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Symlink a local directory into the plugin cache.
|
|
285
|
+
* Backs up existing cache directory if present.
|
|
286
|
+
*/
|
|
287
|
+
async function link_local_plugin(local_path, key) {
|
|
288
|
+
const resolved_path = resolve(local_path);
|
|
289
|
+
const { name, marketplace } = parse_plugin_key(key);
|
|
290
|
+
try {
|
|
291
|
+
if (!(await lstat(resolved_path)).isDirectory()) return {
|
|
292
|
+
success: false,
|
|
293
|
+
key,
|
|
294
|
+
symlinkPath: "",
|
|
295
|
+
targetPath: resolved_path,
|
|
296
|
+
error: `Path is not a directory: ${resolved_path}`
|
|
297
|
+
};
|
|
298
|
+
} catch {
|
|
299
|
+
return {
|
|
300
|
+
success: false,
|
|
301
|
+
key,
|
|
302
|
+
symlinkPath: "",
|
|
303
|
+
targetPath: resolved_path,
|
|
304
|
+
error: `Path does not exist: ${resolved_path}`
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
const cache_dir = get_plugin_cache_dir();
|
|
308
|
+
const plugin_dir = join(cache_dir, marketplace, name);
|
|
309
|
+
await ensure_directory_exists(join(cache_dir, marketplace));
|
|
310
|
+
try {
|
|
311
|
+
const stat = await lstat(plugin_dir);
|
|
312
|
+
if (stat.isSymbolicLink()) await rm(plugin_dir);
|
|
313
|
+
else if (stat.isDirectory()) await rename(plugin_dir, `${plugin_dir}.backup`);
|
|
314
|
+
} catch {}
|
|
315
|
+
try {
|
|
316
|
+
await symlink(resolved_path, plugin_dir, "dir");
|
|
317
|
+
} catch (err) {
|
|
318
|
+
return {
|
|
319
|
+
success: false,
|
|
320
|
+
key,
|
|
321
|
+
symlinkPath: plugin_dir,
|
|
322
|
+
targetPath: resolved_path,
|
|
323
|
+
error: `Failed to create symlink: ${err instanceof Error ? err.message : "Unknown error"}`
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
success: true,
|
|
328
|
+
key,
|
|
329
|
+
symlinkPath: plugin_dir,
|
|
330
|
+
targetPath: resolved_path
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Remove a symlink from the plugin cache and restore backup if present.
|
|
335
|
+
*/
|
|
336
|
+
async function unlink_local_plugin(key) {
|
|
337
|
+
const { name, marketplace } = parse_plugin_key(key);
|
|
338
|
+
const plugin_dir = join(get_plugin_cache_dir(), marketplace, name);
|
|
339
|
+
try {
|
|
340
|
+
if (!(await lstat(plugin_dir)).isSymbolicLink()) return {
|
|
341
|
+
success: false,
|
|
342
|
+
key,
|
|
343
|
+
restored: false,
|
|
344
|
+
error: `'${key}' is not a symlink — nothing to unlink`
|
|
345
|
+
};
|
|
346
|
+
} catch {
|
|
347
|
+
return {
|
|
348
|
+
success: false,
|
|
349
|
+
key,
|
|
350
|
+
restored: false,
|
|
351
|
+
error: `'${key}' not found in cache`
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
await rm(plugin_dir);
|
|
355
|
+
const backup_path = `${plugin_dir}.backup`;
|
|
356
|
+
let restored = false;
|
|
357
|
+
try {
|
|
358
|
+
await lstat(backup_path);
|
|
359
|
+
await rename(backup_path, plugin_dir);
|
|
360
|
+
restored = true;
|
|
361
|
+
} catch {}
|
|
362
|
+
return {
|
|
363
|
+
success: true,
|
|
364
|
+
key,
|
|
365
|
+
restored
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* List all symlinked entries in the plugin cache.
|
|
370
|
+
*/
|
|
371
|
+
async function list_linked_plugins() {
|
|
372
|
+
const cache_dir = get_plugin_cache_dir();
|
|
373
|
+
const links = [];
|
|
374
|
+
try {
|
|
375
|
+
const marketplaces = await readdir(cache_dir, { withFileTypes: true });
|
|
376
|
+
for (const mkt of marketplaces) {
|
|
377
|
+
if (!mkt.isDirectory() && !mkt.isSymbolicLink()) continue;
|
|
378
|
+
const mkt_path = join(cache_dir, mkt.name);
|
|
379
|
+
let entries;
|
|
380
|
+
try {
|
|
381
|
+
entries = await readdir(mkt_path, { withFileTypes: true });
|
|
382
|
+
} catch {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
for (const entry of entries) {
|
|
386
|
+
const entry_path = join(mkt_path, entry.name);
|
|
387
|
+
try {
|
|
388
|
+
if ((await lstat(entry_path)).isSymbolicLink()) {
|
|
389
|
+
const target = await readlink(entry_path);
|
|
390
|
+
links.push({
|
|
391
|
+
key: `${entry.name}@${mkt.name}`,
|
|
392
|
+
symlinkPath: entry_path,
|
|
393
|
+
targetPath: resolve(join(cache_dir, mkt.name), target)
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
} catch {}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
} catch {}
|
|
400
|
+
return links;
|
|
401
|
+
}
|
|
402
|
+
//#endregion
|
|
403
|
+
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
|
+
|
|
405
|
+
//# sourceMappingURL=plugin-cache-Bby9Dxm9.js.map
|
|
@@ -0,0 +1,212 @@
|
|
|
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-BeA-bmoW.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";
|
|
5
|
+
import { defineCommand } from "citty";
|
|
6
|
+
var plugins_default = defineCommand({
|
|
7
|
+
meta: {
|
|
8
|
+
name: "plugins",
|
|
9
|
+
description: "Manage Claude Code plugins (bundles of skills, hooks, agents, and MCP servers). Install from a marketplace with: mcpick plugins install <name>@<marketplace>"
|
|
10
|
+
},
|
|
11
|
+
subCommands: {
|
|
12
|
+
list: defineCommand({
|
|
13
|
+
meta: {
|
|
14
|
+
name: "list",
|
|
15
|
+
description: "List all plugins and their status"
|
|
16
|
+
},
|
|
17
|
+
args: { json: {
|
|
18
|
+
type: "boolean",
|
|
19
|
+
description: "Output as JSON",
|
|
20
|
+
default: false
|
|
21
|
+
} },
|
|
22
|
+
async run({ args }) {
|
|
23
|
+
const plugins = get_all_plugins(await read_claude_settings());
|
|
24
|
+
if (args.json) output(plugins, true);
|
|
25
|
+
else {
|
|
26
|
+
if (plugins.length === 0) {
|
|
27
|
+
console.log("No plugins found.");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const p of plugins) {
|
|
31
|
+
const status = p.enabled ? "on" : "off";
|
|
32
|
+
console.log(`${p.name}@${p.marketplace} ${status}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
enable: defineCommand({
|
|
38
|
+
meta: {
|
|
39
|
+
name: "enable",
|
|
40
|
+
description: "Enable a plugin"
|
|
41
|
+
},
|
|
42
|
+
args: { plugin: {
|
|
43
|
+
type: "positional",
|
|
44
|
+
description: "Plugin key (name@marketplace)",
|
|
45
|
+
required: true
|
|
46
|
+
} },
|
|
47
|
+
async run({ args }) {
|
|
48
|
+
const plugins = get_all_plugins(await read_claude_settings());
|
|
49
|
+
const key = args.plugin;
|
|
50
|
+
const plugin = plugins.find((p) => `${p.name}@${p.marketplace}` === key);
|
|
51
|
+
if (!plugin) error(`Plugin '${key}' not found. Run 'mcpick plugins list' to see available plugins.`);
|
|
52
|
+
plugin.enabled = true;
|
|
53
|
+
await write_claude_settings({ enabledPlugins: build_enabled_plugins(plugins) });
|
|
54
|
+
console.log(`Enabled plugin '${key}'`);
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
disable: defineCommand({
|
|
58
|
+
meta: {
|
|
59
|
+
name: "disable",
|
|
60
|
+
description: "Disable a plugin"
|
|
61
|
+
},
|
|
62
|
+
args: { plugin: {
|
|
63
|
+
type: "positional",
|
|
64
|
+
description: "Plugin key (name@marketplace)",
|
|
65
|
+
required: true
|
|
66
|
+
} },
|
|
67
|
+
async run({ args }) {
|
|
68
|
+
const plugins = get_all_plugins(await read_claude_settings());
|
|
69
|
+
const key = args.plugin;
|
|
70
|
+
const plugin = plugins.find((p) => `${p.name}@${p.marketplace}` === key);
|
|
71
|
+
if (!plugin) error(`Plugin '${key}' not found. Run 'mcpick plugins list' to see available plugins.`);
|
|
72
|
+
plugin.enabled = false;
|
|
73
|
+
await write_claude_settings({ enabledPlugins: build_enabled_plugins(plugins) });
|
|
74
|
+
console.log(`Disabled plugin '${key}'`);
|
|
75
|
+
}
|
|
76
|
+
}),
|
|
77
|
+
install: defineCommand({
|
|
78
|
+
meta: {
|
|
79
|
+
name: "install",
|
|
80
|
+
description: "Install a plugin from a marketplace"
|
|
81
|
+
},
|
|
82
|
+
args: {
|
|
83
|
+
plugin: {
|
|
84
|
+
type: "positional",
|
|
85
|
+
description: "Plugin key (name@marketplace)",
|
|
86
|
+
required: true
|
|
87
|
+
},
|
|
88
|
+
scope: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Installation scope: user, project, or local",
|
|
91
|
+
default: "user"
|
|
92
|
+
},
|
|
93
|
+
json: {
|
|
94
|
+
type: "boolean",
|
|
95
|
+
description: "Output as JSON",
|
|
96
|
+
default: false
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
async run({ args }) {
|
|
100
|
+
const scope = args.scope;
|
|
101
|
+
const result = await install_plugin_via_cli(args.plugin, scope);
|
|
102
|
+
if (args.json) output(result, true);
|
|
103
|
+
else if (result.success) console.log(`Installed plugin '${args.plugin}' (scope: ${scope})`);
|
|
104
|
+
else error(result.error ?? "Unknown error");
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
uninstall: defineCommand({
|
|
108
|
+
meta: {
|
|
109
|
+
name: "uninstall",
|
|
110
|
+
description: "Uninstall a plugin"
|
|
111
|
+
},
|
|
112
|
+
args: {
|
|
113
|
+
plugin: {
|
|
114
|
+
type: "positional",
|
|
115
|
+
description: "Plugin key (name@marketplace)",
|
|
116
|
+
required: true
|
|
117
|
+
},
|
|
118
|
+
scope: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description: "Uninstall from scope: user, project, or local",
|
|
121
|
+
default: "user"
|
|
122
|
+
},
|
|
123
|
+
json: {
|
|
124
|
+
type: "boolean",
|
|
125
|
+
description: "Output as JSON",
|
|
126
|
+
default: false
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
async run({ args }) {
|
|
130
|
+
const scope = args.scope;
|
|
131
|
+
const { marketplace } = parse_plugin_key(args.plugin);
|
|
132
|
+
if ((await read_known_marketplaces())[marketplace]) {
|
|
133
|
+
const msg = `'${args.plugin}' is managed by marketplace '${marketplace}'.\nTo remove the marketplace: mcpick marketplace remove ${marketplace}\nOr via Claude CLI: claude plugin marketplace remove ${marketplace}`;
|
|
134
|
+
if (args.json) output({
|
|
135
|
+
success: false,
|
|
136
|
+
error: msg,
|
|
137
|
+
marketplace_managed: true
|
|
138
|
+
}, true);
|
|
139
|
+
else error(msg);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const result = await uninstall_plugin_via_cli(args.plugin, scope);
|
|
143
|
+
if (args.json) output(result, true);
|
|
144
|
+
else if (result.success) console.log(`Uninstalled plugin '${args.plugin}' (scope: ${scope})`);
|
|
145
|
+
else error(result.error ?? "Unknown error");
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
148
|
+
update: defineCommand({
|
|
149
|
+
meta: {
|
|
150
|
+
name: "update",
|
|
151
|
+
description: "Update a plugin to latest version"
|
|
152
|
+
},
|
|
153
|
+
args: {
|
|
154
|
+
plugin: {
|
|
155
|
+
type: "positional",
|
|
156
|
+
description: "Plugin key (name@marketplace)",
|
|
157
|
+
required: true
|
|
158
|
+
},
|
|
159
|
+
scope: {
|
|
160
|
+
type: "string",
|
|
161
|
+
description: "Scope to update: user, project, or local",
|
|
162
|
+
default: "user"
|
|
163
|
+
},
|
|
164
|
+
json: {
|
|
165
|
+
type: "boolean",
|
|
166
|
+
description: "Output as JSON",
|
|
167
|
+
default: false
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
async run({ args }) {
|
|
171
|
+
const scope = args.scope;
|
|
172
|
+
const result = await update_plugin_via_cli(args.plugin, scope);
|
|
173
|
+
if (args.json) output(result, true);
|
|
174
|
+
else if (result.success) console.log(`Updated plugin '${args.plugin}' (scope: ${scope})`);
|
|
175
|
+
else error(result.error ?? "Unknown error");
|
|
176
|
+
}
|
|
177
|
+
}),
|
|
178
|
+
validate: defineCommand({
|
|
179
|
+
meta: {
|
|
180
|
+
name: "validate",
|
|
181
|
+
description: "Validate a plugin or marketplace manifest"
|
|
182
|
+
},
|
|
183
|
+
args: {
|
|
184
|
+
path: {
|
|
185
|
+
type: "positional",
|
|
186
|
+
description: "Path to plugin or marketplace manifest",
|
|
187
|
+
required: true
|
|
188
|
+
},
|
|
189
|
+
json: {
|
|
190
|
+
type: "boolean",
|
|
191
|
+
description: "Output as JSON",
|
|
192
|
+
default: false
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
async run({ args }) {
|
|
196
|
+
const result = await validate_plugin_via_cli(args.path);
|
|
197
|
+
if (args.json) output({
|
|
198
|
+
path: args.path,
|
|
199
|
+
valid: result.success,
|
|
200
|
+
output: result.stdout,
|
|
201
|
+
error: result.error
|
|
202
|
+
}, true);
|
|
203
|
+
else if (result.success) console.log(result.stdout || "Validation passed.");
|
|
204
|
+
else error(result.error || "Validation failed");
|
|
205
|
+
}
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
//#endregion
|
|
210
|
+
export { plugins_default as default };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=plugins-DHYJF5CP.js.map
|