@mmmbuto/nexuscli 0.8.9 → 0.9.1
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/README.md +9 -8
- package/frontend/dist/assets/{index-Dl9FJBOB.css → index-Ci39i_2l.css} +1 -1
- package/frontend/dist/assets/{index-DFYYfeuX.js → index-x6Jl2qtq.js} +1697 -1697
- package/frontend/dist/index.html +2 -2
- package/frontend/dist/sw.js +1 -1
- package/frontend/package.json +1 -1
- package/lib/cli/api.js +6 -0
- package/lib/cli/status.js +1 -19
- package/lib/config/models.js +15 -0
- package/lib/server/.env.example +1 -1
- package/lib/server/lib/pty-adapter.js +2 -0
- package/lib/server/routes/models.js +1 -1
- package/lib/server/server.js +0 -2
- package/lib/server/services/claude-wrapper.js +115 -16
- package/lib/server/services/output-parser.js +11 -2
- package/package.json +1 -2
- package/lib/server/db.js.old +0 -225
- package/lib/server/docs/API_WRAPPER_CONTRACT.md +0 -682
- package/lib/server/docs/ARCHITECTURE.md +0 -441
- package/lib/server/docs/DATABASE_SCHEMA.md +0 -783
- package/lib/server/docs/DESIGN_PRINCIPLES.md +0 -598
- package/lib/server/docs/NEXUSCHAT_ANALYSIS.md +0 -488
- package/lib/server/docs/PIPELINE_INTEGRATION.md +0 -636
- package/lib/server/docs/README.md +0 -272
- package/lib/server/docs/UI_DESIGN.md +0 -916
- package/lib/server/routes/system.js +0 -29
- package/lib/server/services/version-manager.js +0 -170
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const router = express.Router();
|
|
3
|
-
const versionManager = require('../services/version-manager');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* GET /api/v1/system/version
|
|
7
|
-
* Returns version info and update status.
|
|
8
|
-
*/
|
|
9
|
-
router.get('/version', async (req, res) => {
|
|
10
|
-
try {
|
|
11
|
-
const force = req.query.force === 'true';
|
|
12
|
-
const info = await versionManager.checkUpdate(force);
|
|
13
|
-
res.json(info);
|
|
14
|
-
} catch (error) {
|
|
15
|
-
// Fail safe
|
|
16
|
-
res.json({
|
|
17
|
-
current: versionManager.currentVersion,
|
|
18
|
-
latest: null,
|
|
19
|
-
updateAvailable: false,
|
|
20
|
-
installMethod: 'unknown',
|
|
21
|
-
updateCommand: '',
|
|
22
|
-
status: 'error',
|
|
23
|
-
error: 'internal error',
|
|
24
|
-
checkedAt: new Date().toISOString()
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
module.exports = router;
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
const https = require('https');
|
|
5
|
-
const semver = require('semver');
|
|
6
|
-
const NodeCache = require('node-cache');
|
|
7
|
-
const packageJson = require('../../../package.json');
|
|
8
|
-
|
|
9
|
-
// Cache update checks for 12 hours
|
|
10
|
-
const cache = new NodeCache({ stdTTL: 43200 });
|
|
11
|
-
const CACHE_KEY = 'version_check';
|
|
12
|
-
const CACHE_TTL_OK = 43200; // 12h
|
|
13
|
-
const CACHE_TTL_FAIL = 300; // 5m for unknown/error
|
|
14
|
-
|
|
15
|
-
class VersionManager {
|
|
16
|
-
constructor() {
|
|
17
|
-
this.currentVersion = packageJson.version;
|
|
18
|
-
this.pkgName = packageJson.name;
|
|
19
|
-
this.projectRoot = path.resolve(__dirname, '../../../');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Detects the installation method (git or npm).
|
|
24
|
-
* @returns {'git' | 'npm' | 'unknown'}
|
|
25
|
-
*/
|
|
26
|
-
detectInstallMethod() {
|
|
27
|
-
// Check 1: .git directory existence
|
|
28
|
-
const gitDir = path.join(this.projectRoot, '.git');
|
|
29
|
-
if (fs.existsSync(gitDir)) {
|
|
30
|
-
return 'git';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Check 2: Inference from path (heuristic)
|
|
34
|
-
// Global npm installs often reside in paths containing 'node_modules' but not '.git'
|
|
35
|
-
if (__dirname.includes('node_modules')) {
|
|
36
|
-
return 'npm';
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return 'unknown';
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Fetches the latest version from NPM registry.
|
|
44
|
-
* @returns {Promise<string|null>}
|
|
45
|
-
*/
|
|
46
|
-
async fetchLatestNpmVersion() {
|
|
47
|
-
const controller = new AbortController();
|
|
48
|
-
const timer = setTimeout(() => controller.abort(), 3000); // wall-clock timeout
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(this.pkgName)}/latest`, {
|
|
52
|
-
method: 'GET',
|
|
53
|
-
headers: {
|
|
54
|
-
'Accept': 'application/json',
|
|
55
|
-
'User-Agent': 'NexusCLI-VersionManager'
|
|
56
|
-
},
|
|
57
|
-
signal: controller.signal
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (!res.ok) return null;
|
|
61
|
-
const json = await res.json().catch(() => null);
|
|
62
|
-
return json?.version || null;
|
|
63
|
-
} catch {
|
|
64
|
-
return null;
|
|
65
|
-
} finally {
|
|
66
|
-
clearTimeout(timer);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Checks for updates using Git.
|
|
72
|
-
* @returns {{ status: 'ok'|'unknown'|'error', updateAvailable: boolean, latest: string|null, error: string|null }}
|
|
73
|
-
*/
|
|
74
|
-
checkGitUpdate() {
|
|
75
|
-
try {
|
|
76
|
-
// 1. Verify git exists
|
|
77
|
-
try {
|
|
78
|
-
execSync('git --version', { stdio: 'ignore' });
|
|
79
|
-
} catch (e) {
|
|
80
|
-
return { status: 'error', updateAvailable: false, latest: null, error: 'git binary not found' };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// 2. Verify upstream exists
|
|
84
|
-
let upstream;
|
|
85
|
-
try {
|
|
86
|
-
upstream = execSync('git rev-parse --abbrev-ref --symbolic-full-name @{u}', { cwd: this.projectRoot, encoding: 'utf8' }).trim();
|
|
87
|
-
} catch (e) {
|
|
88
|
-
return { status: 'unknown', updateAvailable: false, latest: null, error: 'no upstream configured' };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const [remoteName, ...branchParts] = upstream.split('/');
|
|
92
|
-
const branchName = branchParts.join('/') || 'main';
|
|
93
|
-
|
|
94
|
-
// 3. Fetch upstream (fail soft)
|
|
95
|
-
try {
|
|
96
|
-
execSync(`git fetch ${remoteName} ${branchName}`, { cwd: this.projectRoot, stdio: 'ignore', timeout: 5000 });
|
|
97
|
-
} catch (e) {
|
|
98
|
-
return { status: 'unknown', updateAvailable: false, latest: null, error: 'git fetch failed' };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// 4. Compare ahead/behind
|
|
102
|
-
try {
|
|
103
|
-
const counts = execSync(`git rev-list --left-right --count HEAD...${upstream}`, { cwd: this.projectRoot, encoding: 'utf8' }).trim();
|
|
104
|
-
const [ahead, behind] = counts.split(/\s+/).map((n) => parseInt(n, 10));
|
|
105
|
-
|
|
106
|
-
const updateAvailable = Number.isFinite(behind) && behind > 0;
|
|
107
|
-
const latest = updateAvailable ? upstream : this.currentVersion;
|
|
108
|
-
|
|
109
|
-
return { status: 'ok', updateAvailable, latest, error: null };
|
|
110
|
-
} catch (e) {
|
|
111
|
-
return { status: 'unknown', updateAvailable: false, latest: null, error: 'git compare failed' };
|
|
112
|
-
}
|
|
113
|
-
} catch (e) {
|
|
114
|
-
return { status: 'error', updateAvailable: false, latest: null, error: 'git check failed' };
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Main entry point to check for updates.
|
|
120
|
-
* Uses cache.
|
|
121
|
-
*/
|
|
122
|
-
async checkUpdate(force = false) {
|
|
123
|
-
if (!force) {
|
|
124
|
-
const cached = cache.get(CACHE_KEY);
|
|
125
|
-
if (cached) return cached;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const installMethod = this.detectInstallMethod();
|
|
129
|
-
let result = {
|
|
130
|
-
current: this.currentVersion,
|
|
131
|
-
latest: this.currentVersion,
|
|
132
|
-
updateAvailable: false,
|
|
133
|
-
installMethod,
|
|
134
|
-
updateCommand: '',
|
|
135
|
-
checkedAt: new Date().toISOString(),
|
|
136
|
-
status: 'ok',
|
|
137
|
-
error: null
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
if (installMethod === 'npm') {
|
|
141
|
-
const latest = await this.fetchLatestNpmVersion();
|
|
142
|
-
if (latest) {
|
|
143
|
-
const latestCoerced = semver.coerce(latest);
|
|
144
|
-
const currentCoerced = semver.coerce(this.currentVersion);
|
|
145
|
-
|
|
146
|
-
result.latest = latest;
|
|
147
|
-
result.updateAvailable = !!(latestCoerced && currentCoerced && semver.gt(latestCoerced, currentCoerced));
|
|
148
|
-
result.updateCommand = `npm install -g ${this.pkgName}`;
|
|
149
|
-
} else {
|
|
150
|
-
result.status = 'unknown'; // Failed to fetch
|
|
151
|
-
result.error = null;
|
|
152
|
-
}
|
|
153
|
-
} else if (installMethod === 'git') {
|
|
154
|
-
const gitCheck = this.checkGitUpdate();
|
|
155
|
-
result.status = gitCheck.status;
|
|
156
|
-
result.error = gitCheck.error;
|
|
157
|
-
result.updateAvailable = gitCheck.updateAvailable;
|
|
158
|
-
result.latest = gitCheck.latest || this.currentVersion;
|
|
159
|
-
result.updateCommand = gitCheck.status === 'ok' ? 'git pull' : '';
|
|
160
|
-
} else {
|
|
161
|
-
result.status = 'unknown';
|
|
162
|
-
result.error = 'install method not detected';
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
cache.set(CACHE_KEY, result, result.status === 'ok' ? CACHE_TTL_OK : CACHE_TTL_FAIL);
|
|
166
|
-
return result;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
module.exports = new VersionManager();
|