@biswaviraj/cc-setup 1.0.0 → 1.0.2
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/LICENSE +21 -0
- package/README.md +104 -0
- package/{index.mjs → dist/index.js} +42 -90
- package/package.json +19 -3
- package/.claude/settings.local.json +0 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Biswajeet Das
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# cc-setup
|
|
2
|
+
|
|
3
|
+
Add your preferred Claude Code plugins and MCP servers to any project in seconds.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @biswaviraj/cc-setup
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Pick what you need, choose the scope, done. No manual config editing.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Run directly
|
|
17
|
+
npx @biswaviraj/cc-setup
|
|
18
|
+
|
|
19
|
+
# Or install globally
|
|
20
|
+
pnpm add -g @biswaviraj/cc-setup
|
|
21
|
+
cc-setup
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Custom tools
|
|
25
|
+
|
|
26
|
+
Create `~/.cc-setup.json` to add your own plugins and MCP servers to the picker:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"defaults": ["superpowers", "context-mode", "my-plugin"],
|
|
31
|
+
"plugins": [
|
|
32
|
+
{
|
|
33
|
+
"value": "my-plugin",
|
|
34
|
+
"label": "My Plugin",
|
|
35
|
+
"hint": "what it does",
|
|
36
|
+
"install": "my-plugin@my-marketplace",
|
|
37
|
+
"marketplace": "org/repo"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"mcpServers": [
|
|
41
|
+
{
|
|
42
|
+
"value": "my-server",
|
|
43
|
+
"label": "My Server",
|
|
44
|
+
"hint": "what it does",
|
|
45
|
+
"command": "npx my-mcp-server"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Your entries are merged with the built-in list. No duplicates.
|
|
52
|
+
|
|
53
|
+
### Plugin fields
|
|
54
|
+
|
|
55
|
+
| Field | Required | Description |
|
|
56
|
+
|-------|----------|-------------|
|
|
57
|
+
| `value` | yes | Unique ID |
|
|
58
|
+
| `label` | yes | Display name |
|
|
59
|
+
| `hint` | yes | Short description |
|
|
60
|
+
| `install` | yes | Plugin install ID (e.g. `my-plugin` or `my-plugin@marketplace`) |
|
|
61
|
+
| `marketplace` | no | GitHub `org/repo` for non-official marketplaces |
|
|
62
|
+
|
|
63
|
+
### MCP Server fields
|
|
64
|
+
|
|
65
|
+
| Field | Required | Description |
|
|
66
|
+
|-------|----------|-------------|
|
|
67
|
+
| `value` | yes | Unique ID |
|
|
68
|
+
| `label` | yes | Display name |
|
|
69
|
+
| `hint` | yes | Short description |
|
|
70
|
+
| `command` | yes | The command to run (e.g. `npx my-mcp-server`) |
|
|
71
|
+
|
|
72
|
+
## Quick mode
|
|
73
|
+
|
|
74
|
+
Set `defaults` in your config, then:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Install defaults, just pick scope
|
|
78
|
+
cc-setup --quick
|
|
79
|
+
|
|
80
|
+
# Fully non-interactive
|
|
81
|
+
cc-setup --quick --scope local
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Scopes
|
|
85
|
+
|
|
86
|
+
| Scope | Where | Use case |
|
|
87
|
+
|-------|-------|----------|
|
|
88
|
+
| `local` | `.claude/settings.local.json` | Just for you, this project |
|
|
89
|
+
| `project` | `.claude/settings.json` | Shared with team (committed to git) |
|
|
90
|
+
| `user` | `~/.claude/settings.json` | All projects on this machine |
|
|
91
|
+
|
|
92
|
+
## How it works
|
|
93
|
+
|
|
94
|
+
Under the hood, `cc-setup` runs:
|
|
95
|
+
|
|
96
|
+
- `claude plugins marketplace add <repo>` for custom marketplaces
|
|
97
|
+
- `claude plugins install <plugin> -s <scope>` for plugins
|
|
98
|
+
- `claude mcp add <name> -s <scope> -- <command>` for MCP servers
|
|
99
|
+
|
|
100
|
+
That's it. No magic.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
|
@@ -1,62 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/index.ts
|
|
3
4
|
import * as p from "@clack/prompts";
|
|
4
|
-
import { execSync } from "
|
|
5
|
-
import { existsSync, readFileSync } from "
|
|
6
|
-
import { homedir } from "
|
|
7
|
-
import { join } from "
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import { existsSync, readFileSync } from "fs";
|
|
7
|
+
import { homedir } from "os";
|
|
8
|
+
import { join } from "path";
|
|
8
9
|
import pc from "picocolors";
|
|
9
|
-
|
|
10
|
-
// ── Built-in Registry ───────────────────────────────────────
|
|
11
|
-
// Popular plugins & servers. Users can extend via ~/.cc-setup.json
|
|
12
|
-
|
|
13
|
-
const BUILTIN_PLUGINS = [
|
|
10
|
+
var BUILTIN_PLUGINS = [
|
|
14
11
|
{
|
|
15
12
|
value: "superpowers",
|
|
16
13
|
label: "Superpowers",
|
|
17
14
|
hint: "brainstorming, TDD, debugging, plans, worktrees",
|
|
18
|
-
install: "superpowers"
|
|
15
|
+
install: "superpowers"
|
|
19
16
|
},
|
|
20
17
|
{
|
|
21
18
|
value: "frontend-design",
|
|
22
19
|
label: "Frontend Design",
|
|
23
20
|
hint: "production-grade UI components",
|
|
24
|
-
install: "frontend-design"
|
|
21
|
+
install: "frontend-design"
|
|
25
22
|
},
|
|
26
23
|
{
|
|
27
24
|
value: "context-mode",
|
|
28
25
|
label: "Context Mode",
|
|
29
26
|
hint: "context window optimization",
|
|
30
27
|
install: "context-mode@context-mode",
|
|
31
|
-
marketplace: "mksglu/context-mode"
|
|
28
|
+
marketplace: "mksglu/context-mode"
|
|
32
29
|
},
|
|
33
30
|
{
|
|
34
31
|
value: "context7",
|
|
35
32
|
label: "Context7",
|
|
36
33
|
hint: "library & framework docs lookup",
|
|
37
34
|
install: "context7-plugin@context7-marketplace",
|
|
38
|
-
marketplace: "upstash/context7"
|
|
35
|
+
marketplace: "upstash/context7"
|
|
39
36
|
},
|
|
40
37
|
{
|
|
41
38
|
value: "feature-dev",
|
|
42
39
|
label: "Feature Dev",
|
|
43
40
|
hint: "guided feature development",
|
|
44
|
-
install: "feature-dev"
|
|
41
|
+
install: "feature-dev"
|
|
45
42
|
},
|
|
46
43
|
{
|
|
47
44
|
value: "mongodb",
|
|
48
45
|
label: "MongoDB",
|
|
49
46
|
hint: "database ops, schema design, queries",
|
|
50
|
-
install: "mongodb"
|
|
51
|
-
}
|
|
47
|
+
install: "mongodb"
|
|
48
|
+
}
|
|
52
49
|
];
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// ── Config ──────────────────────────────────────────────────
|
|
57
|
-
|
|
58
|
-
const CONFIG_PATH = join(homedir(), ".cc-setup.json");
|
|
59
|
-
|
|
50
|
+
var BUILTIN_MCP = [];
|
|
51
|
+
var CONFIG_PATH = join(homedir(), ".cc-setup.json");
|
|
60
52
|
function loadConfig() {
|
|
61
53
|
if (!existsSync(CONFIG_PATH)) return null;
|
|
62
54
|
try {
|
|
@@ -65,43 +57,35 @@ function loadConfig() {
|
|
|
65
57
|
return null;
|
|
66
58
|
}
|
|
67
59
|
}
|
|
68
|
-
|
|
69
60
|
function merge(builtin, user) {
|
|
70
61
|
if (!user?.length) return builtin;
|
|
71
62
|
const seen = new Set(builtin.map((t) => t.value));
|
|
72
63
|
return [...builtin, ...user.filter((t) => !seen.has(t.value))];
|
|
73
64
|
}
|
|
74
|
-
|
|
75
|
-
// ── Helpers ─────────────────────────────────────────────────
|
|
76
|
-
|
|
77
65
|
function run(cmd) {
|
|
78
66
|
try {
|
|
79
67
|
return {
|
|
80
68
|
ok: true,
|
|
81
|
-
output: execSync(cmd, { encoding: "utf-8", stdio: "pipe" }).trim()
|
|
69
|
+
output: execSync(cmd, { encoding: "utf-8", stdio: "pipe" }).trim()
|
|
82
70
|
};
|
|
83
71
|
} catch (e) {
|
|
84
|
-
|
|
72
|
+
const err = e;
|
|
73
|
+
return { ok: false, output: (err.stderr || err.message).trim() };
|
|
85
74
|
}
|
|
86
75
|
}
|
|
87
|
-
|
|
88
76
|
function parseArgs() {
|
|
89
77
|
const args = process.argv.slice(2);
|
|
90
78
|
return {
|
|
91
79
|
quick: args.includes("--quick") || args.includes("-q"),
|
|
92
80
|
scope: args.find((_, i, a) => a[i - 1] === "--scope") || null,
|
|
93
|
-
help: args.includes("--help") || args.includes("-h")
|
|
81
|
+
help: args.includes("--help") || args.includes("-h")
|
|
94
82
|
};
|
|
95
83
|
}
|
|
96
|
-
|
|
97
|
-
// ── Main ────────────────────────────────────────────────────
|
|
98
|
-
|
|
99
84
|
async function main() {
|
|
100
85
|
const args = parseArgs();
|
|
101
|
-
|
|
102
86
|
if (args.help) {
|
|
103
87
|
console.log(`
|
|
104
|
-
${pc.bold("cc-setup")}
|
|
88
|
+
${pc.bold("cc-setup")} \u2014 Add Claude Code plugins & MCP servers to any project
|
|
105
89
|
|
|
106
90
|
${pc.dim("Usage:")}
|
|
107
91
|
cc-setup Interactive picker
|
|
@@ -126,35 +110,24 @@ async function main() {
|
|
|
126
110
|
`);
|
|
127
111
|
process.exit(0);
|
|
128
112
|
}
|
|
129
|
-
|
|
130
113
|
console.clear();
|
|
131
114
|
p.intro(`${pc.bgCyan(pc.black(" cc-setup "))} ${pc.dim("v1.0.0")}`);
|
|
132
|
-
|
|
133
|
-
// Preflight
|
|
134
115
|
const check = run("claude --version");
|
|
135
116
|
if (!check.ok) {
|
|
136
117
|
p.cancel(
|
|
137
|
-
"Claude Code CLI not found. Install: npm i -g @anthropic-ai/claude-code"
|
|
118
|
+
"Claude Code CLI not found. Install: npm i -g @anthropic-ai/claude-code"
|
|
138
119
|
);
|
|
139
120
|
process.exit(1);
|
|
140
121
|
}
|
|
141
122
|
p.log.info(`${pc.dim("Claude Code")} ${check.output}`);
|
|
142
|
-
|
|
143
|
-
// Load & merge
|
|
144
123
|
const config = loadConfig();
|
|
145
124
|
if (config) p.log.info(`${pc.dim("Config loaded from")} ${CONFIG_PATH}`);
|
|
146
|
-
|
|
147
125
|
const plugins = merge(BUILTIN_PLUGINS, config?.plugins);
|
|
148
126
|
const mcpServers = merge(BUILTIN_MCP, config?.mcpServers);
|
|
149
127
|
const defaults = config?.defaults || [];
|
|
150
|
-
|
|
151
128
|
const pluginMap = new Map(plugins.map((pl) => [pl.value, pl]));
|
|
152
129
|
const mcpMap = new Map(mcpServers.map((m) => [m.value, m]));
|
|
153
|
-
|
|
154
|
-
// ── Select ────────────────────────────────────────────────
|
|
155
|
-
|
|
156
130
|
let selectedIds;
|
|
157
|
-
|
|
158
131
|
if (args.quick) {
|
|
159
132
|
if (!defaults.length) {
|
|
160
133
|
p.cancel('No defaults configured. Add "defaults" to ~/.cc-setup.json');
|
|
@@ -168,108 +141,87 @@ async function main() {
|
|
|
168
141
|
groups["Plugins"] = plugins.map((t) => ({
|
|
169
142
|
value: t.value,
|
|
170
143
|
label: t.label,
|
|
171
|
-
hint: t.hint
|
|
144
|
+
hint: t.hint
|
|
172
145
|
}));
|
|
173
146
|
if (mcpServers.length)
|
|
174
147
|
groups["MCP Servers"] = mcpServers.map((t) => ({
|
|
175
148
|
value: t.value,
|
|
176
149
|
label: t.label,
|
|
177
|
-
hint: t.hint
|
|
150
|
+
hint: t.hint
|
|
178
151
|
}));
|
|
179
|
-
|
|
180
|
-
selectedIds = await p.groupMultiselect({
|
|
152
|
+
const result = await p.groupMultiselect({
|
|
181
153
|
message: "Pick tools to add",
|
|
182
154
|
options: groups,
|
|
183
|
-
required: false
|
|
155
|
+
required: false
|
|
184
156
|
});
|
|
185
|
-
|
|
186
|
-
if (p.isCancel(selectedIds) || !selectedIds.length) {
|
|
157
|
+
if (p.isCancel(result) || !result.length) {
|
|
187
158
|
p.cancel("Nothing selected.");
|
|
188
159
|
process.exit(0);
|
|
189
160
|
}
|
|
161
|
+
selectedIds = result;
|
|
190
162
|
}
|
|
191
|
-
|
|
192
163
|
const pluginIds = selectedIds.filter((id) => pluginMap.has(id));
|
|
193
164
|
const mcpIds = selectedIds.filter((id) => mcpMap.has(id));
|
|
194
|
-
|
|
195
165
|
if (!pluginIds.length && !mcpIds.length) {
|
|
196
166
|
p.cancel("Nothing to install.");
|
|
197
167
|
process.exit(0);
|
|
198
168
|
}
|
|
199
|
-
|
|
200
|
-
// ── Scope ─────────────────────────────────────────────────
|
|
201
|
-
|
|
202
169
|
let scope = args.scope;
|
|
203
|
-
|
|
204
170
|
if (!scope) {
|
|
205
|
-
|
|
171
|
+
const result = await p.select({
|
|
206
172
|
message: "Install scope",
|
|
207
173
|
options: [
|
|
208
174
|
{
|
|
209
175
|
value: "local",
|
|
210
176
|
label: "This project",
|
|
211
|
-
hint: ".claude/settings.local.json"
|
|
177
|
+
hint: ".claude/settings.local.json"
|
|
212
178
|
},
|
|
213
179
|
{
|
|
214
180
|
value: "project",
|
|
215
181
|
label: "Shared with team",
|
|
216
|
-
hint: ".claude/settings.json (committed)"
|
|
182
|
+
hint: ".claude/settings.json (committed)"
|
|
217
183
|
},
|
|
218
184
|
{
|
|
219
185
|
value: "user",
|
|
220
186
|
label: "Global",
|
|
221
|
-
hint: "~/.claude/settings.json"
|
|
222
|
-
}
|
|
223
|
-
]
|
|
187
|
+
hint: "~/.claude/settings.json"
|
|
188
|
+
}
|
|
189
|
+
]
|
|
224
190
|
});
|
|
225
|
-
|
|
226
|
-
if (p.isCancel(scope)) {
|
|
191
|
+
if (p.isCancel(result)) {
|
|
227
192
|
p.cancel("Cancelled.");
|
|
228
193
|
process.exit(0);
|
|
229
194
|
}
|
|
195
|
+
scope = result;
|
|
230
196
|
}
|
|
231
|
-
|
|
232
|
-
// ── Install ───────────────────────────────────────────────
|
|
233
|
-
|
|
234
197
|
const s = p.spinner();
|
|
235
198
|
const results = [];
|
|
236
|
-
|
|
237
199
|
for (const id of pluginIds) {
|
|
238
200
|
const plugin = pluginMap.get(id);
|
|
239
|
-
|
|
240
201
|
if (plugin.marketplace) {
|
|
241
202
|
s.start(`Adding marketplace for ${plugin.label}...`);
|
|
242
203
|
run(`claude plugins marketplace add ${plugin.marketplace}`);
|
|
243
204
|
s.stop(`Marketplace ready for ${plugin.label}`);
|
|
244
205
|
}
|
|
245
|
-
|
|
246
206
|
s.start(`Installing ${plugin.label}...`);
|
|
247
207
|
const result = run(`claude plugins install ${plugin.install} -s ${scope}`);
|
|
248
|
-
s.stop(`${result.ok ? pc.green("
|
|
208
|
+
s.stop(`${result.ok ? pc.green("\u2713") : pc.yellow("\u26A0")} ${plugin.label}`);
|
|
249
209
|
results.push({ name: plugin.label, ...result });
|
|
250
210
|
}
|
|
251
|
-
|
|
252
211
|
for (const id of mcpIds) {
|
|
253
212
|
const mcp = mcpMap.get(id);
|
|
254
213
|
s.start(`Adding ${mcp.label}...`);
|
|
255
214
|
const result = run(
|
|
256
|
-
`claude mcp add ${mcp.value} -s ${scope} -- ${mcp.command}
|
|
215
|
+
`claude mcp add ${mcp.value} -s ${scope} -- ${mcp.command}`
|
|
257
216
|
);
|
|
258
|
-
s.stop(`${result.ok ? pc.green("
|
|
217
|
+
s.stop(`${result.ok ? pc.green("\u2713") : pc.yellow("\u26A0")} ${mcp.label}`);
|
|
259
218
|
results.push({ name: mcp.label, ...result });
|
|
260
219
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
.map((r) => {
|
|
266
|
-
if (r.ok) return ` ${pc.green("✓")} ${r.name}`;
|
|
267
|
-
return ` ${pc.red("✗")} ${r.name} ${pc.dim(`— ${r.output.split("\n")[0]}`)}`;
|
|
268
|
-
})
|
|
269
|
-
.join("\n");
|
|
270
|
-
|
|
220
|
+
const summary = results.map((r) => {
|
|
221
|
+
if (r.ok) return ` ${pc.green("\u2713")} ${r.name}`;
|
|
222
|
+
return ` ${pc.red("\u2717")} ${r.name} ${pc.dim(`\u2014 ${r.output.split("\n")[0]}`)}`;
|
|
223
|
+
}).join("\n");
|
|
271
224
|
p.note(summary, "Results");
|
|
272
225
|
p.outro("Restart Claude Code to activate new tools.");
|
|
273
226
|
}
|
|
274
|
-
|
|
275
227
|
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@biswaviraj/cc-setup",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Add your preferred Claude Code plugins and MCP servers to any project in seconds",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"cc-setup": "./index.mjs"
|
|
7
|
+
"cc-setup": "./dist/index.mjs"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
9
12
|
"author": {
|
|
10
13
|
"name": "BiswaViraj",
|
|
11
14
|
"url": "https://github.com/BiswaViraj"
|
|
12
15
|
},
|
|
16
|
+
"homepage": "https://github.com/BiswaViraj/cc-setup#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/BiswaViraj/cc-setup.git"
|
|
20
|
+
},
|
|
13
21
|
"keywords": [
|
|
14
22
|
"claude",
|
|
15
23
|
"claude-code",
|
|
@@ -22,5 +30,13 @@
|
|
|
22
30
|
"dependencies": {
|
|
23
31
|
"@clack/prompts": "^0.11.0",
|
|
24
32
|
"picocolors": "^1.1.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^25.6.0",
|
|
36
|
+
"tsup": "^8.0.0",
|
|
37
|
+
"typescript": "^6.0.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup"
|
|
25
41
|
}
|
|
26
42
|
}
|