@nexus-cortex/cli 4.30.0 → 4.32.0
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/bin/cortex.js +91 -30
- package/package.json +2 -2
package/bin/cortex.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { spawn, spawnSync } from 'child_process';
|
|
26
26
|
import { fileURLToPath } from 'url';
|
|
27
27
|
import { dirname, join, resolve } from 'path';
|
|
28
|
-
import { existsSync, readFileSync, realpathSync,
|
|
28
|
+
import { existsSync, readFileSync, realpathSync, mkdirSync, writeFileSync } from 'fs';
|
|
29
29
|
import { homedir } from 'os';
|
|
30
30
|
import { createRequire } from 'module';
|
|
31
31
|
|
|
@@ -62,36 +62,64 @@ if (!process.env.CORTEX_ROOT) {
|
|
|
62
62
|
const BASE_PORT = process.env.PORT || '4000';
|
|
63
63
|
const BASE_URL = process.env.CORTEX_URL || `http://localhost:${BASE_PORT}`;
|
|
64
64
|
|
|
65
|
-
// ──
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
try { mkdirSync(dirname(marker), { recursive: true }); writeFileSync(marker, String(Date.now())); } catch {}
|
|
65
|
+
// ── Self-update (transparent) ─────────────────────────────────────
|
|
66
|
+
// No silent background install (the old approach failed invisibly and locked itself).
|
|
67
|
+
// Instead: a one-line "update available" notice when a newer release exists (read from
|
|
68
|
+
// a tiny cached version check), and `cortex --update` to update on the spot with visible
|
|
69
|
+
// npm output. Silence the notice with CORTEX_NO_UPDATE_NOTICE=true.
|
|
70
|
+
const UPDATE_CACHE = join(homedir(), '.cortex', '.update-check');
|
|
71
|
+
const PKG_VERSION = (() => {
|
|
72
|
+
try { return JSON.parse(readFileSync(join(__cortex_dirname, '..', 'package.json'), 'utf8')).version; }
|
|
73
|
+
catch { return null; }
|
|
74
|
+
})();
|
|
75
|
+
|
|
76
|
+
function semverGt(a, b) {
|
|
77
|
+
const pa = String(a).split('.').map((n) => parseInt(n, 10) || 0);
|
|
78
|
+
const pb = String(b).split('.').map((n) => parseInt(n, 10) || 0);
|
|
79
|
+
for (let i = 0; i < 3; i++) {
|
|
80
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return true;
|
|
81
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return false;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
async function fetchLatestVersion() {
|
|
87
|
+
try {
|
|
88
|
+
const https = await import('node:https');
|
|
89
|
+
return await new Promise((resolve) => {
|
|
90
|
+
const req = https.get('https://registry.npmjs.org/nexus-cortex/latest', { timeout: 3000 }, (res) => {
|
|
91
|
+
let body = '';
|
|
92
|
+
res.on('data', (c) => { body += c; });
|
|
93
|
+
res.on('end', () => { try { resolve(JSON.parse(body).version); } catch { resolve(null); } });
|
|
94
|
+
});
|
|
95
|
+
req.on('error', () => resolve(null));
|
|
96
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
90
97
|
});
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
} catch { return null; }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Show the notice from cache (instant, no network); refresh the cache in the background
|
|
102
|
+
// when stale — a tiny registry GET, NEVER an install. Best-effort; never blocks/throws.
|
|
103
|
+
function notifyUpdateAvailable() {
|
|
104
|
+
try {
|
|
105
|
+
if (String(process.env.CORTEX_NO_UPDATE_NOTICE).toLowerCase() === 'true') return;
|
|
106
|
+
if (!PKG_VERSION || !__cortex_dirname.includes('node_modules')) return;
|
|
107
|
+
let cache = {};
|
|
108
|
+
try { cache = JSON.parse(readFileSync(UPDATE_CACHE, 'utf8')); } catch { /* none/legacy — refresh below */ }
|
|
109
|
+
if (cache.latest && semverGt(cache.latest, PKG_VERSION)) {
|
|
110
|
+
process.stderr.write(`\n ↑ Update available: ${PKG_VERSION} → ${cache.latest} · run \`cortex --update\`\n\n`);
|
|
111
|
+
}
|
|
112
|
+
const THROTTLE = 12 * 60 * 60 * 1000;
|
|
113
|
+
if (!cache.lastCheck || Date.now() - cache.lastCheck > THROTTLE) {
|
|
114
|
+
fetchLatestVersion().then((latest) => {
|
|
115
|
+
try {
|
|
116
|
+
mkdirSync(dirname(UPDATE_CACHE), { recursive: true });
|
|
117
|
+
writeFileSync(UPDATE_CACHE, JSON.stringify({ lastCheck: Date.now(), latest: latest || cache.latest || null }));
|
|
118
|
+
} catch { /* ignore */ }
|
|
119
|
+
}).catch(() => {});
|
|
120
|
+
}
|
|
121
|
+
} catch { /* never let the notice affect the CLI */ }
|
|
93
122
|
}
|
|
94
|
-
maybeAutoUpdate();
|
|
95
123
|
|
|
96
124
|
let serverProcess = null;
|
|
97
125
|
|
|
@@ -112,6 +140,38 @@ if (args.includes('--version') || args.includes('-v')) {
|
|
|
112
140
|
process.exit(0);
|
|
113
141
|
}
|
|
114
142
|
|
|
143
|
+
// ── Self-update command ───────────────────────────────────────────
|
|
144
|
+
// `cortex --update` — update the global install on the spot, with visible npm output.
|
|
145
|
+
if (args.includes('--update')) {
|
|
146
|
+
process.stdout.write(`Updating nexus-cortex (current: ${PKG_VERSION || 'unknown'})…\n\n`);
|
|
147
|
+
const res = spawnSync('npm', ['install', '-g', 'nexus-cortex@latest'], { stdio: 'inherit' });
|
|
148
|
+
if (res.status === 0) {
|
|
149
|
+
try { mkdirSync(dirname(UPDATE_CACHE), { recursive: true }); writeFileSync(UPDATE_CACHE, JSON.stringify({ lastCheck: Date.now(), latest: null })); } catch { /* ignore */ }
|
|
150
|
+
process.stdout.write('\n✓ Updated. Run `cortex --version` to confirm.\n');
|
|
151
|
+
process.exit(0);
|
|
152
|
+
}
|
|
153
|
+
process.stderr.write('\nUpdate failed — see the npm output above. If it is a permissions error, try:\n sudo npm install -g nexus-cortex@latest\n');
|
|
154
|
+
process.exit(res.status || 1);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// `cortex --uninstall` — remove the global install. Config/keys at ~/.cortex are LEFT
|
|
158
|
+
// in place (so you don't lose your API key by accident); the message says how to remove them.
|
|
159
|
+
if (args.includes('--uninstall')) {
|
|
160
|
+
process.stdout.write('Uninstalling nexus-cortex…\n\n');
|
|
161
|
+
const res = spawnSync('npm', ['uninstall', '-g', 'nexus-cortex'], { stdio: 'inherit' });
|
|
162
|
+
if (res.status === 0) {
|
|
163
|
+
process.stdout.write('\n✓ Uninstalled. Your config and API key remain at ~/.cortex — to remove those too:\n rm -rf ~/.cortex\n');
|
|
164
|
+
process.exit(0);
|
|
165
|
+
}
|
|
166
|
+
process.stderr.write('\nUninstall failed — see the npm output above. If it is a permissions error, try:\n sudo npm uninstall -g nexus-cortex\n');
|
|
167
|
+
process.exit(res.status || 1);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Update-available notice (skip for machine-readable / quiet output).
|
|
171
|
+
if (!args.includes('--json') && !args.includes('--quiet') && !args.includes('-q')) {
|
|
172
|
+
notifyUpdateAvailable();
|
|
173
|
+
}
|
|
174
|
+
|
|
115
175
|
// ── Setup wizard (interactive API-key onboarding) ─────────────────
|
|
116
176
|
// Global config lives at ~/.cortex/.env so a global npm install works from ANY
|
|
117
177
|
// folder (the server loads it). Runs on `cortex config init` and on first run
|
|
@@ -322,8 +382,9 @@ FLAGS:
|
|
|
322
382
|
--timeout MS Request timeout in ms (default: 600000 = 10 min)
|
|
323
383
|
--idle-timeout SECS Auto-shutdown server after N seconds of inactivity
|
|
324
384
|
--cwd DIR (agent) Run in DIR — the agent's file tools operate there
|
|
325
|
-
--
|
|
326
|
-
(
|
|
385
|
+
--update Update nexus-cortex to the latest version (npm i -g)
|
|
386
|
+
(a notice appears when you're behind; CORTEX_NO_UPDATE_NOTICE=true to silence)
|
|
387
|
+
--uninstall Remove the global nexus-cortex install (keeps ~/.cortex config)
|
|
327
388
|
--shutdown Stop the running server and exit
|
|
328
389
|
--tmux List active tmux sessions with dashboard URLs
|
|
329
390
|
--stats Show current session statistics
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexus-cortex/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.0",
|
|
4
4
|
"description": "Nexus Cortex CLI - Terminal interface for multi-provider LLM orchestration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"prepack": "node ../../scripts/copy-pkg-cortex-scaffold.mjs"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@nexus-cortex/core": "^4.
|
|
22
|
+
"@nexus-cortex/core": "^4.32.0",
|
|
23
23
|
"chalk": "^4.1.2",
|
|
24
24
|
"cli-spinners": "^2.9.0",
|
|
25
25
|
"commander": "^11.0.0",
|