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,216 @@
1
+ import { a as split_cli_list, i as run_skills_cli } 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/skills.ts
5
+ function add_agent_args(cli_args, agent) {
6
+ const agents = split_cli_list(agent);
7
+ if (agents.length > 0) cli_args.push("--agent", ...agents);
8
+ }
9
+ function add_skill_args(cli_args, skill) {
10
+ const skills = split_cli_list(skill);
11
+ if (skills.length > 0) cli_args.push("--skill", ...skills);
12
+ }
13
+ async function print_result(result, json, fallback) {
14
+ if (json) {
15
+ if (result.stdout) try {
16
+ output(JSON.parse(result.stdout), true);
17
+ return;
18
+ } catch {}
19
+ output(result, true);
20
+ return;
21
+ }
22
+ if (result.success) {
23
+ output(result.stdout || fallback, false);
24
+ return;
25
+ }
26
+ error(result.stderr || result.error || "skills CLI failed");
27
+ }
28
+ var skills_default = defineCommand({
29
+ meta: {
30
+ name: "skills",
31
+ description: "Manage portable agent skills via the external skills CLI. Examples: mcpick skills add spences10/skills --agent pi --skill svelte-runes; mcpick skills list --agent pi --json"
32
+ },
33
+ subCommands: {
34
+ list: defineCommand({
35
+ meta: {
36
+ name: "list",
37
+ description: "List installed portable skills for supported agent clients"
38
+ },
39
+ args: {
40
+ agent: {
41
+ type: "string",
42
+ description: "Agent/client to filter: claude-code, pi, opencode, codex, cursor, windsurf, or *"
43
+ },
44
+ global: {
45
+ type: "boolean",
46
+ description: "List global/user skills instead of project skills",
47
+ default: false
48
+ },
49
+ json: {
50
+ type: "boolean",
51
+ description: "Output as JSON",
52
+ default: false
53
+ }
54
+ },
55
+ async run({ args }) {
56
+ const cli_args = ["list"];
57
+ if (args.global) cli_args.push("--global");
58
+ add_agent_args(cli_args, args.agent);
59
+ if (args.json) cli_args.push("--json");
60
+ await print_result(await run_skills_cli(cli_args), args.json, "No skills found.");
61
+ }
62
+ }),
63
+ add: defineCommand({
64
+ meta: {
65
+ name: "add",
66
+ description: "Install portable skills from a repo/package using the external skills CLI"
67
+ },
68
+ args: {
69
+ source: {
70
+ type: "positional",
71
+ description: "Skill source, e.g. spences10/skills, a GitHub URL, npm package, or local path",
72
+ required: true
73
+ },
74
+ agent: {
75
+ type: "string",
76
+ description: "Agent/client(s) to install to. Use comma-separated values or * for all agents"
77
+ },
78
+ skill: {
79
+ type: "string",
80
+ description: "Skill name(s) to install. Use comma-separated values or * for all skills"
81
+ },
82
+ global: {
83
+ type: "boolean",
84
+ description: "Install globally/user-level instead of project-level",
85
+ default: false
86
+ },
87
+ list: {
88
+ type: "boolean",
89
+ description: "List available skills in the source without installing",
90
+ default: false
91
+ },
92
+ copy: {
93
+ type: "boolean",
94
+ description: "Copy files instead of symlinking into agent directories",
95
+ default: false
96
+ },
97
+ "full-depth": {
98
+ type: "boolean",
99
+ description: "Search all subdirectories even when a root SKILL.md exists",
100
+ default: false
101
+ },
102
+ yes: {
103
+ type: "boolean",
104
+ description: "Skip confirmation prompts. Defaults true so LLM/CI use does not hang.",
105
+ default: true
106
+ },
107
+ json: {
108
+ type: "boolean",
109
+ description: "Output as JSON",
110
+ default: false
111
+ }
112
+ },
113
+ async run({ args }) {
114
+ const cli_args = ["add", args.source];
115
+ if (args.global) cli_args.push("--global");
116
+ if (args.list) cli_args.push("--list");
117
+ if (args.copy) cli_args.push("--copy");
118
+ if (args["full-depth"]) cli_args.push("--full-depth");
119
+ if (args.yes) cli_args.push("--yes");
120
+ add_agent_args(cli_args, args.agent);
121
+ add_skill_args(cli_args, args.skill);
122
+ await print_result(await run_skills_cli(cli_args), args.json, "Skills command completed.");
123
+ }
124
+ }),
125
+ update: defineCommand({
126
+ meta: {
127
+ name: "update",
128
+ description: "Update installed portable skills to latest versions"
129
+ },
130
+ args: {
131
+ skills: {
132
+ type: "positional",
133
+ description: "Optional comma-separated skill names. Omit to update all selected skills.",
134
+ required: false
135
+ },
136
+ global: {
137
+ type: "boolean",
138
+ description: "Update global/user skills only",
139
+ default: false
140
+ },
141
+ project: {
142
+ type: "boolean",
143
+ description: "Update project skills only",
144
+ default: false
145
+ },
146
+ yes: {
147
+ type: "boolean",
148
+ description: "Skip confirmation prompts. Defaults true so LLM/CI use does not hang.",
149
+ default: true
150
+ },
151
+ json: {
152
+ type: "boolean",
153
+ description: "Output as JSON",
154
+ default: false
155
+ }
156
+ },
157
+ async run({ args }) {
158
+ const cli_args = ["update", ...split_cli_list(args.skills)];
159
+ if (args.global) cli_args.push("--global");
160
+ if (args.project) cli_args.push("--project");
161
+ if (args.yes) cli_args.push("--yes");
162
+ await print_result(await run_skills_cli(cli_args), args.json, "Skills updated.");
163
+ }
164
+ }),
165
+ remove: defineCommand({
166
+ meta: {
167
+ name: "remove",
168
+ description: "Remove installed portable skills"
169
+ },
170
+ args: {
171
+ skills: {
172
+ type: "positional",
173
+ description: "Skill name(s), comma-separated. Use --all to remove all.",
174
+ required: false
175
+ },
176
+ agent: {
177
+ type: "string",
178
+ description: "Agent/client(s) to remove from. Use comma-separated values or * for all agents"
179
+ },
180
+ global: {
181
+ type: "boolean",
182
+ description: "Remove from global/user scope instead of project scope",
183
+ default: false
184
+ },
185
+ all: {
186
+ type: "boolean",
187
+ description: "Remove all matching skills",
188
+ default: false
189
+ },
190
+ yes: {
191
+ type: "boolean",
192
+ description: "Skip confirmation prompts. Defaults true so LLM/CI use does not hang.",
193
+ default: true
194
+ },
195
+ json: {
196
+ type: "boolean",
197
+ description: "Output as JSON",
198
+ default: false
199
+ }
200
+ },
201
+ async run({ args }) {
202
+ if (!args.skills && !args.all) error("Pass a skill name, comma-separated skill names, or --all.");
203
+ const cli_args = ["remove", ...split_cli_list(args.skills)];
204
+ if (args.global) cli_args.push("--global");
205
+ if (args.all) cli_args.push("--all");
206
+ if (args.yes) cli_args.push("--yes");
207
+ add_agent_args(cli_args, args.agent);
208
+ await print_result(await run_skills_cli(cli_args), args.json, "Skills removed.");
209
+ }
210
+ })
211
+ }
212
+ });
213
+ //#endregion
214
+ export { skills_default as default };
215
+
216
+ //# sourceMappingURL=skills-DfWk9mpk.js.map
package/package.json CHANGED
@@ -1,31 +1,45 @@
1
1
  {
2
2
  "name": "mcpick",
3
- "version": "0.0.21",
4
- "description": "Claude Code extension manager MCP servers, plugins (skills, hooks, agents), and marketplaces",
3
+ "version": "0.0.23",
4
+ "description": "Vendor-neutral MCP configuration manager with first-class Claude Code support",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
8
8
  "cli",
9
9
  "configuration",
10
- "mcp"
10
+ "cursor",
11
+ "gemini-cli",
12
+ "mcp",
13
+ "model-context-protocol",
14
+ "opencode",
15
+ "pi-coding-agent",
16
+ "vscode"
11
17
  ],
