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/dist/os.d.ts
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
export type DetectedOS = "Windows" | "macOS" | "Linux";
|
|
1
|
+
export type DetectedOS = "Windows" | "macOS" | "Linux" | "WSL";
|
|
2
2
|
/**
|
|
3
|
-
* Detect OS once per session. Order
|
|
3
|
+
* Detect OS once per session. Order:
|
|
4
4
|
* 1. COMSPEC set → Windows
|
|
5
5
|
* 2. OS === "Windows_NT" → Windows
|
|
6
6
|
* 3. process.platform === "win32" → Windows
|
|
7
|
-
* 4.
|
|
8
|
-
* 5.
|
|
7
|
+
* 4. /proc/version contains "microsoft" or "WSL" → WSL
|
|
8
|
+
* 5. WSL_DISTRO_NAME env var set → WSL
|
|
9
|
+
* 6. uname() === "Darwin" → macOS
|
|
10
|
+
* 7. default → Linux
|
|
9
11
|
*/
|
|
10
12
|
export declare function detectOS(): DetectedOS;
|
|
13
|
+
/** Returns true if the OS uses Unix-style shell commands (bash, npx direct) */
|
|
14
|
+
export declare function isUnixLike(os: DetectedOS): boolean;
|
|
11
15
|
/**
|
|
12
16
|
* Verified MCP package names — ONLY use these.
|
|
13
17
|
* If a service is not in this map, do not guess a package name.
|
|
14
18
|
*/
|
|
15
19
|
export declare const VERIFIED_MCP_PACKAGES: Record<string, string>;
|
|
20
|
+
/** Default connection strings for local services — used when env vars are not set */
|
|
21
|
+
export declare const DEFAULT_SERVICE_CONNECTIONS: Record<string, {
|
|
22
|
+
envVar: string;
|
|
23
|
+
defaultUrl: string;
|
|
24
|
+
testCmd: Record<DetectedOS, string>;
|
|
25
|
+
}>;
|
|
16
26
|
/** MCP command format per OS — always includes -y to prevent npx install hangs */
|
|
17
27
|
export declare function mcpCommandFormat(os: DetectedOS, pkg: string): {
|
|
18
28
|
command: string;
|
|
@@ -23,3 +33,22 @@ export declare function hookShellFormat(os: DetectedOS, cmd: string): {
|
|
|
23
33
|
command: string;
|
|
24
34
|
args: string[];
|
|
25
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Detect which services are available on the local machine.
|
|
38
|
+
* Returns a map of service name → detected info.
|
|
39
|
+
*/
|
|
40
|
+
export declare function detectLocalServices(os: DetectedOS): Record<string, {
|
|
41
|
+
found: boolean;
|
|
42
|
+
defaultUrl: string;
|
|
43
|
+
envVar: string;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Scan project files for service evidence and return auto-discovery instructions.
|
|
47
|
+
* Reads docker-compose, .env.example, package.json to find which services are used.
|
|
48
|
+
*/
|
|
49
|
+
export declare function discoverProjectServices(cwd: string): string[];
|
|
50
|
+
/**
|
|
51
|
+
* Build auto-discovery MCP configuration instructions for the detected OS.
|
|
52
|
+
* Returns markdown text to embed in templates.
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildServiceDiscoveryInstructions(cwd: string): string;
|
package/dist/os.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { execSync } from "child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
2
4
|
/**
|
|
3
|
-
* Detect OS once per session. Order
|
|
5
|
+
* Detect OS once per session. Order:
|
|
4
6
|
* 1. COMSPEC set → Windows
|
|
5
7
|
* 2. OS === "Windows_NT" → Windows
|
|
6
8
|
* 3. process.platform === "win32" → Windows
|
|
7
|
-
* 4.
|
|
8
|
-
* 5.
|
|
9
|
+
* 4. /proc/version contains "microsoft" or "WSL" → WSL
|
|
10
|
+
* 5. WSL_DISTRO_NAME env var set → WSL
|
|
11
|
+
* 6. uname() === "Darwin" → macOS
|
|
12
|
+
* 7. default → Linux
|
|
9
13
|
*/
|
|
10
14
|
export function detectOS() {
|
|
11
15
|
if (process.env.COMSPEC)
|
|
@@ -14,6 +18,15 @@ export function detectOS() {
|
|
|
14
18
|
return "Windows";
|
|
15
19
|
if (process.platform === "win32")
|
|
16
20
|
return "Windows";
|
|
21
|
+
// WSL detection — runs as Linux but under Windows kernel
|
|
22
|
+
if (process.env.WSL_DISTRO_NAME)
|
|
23
|
+
return "WSL";
|
|
24
|
+
try {
|
|
25
|
+
const procVersion = readFileSync("/proc/version", "utf8").toLowerCase();
|
|
26
|
+
if (procVersion.includes("microsoft") || procVersion.includes("wsl"))
|
|
27
|
+
return "WSL";
|
|
28
|
+
}
|
|
29
|
+
catch { /* not WSL or /proc not available */ }
|
|
17
30
|
try {
|
|
18
31
|
const uname = execSync("uname", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
19
32
|
if (uname === "Darwin")
|
|
@@ -22,6 +35,10 @@ export function detectOS() {
|
|
|
22
35
|
catch { /* not unix — unlikely to reach here */ }
|
|
23
36
|
return "Linux";
|
|
24
37
|
}
|
|
38
|
+
/** Returns true if the OS uses Unix-style shell commands (bash, npx direct) */
|
|
39
|
+
export function isUnixLike(os) {
|
|
40
|
+
return os === "Linux" || os === "macOS" || os === "WSL";
|
|
41
|
+
}
|
|
25
42
|
/**
|
|
26
43
|
* Verified MCP package names — ONLY use these.
|
|
27
44
|
* If a service is not in this map, do not guess a package name.
|
|
@@ -41,11 +58,55 @@ export const VERIFIED_MCP_PACKAGES = {
|
|
|
41
58
|
mysql: "@benborla29/mcp-server-mysql",
|
|
42
59
|
mongodb: "mcp-mongo-server",
|
|
43
60
|
};
|
|
61
|
+
/** Default connection strings for local services — used when env vars are not set */
|
|
62
|
+
export const DEFAULT_SERVICE_CONNECTIONS = {
|
|
63
|
+
postgres: {
|
|
64
|
+
envVar: "DATABASE_URL",
|
|
65
|
+
defaultUrl: "postgresql://localhost:5432/postgres",
|
|
66
|
+
testCmd: {
|
|
67
|
+
Windows: "where psql 2>nul || where pg_isready 2>nul",
|
|
68
|
+
macOS: "command -v psql || command -v pg_isready",
|
|
69
|
+
Linux: "command -v psql || command -v pg_isready",
|
|
70
|
+
WSL: "command -v psql || command -v pg_isready || /mnt/c/Program\\ Files/PostgreSQL/*/bin/psql.exe --version 2>/dev/null",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
mysql: {
|
|
74
|
+
envVar: "MYSQL_URL",
|
|
75
|
+
defaultUrl: "mysql://root@localhost:3306",
|
|
76
|
+
testCmd: {
|
|
77
|
+
Windows: "where mysql 2>nul",
|
|
78
|
+
macOS: "command -v mysql || brew list mysql 2>/dev/null",
|
|
79
|
+
Linux: "command -v mysql",
|
|
80
|
+
WSL: "command -v mysql || /mnt/c/Program\\ Files/MySQL/*/bin/mysql.exe --version 2>/dev/null",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
mongodb: {
|
|
84
|
+
envVar: "MONGODB_URI",
|
|
85
|
+
defaultUrl: "mongodb://localhost:27017",
|
|
86
|
+
testCmd: {
|
|
87
|
+
Windows: "where mongosh 2>nul || where mongo 2>nul",
|
|
88
|
+
macOS: "command -v mongosh || command -v mongo || brew list mongodb-community 2>/dev/null",
|
|
89
|
+
Linux: "command -v mongosh || command -v mongo",
|
|
90
|
+
WSL: "command -v mongosh || command -v mongo || mongosh.exe --version 2>/dev/null",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
redis: {
|
|
94
|
+
envVar: "REDIS_URL",
|
|
95
|
+
defaultUrl: "redis://localhost:6379",
|
|
96
|
+
testCmd: {
|
|
97
|
+
Windows: "where redis-cli 2>nul",
|
|
98
|
+
macOS: "command -v redis-cli || brew list redis 2>/dev/null",
|
|
99
|
+
Linux: "command -v redis-cli",
|
|
100
|
+
WSL: "command -v redis-cli || redis-cli.exe --version 2>/dev/null",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
44
104
|
/** MCP command format per OS — always includes -y to prevent npx install hangs */
|
|
45
105
|
export function mcpCommandFormat(os, pkg) {
|
|
46
106
|
if (os === "Windows") {
|
|
47
107
|
return { command: "cmd", args: ["/c", "npx", "-y", pkg] };
|
|
48
108
|
}
|
|
109
|
+
// macOS, Linux, and WSL all use npx directly
|
|
49
110
|
return { command: "npx", args: ["-y", pkg] };
|
|
50
111
|
}
|
|
51
112
|
/** Hook shell format per OS */
|
|
@@ -53,5 +114,179 @@ export function hookShellFormat(os, cmd) {
|
|
|
53
114
|
if (os === "Windows") {
|
|
54
115
|
return { command: "cmd", args: ["/c", cmd] };
|
|
55
116
|
}
|
|
117
|
+
// macOS, Linux, and WSL all use bash
|
|
56
118
|
return { command: "bash", args: ["-c", cmd] };
|
|
57
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Detect which services are available on the local machine.
|
|
122
|
+
* Returns a map of service name → detected info.
|
|
123
|
+
*/
|
|
124
|
+
export function detectLocalServices(os) {
|
|
125
|
+
const results = {};
|
|
126
|
+
for (const [service, config] of Object.entries(DEFAULT_SERVICE_CONNECTIONS)) {
|
|
127
|
+
let found = false;
|
|
128
|
+
try {
|
|
129
|
+
const cmd = config.testCmd[os];
|
|
130
|
+
execSync(cmd, { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"], timeout: 5000 });
|
|
131
|
+
found = true;
|
|
132
|
+
}
|
|
133
|
+
catch { /* not installed */ }
|
|
134
|
+
results[service] = {
|
|
135
|
+
found,
|
|
136
|
+
defaultUrl: config.defaultUrl,
|
|
137
|
+
envVar: config.envVar,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return results;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Scan project files for service evidence and return auto-discovery instructions.
|
|
144
|
+
* Reads docker-compose, .env.example, package.json to find which services are used.
|
|
145
|
+
*/
|
|
146
|
+
export function discoverProjectServices(cwd) {
|
|
147
|
+
const discovered = [];
|
|
148
|
+
const os = detectOS();
|
|
149
|
+
// Check docker-compose.yml for service definitions
|
|
150
|
+
for (const dcFile of ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"]) {
|
|
151
|
+
const dcPath = join(cwd, dcFile);
|
|
152
|
+
if (existsSync(dcPath)) {
|
|
153
|
+
try {
|
|
154
|
+
const content = readFileSync(dcPath, "utf8");
|
|
155
|
+
if (/postgres|pg_/i.test(content))
|
|
156
|
+
discovered.push("postgres");
|
|
157
|
+
if (/mysql|mariadb/i.test(content))
|
|
158
|
+
discovered.push("mysql");
|
|
159
|
+
if (/mongo/i.test(content))
|
|
160
|
+
discovered.push("mongodb");
|
|
161
|
+
if (/redis/i.test(content))
|
|
162
|
+
discovered.push("redis");
|
|
163
|
+
}
|
|
164
|
+
catch { /* skip */ }
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Check .env.example or .env.sample for service-related vars
|
|
168
|
+
for (const envFile of [".env.example", ".env.sample", ".env.template"]) {
|
|
169
|
+
const envPath = join(cwd, envFile);
|
|
170
|
+
if (existsSync(envPath)) {
|
|
171
|
+
try {
|
|
172
|
+
const content = readFileSync(envPath, "utf8");
|
|
173
|
+
if (/DATABASE_URL|POSTGRES|PG_/i.test(content) && !discovered.includes("postgres"))
|
|
174
|
+
discovered.push("postgres");
|
|
175
|
+
if (/MYSQL/i.test(content) && !discovered.includes("mysql"))
|
|
176
|
+
discovered.push("mysql");
|
|
177
|
+
if (/MONGO/i.test(content) && !discovered.includes("mongodb"))
|
|
178
|
+
discovered.push("mongodb");
|
|
179
|
+
if (/REDIS/i.test(content) && !discovered.includes("redis"))
|
|
180
|
+
discovered.push("redis");
|
|
181
|
+
}
|
|
182
|
+
catch { /* skip */ }
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Check package.json for database dependencies
|
|
186
|
+
const pkgPath = join(cwd, "package.json");
|
|
187
|
+
if (existsSync(pkgPath)) {
|
|
188
|
+
try {
|
|
189
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
190
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
191
|
+
if (allDeps.pg || allDeps.prisma || allDeps["@prisma/client"] || allDeps.knex) {
|
|
192
|
+
if (!discovered.includes("postgres"))
|
|
193
|
+
discovered.push("postgres");
|
|
194
|
+
}
|
|
195
|
+
if (allDeps.mysql2 || allDeps.mysql) {
|
|
196
|
+
if (!discovered.includes("mysql"))
|
|
197
|
+
discovered.push("mysql");
|
|
198
|
+
}
|
|
199
|
+
if (allDeps.mongoose || allDeps.mongodb) {
|
|
200
|
+
if (!discovered.includes("mongodb"))
|
|
201
|
+
discovered.push("mongodb");
|
|
202
|
+
}
|
|
203
|
+
if (allDeps.redis || allDeps.ioredis) {
|
|
204
|
+
if (!discovered.includes("redis"))
|
|
205
|
+
discovered.push("redis");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch { /* skip */ }
|
|
209
|
+
}
|
|
210
|
+
// Check requirements.txt / pyproject.toml for Python projects
|
|
211
|
+
for (const pyFile of ["requirements.txt", "pyproject.toml"]) {
|
|
212
|
+
const pyPath = join(cwd, pyFile);
|
|
213
|
+
if (existsSync(pyPath)) {
|
|
214
|
+
try {
|
|
215
|
+
const content = readFileSync(pyPath, "utf8");
|
|
216
|
+
if (/psycopg|asyncpg|sqlalchemy/i.test(content) && !discovered.includes("postgres"))
|
|
217
|
+
discovered.push("postgres");
|
|
218
|
+
if (/pymysql|mysqlclient/i.test(content) && !discovered.includes("mysql"))
|
|
219
|
+
discovered.push("mysql");
|
|
220
|
+
if (/pymongo|motor/i.test(content) && !discovered.includes("mongodb"))
|
|
221
|
+
discovered.push("mongodb");
|
|
222
|
+
if (/redis/i.test(content) && !discovered.includes("redis"))
|
|
223
|
+
discovered.push("redis");
|
|
224
|
+
}
|
|
225
|
+
catch { /* skip */ }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return [...new Set(discovered)];
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Build auto-discovery MCP configuration instructions for the detected OS.
|
|
232
|
+
* Returns markdown text to embed in templates.
|
|
233
|
+
*/
|
|
234
|
+
export function buildServiceDiscoveryInstructions(cwd) {
|
|
235
|
+
const os = detectOS();
|
|
236
|
+
const projectServices = discoverProjectServices(cwd);
|
|
237
|
+
const localServices = detectLocalServices(os);
|
|
238
|
+
const lines = [];
|
|
239
|
+
if (projectServices.length === 0)
|
|
240
|
+
return "";
|
|
241
|
+
lines.push(`### Auto-discovered services`);
|
|
242
|
+
lines.push(`The following services were detected in your project files:\n`);
|
|
243
|
+
for (const service of projectServices) {
|
|
244
|
+
const local = localServices[service];
|
|
245
|
+
const pkg = VERIFIED_MCP_PACKAGES[service];
|
|
246
|
+
if (!pkg || !local)
|
|
247
|
+
continue;
|
|
248
|
+
const status = local.found ? "installed locally" : "not found locally";
|
|
249
|
+
const statusIcon = local.found ? "✅" : "⚠️";
|
|
250
|
+
lines.push(`**${service}** — ${statusIcon} ${status}`);
|
|
251
|
+
if (local.found) {
|
|
252
|
+
lines.push(`- Default connection: \`${local.defaultUrl}\``);
|
|
253
|
+
lines.push(`- Env var: \`${local.envVar}\``);
|
|
254
|
+
lines.push(`- If \`${local.envVar}\` is not set in the environment, use the default: \`${local.defaultUrl}\``);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
lines.push(`- Env var: \`${local.envVar}\` — must be set before starting Claude Code`);
|
|
258
|
+
lines.push(`- Use \`\${${local.envVar}}\` in .mcp.json env block`);
|
|
259
|
+
}
|
|
260
|
+
lines.push(``);
|
|
261
|
+
}
|
|
262
|
+
lines.push(`### MCP auto-configuration strategy`);
|
|
263
|
+
lines.push(``);
|
|
264
|
+
lines.push(`For each service above, configure .mcp.json as follows:`);
|
|
265
|
+
lines.push(`1. **Check if the env var is already set** in the user's environment`);
|
|
266
|
+
lines.push(`2. **If set** → use \`\${VARNAME}\` syntax in the env block`);
|
|
267
|
+
lines.push(`3. **If not set but service is installed locally** → use the default connection URL directly in the env block AND document the var in .env.example`);
|
|
268
|
+
lines.push(`4. **If not set and not installed** → use \`\${VARNAME}\` syntax and flag: "⚠️ Set ${"{VARNAME}"} before starting Claude Code"`);
|
|
269
|
+
lines.push(``);
|
|
270
|
+
// OS-specific MCP format reminder
|
|
271
|
+
if (os === "Windows") {
|
|
272
|
+
lines.push(`### OS format (Windows detected)`);
|
|
273
|
+
lines.push(`\`\`\`json`);
|
|
274
|
+
lines.push(`{ "command": "cmd", "args": ["/c", "npx", "-y", "<package>"], "env": { ... } }`);
|
|
275
|
+
lines.push(`\`\`\``);
|
|
276
|
+
}
|
|
277
|
+
else if (os === "WSL") {
|
|
278
|
+
lines.push(`### OS format (WSL detected — uses Linux-style commands)`);
|
|
279
|
+
lines.push(`\`\`\`json`);
|
|
280
|
+
lines.push(`{ "command": "npx", "args": ["-y", "<package>"], "env": { ... } }`);
|
|
281
|
+
lines.push(`\`\`\``);
|
|
282
|
+
lines.push(`Note: WSL can also access Windows-side services on localhost. If a service runs on the Windows host, it is reachable at \`localhost\` from WSL.`);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
lines.push(`### OS format (${os} detected)`);
|
|
286
|
+
lines.push(`\`\`\`json`);
|
|
287
|
+
lines.push(`{ "command": "npx", "args": ["-y", "<package>"], "env": { ... } }`);
|
|
288
|
+
lines.push(`\`\`\``);
|
|
289
|
+
}
|
|
290
|
+
lines.push(``);
|
|
291
|
+
return lines.join("\n");
|
|
292
|
+
}
|
package/package.json
CHANGED
package/templates/add.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Add to Claude Code setup: "{{USER_INPUT}}"
|
|
4
4
|
|
|
5
|
+
**CRITICAL: Marketplace-first. Do NOT ask clarifying questions. Search and install automatically.**
|
|
6
|
+
**Execute every curl/install command yourself. The user expects zero-friction automation.**
|
|
7
|
+
**A fetch failure is NOT a stop — it is a routing signal to the next catalog.**
|
|
8
|
+
|
|
5
9
|
## Project context
|
|
6
10
|
{{PROJECT_CONTEXT}}
|
|
7
11
|
|
|
@@ -34,13 +38,55 @@ Skills: {{SKILLS_LIST}} | Commands: {{COMMANDS_LIST}}
|
|
|
34
38
|
|
|
35
39
|
Parse the user's request and take ALL applicable actions:
|
|
36
40
|
|
|
37
|
-
### 1.
|
|
41
|
+
### 1. Agents (if request is about agents/orchestration/subagents)
|
|
42
|
+
If the marketplace pipeline installed an agent file to `.claude/agents/`:
|
|
43
|
+
- Verify the file has YAML frontmatter (name, description, tools, model) and a body
|
|
44
|
+
- Document it in CLAUDE.md under a **separate agents section** (not mixed with skills)
|
|
45
|
+
- Agent entry format in CLAUDE.md:
|
|
46
|
+
```
|
|
47
|
+
## Agents
|
|
48
|
+
- **agent-name** — what it orchestrates, when to invoke it
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Agent files live in `.claude/agents/<name>.md` — NOT in `.claude/skills/`.
|
|
52
|
+
Agents and skills are architecturally different and must never be mixed.
|
|
53
|
+
|
|
54
|
+
### 2. MCP servers
|
|
38
55
|
If the request mentions an external service (database, API, browser, etc.):
|
|
39
56
|
- Check the verified MCP package list below
|
|
40
57
|
- If found: add to `.mcp.json` with OS-correct format (detected: {{DETECTED_OS}})
|
|
41
|
-
-
|
|
58
|
+
- **Smart connection strings** — follow this order:
|
|
59
|
+
1. Check if the env var is already set in the environment
|
|
60
|
+
2. If not set, detect if the service is installed locally (run check command below)
|
|
61
|
+
3. If local service found: use default localhost URL directly in env block
|
|
62
|
+
4. If nothing found: use `${VARNAME}` syntax and flag the missing var
|
|
42
63
|
- Document new env vars in `.env.example`
|
|
43
64
|
|
|
65
|
+
**Service detection commands ({{DETECTED_OS}}):**
|
|
66
|
+
{{#if IS_WINDOWS}}
|
|
67
|
+
- PostgreSQL: `where psql 2>nul` → default: `postgresql://localhost:5432/postgres`
|
|
68
|
+
- MongoDB: `where mongosh 2>nul` → default: `mongodb://localhost:27017`
|
|
69
|
+
- Redis: `where redis-cli 2>nul` → default: `redis://localhost:6379`
|
|
70
|
+
- MySQL: `where mysql 2>nul` → default: `mysql://root@localhost:3306`
|
|
71
|
+
{{else}}
|
|
72
|
+
{{#if IS_MACOS}}
|
|
73
|
+
- PostgreSQL: `command -v psql || brew list postgresql 2>/dev/null` → default: `postgresql://localhost:5432/postgres`
|
|
74
|
+
- MongoDB: `command -v mongosh || brew list mongodb-community 2>/dev/null` → default: `mongodb://localhost:27017`
|
|
75
|
+
- Redis: `command -v redis-cli || brew list redis 2>/dev/null` → default: `redis://localhost:6379`
|
|
76
|
+
- MySQL: `command -v mysql || brew list mysql 2>/dev/null` → default: `mysql://root@localhost:3306`
|
|
77
|
+
{{else}}
|
|
78
|
+
- PostgreSQL: `command -v psql` → default: `postgresql://localhost:5432/postgres`
|
|
79
|
+
- MongoDB: `command -v mongosh` → default: `mongodb://localhost:27017`
|
|
80
|
+
- Redis: `command -v redis-cli` → default: `redis://localhost:6379`
|
|
81
|
+
- MySQL: `command -v mysql` → default: `mysql://root@localhost:3306`
|
|
82
|
+
{{/if}}
|
|
83
|
+
{{#if IS_WSL}}
|
|
84
|
+
Note: WSL can access Windows-host services on localhost. If the service runs on the Windows side, it is reachable at `localhost` from WSL.
|
|
85
|
+
{{/if}}
|
|
86
|
+
{{/if}}
|
|
87
|
+
|
|
88
|
+
Run the check command. If the service IS installed locally and the env var is NOT set, use the default URL directly. This avoids the "MCP server not showing" problem where `${VARNAME}` fails silently.
|
|
89
|
+
|
|
44
90
|
Verified MCP packages — ONLY use these for MCP servers:
|
|
45
91
|
```
|
|
46
92
|
playwright → @playwright/mcp@latest
|
|
@@ -93,8 +139,8 @@ MCP format — create new .mcp.json:
|
|
|
93
139
|
```
|
|
94
140
|
{{/if}}
|
|
95
141
|
|
|
96
|
-
###
|
|
97
|
-
If the request mentions skills or capabilities:
|
|
142
|
+
### 3. Skills
|
|
143
|
+
If the request mentions skills or capabilities (NOT agents):
|
|
98
144
|
- Create `.claude/skills/<name>/SKILL.md` with proper frontmatter
|
|
99
145
|
- Use `description:` so Claude knows when to load the skill
|
|
100
146
|
- Search the marketplace for matching pre-built skills (see above)
|
|
@@ -109,7 +155,7 @@ description: What this skill does
|
|
|
109
155
|
Instructions...
|
|
110
156
|
```
|
|
111
157
|
|
|
112
|
-
###
|
|
158
|
+
### 4. Hooks
|
|
113
159
|
If the request implies automated actions (formatting, building, notifications):
|
|
114
160
|
- Add to `.claude/settings.json` using the CORRECT hooks format
|
|
115
161
|
- Verify the tool exists before adding a hook for it
|
|
@@ -133,13 +179,11 @@ Correct hooks format:
|
|
|
133
179
|
}
|
|
134
180
|
```
|
|
135
181
|
|
|
136
|
-
### 4. Plugins
|
|
137
|
-
If the request matches a marketplace category or SaaS platform:
|
|
138
|
-
- Suggest the relevant plugin with install commands
|
|
139
|
-
- Show the user exactly how to install it
|
|
140
|
-
|
|
141
182
|
### 5. CLAUDE.md
|
|
142
183
|
Document any new capabilities, services, or patterns added.
|
|
184
|
+
- Skills go under `## Skills` section
|
|
185
|
+
- Agents go under `## Agents` section (separate — never mixed)
|
|
186
|
+
- MCP servers go under `## MCP Servers` section
|
|
143
187
|
|
|
144
188
|
## Rules
|
|
145
189
|
- Read current content above before writing. Merge/append only.
|
|
@@ -148,6 +192,9 @@ Document any new capabilities, services, or patterns added.
|
|
|
148
192
|
- All env var refs use `${VARNAME}` syntax. Document new vars in .env.example.
|
|
149
193
|
- **NEVER write a "model" key into settings.json**
|
|
150
194
|
- Produce valid JSON only.
|
|
195
|
+
- Agents install to `.claude/agents/` — Skills install to `.claude/skills/`
|
|
196
|
+
- Every installed file must contain real, functional content (Rule 7).
|
|
197
|
+
- A fetch failure is a routing signal, not a stop condition (Rule 6).
|
|
151
198
|
|
|
152
199
|
## Output — one line per file
|
|
153
200
|
Updated: ✅ [path] — [what and why]
|
package/templates/sync.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<!-- claude-setup sync {{DATE}} | last: {{LAST_RUN_DATE}} -->
|
|
2
2
|
|
|
3
3
|
> **Step 1 — always do this first:** Run `npx claude-setup sync` to refresh this file with the latest diff.
|
|
4
|
-
> - If
|
|
5
|
-
> -
|
|
4
|
+
> - 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.
|
|
5
|
+
> - If the output shows **changes** (any "+N added", "~N modified", or "-N deleted" with N > 0) → continue to Step 2.
|
|
6
|
+
> **Step 2:** Re-read `.claude/commands/stack-sync.md` — it now contains the actual diff with line-level changes.
|
|
7
|
+
> **Step 3:** Process every change listed below. Update CLAUDE.md, .mcp.json, settings.json as needed.
|
|
8
|
+
|
|
9
|
+
**IMPORTANT:** Do NOT tell the user to "run /stack-sync" — you ARE running it right now. Process the diff below.
|
|
6
10
|
|
|
7
11
|
Project changed since last setup. Update ONLY what the changes demand.
|
|
8
12
|
|