claude-all-config 3.7.5 → 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.5
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.5",
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
 
@@ -229,19 +303,18 @@ function installClaude() {
229
303
  }
230
304
  }
231
305
 
232
- // 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.
233
308
  const envSrc = path.join(PKG_DIR, '.env.example');
234
309
  const envDest = path.join(CLAUDE_DIR, '.env');
235
- if (fs.existsSync(envSrc) && !fs.existsSync(envDest)) {
310
+ if (fs.existsSync(envSrc)) {
236
311
  try {
237
- fs.copyFileSync(envSrc, envDest);
312
+ const result = mergeEnvFile(envSrc, envDest);
238
313
  try { fs.chmodSync(envDest, 0o600); } catch {}
239
- 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)`);
240
315
  } catch (e) {
241
- console.log(` ⚠️ .env template skipped (${e.code || 'error'})`);
316
+ console.log(` ⚠️ .env merge skipped (${e.code || 'error'})`);
242
317
  }
243
- } else if (fs.existsSync(envDest)) {
244
- console.log(` 🔐 .env preserved (already exists)`);
245
318
  }
246
319
  }
247
320
 
@@ -293,19 +366,17 @@ function installGemini() {
293
366
  }
294
367
  }
295
368
 
296
- // .env template for Gemini (same secrets as Claude)
369
+ // .env merge for Gemini (same secrets as Claude)
297
370
  const envSrc = path.join(PKG_DIR, '.env.example');
298
371
  const envDest = path.join(GEMINI_DIR, '.env');
299
- if (fs.existsSync(envSrc) && !fs.existsSync(envDest)) {
372
+ if (fs.existsSync(envSrc)) {
300
373
  try {
301
- fs.copyFileSync(envSrc, envDest);
374
+ const r = mergeEnvFile(envSrc, envDest);
302
375
  try { fs.chmodSync(envDest, 0o600); } catch {}
303
- console.log(` 🔐 .env template (edit ~/.gemini/.env to set your API keys)`);
376
+ console.log(` 🔐 .env ${r.action} (${r.filled} filled, ${r.preserved} preserved)`);
304
377
  } catch (e) {
305
- console.log(` ⚠️ .env template skipped (${e.code || 'error'})`);
378
+ console.log(` ⚠️ .env merge skipped (${e.code || 'error'})`);
306
379
  }
307
- } else if (fs.existsSync(envDest)) {
308
- console.log(` 🔐 .env preserved (already exists)`);
309
380
  }
310
381
 
311
382
  // GEMINI.md - kept in sync with CLAUDE.md (read from package, not hardcoded)