claude-setup 1.1.7 → 1.1.9
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/README.md +88 -107
- package/dist/builder.d.ts +6 -0
- package/dist/builder.js +143 -80
- package/dist/commands/init.js +8 -1
- package/dist/commands/sync.js +76 -12
- package/dist/marketplace.d.ts +24 -19
- package/dist/marketplace.js +429 -86
- package/dist/os.d.ts +33 -4
- package/dist/os.js +238 -3
- package/package.json +1 -1
- package/templates/add.md +57 -10
- package/templates/sync.md +6 -2
package/README.md
CHANGED
|
@@ -1,161 +1,142 @@
|
|
|
1
1
|
# claude-setup
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Your project already has the answers — `claude-setup` reads them and configures Claude Code so you don't have to.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
One command. No manual config. Works on **Windows, macOS, Linux, and WSL**.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Get started
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx claude-setup
|
|
10
|
+
npx claude-setup
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Then open Claude Code and run
|
|
13
|
+
Pick `1` (init). Then open Claude Code and run:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| Command | What it does |
|
|
18
|
-
|---------|-------------|
|
|
19
|
-
| `init` | Full project setup — detects empty projects, generates atomic setup steps |
|
|
20
|
-
| `add` | Add capabilities — MCP servers, skills, hooks, plugins in one go |
|
|
21
|
-
| `sync` | Update setup after project changes — diff-based, not full re-scan |
|
|
22
|
-
| `status` | Dashboard — project info, setup files, snapshots, token usage |
|
|
23
|
-
| `doctor` | Validate everything — OS format, hooks, env vars, stale skills |
|
|
24
|
-
| `remove` | Remove capabilities cleanly with dangling reference detection |
|
|
25
|
-
| `restore` | Jump to any snapshot — restore files to a previous state |
|
|
26
|
-
| `compare` | Diff two snapshots — find exactly where something changed |
|
|
27
|
-
| `export` | Save your setup as a reusable template |
|
|
28
|
-
|
|
29
|
-
### Flags
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npx claude-setup init --dry-run # Preview without writing
|
|
33
|
-
npx claude-setup init --template my.json # Apply a saved template
|
|
34
|
-
npx claude-setup sync --dry-run # Show changes without writing
|
|
35
|
-
npx claude-setup sync --budget 3000 # Override token budget
|
|
36
|
-
npx claude-setup doctor --verbose # Include passing checks
|
|
37
|
-
npx claude-setup doctor --fix # Auto-fix issues
|
|
38
|
-
npx claude-setup doctor --test-hooks # Run every hook in sandbox
|
|
15
|
+
```
|
|
16
|
+
/stack-init
|
|
39
17
|
```
|
|
40
18
|
|
|
41
|
-
|
|
19
|
+
That's it. Claude Code now knows your stack, your services, your conventions.
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
2. **CLI writes** — generates markdown instructions into `.claude/commands/`
|
|
45
|
-
3. **Claude Code executes** — you run `/stack-init`, `/stack-sync`, etc.
|
|
21
|
+
## What happens during init
|
|
46
22
|
|
|
47
|
-
|
|
23
|
+
`claude-setup` scans your project files — `package.json`, `docker-compose.yml`, `.env.example`, source code — and generates everything Claude Code needs:
|
|
48
24
|
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
| `.github/workflows/` | CI workflows (only with confirmation) |
|
|
25
|
+
| Generated | What it does |
|
|
26
|
+
|-----------|-------------|
|
|
27
|
+
| **CLAUDE.md** | Project context — stack, structure, commands, conventions |
|
|
28
|
+
| **.mcp.json** | MCP server connections — auto-detected from your dependencies |
|
|
29
|
+
| **settings.json** | Hooks — auto-format, token tracking, build triggers |
|
|
30
|
+
| **skills/** | Reusable patterns for your workflow |
|
|
31
|
+
| **commands/** | Slash commands that work inside Claude Code |
|
|
57
32
|
|
|
58
|
-
|
|
33
|
+
Every line comes from evidence in your project files. No guessing.
|
|
59
34
|
|
|
60
|
-
|
|
35
|
+
### MCP servers are auto-configured
|
|
61
36
|
|
|
62
|
-
|
|
63
|
-
init ──→ sync#1 ──→ sync#2 ──→ sync#3 (current)
|
|
64
|
-
│ │
|
|
65
|
-
│ └─ bug introduced here
|
|
66
|
-
└─ jump back here
|
|
67
|
-
```
|
|
37
|
+
`claude-setup` detects your databases and services automatically:
|
|
68
38
|
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
39
|
+
- Finds PostgreSQL, MongoDB, Redis, MySQL from your deps, docker-compose, or env files
|
|
40
|
+
- Checks if the service is installed locally (`psql`, `mongosh`, `redis-cli`)
|
|
41
|
+
- Uses the right connection URL — no broken `${VARNAME}` that fails silently
|
|
42
|
+
- Formats commands for your OS (`cmd /c npx` on Windows, `npx` everywhere else)
|
|
72
43
|
|
|
73
|
-
##
|
|
44
|
+
## After init
|
|
74
45
|
|
|
75
|
-
|
|
46
|
+
These slash commands work inside Claude Code:
|
|
76
47
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
| Command | What it does |
|
|
49
|
+
|---------|-------------|
|
|
50
|
+
| `/stack-sync` | Detect file changes, update your setup |
|
|
51
|
+
| `/stack-add` | Add a capability — searches 400+ marketplace plugins first |
|
|
52
|
+
| `/stack-status` | Show project state, snapshots, token usage |
|
|
53
|
+
| `/stack-doctor` | Validate environment, auto-fix issues |
|
|
54
|
+
| `/stack-restore` | Time-travel to any snapshot |
|
|
55
|
+
| `/stack-remove` | Remove a capability cleanly |
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
npx claude-setup init --template my-template.claude-template.json
|
|
57
|
+
### `/stack-add` searches the marketplace for you
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
npx claude-setup init --template https://example.com/template.json
|
|
87
|
-
```
|
|
59
|
+
Say what you want — it searches 400+ community plugins and 13 official Anthropic plugins, downloads and installs matching skills automatically. No manual steps.
|
|
88
60
|
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
61
|
+
```
|
|
62
|
+
/stack-add
|
|
63
|
+
> "E2E testing and Stripe integration"
|
|
64
|
+
```
|
|
93
65
|
|
|
94
|
-
|
|
66
|
+
### `/stack-sync` shows what changed
|
|
95
67
|
|
|
96
|
-
Every
|
|
68
|
+
Every sync creates a snapshot and shows a color-coded diff:
|
|
97
69
|
|
|
98
70
|
```
|
|
99
|
-
|
|
100
|
-
|
|
71
|
+
Changes since 2026-03-28T14:32:01.904Z:
|
|
72
|
+
+2 added ~3 modified -1 deleted
|
|
73
|
+
|
|
74
|
+
Added files:
|
|
75
|
+
+ src/api/payments.ts (48 lines)
|
|
76
|
+
+ src/api/webhooks.ts (32 lines)
|
|
77
|
+
|
|
78
|
+
Modified files:
|
|
79
|
+
~ package.json (+3 lines, -1 lines)
|
|
80
|
+
~ src/index.ts (+8 lines, -2 lines)
|
|
101
81
|
```
|
|
102
82
|
|
|
103
|
-
|
|
83
|
+
Claude Code sees the actual line-level changes and updates your setup surgically.
|
|
104
84
|
|
|
105
|
-
##
|
|
85
|
+
## Snapshots
|
|
106
86
|
|
|
107
|
-
|
|
87
|
+
Every init and sync saves a full snapshot. You can jump to any point in time:
|
|
108
88
|
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
npx claude-setup doctor --fix # Auto-fix what's possible
|
|
112
|
-
npx claude-setup doctor --test-hooks # Run each hook, report pass/fail
|
|
89
|
+
```
|
|
90
|
+
/stack-restore
|
|
113
91
|
```
|
|
114
92
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
What `--test-hooks` checks per hook:
|
|
122
|
-
- Command exists on the system
|
|
123
|
-
- Command executes without error
|
|
124
|
-
- Exit code and stderr
|
|
125
|
-
- Execution time and timeout detection
|
|
126
|
-
- Matcher regex validity
|
|
93
|
+
```
|
|
94
|
+
init ──> sync#1 ──> sync#2 ──> sync#3 (you are here)
|
|
95
|
+
|
|
|
96
|
+
└── jump back here anytime
|
|
97
|
+
```
|
|
127
98
|
|
|
128
|
-
|
|
99
|
+
Snapshots are never deleted. Go back, go forward, freely.
|
|
129
100
|
|
|
130
|
-
|
|
101
|
+
## All CLI commands
|
|
131
102
|
|
|
132
103
|
```bash
|
|
133
|
-
npx claude-setup
|
|
134
|
-
|
|
135
|
-
|
|
104
|
+
npx claude-setup # Interactive menu
|
|
105
|
+
npx claude-setup init # Full project setup
|
|
106
|
+
npx claude-setup sync # Checkpoint + update
|
|
107
|
+
npx claude-setup add "postgres and testing" # Add capabilities
|
|
108
|
+
npx claude-setup status # Dashboard
|
|
109
|
+
npx claude-setup doctor # Validate everything
|
|
110
|
+
npx claude-setup doctor --fix # Auto-fix issues
|
|
111
|
+
npx claude-setup restore # Time-travel
|
|
112
|
+
npx claude-setup compare # Diff two snapshots
|
|
113
|
+
npx claude-setup remove "redis" # Remove cleanly
|
|
114
|
+
npx claude-setup export # Save as template
|
|
115
|
+
npx claude-setup init --template file # Apply a template
|
|
136
116
|
```
|
|
137
117
|
|
|
138
118
|
## Configuration
|
|
139
119
|
|
|
140
|
-
Auto-generated on first run. Edit `.claude-setup.json`
|
|
120
|
+
Auto-generated on first run. Edit `.claude-setup.json` if needed:
|
|
141
121
|
|
|
142
122
|
```json
|
|
143
123
|
{
|
|
144
124
|
"maxSourceFiles": 15,
|
|
145
125
|
"maxDepth": 6,
|
|
146
|
-
"
|
|
147
|
-
"
|
|
148
|
-
"init": 12000,
|
|
149
|
-
"sync": 6000,
|
|
150
|
-
"add": 3000,
|
|
151
|
-
"remove": 2000
|
|
152
|
-
},
|
|
153
|
-
"digestMode": true,
|
|
154
|
-
"extraBlockedDirs": [],
|
|
155
|
-
"sourceDirs": []
|
|
126
|
+
"tokenBudget": { "init": 12000, "sync": 6000, "add": 3000 },
|
|
127
|
+
"digestMode": true
|
|
156
128
|
}
|
|
157
129
|
```
|
|
158
130
|
|
|
131
|
+
## Supported platforms
|
|
132
|
+
|
|
133
|
+
| Platform | Status | MCP format |
|
|
134
|
+
|----------|--------|-----------|
|
|
135
|
+
| Windows | Full support | `cmd /c npx -y <pkg>` |
|
|
136
|
+
| macOS | Full support + Homebrew detection | `npx -y <pkg>` |
|
|
137
|
+
| Linux | Full support | `npx -y <pkg>` |
|
|
138
|
+
| WSL | Full support + Windows host access | `npx -y <pkg>` |
|
|
139
|
+
|
|
159
140
|
## License
|
|
160
141
|
|
|
161
142
|
MIT
|
package/dist/builder.d.ts
CHANGED
package/dist/builder.js
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from "fs";
|
|
|
2
2
|
import { join, dirname } from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { loadConfig } from "./config.js";
|
|
5
|
-
import { detectOS, VERIFIED_MCP_PACKAGES } from "./os.js";
|
|
5
|
+
import { detectOS, isUnixLike, VERIFIED_MCP_PACKAGES, buildServiceDiscoveryInstructions } from "./os.js";
|
|
6
6
|
import { buildMarketplaceInstructions } from "./marketplace.js";
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const TEMPLATES_DIR = join(__dirname, "..", "templates");
|
|
@@ -21,10 +21,16 @@ function replaceVars(template, vars) {
|
|
|
21
21
|
}
|
|
22
22
|
function processConditionals(template, flags) {
|
|
23
23
|
let result = template;
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
// Process innermost conditionals first, repeat until stable.
|
|
25
|
+
// This prevents outer {{#if}} from greedily matching inner {{else}}/{{/if}}.
|
|
26
|
+
let prev = "";
|
|
27
|
+
while (prev !== result) {
|
|
28
|
+
prev = result;
|
|
29
|
+
// {{#if VAR}}...{{else}}...{{/if}} first (innermost — no nested {{#if}} in either branch)
|
|
30
|
+
result = result.replace(/\{\{#if\s+(\w+)\}\}\n?((?:(?!\{\{#if\b)[\s\S])*?)\{\{else\}\}\n?((?:(?!\{\{#if\b)[\s\S])*?)\{\{\/if\}\}/g, (_m, key, ifBlock, elseBlock) => flags[key] ? ifBlock : elseBlock);
|
|
31
|
+
// Simple {{#if VAR}}...{{/if}} (no else, no nested if inside)
|
|
32
|
+
result = result.replace(/\{\{#if\s+(\w+)\}\}\n?((?:(?!\{\{#if\b|\{\{else\}\})[\s\S])*?)\{\{\/if\}\}/g, (_m, key, block) => flags[key] ? block : "");
|
|
33
|
+
}
|
|
28
34
|
return result;
|
|
29
35
|
}
|
|
30
36
|
function formatList(items) {
|
|
@@ -91,6 +97,7 @@ function buildVars(collected, state) {
|
|
|
91
97
|
};
|
|
92
98
|
}
|
|
93
99
|
function buildFlags(_collected, state) {
|
|
100
|
+
const os = detectOS();
|
|
94
101
|
return {
|
|
95
102
|
HAS_SOURCE: _collected.source.length > 0,
|
|
96
103
|
HAS_SKIPPED: _collected.skipped.length > 0,
|
|
@@ -98,7 +105,10 @@ function buildFlags(_collected, state) {
|
|
|
98
105
|
HAS_MCP_JSON: state.mcpJson.exists,
|
|
99
106
|
HAS_SETTINGS: state.settings.exists,
|
|
100
107
|
HAS_GITHUB_DIR: state.hasGithubDir,
|
|
101
|
-
IS_WINDOWS:
|
|
108
|
+
IS_WINDOWS: os === "Windows", // WSL uses Unix-style commands, not cmd
|
|
109
|
+
IS_WSL: os === "WSL",
|
|
110
|
+
IS_MACOS: os === "macOS",
|
|
111
|
+
IS_UNIX_LIKE: isUnixLike(os),
|
|
102
112
|
};
|
|
103
113
|
}
|
|
104
114
|
// --- Token budget enforcement ---
|
|
@@ -153,15 +163,43 @@ export function buildAddCommand(input, collected, state) {
|
|
|
153
163
|
}, "add");
|
|
154
164
|
}
|
|
155
165
|
export function buildSyncCommand(diff, collected, state) {
|
|
156
|
-
//
|
|
166
|
+
// Rich diff format — paths + line-level changes for modified files
|
|
157
167
|
const addedStr = diff.added.length > 0
|
|
158
168
|
? diff.added.map(f => `- **${f.path}** (new) — ${f.content.split("\n").length} lines`).join("\n")
|
|
159
169
|
: "(none)";
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
// Modified files now include line-level diffs
|
|
171
|
+
let modifiedStr;
|
|
172
|
+
if (diff.changed.length > 0) {
|
|
173
|
+
const parts = [];
|
|
174
|
+
for (const f of diff.changed) {
|
|
175
|
+
const lines = [`- **${f.path}** (modified)`];
|
|
176
|
+
if (f.lineDiff) {
|
|
177
|
+
lines[0] += ` — ${f.lineDiff.summary}`;
|
|
178
|
+
if (f.lineDiff.removed.length > 0 || f.lineDiff.added.length > 0) {
|
|
179
|
+
lines.push(" ```diff");
|
|
180
|
+
for (const l of f.lineDiff.removed.slice(0, 8)) {
|
|
181
|
+
lines.push(` - ${l.trimEnd().slice(0, 120)}`);
|
|
182
|
+
}
|
|
183
|
+
for (const l of f.lineDiff.added.slice(0, 8)) {
|
|
184
|
+
lines.push(` + ${l.trimEnd().slice(0, 120)}`);
|
|
185
|
+
}
|
|
186
|
+
const totalShown = Math.min(f.lineDiff.removed.length, 8) + Math.min(f.lineDiff.added.length, 8);
|
|
187
|
+
const total = f.lineDiff.removed.length + f.lineDiff.added.length;
|
|
188
|
+
if (total > totalShown) {
|
|
189
|
+
lines.push(` # ... +${total - totalShown} more changes`);
|
|
190
|
+
}
|
|
191
|
+
lines.push(" ```");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
parts.push(lines.join("\n"));
|
|
195
|
+
}
|
|
196
|
+
modifiedStr = parts.join("\n");
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
modifiedStr = "(none)";
|
|
200
|
+
}
|
|
163
201
|
const deletedStr = diff.deleted.length > 0
|
|
164
|
-
? diff.deleted.map(f => `-
|
|
202
|
+
? diff.deleted.map(f => `- ~~${f}~~ (deleted)`).join("\n")
|
|
165
203
|
: "(none)";
|
|
166
204
|
const lastRun = state.manifest?.runs.at(-1);
|
|
167
205
|
return applyTemplate("sync.md", collected, state, {
|
|
@@ -180,8 +218,12 @@ export function buildBootstrapSync() {
|
|
|
180
218
|
return `<!-- stack-sync: self-refreshing sync command. Last generated: ${new Date().toISOString().split("T")[0]} -->
|
|
181
219
|
|
|
182
220
|
> **Step 1 — always do this first:** Run \`npx claude-setup sync\` to refresh this file with the latest diff.
|
|
183
|
-
> - If
|
|
184
|
-
> -
|
|
221
|
+
> - If the output says **"No changes"** and shows "Setup is current" → respond "No changes detected since last sync. Everything is up to date." and STOP.
|
|
222
|
+
> - If the output shows **changes** (any "+N added", "~N modified", or "-N deleted" with N > 0) → it means the file has been regenerated. Continue to Step 2.
|
|
223
|
+
> **Step 2:** Re-read \`.claude/commands/stack-sync.md\` — it now contains the actual diff with line-level changes.
|
|
224
|
+
> **Step 3:** Process every change listed. Update CLAUDE.md, .mcp.json, settings.json as needed. Surgical edits only.
|
|
225
|
+
|
|
226
|
+
**IMPORTANT:** The sync command creates a snapshot AND regenerates this file. The "Run /stack-sync" message in the output is for YOU — it means this file is now ready to be re-read. Do NOT tell the user to run /stack-sync again.
|
|
185
227
|
|
|
186
228
|
## Changes since last setup
|
|
187
229
|
|
|
@@ -246,73 +288,94 @@ export function buildAtomicSteps(collected, state) {
|
|
|
246
288
|
// --- Step 2: .mcp.json ---
|
|
247
289
|
{
|
|
248
290
|
filename: "stack-2-mcp.md",
|
|
249
|
-
content:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
291
|
+
content: (() => {
|
|
292
|
+
const serviceDiscovery = buildServiceDiscoveryInstructions(process.cwd());
|
|
293
|
+
return header + preamble +
|
|
294
|
+
`## Target: .mcp.json\n\n` +
|
|
295
|
+
(state.mcpJson.exists
|
|
296
|
+
? `### Current content — MERGE ONLY, never remove existing entries:\n${vars.MCP_JSON_CONTENT}\n\n`
|
|
297
|
+
: `Does not exist.\n\n`) +
|
|
298
|
+
`### When to create/update\n` +
|
|
299
|
+
`Add an MCP server if you find ANY of these signals in /stack-0-context:\n` +
|
|
300
|
+
`- Import statement referencing an external service (e.g., pg, mysql2, mongoose, redis, stripe)\n` +
|
|
301
|
+
`- docker-compose service (database, cache, queue, message broker)\n` +
|
|
302
|
+
`- Env var name in .env.example matching a known service pattern (DATABASE_URL, REDIS_URL, STRIPE_KEY, etc.)\n` +
|
|
303
|
+
`- Explicit dependency on an MCP-compatible package\n` +
|
|
304
|
+
`- User mentioned external services during init questions\n\n` +
|
|
305
|
+
`If ANY evidence is found, create .mcp.json with the corresponding servers.\n` +
|
|
306
|
+
`No evidence = no server. Do not invent services.\n\n` +
|
|
307
|
+
(serviceDiscovery ? serviceDiscovery + `\n` : ``) +
|
|
308
|
+
`### Verified MCP package names — ONLY use these\n` +
|
|
309
|
+
`\`\`\`\n` +
|
|
310
|
+
Object.entries(VERIFIED_MCP_PACKAGES).map(([k, v]) => `${k.padEnd(12)} → ${v}`).join("\n") +
|
|
311
|
+
`\n\`\`\`\n` +
|
|
312
|
+
`If the service is not in this list, print:\n` +
|
|
313
|
+
`\`⚠️ UNKNOWN PACKAGE — [service] MCP server not added: package name unverified. Find it at https://github.com/modelcontextprotocol/servers\`\n` +
|
|
314
|
+
`Do not add a placeholder. Do not guess.\n\n` +
|
|
315
|
+
`### OS-correct format (detected: ${os}${os === "WSL" ? " — uses Unix-style commands, services reachable on localhost" : ""})\n` +
|
|
316
|
+
`**Preferred: use CLI to add (writes to .mcp.json automatically):**\n` +
|
|
317
|
+
(os === "Windows"
|
|
318
|
+
? `\`\`\`\nclaude mcp add --scope project --transport stdio <name> -- cmd /c npx -y <package>\n\`\`\`\n`
|
|
319
|
+
: `\`\`\`\nclaude mcp add --scope project --transport stdio <name> -- npx -y <package>\n\`\`\`\n`) +
|
|
320
|
+
`**Or write .mcp.json directly:**\n` +
|
|
321
|
+
(os === "Windows"
|
|
322
|
+
? `Use: \`{ "command": "cmd", "args": ["/c", "npx", "-y", "<package>"] }\`\n`
|
|
323
|
+
: `Use: \`{ "command": "npx", "args": ["-y", "<package>"] }\`\n`) +
|
|
324
|
+
`Always include \`-y\` in npx args to prevent install hangs.\n` +
|
|
325
|
+
(os === "WSL" ? `Note: WSL uses Unix-style npx — do NOT use \`cmd /c\` wrapper.\n` : ``) +
|
|
326
|
+
(os === "macOS" ? `Note: On macOS, Homebrew services run on localhost by default. Check with \`brew services list\`.\n` : ``) +
|
|
327
|
+
`\n` +
|
|
328
|
+
`### Connection strings — smart auto-configuration\n` +
|
|
329
|
+
`For each MCP server that needs a connection string:\n` +
|
|
330
|
+
`1. **Check environment first:** If \`\${VARNAME}\` is set in the user's environment, use \`"env": { "VAR": "\${VAR}" }\`\n` +
|
|
331
|
+
`2. **Detect local service:** Run the OS-appropriate check command to see if the service is installed locally\n` +
|
|
332
|
+
(os === "Windows"
|
|
333
|
+
? ` - PostgreSQL: \`where psql 2>nul\`\n - MongoDB: \`where mongosh 2>nul\`\n - Redis: \`where redis-cli 2>nul\`\n - MySQL: \`where mysql 2>nul\`\n`
|
|
334
|
+
: os === "macOS"
|
|
335
|
+
? ` - PostgreSQL: \`command -v psql || brew list postgresql 2>/dev/null\`\n - MongoDB: \`command -v mongosh || brew list mongodb-community 2>/dev/null\`\n - Redis: \`command -v redis-cli || brew list redis 2>/dev/null\`\n - MySQL: \`command -v mysql || brew list mysql 2>/dev/null\`\n`
|
|
336
|
+
: ` - PostgreSQL: \`command -v psql\`\n - MongoDB: \`command -v mongosh\`\n - Redis: \`command -v redis-cli\`\n - MySQL: \`command -v mysql\`\n`) +
|
|
337
|
+
`3. **If local service found and env var NOT set:** Use the well-known default URL directly in the env block:\n` +
|
|
338
|
+
` - PostgreSQL: \`postgresql://localhost:5432/postgres\`\n` +
|
|
339
|
+
` - MongoDB: \`mongodb://localhost:27017\`\n` +
|
|
340
|
+
` - Redis: \`redis://localhost:6379\`\n` +
|
|
341
|
+
` - MySQL: \`mysql://root@localhost:3306\`\n` +
|
|
342
|
+
` AND document the var in .env.example with the default value\n` +
|
|
343
|
+
`4. **If neither env var nor local service found:** Use \`\${VARNAME}\` syntax and flag:\n` +
|
|
344
|
+
` \`⚠️ Set VARNAME in your environment or .env file before starting Claude Code\`\n\n` +
|
|
345
|
+
`**NEVER hardcode credentials.** Default localhost URLs are acceptable for dev environments.\n` +
|
|
346
|
+
`After adding any server with env vars, always document them in .env.example.\n\n` +
|
|
347
|
+
`### Rules\n` +
|
|
348
|
+
`- Produce valid JSON only\n` +
|
|
349
|
+
`- If creating: document every new env var in .env.example\n` +
|
|
350
|
+
`- OS format must match detected OS: ${os}\n\n` +
|
|
351
|
+
`### Channels (Telegram, Discord) — special MCP servers\n` +
|
|
352
|
+
`Channels are MCP servers that push events INTO a session. They require:\n` +
|
|
353
|
+
`- Claude Code v2.1.80+\n` +
|
|
354
|
+
`- claude.ai login (not API key / Console)\n` +
|
|
355
|
+
`- Bun runtime installed\n` +
|
|
356
|
+
`- \`--channels\` flag at EVERY session launch\n\n` +
|
|
357
|
+
`Verified channel plugins:\n` +
|
|
358
|
+
`\`\`\`\n` +
|
|
359
|
+
`Telegram → plugin:telegram@claude-plugins-official\n` +
|
|
360
|
+
`Discord → plugin:discord@claude-plugins-official\n` +
|
|
361
|
+
`\`\`\`\n\n` +
|
|
362
|
+
`If adding a channel-type server, bot tokens must NEVER be hardcoded:\n` +
|
|
363
|
+
(os === "Windows"
|
|
364
|
+
? `\`{ "command": "cmd", "args": ["/c", "bun", "run", "\${CLAUDE_PLUGIN_ROOT}/servers/telegram"], "env": { "TELEGRAM_BOT_TOKEN": "\${TELEGRAM_BOT_TOKEN}" } }\`\n`
|
|
365
|
+
: `\`{ "command": "bun", "args": ["run", "\${CLAUDE_PLUGIN_ROOT}/servers/telegram"], "env": { "TELEGRAM_BOT_TOKEN": "\${TELEGRAM_BOT_TOKEN}" } }\`\n`) +
|
|
366
|
+
(os === "WSL" ? `(WSL note: Bun must be installed inside WSL, not the Windows-side installation.)\n` : ``) +
|
|
367
|
+
`After adding, flag: \`⚠️ CHANNEL ACTIVATION REQUIRED — launch with: claude --channels plugin:telegram@claude-plugins-official\`\n\n` +
|
|
368
|
+
`### Self-correction fallback\n` +
|
|
369
|
+
`If MCP configuration fails or produces warnings:\n` +
|
|
370
|
+
`1. Read the official MCP documentation: https://modelcontextprotocol.io/introduction\n` +
|
|
371
|
+
`2. Verify the package name against the MCP servers registry: https://github.com/modelcontextprotocol/servers\n` +
|
|
372
|
+
`3. Check the server's README for required env vars and correct args format\n` +
|
|
373
|
+
`4. Re-run \`npx claude-setup doctor\` to validate the fix\n` +
|
|
374
|
+
`Do NOT leave broken MCP configuration in place — either fix it or remove the entry.\n\n` +
|
|
375
|
+
`### Output\n` +
|
|
376
|
+
`Created/Updated: ✅ .mcp.json — [what server and evidence source]\n` +
|
|
377
|
+
`Skipped: ⏭ .mcp.json — checked [files], found [nothing], no action\n`;
|
|
378
|
+
})(),
|
|
316
379
|
},
|
|
317
380
|
// --- Step 3: .claude/settings.json ---
|
|
318
381
|
{
|
package/dist/commands/init.js
CHANGED
|
@@ -21,7 +21,14 @@ function installBootstrapCommands(dir) {
|
|
|
21
21
|
> **Step 1:** Ask the user: "What do you want to add to your Claude Code setup?"
|
|
22
22
|
> **Step 2:** After the user responds, run: \`npx claude-setup add "<their exact answer>"\`
|
|
23
23
|
> **Step 3:** Re-read this file (\`.claude/commands/stack-add.md\`) — it was just regenerated with full marketplace instructions.
|
|
24
|
-
> **Step 4:** Follow the instructions in the updated file.
|
|
24
|
+
> **Step 4:** Follow the marketplace install instructions in the updated file. Do NOT ask clarifying questions — go straight to searching and installing.
|
|
25
|
+
|
|
26
|
+
**IMPORTANT — marketplace-first approach:**
|
|
27
|
+
- After Step 3, the regenerated file contains a 4-step marketplace search flow. Follow it AUTOMATICALLY.
|
|
28
|
+
- Do NOT ask the user "do you mean X or Y?" — search the marketplace for ALL interpretations.
|
|
29
|
+
- Do NOT suggest manual installation steps — execute the curl/install commands yourself.
|
|
30
|
+
- The goal is ZERO friction: user says what they want → you search → you install → done.
|
|
31
|
+
- Only ask the user if the marketplace returns multiple equally-valid matches and you need to pick one.
|
|
25
32
|
`,
|
|
26
33
|
"stack-status.md": `<!-- stack-status: show project state -->
|
|
27
34
|
|