@agent-webui/ai-desk-daemon 1.0.61-beta6 → 1.0.61-beta7

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
@@ -12,7 +12,12 @@ const { start, stop, restart, status } = require('../lib/daemon-manager');
12
12
  const { getLogPath } = require('../lib/platform');
13
13
  const { VERSION } = require('../lib/platform');
14
14
  const { getPort } = require('../lib/config');
15
- const { reportLifecycle, syncRegistryConfigToDaemonConfig } = require('../lib/daemon-registry');
15
+ const {
16
+ configureRegistryUrl,
17
+ getRegistryConfig,
18
+ reportLifecycle,
19
+ syncRegistryConfigToDaemonConfig,
20
+ } = require('../lib/daemon-registry');
16
21
  const { upgradePackage } = require('../lib/self-upgrade');
17
22
 
18
23
  function wait(ms) {
@@ -154,6 +159,50 @@ program
154
159
  .description('AI Desk Daemon - CLI tool for managing the AI Desk daemon service')
155
160
  .version(VERSION);
156
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
+
157
206
  // Start command
158
207
  program
159
208
  .command('start')
@@ -25,6 +25,29 @@ function parseTruthyEnv(value) {
25
25
  return raw === '1' || raw === 'true' || raw === 'yes' || raw === 'on';
26
26
  }
27
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
+
28
51
  function readRegistrySessionIdentity(homeDir = os.homedir()) {
29
52
  const sessionPath = path.join(homeDir, '.aidesktop', 'session.json');
30
53
  try {
@@ -79,12 +102,11 @@ function getRegistryConfig(env = process.env, homeDir = os.homedir()) {
79
102
  const envApiBaseUrl = normalizeApiBaseUrl(
80
103
  env.AI_DESK_API_BASE_URL || env.AI_DESK_BACKEND_API_URL || env.AI_DESK_BACKEND_URL,
81
104
  );
82
- const hasSessionUserIdentity = Boolean(sessionIdentity?.rcAccountId || sessionIdentity?.rcExtensionId);
83
105
  const apiBaseUrl = normalizeApiBaseUrl(
84
106
  envApiBaseUrl ||
85
- sessionIdentity?.apiBaseUrl ||
86
107
  daemonConfig?.apiBaseUrl ||
87
- (hasSessionUserIdentity ? DEFAULT_REGISTRY_API_BASE_URL : ''),
108
+ sessionIdentity?.apiBaseUrl ||
109
+ DEFAULT_REGISTRY_API_BASE_URL,
88
110
  );
89
111
  const rcAccountId = trim(env.AI_DESK_RC_ACCOUNT_ID || env.rcAccountId) ||
90
112
  sessionIdentity?.rcAccountId ||
@@ -105,7 +127,7 @@ function getRegistryConfig(env = process.env, homeDir = os.homedir()) {
105
127
  daemonConfig?.rcUsername ||
106
128
  '',
107
129
  tlsInsecureSkipVerify: tlsEnvValue === null
108
- ? Boolean(sessionIdentity?.tlsInsecureSkipVerify ?? daemonConfig?.tlsInsecureSkipVerify)
130
+ ? Boolean(daemonConfig?.tlsInsecureSkipVerify ?? sessionIdentity?.tlsInsecureSkipVerify ?? inferTLSInsecureSkipVerify(apiBaseUrl))
109
131
  : tlsEnvValue,
110
132
  };
111
133
  }
@@ -145,6 +167,53 @@ function syncRegistryConfigToDaemonConfig(env = process.env, homeDir = os.homedi
145
167
  return config;
146
168
  }
147
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
+
148
217
  function registryStatePaths(homeDir = os.homedir()) {
149
218
  const root = path.join(homeDir, '.aidesktop');
150
219
  return {
@@ -307,7 +376,9 @@ async function reportLifecycle(event, { port, version, seq = 1 } = {}) {
307
376
 
308
377
  module.exports = {
309
378
  buildLifecyclePayload,
379
+ configureRegistryUrl,
310
380
  DEFAULT_REGISTRY_API_BASE_URL,
381
+ inferTLSInsecureSkipVerify,
311
382
  getRegistryConfig,
312
383
  syncRegistryConfigToDaemonConfig,
313
384
  readRegistrySessionIdentity,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-webui/ai-desk-daemon",
3
- "version": "1.0.61-beta6",
3
+ "version": "1.0.61-beta7",
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.61-beta6",
43
- "@agent-webui/ai-desk-daemon-darwin-x64": "1.0.61-beta6",
44
- "@agent-webui/ai-desk-daemon-linux-arm64": "1.0.61-beta6",
45
- "@agent-webui/ai-desk-daemon-linux-x64": "1.0.61-beta6",
46
- "@agent-webui/ai-desk-daemon-win32-x64": "1.0.61-beta6",
47
- "@agent-webui/ai-desk-python-darwin-arm64": "1.0.61-beta6",
48
- "@agent-webui/ai-desk-python-darwin-x64": "1.0.61-beta6",
49
- "@agent-webui/ai-desk-python-linux-arm64": "1.0.61-beta6",
50
- "@agent-webui/ai-desk-python-linux-x64": "1.0.61-beta6",
51
- "@agent-webui/ai-desk-python-win32-x64": "1.0.61-beta6"
42
+ "@agent-webui/ai-desk-daemon-darwin-arm64": "1.0.61-beta7",
43
+ "@agent-webui/ai-desk-daemon-darwin-x64": "1.0.61-beta7",
44
+ "@agent-webui/ai-desk-daemon-linux-arm64": "1.0.61-beta7",
45
+ "@agent-webui/ai-desk-daemon-linux-x64": "1.0.61-beta7",
46
+ "@agent-webui/ai-desk-daemon-win32-x64": "1.0.61-beta7",
47
+ "@agent-webui/ai-desk-python-darwin-arm64": "1.0.61-beta7",
48
+ "@agent-webui/ai-desk-python-darwin-x64": "1.0.61-beta7",
49
+ "@agent-webui/ai-desk-python-linux-arm64": "1.0.61-beta7",
50
+ "@agent-webui/ai-desk-python-linux-x64": "1.0.61-beta7",
51
+ "@agent-webui/ai-desk-python-win32-x64": "1.0.61-beta7"
52
52
  },
53
53
  "repository": {
54
54
  "type": "git",