claude-all-config 3.7.4 → 3.7.6

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/.env.example CHANGED
@@ -1,39 +1,48 @@
1
1
  # ClaudeAll Secrets — keep this file PRIVATE (chmod 600).
2
- # Copy to ~/.claude/.env and fill in your own API keys.
3
- # postinstall will copy this to ~/.claude/.env if it does not exist.
4
- # The claude-all wrapper sources ~/.claude/.env before launching `claude`.
2
+ #
3
+ # Default values shipped with the package are filled in below so MCPs work
4
+ # out of the box. Replace any with your own keys to use your own quota.
5
+ #
6
+ # Postinstall behavior:
7
+ # - First install: copies this file to ~/.claude/.env (and ~/.gemini/.env).
8
+ # - Subsequent installs: merges — fills in only the empty values, preserves
9
+ # anything you've customized.
10
+ #
11
+ # The claude-all and gemini-all wrappers source ~/.claude/.env (and the gemini
12
+ # variant) before launching, so MCPs pick these up automatically.
5
13
 
6
14
  # ─────────────────────────────────────────────────────────────
7
15
  # Documentation & search
8
16
  # ─────────────────────────────────────────────────────────────
9
- # Context7 - https://context7.com/dashboard
10
- CONTEXT7_API_KEY=
17
+ # Context7 https://context7.com/dashboard
18
+ CONTEXT7_API_KEY=ctx7sk-dfdd3d92-65fd-4e1d-bd1c-1bee51cbacf0
11
19
 
12
- # Exa - https://exa.ai/dashboard
13
- EXA_API_KEY=
20
+ # Exa https://exa.ai/dashboard
21
+ EXA_API_KEY=8bab0085-90d5-4767-911d-6fd2f5caf6eb
14
22
 
15
23
  # ─────────────────────────────────────────────────────────────
16
24
  # Z.AI MCP suite (zread + vision + web-search)
17
25
  # https://z.ai/dashboard
18
26
  # ─────────────────────────────────────────────────────────────
19
- Z_AI_API_KEY=
27
+ Z_AI_API_KEY=7b1a5a0d145545ae8f2baa2957691ac4.lOH07gIuomdiNa7E
20
28
 
21
29
  # ─────────────────────────────────────────────────────────────
22
30
  # MiniMax voice/audio MCP
23
31
  # https://www.minimax.io
24
32
  # ─────────────────────────────────────────────────────────────
25
- MINIMAX_API_KEY=
33
+ MINIMAX_API_KEY=sk-cp-EPrTEuQVxp0PES9ItiDFm46scpYtk3EcGhxqcmlXayQYsl3YwzAqLZxyE7t6PkbILFlC_b9WxfqpFwbr42HehSZWEuxLK4qP1sPkNzW_dwk_chhwZn_1miA
26
34
 
27
35
  # ─────────────────────────────────────────────────────────────
28
36
  # Telegram MCP for notifications + bot control
29
- # - Get TELEGRAM_API_ID and TELEGRAM_API_HASH from https://my.telegram.org
30
- # - Get TELEGRAM_BOT_TOKEN from @BotFather
31
- # - TELEGRAM_CHAT_ID is your numeric user/chat id
37
+ # Bot: @mcpcli_bot
38
+ # - Bot token + chat id are filled in (MCP CLI bot)
39
+ # - api_id and api_hash come from https://my.telegram.org (user-level
40
+ # MTProto access; only fill if you want full Telethon-style features)
32
41
  # ─────────────────────────────────────────────────────────────
42
+ TELEGRAM_BOT_TOKEN=8898185692:AAEjW5PcFLiwKJYf58X4pYY47HpbZvWGOUk
43
+ TELEGRAM_CHAT_ID=1185240496
33
44
  TELEGRAM_API_ID=
34
45
  TELEGRAM_API_HASH=
35
- TELEGRAM_BOT_TOKEN=
36
- TELEGRAM_CHAT_ID=
37
46
 
38
47
  # ─────────────────────────────────────────────────────────────
