@agent-webui/ai-desk-daemon 1.0.62 → 1.0.63-beta1

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 CHANGED
@@ -11,6 +11,13 @@ 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 { getPort } = require('../lib/config');
15
+ const {
16
+ configureRegistryUrl,
17
+ getRegistryConfig,
18
+ reportLifecycle,
19
+ syncRegistryConfigToDaemonConfig,
20
+ } = require('../lib/daemon-registry');
14
21
  const { upgradePackage } = require('../lib/self-upgrade');
15
22
 
16
23
  function wait(ms) {
@@ -128,11 +135,74 @@ function configureRequestedMode(mode) {
128
135
  });
129
136
  }
130
137
 
138
+ async function reportRegistryLifecycle(event) {
139
+ try {
140
+ await reportLifecycle(event, {
141
+ port: Number(getPort()),
142
+ version: VERSION,
143
+ });
144
+ } catch (error) {
145
+ console.warn(chalk.yellow(`[registry] Failed to report daemon ${event}: ${error.message || error}`));
146
+ }
147
+ }
148
+
149
+ function syncRegistryConfigForDaemonStart() {
150
+ try {
151
+ syncRegistryConfigToDaemonConfig();
152
+ } catch (error) {
153
+ console.warn(chalk.yellow(`[registry] Failed to sync daemon registry config: ${error.message || error}`));
154
+ }
155
+ }
156
+
131
157
  program
132
158
  .name('aidesk')
133
159
  .description('AI Desk Daemon - CLI tool for managing the AI Desk daemon service')
134
160
  .version(VERSION);
135
161
 
162
+ const registryCommand = program
163
+ .command('registry')
164
+ .description('Manage shared runtime registry backend settings');
165
+
166
+ registryCommand
167
+ .command('set-url <url>')
168
+ .description('Persist the AI Desk backend URL used for daemon registry reporting')
169
+ .option('--insecure-skip-tls-verify', 'Skip TLS certificate verification for this registry URL')
170
+ .option('--strict-tls', 'Require strict TLS certificate verification for this registry URL')
171
+ .action((url, options) => {
172
+ try {
173
+ if (options.insecureSkipTlsVerify && options.strictTls) {
174
+ throw new Error('Use either --insecure-skip-tls-verify or --strict-tls, not both');
175
+ }
176
+ const tlsInsecureSkipVerify = options.insecureSkipTlsVerify
177
+ ? true
178
+ : (options.strictTls ? false : undefined);
179
+ const config = configureRegistryUrl(url, { tlsInsecureSkipVerify });
180
+ console.log(chalk.green('✓ Registry URL updated'));
181
+ console.log(`API base URL: ${config.apiBaseUrl}`);
182
+ console.log(`TLS verification: ${config.tlsInsecureSkipVerify ? 'skip for this URL' : 'strict'}`);
183
+ console.log(chalk.cyan('Restart the daemon for the new registry URL to be used by background heartbeats.'));
184
+ } catch (error) {
185
+ console.error(chalk.red('Failed to update registry URL:'), error.message);
186
+ process.exit(1);
187
+ }
188
+ });
189
+
190
+ registryCommand
191
+ .command('status')
192
+ .description('Show the effective daemon registry backend settings')
193
+ .action(() => {
194
+ const config = getRegistryConfig();
195
+ if (!config) {
196
+ console.log(chalk.yellow('Registry reporting is disabled'));
197
+ return;
198
+ }
199
+ console.log(`API base URL: ${config.apiBaseUrl}`);
200
+ console.log(`RC account ID: ${config.rcAccountId || '(empty)'}`);
201
+ console.log(`RC extension ID: ${config.rcExtensionId || '(empty)'}`);
202
+ console.log(`RC username: ${config.rcUsername || '(empty)'}`);
203
+ console.log(`TLS verification: ${config.tlsInsecureSkipVerify ? 'skip for this URL' : 'strict'}`);
204
+ });
205
+
136
206
  // Start command
137
207
  program
138
208
  .command('start')
