@agent-webui/ai-desk-daemon 1.0.60 → 1.0.61
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/cli.js +19 -0
- package/lib/daemon-manager.js +154 -14
- package/lib/self-upgrade.js +313 -0
- package/package.json +12 -12
package/bin/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ const path = require('path');
|
|
|
11
11
|
const { start, stop, restart, status } = require('../lib/daemon-manager');
|
|
12
12
|
const { getLogPath } = require('../lib/platform');
|
|
13
13
|
const { VERSION } = require('../lib/platform');
|
|
14
|
+
const { upgradePackage } = require('../lib/self-upgrade');
|
|
14
15
|
|
|
15
16
|
function wait(ms) {
|
|
16
17
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -286,6 +287,24 @@ program
|
|
|
286
287
|
}
|
|
287
288
|
});
|
|
288
289
|
|
|
290
|
+
// Upgrade command
|
|
291
|
+
program
|
|
292
|
+
.command('upgrade')
|
|
293
|
+
.description('Upgrade AI Desk CLI to the latest published version')
|
|
294
|
+
.option('--force', 'Reinstall the latest version even when the current version is already latest')
|
|
295
|
+
.action(async (options) => {
|
|
296
|
+
try {
|
|
297
|
+
upgradePackage({
|
|
298
|
+
packageName: '@agent-webui/ai-desk-daemon',
|
|
299
|
+
packageRoot: path.join(__dirname, '..'),
|
|
300
|
+
force: Boolean(options.force),
|
|
301
|
+
});
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.error(chalk.red('✗ Failed to upgrade AI Desk:'), error.message);
|
|
304
|
+
process.exit(error.exitCode || 1);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
289
308
|
// Logs command
|
|
290
309
|
program
|
|
291
310
|
.command('logs')
|
package/lib/daemon-manager.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
|
-
const { spawn, execSync } = require('child_process');
|
|
6
|
+
const { spawn, spawnSync, execSync } = require('child_process');
|
|
7
7
|
const http = require('http');
|
|
8
8
|
const { getDaemonBinaryPath, getPidPath, getConfiguredLogPath, getLogPath, VERSION } = require('./platform');
|
|
9
9
|
const { getPort, getConfigPath } = require('./config');
|
|
@@ -143,26 +143,166 @@ function start() {
|
|
|
143
143
|
return child.pid;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
function parsePid(value) {
|
|
147
|
+
const pid = Number.parseInt(String(value || '').trim(), 10);
|
|
148
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return pid;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function parsePidList(output) {
|
|
155
|
+
return String(output || '')
|
|
156
|
+
.split(/\r?\n/)
|
|
157
|
+
.map((line) => parsePid(line))
|
|
158
|
+
.filter((pid) => pid && pid !== process.pid);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function listPidsByNameUnix(processName) {
|
|
162
|
+
const pgrep = spawnSync('pgrep', ['-x', processName], { encoding: 'utf8' });
|
|
163
|
+
if (pgrep.status === 0) {
|
|
164
|
+
return parsePidList(pgrep.stdout);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (pgrep.error && pgrep.error.code !== 'ENOENT') {
|
|
168
|
+
throw pgrep.error;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const ps = spawnSync('ps', ['-A', '-o', 'pid=', '-o', 'comm='], { encoding: 'utf8' });
|
|
172
|
+
if (ps.status !== 0) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const pids = [];
|
|
177
|
+
for (const line of String(ps.stdout || '').split(/\r?\n/)) {
|
|
178
|
+
const trimmed = line.trim();
|
|
179
|
+
if (!trimmed) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const match = trimmed.match(/^(\d+)\s+(.+)$/);
|
|
184
|
+
if (!match) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (require('path').basename(match[2]) === processName) {
|
|
189
|
+
const pid = parsePid(match[1]);
|
|
190
|
+
if (pid && pid !== process.pid) {
|
|
191
|
+
pids.push(pid);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return pids;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function isIgnorableKillError(error) {
|
|
199
|
+
return error && (error.code === 'ESRCH' || error.message === 'kill ESRCH');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function terminatePid(pid, signal = 'SIGTERM') {
|
|
203
|
+
process.kill(pid, signal);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function terminateAllByNameUnix(processName) {
|
|
207
|
+
const killedPids = [];
|
|
208
|
+
for (const pid of listPidsByNameUnix(processName)) {
|
|
209
|
+
try {
|
|
210
|
+
terminatePid(pid, 'SIGTERM');
|
|
211
|
+
killedPids.push(pid);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
if (!isIgnorableKillError(error)) {
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return killedPids;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function terminateAllByNameWindows(processName) {
|
|
222
|
+
const imageName = processName.endsWith('.exe') ? processName : `${processName}.exe`;
|
|
223
|
+
const result = spawnSync('taskkill', ['/F', '/T', '/IM', imageName], { encoding: 'utf8' });
|
|
224
|
+
if (result.status === 0) {
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const output = `${result.stderr || ''}${result.stdout || ''}`;
|
|
229
|
+
if (/not found|no running instance|not running/i.test(output)) {
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (result.error) {
|
|
234
|
+
throw result.error;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
throw new Error(output.trim() || `taskkill failed for ${imageName}`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function terminateAllByName(processName) {
|
|
241
|
+
if (process.platform === 'win32') {
|
|
242
|
+
return terminateAllByNameWindows(processName);
|
|
243
|
+
}
|
|
244
|
+
return terminateAllByNameUnix(processName);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function addKilledPid(killedPids, pid) {
|
|
248
|
+
if (pid && !killedPids.includes(pid)) {
|
|
249
|
+
killedPids.push(pid);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
146
253
|
/**
|
|
147
254
|
* Stop daemon
|
|
148
255
|
*/
|
|
149
|
-
function stop() {
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
256
|
+
function stop(deps = {}) {
|
|
257
|
+
const fsApi = deps.fs || fs;
|
|
258
|
+
const platformApi = deps.platform || { getPidPath };
|
|
259
|
+
const processManager = deps.processManager || {
|
|
260
|
+
terminatePid,
|
|
261
|
+
terminateAllByName,
|
|
262
|
+
};
|
|
263
|
+
const logger = deps.logger || console;
|
|
264
|
+
const pidPath = platformApi.getPidPath();
|
|
265
|
+
let pidFilePid = null;
|
|
266
|
+
const killedPids = [];
|
|
267
|
+
const errors = [];
|
|
268
|
+
|
|
269
|
+
if (fsApi.existsSync(pidPath)) {
|
|
270
|
+
pidFilePid = parsePid(fsApi.readFileSync(pidPath, 'utf8'));
|
|
271
|
+
if (pidFilePid) {
|
|
272
|
+
try {
|
|
273
|
+
processManager.terminatePid(pidFilePid, 'SIGTERM');
|
|
274
|
+
addKilledPid(killedPids, pidFilePid);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
if (!isIgnorableKillError(error)) {
|
|
277
|
+
errors.push(error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
fsApi.unlinkSync(pidPath);
|
|
284
|
+
} catch (error) {
|
|
285
|
+
errors.push(error);
|
|
286
|
+
}
|
|
154
287
|
}
|
|
155
|
-
|
|
156
|
-
const pid = parseInt(fs.readFileSync(pidPath, 'utf8').trim());
|
|
157
|
-
|
|
288
|
+
|
|
158
289
|
try {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
290
|
+
for (const pid of processManager.terminateAllByName('ai-desk-daemon') || []) {
|
|
291
|
+
addKilledPid(killedPids, pid);
|
|
292
|
+
}
|
|
162
293
|
} catch (error) {
|
|
163
|
-
|
|
164
|
-
|
|
294
|
+
errors.push(error);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (errors.length > 0) {
|
|
298
|
+
throw new Error(`Failed to stop daemon: ${errors.map((error) => error.message).join('; ')}`);
|
|
165
299
|
}
|
|
300
|
+
|
|
301
|
+
logger.log('Daemon stopped');
|
|
302
|
+
return {
|
|
303
|
+
pidFilePid,
|
|
304
|
+
killedPids,
|
|
305
|
+
};
|
|
166
306
|
}
|
|
167
307
|
|
|
168
308
|
/**
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const OFFICIAL_NPM_REGISTRY = 'https://registry.npmjs.org/';
|
|
6
|
+
const DEFAULT_PACKAGE_NAME = '@agent-webui/ai-desk';
|
|
7
|
+
const SKIP_UPDATE_ENV = 'AI_DESK_SKIP_SELF_UPDATE';
|
|
8
|
+
const DEFAULT_UPDATE_COMMANDS = new Set(['start', 'restart', 'upgrade']);
|
|
9
|
+
|
|
10
|
+
function readJSON(filePath) {
|
|
11
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function currentVersion(packageRoot) {
|
|
15
|
+
return readJSON(path.join(packageRoot, 'package.json')).version;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isPackagedInstall(packageRoot) {
|
|
19
|
+
return path.resolve(packageRoot).split(path.sep).includes('node_modules');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseVersion(version) {
|
|
23
|
+
return String(version || '')
|
|
24
|
+
.trim()
|
|
25
|
+
.replace(/^v/, '')
|
|
26
|
+
.split('-')[0]
|
|
27
|
+
.split('.')
|
|
28
|
+
.map((part) => Number.parseInt(part, 10) || 0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function compareVersions(left, right) {
|
|
32
|
+
const leftParts = parseVersion(left);
|
|
33
|
+
const rightParts = parseVersion(right);
|
|
34
|
+
const length = Math.max(leftParts.length, rightParts.length);
|
|
35
|
+
for (let index = 0; index < length; index += 1) {
|
|
36
|
+
const delta = (leftParts[index] || 0) - (rightParts[index] || 0);
|
|
37
|
+
if (delta !== 0) {
|
|
38
|
+
return delta;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function npmCommand(env = process.env) {
|
|
45
|
+
if (env.npm_execpath && fs.existsSync(env.npm_execpath)) {
|
|
46
|
+
return {
|
|
47
|
+
command: process.execPath,
|
|
48
|
+
args: [env.npm_execpath],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
command: process.platform === 'win32' ? 'npm.cmd' : 'npm',
|
|
54
|
+
args: [],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function runNpm(args, options = {}) {
|
|
59
|
+
const npm = npmCommand(options.env || process.env);
|
|
60
|
+
return spawnSync(npm.command, [...npm.args, ...args], {
|
|
61
|
+
encoding: 'utf8',
|
|
62
|
+
...options,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function npmOutput(result) {
|
|
67
|
+
return `${result.stderr || ''}${result.stdout || ''}`.trim();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function withOfficialRegistry(args) {
|
|
71
|
+
return [...args, `--registry=${OFFICIAL_NPM_REGISTRY}`];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function runNpmWithRegistryFallback(args, options = {}) {
|
|
75
|
+
const primaryResult = runNpm(withOfficialRegistry(args), options);
|
|
76
|
+
if (primaryResult.status === 0) {
|
|
77
|
+
return primaryResult;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const fallbackResult = runNpm(args, options);
|
|
81
|
+
if (fallbackResult.status === 0) {
|
|
82
|
+
return fallbackResult;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fallbackResult.primaryError = npmOutput(primaryResult);
|
|
86
|
+
return fallbackResult;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function latestPublishedVersion(packageName = DEFAULT_PACKAGE_NAME) {
|
|
90
|
+
const result = runNpmWithRegistryFallback(['view', packageName, 'version'], {
|
|
91
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.status !== 0) {
|
|
95
|
+
const output = npmOutput(result);
|
|
96
|
+
const primaryError = result.primaryError ? `Official registry error: ${result.primaryError}\n` : '';
|
|
97
|
+
const fallbackError = output ? `Fallback registry error: ${output}` : '';
|
|
98
|
+
const errorMessage = `${primaryError}${fallbackError}`.trim();
|
|
99
|
+
throw new Error(errorMessage || 'Unable to check npm registry');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return String(result.stdout || '').trim();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function realpathIfExists(targetPath) {
|
|
106
|
+
try {
|
|
107
|
+
return fs.realpathSync(targetPath);
|
|
108
|
+
} catch {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isSubPath(childPath, parentPath) {
|
|
114
|
+
const relativePath = path.relative(parentPath, childPath);
|
|
115
|
+
return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function globalNpmRoot() {
|
|
119
|
+
const result = runNpm(['root', '-g'], {
|
|
120
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
121
|
+
});
|
|
122
|
+
if (result.status !== 0) {
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
return realpathIfExists(String(result.stdout || '').trim());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function packagePathFromProjectRoot(projectRoot, packageName = DEFAULT_PACKAGE_NAME) {
|
|
129
|
+
return path.join(projectRoot, 'node_modules', ...packageName.split('/'));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function findLocalProjectRoot(packageRoot, packageName = DEFAULT_PACKAGE_NAME) {
|
|
133
|
+
const realPackageRoot = realpathIfExists(packageRoot);
|
|
134
|
+
const realGlobalRoot = globalNpmRoot();
|
|
135
|
+
if (realGlobalRoot && isSubPath(realPackageRoot, realGlobalRoot)) {
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
let currentDir = packageRoot;
|
|
140
|
+
while (currentDir && currentDir !== path.dirname(currentDir)) {
|
|
141
|
+
const candidate = realpathIfExists(packagePathFromProjectRoot(currentDir, packageName));
|
|
142
|
+
if (candidate && candidate === realPackageRoot) {
|
|
143
|
+
return currentDir;
|
|
144
|
+
}
|
|
145
|
+
currentDir = path.dirname(currentDir);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return '';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function installLatestVersion({
|
|
152
|
+
packageName = DEFAULT_PACKAGE_NAME,
|
|
153
|
+
packageRoot,
|
|
154
|
+
latestVersion,
|
|
155
|
+
}) {
|
|
156
|
+
const projectRoot = findLocalProjectRoot(packageRoot, packageName);
|
|
157
|
+
const installTarget = `${packageName}@${latestVersion}`;
|
|
158
|
+
|
|
159
|
+
if (projectRoot) {
|
|
160
|
+
return runNpmWithRegistryFallback(['install', installTarget, '--include=optional'], {
|
|
161
|
+
cwd: projectRoot,
|
|
162
|
+
stdio: 'inherit',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return runNpmWithRegistryFallback(['install', '-g', installTarget, '--include=optional'], {
|
|
167
|
+
stdio: 'inherit',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function assertInstallSucceeded(result) {
|
|
172
|
+
if (result.error) {
|
|
173
|
+
throw result.error;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (result.status !== 0) {
|
|
177
|
+
const error = new Error(`npm install failed with exit code ${result.status}`);
|
|
178
|
+
error.exitCode = typeof result.status === 'number' ? result.status : 1;
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function upgradePackage({
|
|
184
|
+
packageName = DEFAULT_PACKAGE_NAME,
|
|
185
|
+
packageRoot,
|
|
186
|
+
installedVersion,
|
|
187
|
+
latestVersion,
|
|
188
|
+
force = false,
|
|
189
|
+
logger = console,
|
|
190
|
+
latestPublishedVersion: latestPublishedVersionFn = latestPublishedVersion,
|
|
191
|
+
installLatestVersion: installLatestVersionFn = (version) => installLatestVersion({
|
|
192
|
+
packageName,
|
|
193
|
+
packageRoot,
|
|
194
|
+
latestVersion: version,
|
|
195
|
+
}),
|
|
196
|
+
} = {}) {
|
|
197
|
+
const current = installedVersion || currentVersion(packageRoot);
|
|
198
|
+
const latest = latestVersion || latestPublishedVersionFn(packageName);
|
|
199
|
+
|
|
200
|
+
if (!force && compareVersions(latest, current) <= 0) {
|
|
201
|
+
logger.log(`AI Desk is already up to date (${current}).`);
|
|
202
|
+
return {
|
|
203
|
+
upgraded: false,
|
|
204
|
+
installedVersion: current,
|
|
205
|
+
latestVersion: latest,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const verb = force && compareVersions(latest, current) <= 0 ? 'Reinstalling' : 'Updating';
|
|
210
|
+
logger.log(`${verb} AI Desk from ${current} to ${latest}...`);
|
|
211
|
+
const installResult = installLatestVersionFn(latest);
|
|
212
|
+
assertInstallSucceeded(installResult);
|
|
213
|
+
logger.log(`AI Desk updated to ${latest}.`);
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
upgraded: true,
|
|
217
|
+
installedVersion: current,
|
|
218
|
+
latestVersion: latest,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function requestedCommand(args) {
|
|
223
|
+
for (const arg of args) {
|
|
224
|
+
if (arg === '--') {
|
|
225
|
+
return '';
|
|
226
|
+
}
|
|
227
|
+
if (!arg.startsWith('-')) {
|
|
228
|
+
return arg;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return '';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function shouldCheckForUpdate({
|
|
235
|
+
args,
|
|
236
|
+
isPackagedInstall: packagedInstall,
|
|
237
|
+
skipUpdate,
|
|
238
|
+
updateCommands = DEFAULT_UPDATE_COMMANDS,
|
|
239
|
+
}) {
|
|
240
|
+
if (skipUpdate) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!packagedInstall || args.includes('--help') || args.includes('-h')) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return updateCommands.has(requestedCommand(args));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function updateBeforeCommand({
|
|
252
|
+
args,
|
|
253
|
+
packageName = DEFAULT_PACKAGE_NAME,
|
|
254
|
+
packageRoot,
|
|
255
|
+
env = process.env,
|
|
256
|
+
logger = console,
|
|
257
|
+
restartWithUpdatedCli,
|
|
258
|
+
updateCommands = DEFAULT_UPDATE_COMMANDS,
|
|
259
|
+
} = {}) {
|
|
260
|
+
const command = requestedCommand(args);
|
|
261
|
+
if (!shouldCheckForUpdate({
|
|
262
|
+
args,
|
|
263
|
+
isPackagedInstall: isPackagedInstall(packageRoot),
|
|
264
|
+
skipUpdate: Boolean(env[SKIP_UPDATE_ENV]),
|
|
265
|
+
updateCommands,
|
|
266
|
+
})) {
|
|
267
|
+
return { checked: false };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
logger.log('Checking for AI Desk updates...');
|
|
271
|
+
|
|
272
|
+
let result;
|
|
273
|
+
try {
|
|
274
|
+
result = upgradePackage({
|
|
275
|
+
packageName,
|
|
276
|
+
packageRoot,
|
|
277
|
+
logger,
|
|
278
|
+
});
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (command === 'upgrade') {
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
logger.warn(`Unable to check for AI Desk updates: ${error.message}`);
|
|
284
|
+
return { checked: true, upgraded: false, error };
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (result.upgraded && command !== 'upgrade' && typeof restartWithUpdatedCli === 'function') {
|
|
288
|
+
logger.log(`Restarting aidesk ${command} with the updated CLI...`);
|
|
289
|
+
restartWithUpdatedCli(args);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
checked: true,
|
|
294
|
+
command,
|
|
295
|
+
...result,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
module.exports = {
|
|
300
|
+
DEFAULT_PACKAGE_NAME,
|
|
301
|
+
DEFAULT_UPDATE_COMMANDS,
|
|
302
|
+
SKIP_UPDATE_ENV,
|
|
303
|
+
compareVersions,
|
|
304
|
+
currentVersion,
|
|
305
|
+
findLocalProjectRoot,
|
|
306
|
+
installLatestVersion,
|
|
307
|
+
isPackagedInstall,
|
|
308
|
+
latestPublishedVersion,
|
|
309
|
+
requestedCommand,
|
|
310
|
+
shouldCheckForUpdate,
|
|
311
|
+
updateBeforeCommand,
|
|
312
|
+
upgradePackage,
|
|
313
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-webui/ai-desk-daemon",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.61",
|
|
4
4
|
"description": "AI Desk Daemon - CLI tool for managing the AI Desk daemon service",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"packages/*"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"postinstall": "node scripts/postinstall.js",
|
|
14
14
|
"prepare:packages": "node scripts/prepare-npm-packages.js",
|
|
15
15
|
"publish:npm:workspaces": "node scripts/publish-npm-packages.js",
|
|
16
|
-
"test": "node bin/cli.js --help"
|
|
16
|
+
"test": "node bin/cli.js --help && node test/daemon-manager-output.test.js && node test/daemon-manager-stop-all.test.js && node test/self-upgrade.test.js"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
19
|
"ai-desk",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"chalk": "^4.1.2"
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
|
-
"@agent-webui/ai-desk-daemon-darwin-arm64": "1.0.
|
|
43
|
-
"@agent-webui/ai-desk-daemon-darwin-x64": "1.0.
|
|
44
|
-
"@agent-webui/ai-desk-daemon-linux-arm64": "1.0.
|
|
45
|
-
"@agent-webui/ai-desk-daemon-linux-x64": "1.0.
|
|
46
|
-
"@agent-webui/ai-desk-daemon-win32-x64": "1.0.
|
|
47
|
-
"@agent-webui/ai-desk-python-darwin-arm64": "1.0.
|
|
48
|
-
"@agent-webui/ai-desk-python-darwin-x64": "1.0.
|
|
49
|
-
"@agent-webui/ai-desk-python-linux-arm64": "1.0.
|
|
50
|
-
"@agent-webui/ai-desk-python-linux-x64": "1.0.
|
|
51
|
-
"@agent-webui/ai-desk-python-win32-x64": "1.0.
|
|
42
|
+
"@agent-webui/ai-desk-daemon-darwin-arm64": "1.0.61",
|
|
43
|
+
"@agent-webui/ai-desk-daemon-darwin-x64": "1.0.61",
|
|
44
|
+
"@agent-webui/ai-desk-daemon-linux-arm64": "1.0.61",
|
|
45
|
+
"@agent-webui/ai-desk-daemon-linux-x64": "1.0.61",
|
|
46
|
+
"@agent-webui/ai-desk-daemon-win32-x64": "1.0.61",
|
|
47
|
+
"@agent-webui/ai-desk-python-darwin-arm64": "1.0.61",
|
|
48
|
+
"@agent-webui/ai-desk-python-darwin-x64": "1.0.61",
|
|
49
|
+
"@agent-webui/ai-desk-python-linux-arm64": "1.0.61",
|
|
50
|
+
"@agent-webui/ai-desk-python-linux-x64": "1.0.61",
|
|
51
|
+
"@agent-webui/ai-desk-python-win32-x64": "1.0.61"
|
|
52
52
|
},
|
|
53
53
|
"repository": {
|
|
54
54
|
"type": "git",
|