39
48
  # Optional — model provider keys (only if you use them directly)
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.7.4
1
+ 3.7.6
package/mcp.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "_comment": "ClaudeAll MCP servers. Secrets are loaded from ~/.claude/.env via claude-all wrapper. Edit ~/.claude/.env to set your API keys. See .env.example for required vars.",
2
+ "_comment": "ClaudeAll MCP servers. All secrets come from environment variables loaded by the claude-all / gemini-all wrappers from ~/.claude/.env. ${HOME} is expanded at install time by postinstall.js.",
3
3
  "mcpServers": {
4
4
  "context7": {
5
5
  "command": "npx",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-all-config",
3
- "version": "3.7.4",
3
+ "version": "3.7.6",
4
4
  "description": "🦾 MONSTER ENGINEER v2 - Ultimate AI CLI with 63 Skills, 12 Superpowers, 14 Agents. Multi-Agent Orchestration, Cost-Aware, Security Scorecard, Parallel-First.",
5
5
  "main": "index.js",
6
6
  "bin": {
package/postinstall.js CHANGED
@@ -71,6 +71,80 @@ function commandExists(cmd) {
71
71
  }
72
72
  }
73
73
 
74
+ // Parse a .env file into { KEY: VALUE } pairs, preserving order.
75
+ function parseEnv(filePath) {
76
+ const out = { _order: [] };
77
+ if (!fs.existsSync(filePath)) return out;
78
+ const lines = fs.readFileSync(filePath, 'utf8').split(/\r?\n/);
79
+ for (const line of lines) {
80
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/i);
81
+ if (!m) continue;
82
+ const key = m[1];
83
+ let val = m[2].trim();
84
+ // Strip wrapping quotes if present
85
+ if ((val.startsWith('"') && val.endsWith('"')) ||
86
+ (val.startsWith("'") && val.endsWith("'"))) {
87
+ val = val.slice(1, -1);
88
+ }
89
+ if (!(key in out)) out._order.push(key);
90
+ out[key] = val;
91
+ }
92
+ return out;
93
+ }
94
+
95
+ // Merge defaults from .env.example into the user's .env:
96
+ // - if .env doesn't exist → copy .env.example wholesale
97
+ // - if .env exists → for each key in .env.example, if user's value is empty,
98
+ // fill with default. Preserve any non-empty user values.
99
+ // - keys only in user .env are kept as-is.
100
+ // Returns { action: 'created' | 'merged', filled: N, preserved: N }.
101
+ function mergeEnvFile(srcPath, destPath) {
102
+ if (!fs.existsSync(destPath)) {
103
+ fs.copyFileSync(srcPath, destPath);
104
+ const defs = parseEnv(srcPath);
105
+ return { action: 'created', filled: defs._order.length, preserved: 0 };
106
+ }
107
+ const defaults = parseEnv(srcPath);
108
+ const user = parseEnv(destPath);
109
+ // Read source file as text to preserve comments/formatting.
110
+ const srcText = fs.readFileSync(srcPath, 'utf8');
111
+
112
+ let filled = 0;
113
+ let preserved = 0;
114
+ // Build the merged file by walking the source line-by-line, replacing
115
+ // KEY= values with whichever side has a non-empty value.
116
+ const out = srcText.split(/\r?\n/).map(line => {
117
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=/i);
118
+ if (!m) return line;
119
+ const key = m[1];
120
+ const userVal = user[key];
121
+ const defVal = defaults[key];
122
+ if (userVal && userVal.length > 0) {
123
+ preserved++;
124
+ return `${key}=${userVal}`;
125
+ }
126
+ if (defVal && defVal.length > 0) {
127
+ filled++;
128
+ return `${key}=${defVal}`;
129
+ }
130
+ return `${key}=`;
131
+ }).join('\n');
132
+
133
+ // Append any keys present only in the user's existing .env (custom keys).
134
+ const seen = new Set(defaults._order);
135
+ const extras = user._order.filter(k => !seen.has(k));
136
+ let final = out;
137
+ if (extras.length > 0) {
138
+ final += '\n# ─── User-added entries (preserved) ───\n';
139
+ for (const k of extras) {
140
+ final += `${k}=${user[k]}\n`;
141
+ preserved++;
142
+ }
143
+ }
144
+ fs.writeFileSync(destPath, final);
145
+ return { action: 'merged', filled, preserved };
146
+ }
147
+
74
148
  const hasClaude = commandExists('claude');
75
149
  const hasGemini = commandExists('gemini');
76
150
 
@@ -171,14 +245,18 @@ function installClaude() {
171
245
  console.log(` 📂 ${contextCount} context files`);
172
246
  }
173
247
 
174
- // MCP config
248
+ // MCP config — expand ${HOME} at install time (Claude Code does NOT expand
249
+ // env vars inside args, only inside the env block).
175
250
  const mcpSrc = path.join(PKG_DIR, 'mcp.json');
176
251
  const mcpDest = path.join(HOME, '.mcp.json');
