nothumanallowed 15.1.6 → 15.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "15.1.6",
3
+ "version": "15.1.7",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.mjs CHANGED
@@ -52,12 +52,15 @@ export async function main(argv) {
52
52
  }
53
53
  }).catch(() => {});
54
54
 
55
- // npm version check (non-blocking)
55
+ // npm version check (non-blocking). The one-liner uses --prefer-online to
56
+ // bypass npm's metadata cache, which is the #1 reason `npm install -g`
57
+ // appears to "do nothing" — it had stale "latest" in the local cache.
56
58
  checkNpmVersion().then(result => {
57
59
  if (result?.updateAvailable) {
58
60
  console.log('');
59
61
  warn(`New NHA version available: ${result.current} → ${result.latest}`);
60
- info(`Run "nha update" to upgrade, or: npm cache clean --force && npm install -g nothumanallowed@${result.latest}`);
62
+ info(`Run "nha update" (recommended auto-installs npm + agents)`);
63
+ info(`Or manually: npm cache clean --force && npm install -g nothumanallowed@${result.latest} --prefer-online`);
61
64
  }
62
65
  }).catch(() => {});
63
66
  }
package/src/constants.mjs CHANGED
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
 
8
- export const VERSION = '15.1.6';
8
+ export const VERSION = '15.1.7';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
package/src/updater.mjs CHANGED
@@ -87,17 +87,95 @@ function compareSemver(a, b) {
87
87
  }
88
88
 
89
89
  /**
90
- * Full update: re-download core files + agents.
90
+ * Detect whether the current `nha` binary is reachable from multiple PATH
91
+ * locations. This is the classic "I ran npm install -g but nothing changed"
92
+ * trap on macOS where a system-wide /usr/local/bin/nha shadows a user-space
93
+ * ~/.npm-global/bin/nha (or vice versa).
94
+ */
95
+ async function detectDuplicateInstall() {
96
+ try {
97
+ const { execSync } = await import('child_process');
98
+ const out = execSync('which -a nha 2>/dev/null', { encoding: 'utf-8' });
99
+ const paths = out.split('\n').map(s => s.trim()).filter(Boolean);
100
+ return paths.length > 1 ? paths : null;
101
+ } catch { return null; }
102
+ }
103
+
104
+ /**
105
+ * Run `npm install -g nothumanallowed@latest` from inside the CLI itself.
106
+ * Uses --prefer-online to defeat npm's metadata cache, which is the usual
107
+ * culprit when the user already ran "npm install -g nothumanallowed" but got
108
+ * an older version because the manifest in cache was stale.
109
+ */
110
+ async function npmSelfInstall(targetVersion) {
111
+ const { spawn } = await import('child_process');
112
+ return new Promise((resolve) => {
113
+ info(`Installing nothumanallowed@${targetVersion} via npm (this may take 10-30s)...`);
114
+ const args = [
115
+ 'install', '-g', `nothumanallowed@${targetVersion}`,
116
+ '--registry=https://registry.npmjs.org/',
117
+ '--prefer-online',
118
+ '--no-fund',
119
+ '--no-audit',
120
+ ];
121
+ const child = spawn('npm', args, { stdio: 'inherit' });
122
+ child.on('exit', (code) => resolve(code === 0));
123
+ child.on('error', (err) => {
124
+ warn(`npm spawn failed: ${err.message}`);
125
+ resolve(false);
126
+ });
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Full update: re-download core files + agents + self-upgrade the npm package.
91
132
  */
92
133
  export async function runUpdate() {
93
134
  info('Checking for updates...');
94
135
 
136
+ // ── npm package self-update ────────────────────────────────────────────
137
+ // Done FIRST so the freshly installed version applies on the next invocation.
138
+ // We bypass npm's metadata cache (--prefer-online) because that's the
139
+ // single most common reason "I just installed and it's still old".
140
+ let npmUpdated = false;
141
+ const npmCheck = await checkNpmVersion();
142
+ if (npmCheck?.updateAvailable) {
143
+ info(`npm package: ${npmCheck.current} → ${npmCheck.latest}`);
144
+ // Clean the local manifest cache first — defeats the stale-cache trap.
145
+ try {
146
+ const { execSync } = await import('child_process');
147
+ execSync('npm cache clean --force', { stdio: 'pipe' });
148
+ } catch { /* non-fatal */ }
149
+
150
+ const ok2 = await npmSelfInstall(npmCheck.latest);
151
+ if (ok2) {
152
+ ok(`npm package upgraded to ${npmCheck.latest}`);
153
+ npmUpdated = true;
154
+
155
+ // Detect duplicate global installs — common on macOS.
156
+ const dups = await detectDuplicateInstall();
157
+ if (dups && dups.length > 1) {
158
+ warn('Multiple nha installations detected on PATH:');
159
+ for (const p of dups) console.log(` ${p}`);
160
+ warn('Only the FIRST in PATH is what your shell will run. If the version still');
161
+ warn('appears unchanged, remove the older one (e.g. `sudo rm /usr/local/bin/nha`)');
162
+ warn('or reorder your PATH so the newer install is found first.');
163
+ }
164
+ } else {
165
+ warn('npm install failed. Run manually:');
166
+ console.log(` npm cache clean --force && npm install -g nothumanallowed@${npmCheck.latest} --prefer-online`);
167
+ }
168
+ } else if (npmCheck) {
169
+ ok(`npm package nothumanallowed@${npmCheck.current} (up to date)`);
170
+ }
171
+
172
+ // ── Agents + Legion + PIF (downloaded from website, not npm) ───────────
95
173
  const res = await fetch(`${BASE_URL}/versions.json`, {
96
174
  signal: AbortSignal.timeout(15000),
97
175
  headers: { 'User-Agent': 'nha-cli/1.0.0' },
98
176
  });
99
177
  if (!res.ok) {
100
- warn('Could not reach nothumanallowed.com');
178
+ warn('Could not reach nothumanallowed.com for agent updates.');
101
179
  return;
102
180
  }
103
181
 
@@ -112,7 +190,7 @@ export async function runUpdate() {
112
190
  const pifCurrent = local['pif']?.latest ?? '?';
113
191
  const pifLatest = remote['pif']?.latest ?? '?';
114
192
 
115
- let updated = false;
193
+ let updated = npmUpdated;
116
194
 
117
195
  // Update Legion
118
196
  if (legionCurrent !== legionLatest) {