18
+ "homepage": "https://github.com/spences10/mcpick#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/spences10/mcpick/issues"
21
+ },
12
22
  "license": "MIT",
13
- "author": "",
23
+ "author": "spences10 <spences10apps@gmail.com>",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/spences10/mcpick.git"
27
+ },
14
28
  "bin": {
15
29
  "mcpick": "./dist/index.js"
16
30
  },
17
31
  "type": "module",
18
32
  "main": "./dist/index.js",
19
33
  "dependencies": {
20
- "@clack/prompts": "^1.2.0",
34
+ "@clack/prompts": "^1.3.0",
21
35
  "citty": "^0.2.2",
22
36
  "valibot": "^1.3.1"
23
37
  },
24
38
  "devDependencies": {
25
- "@changesets/cli": "^2.30.0",
39
+ "@changesets/cli": "^2.31.0",
26
40
  "@types/node": "^25.6.0",
27
- "vite-plus": "^0.1.16",
28
- "vitest": "^4.1.4"
41
+ "vite-plus": "^0.1.20",
42
+ "vitest": "^4.1.5"
29
43
  },
30
44
  "engines": {
31
45
  "node": ">=22.0.0"
@@ -1,32 +0,0 @@
1
- # McPick Development Instructions
2
-
3
- **Always reference these instructions first and fallback to search or
4
- bash commands only when you encounter unexpected information that does
5
- not match the info here.**
6
-
7
- ## Working Effectively
8
-
9
- ### Prerequisites and Setup
10
-
11
- - Install Node.js >=22.0.0
12
- - Install pnpm globally: `npm install -g pnpm` (takes ~2 seconds)
13
-
14
- ### Development Commands
15
-
16
- - **Format code**: `pnpm run format`
17
- - **Build**: `pnpm run build`
18
-
19
- ## Validation Requirements
20
-
21
- ### ALWAYS run these before submitting changes:
22
-
23
- 1. `pnpm run format` - Auto-format all code
24
- 2. `pnpm run build` - Check for build issues
25
-
26
- #### Add changeset once you're done
27
-
28
- Run `pnpm changeset` then follow the prompts. Use this after having
29
- finished the task. Most of the time this is a patch release for
30
- `mcpick`. Use a short and descriptive message. Always prefix the
31
- message with either `fix`, `feat`, `breaking`, or `chore` (most likely
32
- `fix` since you're mostly working on bugfixes).
@@ -1,26 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - uses: actions/checkout@v6
14
-
15
- - uses: pnpm/action-setup@v6
16
-
17
- - uses: actions/setup-node@v6
18
- with:
19
- node-version-file: package.json
20
- cache: pnpm
21
-
22
- - run: pnpm install --frozen-lockfile
23
-
24
- - run: pnpm run build
25
-
26
- - run: pnpm run test
@@ -1,5 +0,0 @@
1
- {
2
- "editor.defaultFormatter": "oxc.oxc-vscode",
3
- "editor.formatOnSave": true,
4
- "oxc.fmt.configPath": "./vite.config.ts"
5
- }
@@ -1,113 +0,0 @@
1
- import { n as validate_mcp_server } from "./validation-xMlbgGCF.js";
2
- import { t as add_server_to_registry } from "./registry-CfUKT7_C.js";
3
- import { t as add_mcp_via_cli } from "./claude-cli-DnmBJrjg.js";
4
- import { n as output, t as error } from "./output-BchYq0mR.js";
5
- import { defineCommand } from "citty";
6
- //#region src/cli/commands/add.ts
7
- var add_default = defineCommand({
8
- meta: {
9
- name: "add",
10
- description: "Add a new MCP server to the registry and enable it"
11
- },
12
- args: {
13
- name: {
14
- type: "string",
15
- description: "Server name",
16
- required: true
17
- },
18
- command: {
19
- type: "string",
20
- description: "Command to run (for stdio transport)"
21
- },
22
- args: {
23
- type: "string",
24
- description: "Comma-separated arguments (e.g. \"npx,-y,mcp-sqlite\")"
25
- },
26
- url: {
27
- type: "string",
28
- description: "URL (for sse or http transport)"
29
- },
30
- type: {
31
- type: "string",
32
- description: "Transport type: stdio, sse, or http (default: stdio)",
33
- default: "stdio"
34
- },
35
- env: {
36
- type: "string",
37
- description: "Environment variables as KEY=val,KEY=val"
38
- },
39
- headers: {
40
- type: "string",
41
- description: "HTTP headers as KEY=val,KEY=val"
42
- },
43
- description: {
44
- type: "string",
45
- description: "Server description"
46
- },
47
- scope: {
48
- type: "string",
49
- description: "Scope: local, project, or user (default: local)",
50
- default: "local"
51
- },
52
- json: {
53
- type: "boolean",
54
- description: "Output as JSON",
55
- default: false
56
- }
57
- },
58
- async run({ args }) {
59
- const scope = args.scope;
60
- if (![
61
- "local",
62
- "project",
63
- "user"
64
- ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
65
- const transport = args.type;
66
- if (![
67
- "stdio",
68
- "sse",
69
- "http"
70
- ].includes(transport)) error(`Invalid type: ${transport}. Use stdio, sse, or http.`);
71
- const server_data = { name: args.name };
72
- if (transport === "stdio") {
73
- if (!args.command) error("--command is required for stdio transport");
74
- server_data.command = args.command;
75
- if (args.args) server_data.args = args.args.split(",");
76
- } else {
77
- if (!args.url) error(`--url is required for ${transport} transport`);
78
- server_data.type = transport;
79
- server_data.url = args.url;
80
- if (args.headers) server_data.headers = parse_key_value_pairs(args.headers);
81
- }
82
- if (args.env) server_data.env = parse_key_value_pairs(args.env);
83
- if (args.description) server_data.description = args.description;
84
- let server;
85
- try {
86
- server = validate_mcp_server(server_data);
87
- } catch (err) {
88
- error(`Invalid server config: ${err instanceof Error ? err.message : "validation failed"}`);
89
- }
90
- await add_server_to_registry(server);
91
- const result = await add_mcp_via_cli(server, scope);
92
- if (args.json) output({
93
- added: server.name,
94
- scope,
95
- cli: result.success,
96
- error: result.error
97
- }, true);
98
- else if (result.success) console.log(`Added '${server.name}' and enabled (scope: ${scope})`);
99
- else console.log(`Added '${server.name}' to registry but CLI failed: ${result.error}`);
100
- }
101
- });
102
- function parse_key_value_pairs(input) {
103
- const result = {};
104
- for (const pair of input.split(",")) {
105
- const eq = pair.indexOf("=");
106
- if (eq > 0) result[pair.substring(0, eq)] = pair.substring(eq + 1);
107
- }
108
- return result;
109
- }
110
- //#endregion
111
- export { add_default as default };
112
-
113
- //# sourceMappingURL=add-BDyaBew0.js.map
@@ -1,58 +0,0 @@
1
- import { u as mcp_add_json_via_cli } from "./claude-cli-DnmBJrjg.js";
2
- import { n as output, t as error } from "./output-BchYq0mR.js";
3
- import { defineCommand } from "citty";
4
- //#region src/cli/commands/add-json.ts
5
- var add_json_default = defineCommand({
6
- meta: {
7
- name: "add-json",
8
- description: "Add an MCP server from a JSON configuration string"
9
- },
10
- args: {
11
- name: {
12
- type: "positional",
13
- description: "Server name",
14
- required: true
15
- },
16
- config: {
17
- type: "positional",
18
- description: "JSON configuration string",
19
- required: true
20
- },
21
- scope: {
22
- type: "string",
23
- description: "Scope: local, project, or user (default: local)",
24
- default: "local"
25
- },
26
- json: {
27
- type: "boolean",
28
- description: "Output as JSON",
29
- default: false
30
- }
31
- },
32
- async run({ args }) {
33
- const scope = args.scope;
34
- if (![
35
- "local",
36
- "project",
37
- "user"
38
- ].includes(scope)) error(`Invalid scope: ${scope}. Use local, project, or user.`);
39
- try {
40
- JSON.parse(args.config);
41
- } catch {
42
- error("Invalid JSON configuration. Provide a valid JSON string.");
43
- }
44
- const result = await mcp_add_json_via_cli(args.name, args.config, scope);
45
- if (args.json) output({
46
- added: args.name,
47
- scope,
48
- success: result.success,
49
- error: result.error
50
- }, true);
51
- else if (result.success) console.log(`Added '${args.name}' from JSON (scope: ${scope})`);
52
- else error(result.error || "Unknown error");
53
- }
54
- });
55
- //#endregion
56
- export { add_json_default as default };
57
-
58
- //# sourceMappingURL=add-json-BjgzdeG-.js.map
@@ -1,26 +0,0 @@
1
- import { readFile, rename, writeFile } from "node:fs/promises";
2
- import { dirname, join } from "node:path";
3
- //#region src/utils/atomic-write.ts
4
- /**
5
- * Atomically write a JSON file with fresh-read merging.
6
- *
7
- * 1. Re-reads the file right before writing to pick up concurrent changes
8
- * 2. Applies the merge function to the freshest data
9
- * 3. Writes to a temp file, then renames (atomic on same filesystem)
10
- */
11
- async function atomic_json_write(file_path, merge) {
12
- let existing = {};
13
- try {
14
- const content = await readFile(file_path, "utf-8");
15
- existing = JSON.parse(content);
16
- } catch {}
17
- const merged = merge(existing);
18
- const content = JSON.stringify(merged, null, 2);
19
- const tmp_path = join(dirname(file_path), `.${Date.now()}.tmp`);
20
- await writeFile(tmp_path, content, "utf-8");
21
- await rename(tmp_path, file_path);
22
- }
23
- //#endregion
24
- export { atomic_json_write as t };
25
-
26
- //# sourceMappingURL=atomic-write-BqEykHp9.js.map