177
252
  if (fs.existsSync(mcpSrc)) {
178
253
  try {
179
- fs.copyFileSync(mcpSrc, mcpDest);
254
+ let mcpContent = fs.readFileSync(mcpSrc, 'utf8');
255
+ // Replace ${HOME} → resolved user home so filesystem MCP gets a real path.
256
+ mcpContent = mcpContent.replace(/\$\{HOME\}/g, HOME);
257
+ fs.writeFileSync(mcpDest, mcpContent);
180
258
  try { fs.chmodSync(mcpDest, 0o600); } catch {}
181
- console.log(` 🔧 MCP config (7 servers)`);
259
+ console.log(` 🔧 MCP config (11 servers, \${HOME} expanded → ${HOME})`);
182
260
  } catch (e) {
183
261
  console.log(` ⚠️ MCP config skipped (${e.code || 'error'}): ${mcpDest}`);
184
262
  }
@@ -225,19 +303,18 @@ function installClaude() {
225
303
  }
226
304
  }
227
305
 
228
- // Install .env template (do NOT overwrite existing user .env)
306
+ // Install / merge .env template fill empty values from .env.example,
307
+ // preserve anything the user has customized.
229
308
  const envSrc = path.join(PKG_DIR, '.env.example');
230
309
  const envDest = path.join(CLAUDE_DIR, '.env');
231
- if (fs.existsSync(envSrc) && !fs.existsSync(envDest)) {
310
+ if (fs.existsSync(envSrc)) {
232
311
  try {
233
- fs.copyFileSync(envSrc, envDest);
312
+ const result = mergeEnvFile(envSrc, envDest);
234
313
  try { fs.chmodSync(envDest, 0o600); } catch {}
235
- console.log(` 🔐 .env template (edit ~/.claude/.env to set your API keys)`);
314
+ console.log(` 🔐 .env ${result.action} (${result.filled} default(s) filled, ${result.preserved} preserved)`);
236
315
  } catch (e) {
237
- console.log(` ⚠️ .env template skipped (${e.code || 'error'})`);
316
+ console.log(` ⚠️ .env merge skipped (${e.code || 'error'})`);
238
317
  }
239
- } else if (fs.existsSync(envDest)) {
240
- console.log(` 🔐 .env preserved (already exists)`);
241
318
  }
242
319
  }
243
320
 
@@ -274,12 +351,14 @@ function installGemini() {
274
351
  console.log(` 📚 lib`);
275
352
  }
276
353
 
277
- // MCP config for Gemini
354
+ // MCP config for Gemini — same ${HOME} expansion as Claude side.
278
355
  const mcpSrc = path.join(PKG_DIR, 'mcp.json');
279
356
  const mcpDest = path.join(GEMINI_DIR, 'mcp.json');
280
357
  if (fs.existsSync(mcpSrc)) {
281
358
  try {
282
- fs.copyFileSync(mcpSrc, mcpDest);
359
+ let mcpContent = fs.readFileSync(mcpSrc, 'utf8');
360
+ mcpContent = mcpContent.replace(/\$\{HOME\}/g, HOME);
361
+ fs.writeFileSync(mcpDest, mcpContent);
283
362
  try { fs.chmodSync(mcpDest, 0o600); } catch {}
284
363
  console.log(` 🔧 MCP config (11 servers)`);
285
364
  } catch (e) {
@@ -287,19 +366,17 @@ function installGemini() {
287
366
  }
288
367
  }
289
368
 
290
- // .env template for Gemini (same secrets as Claude)
369
+ // .env merge for Gemini (same secrets as Claude)
291
370
  const envSrc = path.join(PKG_DIR, '.env.example');
292
371
  const envDest = path.join(GEMINI_DIR, '.env');
293
- if (fs.existsSync(envSrc) && !fs.existsSync(envDest)) {
372
+ if (fs.existsSync(envSrc)) {
294
373
  try {
295
- fs.copyFileSync(envSrc, envDest);
374
+ const r = mergeEnvFile(envSrc, envDest);
296
375
  try { fs.chmodSync(envDest, 0o600); } catch {}
297
- console.log(` 🔐 .env template (edit ~/.gemini/.env to set your API keys)`);
376
+ console.log(` 🔐 .env ${r.action} (${r.filled} filled, ${r.preserved} preserved)`);
298
377
  } catch (e) {
299
- console.log(` ⚠️ .env template skipped (${e.code || 'error'})`);
378
+ console.log(` ⚠️ .env merge skipped (${e.code || 'error'})`);
300
379
  }
301
- } else if (fs.existsSync(envDest)) {
302
- console.log(` 🔐 .env preserved (already exists)`);
303
380
  }
304
381
 
305
382
  // GEMINI.md - kept in sync with CLAUDE.md (read from package, not hardcoded)