@@ -145,7 +215,9 @@ program
145
215
  try {
146
216
  const mode = resolveRequestedMode(options) || 'native';
147
217
  const modeResult = configureRequestedMode(mode);
218
+ syncRegistryConfigForDaemonStart();
148
219
  start();
220
+ await reportRegistryLifecycle('start');
149
221
  if (mode === 'cli-anything' && modeResult?.runtimeInfo?.cliAnythingPath) {
150
222
  console.log(chalk.cyan(`CLI-Anything mode configured: ${modeResult.runtimeInfo.cliAnythingPath}`));
151
223
  } else if (mode === 'native') {
@@ -171,7 +243,7 @@ program
171
243
  const tail = startUnixLogFollow(logPath);
172
244
 
173
245
  // Handle Ctrl+C - stop the daemon
174
- process.on('SIGINT', () => {
246
+ process.on('SIGINT', async () => {
175
247
  console.log(chalk.yellow('\n\n⏹ Stopping daemon...'));
176
248
  tail.kill();
177
249
 
@@ -179,6 +251,7 @@ program
179
251
  // Stop the daemon
180
252
  const { stop } = require('../lib/daemon-manager');
181
253
  stop();
254
+ await reportRegistryLifecycle('stop');
182
255
  console.log(chalk.green('✓ Daemon stopped successfully'));
183
256
  } catch (error) {
184
257
  console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
@@ -192,7 +265,7 @@ program
192
265
 
193
266
  const pollInterval = startWindowsLogFollow(logPath);
194
267
 
195
- process.on('SIGINT', () => {
268
+ process.on('SIGINT', async () => {
196
269
  clearInterval(pollInterval);
197
270
  console.log(chalk.yellow('\n\n⏹ Stopping daemon...'));
198
271
 
@@ -200,6 +273,7 @@ program
200
273
  // Stop the daemon
201
274
  const { stop } = require('../lib/daemon-manager');
202
275
  stop();
276
+ await reportRegistryLifecycle('stop');
203
277
  console.log(chalk.green('✓ Daemon stopped successfully'));
204
278
  } catch (error) {
205
279
  console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
@@ -222,6 +296,7 @@ program
222
296
  .action(async () => {
223
297
  try {
224
298
  stop();
299
+ await reportRegistryLifecycle('stop');
225
300
  console.log(chalk.green('✓ Daemon stopped successfully'));
226
301
  } catch (error) {
227
302
  console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
@@ -240,7 +315,9 @@ program
240
315
  try {
241
316
  const mode = resolveRequestedMode(options);
242
317
  const modeResult = configureRequestedMode(mode);
318
+ syncRegistryConfigForDaemonStart();
243
319
  restart();
320
+ await reportRegistryLifecycle('restart');
244
321
  if (mode === 'cli-anything' && modeResult?.runtimeInfo?.cliAnythingPath) {
245
322
  console.log(chalk.cyan(`CLI-Anything mode configured: ${modeResult.runtimeInfo.cliAnythingPath}`));
246
323
  } else if (mode === 'native') {
@@ -0,0 +1,392 @@
1
+ const fs = require('fs');
2
+ const os = require('os');
3
+ const path = require('path');
4
+ const http = require('http');
5
+ const https = require('https');
6
+ const crypto = require('crypto');
7
+
8
+ const DEFAULT_REGISTRY_API_BASE_URL = 'https://desk.int.rclabenv.com/';
9
+
10
+ function trim(value) {
11
+ if (typeof value === 'string') return value.trim();
12
+ if (typeof value === 'number' && Number.isFinite(value)) return String(value);
13
+ return '';
14
+ }
15
+
16
+ function normalizeApiBaseUrl(value) {
17
+ const raw = trim(value).replace(/\/+$/, '');
18
+ if (!raw) return '';
19
+ return raw.endsWith('/api/v1') ? raw : `${raw}/api/v1`;
20
+ }
21
+
22
+ function parseTruthyEnv(value) {
23
+ const raw = trim(value).toLowerCase();
24
+ if (!raw) return null;
25
+ return raw === '1' || raw === 'true' || raw === 'yes' || raw === 'on';
26
+ }
27
+
28
+ function isPrivateRegistryHost(hostname) {
29
+ const host = trim(hostname).toLowerCase();
30
+ return (
31
+ host === 'localhost' ||
32
+ host === '127.0.0.1' ||
33
+ host.endsWith('.local') ||
34
+ /^10\./.test(host) ||
35
+ /^192\.168\./.test(host) ||
36
+ /^172\.(1[6-9]|2\d|3[0-1])\./.test(host)
37
+ );
38
+ }
39
+
40
+ function inferTLSInsecureSkipVerify(apiBaseUrl) {
41
+ try {
42
+ const url = new URL(normalizeApiBaseUrl(apiBaseUrl));
43
+ if (url.protocol !== 'https:') return false;
44
+ if (url.hostname === 'desk.int.rclabenv.com') return false;
45
+ return isPrivateRegistryHost(url.hostname);
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ function readRegistrySessionIdentity(homeDir = os.homedir()) {
52
+ const sessionPath = path.join(homeDir, '.aidesktop', 'session.json');
53
+ try {
54
+ if (!fs.existsSync(sessionPath)) return null;
55
+ const session = JSON.parse(fs.readFileSync(sessionPath, 'utf8'));
56
+ if (!session || typeof session !== 'object') return null;
57
+ const apiBaseUrl = normalizeApiBaseUrl(session.api_base_url || session.apiBaseUrl);
58
+ const rcAccountId = trim(session.account_id || session.accountId);
59
+ const rcExtensionId = trim(session.extension_id || session.extensionId);
60
+ const rcUsername = trim(session.rc_username || session.rcUsername);
61
+ const tlsInsecureSkipVerify = Boolean(
62
+ session.tls_insecure_skip_verify || session.tlsInsecureSkipVerify,
63
+ );
64
+ if (!apiBaseUrl && !rcAccountId && !rcExtensionId && !rcUsername) return null;
65
+ return { apiBaseUrl, rcAccountId, rcExtensionId, rcUsername, tlsInsecureSkipVerify };
66
+ } catch {
67
+ return null;
68
+ }
69
+ }
70
+
71
+ function readRegistryConfigFromDaemonConfig(homeDir = os.homedir()) {
72
+ const configPath = path.join(homeDir, '.aidesktop', 'daemon-config.json');
73
+ try {
74
+ if (!fs.existsSync(configPath)) return null;
75
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
76
+ const registry = config && typeof config === 'object' ? config.registry : null;
77
+ if (!registry || typeof registry !== 'object') return null;
78
+ const sessionIdentity = readRegistrySessionIdentity(homeDir);
79
+ const apiBaseUrl = normalizeApiBaseUrl(
80
+ registry.api_base_url || registry.apiBaseUrl || DEFAULT_REGISTRY_API_BASE_URL,
81
+ );
82
+ const rcAccountId = trim(registry.rc_account_id || registry.rcAccountId) ||
83
+ sessionIdentity?.rcAccountId || '';
84
+ const rcExtensionId = trim(registry.rc_extension_id || registry.rcExtensionId) ||
85
+ sessionIdentity?.rcExtensionId || '';
86
+ if (!apiBaseUrl) return null;
87
+ return {
88
+ apiBaseUrl,
89
+ rcAccountId,
90
+ rcExtensionId,
91
+ rcUsername: trim(registry.rc_username || registry.rcUsername) || sessionIdentity?.rcUsername || '',
92
+ tlsInsecureSkipVerify: Boolean(registry.tls_insecure_skip_verify || registry.tlsInsecureSkipVerify),
93
+ };
94
+ } catch {
95
+ return null;
96
+ }
97
+ }
98
+
99
+ function getRegistryConfig(env = process.env, homeDir = os.homedir()) {
100
+ const daemonConfig = readRegistryConfigFromDaemonConfig(homeDir);
101
+ const sessionIdentity = readRegistrySessionIdentity(homeDir);
102
+ const envApiBaseUrl = normalizeApiBaseUrl(
103
+ env.AI_DESK_API_BASE_URL || env.AI_DESK_BACKEND_API_URL || env.AI_DESK_BACKEND_URL,
104
+ );
105
+ const apiBaseUrl = normalizeApiBaseUrl(
106
+ envApiBaseUrl ||
107
+ daemonConfig?.apiBaseUrl ||
108
+ sessionIdentity?.apiBaseUrl ||
109
+ DEFAULT_REGISTRY_API_BASE_URL,
110
+ );
111
+ const rcAccountId = trim(env.AI_DESK_RC_ACCOUNT_ID || env.rcAccountId) ||
112
+ sessionIdentity?.rcAccountId ||
113
+ daemonConfig?.rcAccountId ||
114
+ '';
115
+ const rcExtensionId = trim(env.AI_DESK_RC_EXTENSION_ID || env.rcExtensionId) ||
116
+ sessionIdentity?.rcExtensionId ||
117
+ daemonConfig?.rcExtensionId ||
118
+ '';
119
+ if (apiBaseUrl) {
120
+ const tlsEnvValue = parseTruthyEnv(env.AI_DESK_TLS_INSECURE_SKIP_VERIFY);
121
+ return {
122
+ apiBaseUrl,
123
+ rcAccountId,
124
+ rcExtensionId,
125
+ rcUsername: trim(env.AI_DESK_RC_USERNAME || env.rcUsername) ||
126
+ sessionIdentity?.rcUsername ||
127
+ daemonConfig?.rcUsername ||
128
+ '',
129
+ tlsInsecureSkipVerify: tlsEnvValue === null
130
+ ? Boolean(daemonConfig?.tlsInsecureSkipVerify ?? sessionIdentity?.tlsInsecureSkipVerify ?? inferTLSInsecureSkipVerify(apiBaseUrl))
131
+ : tlsEnvValue,
132
+ };
133
+ }
134
+ return null;
135
+ }
136
+
137
+ function daemonConfigPath(homeDir = os.homedir()) {
138
+ return path.join(homeDir, '.aidesktop', 'daemon-config.json');
139
+ }
140
+
141
+ function syncRegistryConfigToDaemonConfig(env = process.env, homeDir = os.homedir()) {
142
+ const config = getRegistryConfig(env, homeDir);
143
+ if (!config) return null;
144
+
145
+ const configPath = daemonConfigPath(homeDir);
146
+ let daemonConfig = {};
147
+ try {
148
+ if (fs.existsSync(configPath)) {
149
+ const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8'));
150
+ if (parsed && typeof parsed === 'object') daemonConfig = parsed;
151
+ }
152
+ } catch {
153
+ daemonConfig = {};
154
+ }
155
+
156
+ daemonConfig.registry = {
157
+ ...(daemonConfig.registry && typeof daemonConfig.registry === 'object' ? daemonConfig.registry : {}),
158
+ api_base_url: config.apiBaseUrl,
159
+ rc_account_id: config.rcAccountId,
160
+ rc_extension_id: config.rcExtensionId,
161
+ rc_username: config.rcUsername,
162
+ tls_insecure_skip_verify: Boolean(config.tlsInsecureSkipVerify),
163
+ };
164
+
165
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
166
+ fs.writeFileSync(configPath, `${JSON.stringify(daemonConfig, null, 2)}\n`, 'utf8');
167
+ return config;
168
+ }
169
+
170
+ function configureRegistryUrl(apiBaseUrl, options = {}) {
171
+ const homeDir = options.homeDir || os.homedir();
172
+ const normalizedApiBaseUrl = normalizeApiBaseUrl(apiBaseUrl);
173
+ if (!normalizedApiBaseUrl) {
174
+ throw new Error('Registry URL is required');
175
+ }
176
+
177
+ let parsedUrl;
178
+ try {
179
+ parsedUrl = new URL(normalizedApiBaseUrl);
180
+ } catch {
181
+ throw new Error(`Invalid registry URL: ${apiBaseUrl}`);
182
+ }
183
+ if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
184
+ throw new Error(`Registry URL must use http or https: ${apiBaseUrl}`);
185
+ }
186
+
187
+ const configPath = daemonConfigPath(homeDir);
188
+ let daemonConfig = {};
189
+ try {
190
+ if (fs.existsSync(configPath)) {
191
+ const parsedConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
192
+ if (parsedConfig && typeof parsedConfig === 'object') daemonConfig = parsedConfig;
193
+ }
194
+ } catch {
195
+ daemonConfig = {};
196
+ }
197
+
198
+ const tlsInsecureSkipVerify = typeof options.tlsInsecureSkipVerify === 'boolean'
199
+ ? options.tlsInsecureSkipVerify
200
+ : inferTLSInsecureSkipVerify(normalizedApiBaseUrl);
201
+
202
+ daemonConfig.registry = {
203
+ ...(daemonConfig.registry && typeof daemonConfig.registry === 'object' ? daemonConfig.registry : {}),
204
+ api_base_url: normalizedApiBaseUrl,
205
+ tls_insecure_skip_verify: tlsInsecureSkipVerify,
206
+ };
207
+
208
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
209
+ fs.writeFileSync(configPath, `${JSON.stringify(daemonConfig, null, 2)}\n`, 'utf8');
210
+
211
+ return {
212
+ apiBaseUrl: normalizedApiBaseUrl,
213
+ tlsInsecureSkipVerify,
214
+ };
215
+ }
216
+
217
+ function registryStatePaths(homeDir = os.homedir()) {
218
+ const root = path.join(homeDir, '.aidesktop');
219
+ return {
220
+ root,
221
+ instanceIdPath: path.join(root, 'daemon-instance-id'),
222
+ runStatePath: path.join(root, 'daemon-run-state.json'),
223
+ };
224
+ }
225
+
226
+ function ensureDaemonInstanceId(paths = registryStatePaths()) {
227
+ try {
228
+ fs.mkdirSync(paths.root, { recursive: true });
229
+ if (fs.existsSync(paths.instanceIdPath)) {
230
+ const existing = fs.readFileSync(paths.instanceIdPath, 'utf8').trim();
231
+ if (existing) return existing;
232
+ }
233
+ const next = `daemon-${crypto.randomUUID()}`;
234
+ fs.writeFileSync(paths.instanceIdPath, `${next}\n`, 'utf8');
235
+ return next;
236
+ } catch {
237
+ return `daemon-${crypto.randomUUID()}`;
238
+ }
239
+ }
240
+
241
+ function readRunState(paths = registryStatePaths()) {
242
+ try {
243
+ if (!fs.existsSync(paths.runStatePath)) return null;
244
+ const data = JSON.parse(fs.readFileSync(paths.runStatePath, 'utf8'));
245
+ return data && typeof data === 'object' ? data : null;
246
+ } catch {
247
+ return null;
248
+ }
249
+ }
250
+
251
+ function writeRunState(state, paths = registryStatePaths()) {
252
+ try {
253
+ fs.mkdirSync(paths.root, { recursive: true });
254
+ fs.writeFileSync(paths.runStatePath, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
255
+ } catch {
256
+ // best effort only
257
+ }
258
+ }
259
+
260
+ function listIpAddresses() {
261
+ const out = [];
262
+ const interfaces = os.networkInterfaces();
263
+ for (const items of Object.values(interfaces)) {
264
+ for (const item of items || []) {
265
+ if (!item.internal && item.address) {
266
+ out.push(item.address);
267
+ }
268
+ }
269
+ }
270
+ return [...new Set(out)];
271
+ }
272
+
273
+ function listMacAddresses() {
274
+ const out = [];
275
+ const interfaces = os.networkInterfaces();
276
+ for (const items of Object.values(interfaces)) {
277
+ for (const item of items || []) {
278
+ const mac = trim(item.mac).toLowerCase();
279
+ if (!item.internal && mac && mac !== '00:00:00:00:00:00') {
280
+ out.push(mac);
281
+ }
282
+ }
283
+ }
284
+ return [...new Set(out)];
285
+ }
286
+
287
+ function buildLifecyclePayload({
288
+ event,
289
+ runId,
290
+ seq = 1,
291
+ port,
292
+ version,
293
+ daemonInstanceId,
294
+ }) {
295
+ const macAddresses = listMacAddresses();
296
+ return {
297
+ daemonInstanceId,
298
+ runId,
299
+ event,
300
+ seq,
301
+ machineId: macAddresses[0] || daemonInstanceId,
302
+ hostname: os.hostname(),
303
+ osUsername: os.userInfo().username,
304
+ daemonVersion: version,
305
+ port,
306
+ ipAddresses: listIpAddresses(),
307
+ macAddresses,
308
+ };
309
+ }
310
+
311
+ function postJSON(urlString, payload, config) {
312
+ return new Promise((resolve, reject) => {
313
+ const url = new URL(urlString);
314
+ const body = JSON.stringify(payload);
315
+ const transport = url.protocol === 'https:' ? https : http;
316
+ const req = transport.request(
317
+ url,
318
+ {
319
+ method: 'POST',
320
+ ...(url.protocol === 'https:' && config.tlsInsecureSkipVerify
321
+ ? { agent: new https.Agent({ rejectUnauthorized: false }) }
322
+ : {}),
323
+ headers: {
324
+ 'Content-Type': 'application/json',
325
+ 'Content-Length': Buffer.byteLength(body),
326
+ ...(config.rcAccountId ? { rcAccountId: config.rcAccountId } : {}),
327
+ ...(config.rcExtensionId ? { rcExtensionId: config.rcExtensionId } : {}),
328
+ ...(config.rcUsername ? { rcUsername: config.rcUsername } : {}),
329
+ },
330
+ timeout: 3000,
331
+ },
332
+ (res) => {
333
+ res.resume();
334
+ res.on('end', () => {
335
+ if (res.statusCode >= 200 && res.statusCode < 300) {
336
+ resolve(true);
337
+ } else {
338
+ reject(new Error(`registry returned ${res.statusCode}`));
339
+ }
340
+ });
341
+ },
342
+ );
343
+ req.on('timeout', () => {
344
+ req.destroy(new Error('registry request timed out'));
345
+ });
346
+ req.on('error', reject);
347
+ req.write(body);
348
+ req.end();
349
+ });
350
+ }
351
+
352
+ async function reportLifecycle(event, { port, version, seq = 1 } = {}) {
353
+ const config = getRegistryConfig();
354
+ if (!config) return false;
355
+
356
+ const paths = registryStatePaths();
357
+ const daemonInstanceId = ensureDaemonInstanceId(paths);
358
+ let runState = readRunState(paths);
359
+ if (event === 'start' || event === 'restart' || !runState?.runId) {
360
+ runState = { runId: crypto.randomUUID(), seq: 0 };
361
+ }
362
+ runState.seq = Math.max(Number(runState.seq || 0) + 1, seq);
363
+ writeRunState(runState, paths);
364
+
365
+ const payload = buildLifecyclePayload({
366
+ event,
367
+ runId: runState.runId,
368
+ seq: runState.seq,
369
+ port,
370
+ version,
371
+ daemonInstanceId,
372
+ });
373
+ await postJSON(`${config.apiBaseUrl}/daemon-instances/lifecycle`, payload, config);
374
+ return true;
375
+ }
376
+
377
+ module.exports = {
378
+ buildLifecyclePayload,
379
+ configureRegistryUrl,
380
+ DEFAULT_REGISTRY_API_BASE_URL,
381
+ inferTLSInsecureSkipVerify,
382
+ getRegistryConfig,
383
+ syncRegistryConfigToDaemonConfig,
384
+ readRegistrySessionIdentity,
385
+ readRegistryConfigFromDaemonConfig,
386
+ registryStatePaths,
387
+ ensureDaemonInstanceId,
388
+ readRunState,
389
+ writeRunState,
390
+ listMacAddresses,
391
+ reportLifecycle,
392
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-webui/ai-desk-daemon",
3
- "version": "1.0.62",
3
+ "version": "1.0.63-beta1",
4
4
  "description": "AI Desk Daemon - CLI tool for managing the AI Desk daemon service",
5
5
  "workspaces": [
6
6
  "packages/*"
@@ -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.62",
43
- "@agent-webui/ai-desk-daemon-darwin-x64": "1.0.62",
44
- "@agent-webui/ai-desk-daemon-linux-arm64": "1.0.62",
45
- "@agent-webui/ai-desk-daemon-linux-x64": "1.0.62",
46
- "@agent-webui/ai-desk-daemon-win32-x64": "1.0.62",
47
- "@agent-webui/ai-desk-python-darwin-arm64": "1.0.62",
48
- "@agent-webui/ai-desk-python-darwin-x64": "1.0.62",
49
- "@agent-webui/ai-desk-python-linux-arm64": "1.0.62",
50
- "@agent-webui/ai-desk-python-linux-x64": "1.0.62",
51
- "@agent-webui/ai-desk-python-win32-x64": "1.0.62"
42
+ "@agent-webui/ai-desk-daemon-darwin-arm64": "1.0.63-beta1",
43
+ "@agent-webui/ai-desk-daemon-darwin-x64": "1.0.63-beta1",
44
+ "@agent-webui/ai-desk-daemon-linux-arm64": "1.0.63-beta1",
45
+ "@agent-webui/ai-desk-daemon-linux-x64": "1.0.63-beta1",
46
+ "@agent-webui/ai-desk-daemon-win32-x64": "1.0.63-beta1",
47
+ "@agent-webui/ai-desk-python-darwin-arm64": "1.0.63-beta1",
48
+ "@agent-webui/ai-desk-python-darwin-x64": "1.0.63-beta1",
49
+ "@agent-webui/ai-desk-python-linux-arm64": "1.0.63-beta1",
50
+ "@agent-webui/ai-desk-python-linux-x64": "1.0.63-beta1",
51
+ "@agent-webui/ai-desk-python-win32-x64": "1.0.63-beta1"
52
52
  },
53
53
  "repository": {
54
54
  "type": "git",