claude-all-config 3.5.9 → 3.5.10

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/VERSION CHANGED
@@ -1 +1 @@
1
- 3.5.9
1
+ 3.5.10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-all-config",
3
- "version": "3.5.9",
3
+ "version": "3.5.10",
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
@@ -8,15 +8,65 @@ const fs = require('fs');
8
8
  const path = require('path');
9
9
  const { execSync } = require('child_process');
10
10
 
11
- const HOME = process.env.HOME || process.env.USERPROFILE;
11
+ // --- Sudo-aware HOME detection ----------------------------------------------
12
+ // When the package is installed via `sudo npm install -g`, npm runs the
13
+ // postinstall as root, so process.env.HOME is /root and configs would land in
14
+ // the wrong place. We honor SUDO_USER to write into the invoking user's HOME
15
+ // and chown the result back to them so a follow-up non-sudo install does not
16
+ // trip over EACCES on root-owned files.
17
+ const SUDO_USER = process.env.SUDO_USER && process.env.SUDO_USER !== 'root'
18
+ ? process.env.SUDO_USER : null;
19
+ const SUDO_UID = process.env.SUDO_UID ? Number(process.env.SUDO_UID) : null;
20
+ const SUDO_GID = process.env.SUDO_GID ? Number(process.env.SUDO_GID) : null;
21
+
22
+ function resolveHome() {
23
+ if (SUDO_USER) {
24
+ // Look up the real home from /etc/passwd
25
+ try {
26
+ const passwd = fs.readFileSync('/etc/passwd', 'utf8');
27
+ const line = passwd.split('\n').find(l => l.startsWith(SUDO_USER + ':'));
28
+ if (line) {
29
+ const parts = line.split(':');
30
+ if (parts[5] && fs.existsSync(parts[5])) return parts[5];
31
+ }
32
+ } catch {}
33
+ // Fallback to /home/$SUDO_USER
34
+ const fallback = `/home/${SUDO_USER}`;
35
+ if (fs.existsSync(fallback)) return fallback;
36
+ }
37
+ return process.env.HOME || process.env.USERPROFILE;
38
+ }
39
+
40
+ const HOME = resolveHome();
12
41
  const PKG_DIR = __dirname;
13
42
 
14
- // Detect installed CLIs
43
+ if (SUDO_USER) {
44
+ console.log(`ā„¹ļø Running under sudo — installing for user '${SUDO_USER}' (HOME=${HOME})\n`);
45
+ }
46
+
47
+ // Recursively chown a path back to the invoking user when running under sudo.
48
+ function fixOwnership(target) {
49
+ if (SUDO_UID === null || SUDO_GID === null) return;
50
+ try { fs.lchownSync(target, SUDO_UID, SUDO_GID); } catch {}
51
+ let stat;
52
+ try { stat = fs.lstatSync(target); } catch { return; }
53
+ if (stat.isSymbolicLink() || !stat.isDirectory()) return;
54
+ let entries;
55
+ try { entries = fs.readdirSync(target); } catch { return; }
56
+ for (const entry of entries) fixOwnership(path.join(target, entry));
57
+ }
58
+
59
+ // Detect installed CLIs — also check the resolved user's ~/.local/bin so that
60
+ // a sudo invocation still finds claude installed via the native installer.
15
61
  function commandExists(cmd) {
16
62
  try {
17
63
  execSync(`which ${cmd}`, { stdio: 'ignore' });
18
64
  return true;
19
65
  } catch {
66
+ if (HOME) {
67
+ const userBin = path.join(HOME, '.local', 'bin', cmd);
68
+ if (fs.existsSync(userBin)) return true;
69
+ }
20
70
  return false;
21
71
  }
22
72
  }
@@ -377,6 +427,17 @@ if (hasGemini) {
377
427
 
378
428
  setupLocalBinSymlinks();
379
429
 
430
+ // If we ran under sudo, hand ownership back to the original user so that a
431
+ // follow-up non-sudo `npm install -g claude-all-config` does not hit EACCES.
432
+ if (SUDO_USER) {
433
+ console.log(`\nšŸ”’ Restoring ownership to ${SUDO_USER}...`);
434
+ fixOwnership(path.join(HOME, '.claude'));
435
+ fixOwnership(path.join(HOME, '.gemini'));
436
+ fixOwnership(path.join(HOME, '.mcp.json'));
437
+ fixOwnership(path.join(HOME, '.local'));
438
+ console.log(' āœ… Ownership fixed.');
439
+ }
440
+
380
441
  const skips = Number(process.env._CA_COPY_SKIPS || 0);
381
442
  if (skips > 0) {
382
443
  console.log('');