@questionbase/deskfree 0.6.10 → 0.7.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/dist/bin.js CHANGED
@@ -33,8 +33,8 @@ var __commonJS = (cb, mod) => function __require3() {
33
33
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
34
34
  };
35
35
  var __export = (target, all) => {
36
- for (var name2 in all)
37
- __defProp(target, name2, { get: all[name2], enumerable: true });
36
+ for (var name in all)
37
+ __defProp(target, name, { get: all[name], enumerable: true });
38
38
  };
39
39
  var __copyProps = (to, from, except, desc) => {
40
40
  if (from && typeof from === "object" || typeof from === "function") {
@@ -52,16 +52,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
52
52
  __defProp(target, "default", { value: mod, enumerable: true }) ,
53
53
  mod
54
54
  ));
55
- function getPlistLabel(name2) {
56
- return `com.deskfree.agent.${name2}`;
55
+ function getPlistLabel(botId) {
56
+ return `com.deskfree.agent.${botId}`;
57
57
  }
58
- function getServiceName(name2) {
59
- return `deskfree-${name2}`;
58
+ function getServiceName(botId) {
59
+ return `deskfree-${botId}`;
60
60
  }
61
- function getMacPaths(name2) {
61
+ function getMacPaths(botId) {
62
62
  const home = homedir();
63
- const deskfreeDir = join(home, ".deskfree", name2);
64
- const plistLabel = getPlistLabel(name2);
63
+ const deskfreeDir = join(home, ".deskfree", botId);
64
+ const plistLabel = getPlistLabel(botId);
65
65
  return {
66
66
  deskfreeDir,
67
67
  envFile: join(deskfreeDir, ".env"),
@@ -70,8 +70,8 @@ function getMacPaths(name2) {
70
70
  plist: join(home, "Library", "LaunchAgents", `${plistLabel}.plist`)
71
71
  };
72
72
  }
73
- function getLinuxPaths(name2) {
74
- const serviceName = getServiceName(name2);
73
+ function getLinuxPaths(botId) {
74
+ const serviceName = getServiceName(botId);
75
75
  return {
76
76
  serviceName,
77
77
  serviceFile: `/etc/systemd/system/${serviceName}.service`,
@@ -80,57 +80,40 @@ function getLinuxPaths(name2) {
80
80
  logDir: `/var/log/${serviceName}`
81
81
  };
82
82
  }
83
- function parseName(args) {
84
- const idx = args.indexOf("--name");
85
- if (idx === -1) return [DEFAULT_NAME, args];
86
- const name2 = args[idx + 1];
87
- if (!name2 || name2.startsWith("-")) {
88
- console.error("Error: --name requires a value (e.g. --name kasper)");
89
- process.exit(1);
90
- }
91
- if (!/^[a-z0-9-]+$/i.test(name2)) {
92
- console.error(
93
- "Error: --name must contain only letters, numbers, and hyphens"
94
- );
95
- process.exit(1);
96
- }
97
- const remaining = [...args.slice(0, idx), ...args.slice(idx + 2)];
98
- return [name2, remaining];
99
- }
100
- var DEFAULT_NAME;
101
83
  var init_paths = __esm({
102
84
  "src/cli/paths.ts"() {
103
- DEFAULT_NAME = "main";
104
85
  }
105
86
  });
106
87
 
107
- // src/cli/install.ts
108
- var install_exports = {};
109
- __export(install_exports, {
110
- install: () => install
88
+ // src/cli/start.ts
89
+ var start_exports = {};
90
+ __export(start_exports, {
91
+ start: () => start
111
92
  });
112
- function installMac(botId, name2, stage) {
113
- const paths = getMacPaths(name2);
114
- const plistLabel = getPlistLabel(name2);
115
- let nodeBinDir;
116
- try {
117
- const nodePath = execSync("which node", { encoding: "utf8" }).trim();
118
- nodeBinDir = dirname(nodePath);
119
- } catch {
120
- console.error("Error: node not found in PATH");
121
- process.exit(1);
122
- }
123
- const extraPathDirs = (process.env["PATH"] ?? "").split(":").filter((d) => d && d !== nodeBinDir);
124
- const fullPath = [nodeBinDir, ...extraPathDirs].join(":");
125
- mkdirSync(paths.deskfreeDir, { recursive: true });
126
- mkdirSync(paths.logDir, { recursive: true });
127
- mkdirSync(dirname(paths.plist), { recursive: true });
128
- const envLines = [`BOT=${botId}`, `DESKFREE_INSTANCE_NAME=${name2}`];
129
- if (stage) envLines.push(`STAGE=${stage}`);
130
- writeFileSync(paths.envFile, envLines.join("\n") + "\n", { mode: 384 });
131
- chmodSync(paths.envFile, 384);
132
- console.log(`Wrote ${paths.envFile}`);
133
- const launcher = `#!/bin/bash
93
+ function startMac(botId, stage) {
94
+ const paths = getMacPaths(botId);
95
+ const plistLabel = getPlistLabel(botId);
96
+ const isInstalled = existsSync(paths.plist);
97
+ if (!isInstalled) {
98
+ let nodeBinDir;
99
+ try {
100
+ const nodePath = execSync("which node", { encoding: "utf8" }).trim();
101
+ nodeBinDir = dirname(nodePath);
102
+ } catch {
103
+ console.error("Error: node not found in PATH");
104
+ process.exit(1);
105
+ }
106
+ const extraPathDirs = (process.env["PATH"] ?? "").split(":").filter((d) => d && d !== nodeBinDir);
107
+ const fullPath = [nodeBinDir, ...extraPathDirs].join(":");
108
+ mkdirSync(paths.deskfreeDir, { recursive: true });
109
+ mkdirSync(paths.logDir, { recursive: true });
110
+ mkdirSync(dirname(paths.plist), { recursive: true });
111
+ const envLines = [`BOT=${botId}`];
112
+ if (stage) envLines.push(`STAGE=${stage}`);
113
+ writeFileSync(paths.envFile, envLines.join("\n") + "\n", { mode: 384 });
114
+ chmodSync(paths.envFile, 384);
115
+ console.log(`Wrote ${paths.envFile}`);
116
+ const launcher = `#!/bin/bash
134
117
  set -euo pipefail
135
118
 
136
119
  export PATH="${fullPath}"
@@ -143,12 +126,12 @@ set -a
143
126
  source "${paths.envFile}"
144
127
  set +a
145
128
 
146
- exec deskfree start
129
+ exec deskfree run "$BOT"
147
130
  `;
148
- writeFileSync(paths.launcher, launcher, { mode: 493 });
149
- chmodSync(paths.launcher, 493);
150
- console.log(`Wrote ${paths.launcher}`);
151
- const plist = `<?xml version="1.0" encoding="UTF-8"?>
131
+ writeFileSync(paths.launcher, launcher, { mode: 493 });
132
+ chmodSync(paths.launcher, 493);
133
+ console.log(`Wrote ${paths.launcher}`);
134
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
152
135
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
153
136
  <plist version="1.0">
154
137
  <dict>
@@ -171,8 +154,9 @@ exec deskfree start
171
154
  </dict>
172
155
  </plist>
173
156
  `;
174
- writeFileSync(paths.plist, plist);
175
- console.log(`Wrote ${paths.plist}`);
157
+ writeFileSync(paths.plist, plist);
158
+ console.log(`Wrote ${paths.plist}`);
159
+ }
176
160
  try {
177
161
  execSync(`launchctl bootout gui/$(id -u) ${paths.plist}`, {
178
162
  stdio: "ignore"
@@ -180,49 +164,54 @@ exec deskfree start
180
164
  } catch {
181
165
  }
182
166
  execSync(`launchctl bootstrap gui/$(id -u) ${paths.plist}`);
183
- console.log(`
184
- Service ${plistLabel} installed and started.`);
185
- console.log(`Check status: launchctl print gui/$(id -u)/${plistLabel}`);
167
+ if (isInstalled) {
168
+ console.log(`Bot ${botId} started.`);
169
+ } else {
170
+ console.log(`
171
+ Bot ${botId} installed and started.`);
172
+ }
186
173
  console.log(`Logs: tail -f ${join(paths.logDir, "stdout.log")}`);
187
174
  }
188
- function installLinux(botId, name2, stage) {
189
- if (process.getuid?.() !== 0) {
190
- console.error("Error: install must be run as root (use sudo)");
191
- process.exit(1);
192
- }
193
- const paths = getLinuxPaths(name2);
194
- const serviceName = getServiceName(name2);
195
- const systemUser = serviceName;
196
- let npmPath;
197
- let nodeBinDir;
198
- try {
199
- npmPath = execSync("which npm", { encoding: "utf8" }).trim();
200
- nodeBinDir = dirname(npmPath);
201
- } catch {
202
- console.error("Error: npm not found in PATH");
203
- process.exit(1);
204
- }
205
- try {
206
- execSync(`id ${systemUser}`, { stdio: "ignore" });
207
- } catch {
175
+ function startLinux(botId, stage) {
176
+ const paths = getLinuxPaths(botId);
177
+ const serviceName = getServiceName(botId);
178
+ const isInstalled = existsSync(paths.serviceFile);
179
+ if (!isInstalled) {
180
+ if (process.getuid?.() !== 0) {
181
+ console.error("Error: first-time setup must be run as root (use sudo)");
182
+ process.exit(1);
183
+ }
184
+ const systemUser = serviceName;
185
+ let npmPath;
186
+ let nodeBinDir;
187
+ try {
188
+ npmPath = execSync("which npm", { encoding: "utf8" }).trim();
189
+ nodeBinDir = dirname(npmPath);
190
+ } catch {
191
+ console.error("Error: npm not found in PATH");
192
+ process.exit(1);
193
+ }
194
+ try {
195
+ execSync(`id ${systemUser}`, { stdio: "ignore" });
196
+ } catch {
197
+ execSync(
198
+ `useradd --system --no-create-home --shell /usr/sbin/nologin ${systemUser}`
199
+ );
200
+ console.log(`Created system user: ${systemUser}`);
201
+ }
202
+ mkdirSync(paths.stateDir, { recursive: true });
203
+ mkdirSync(paths.logDir, { recursive: true });
208
204
  execSync(
209
- `useradd --system --no-create-home --shell /usr/sbin/nologin ${systemUser}`
205
+ `chown ${systemUser}:${systemUser} ${paths.stateDir} ${paths.logDir}`
210
206
  );
211
- console.log(`Created system user: ${systemUser}`);
212
- }
213
- mkdirSync(paths.stateDir, { recursive: true });
214
- mkdirSync(paths.logDir, { recursive: true });
215
- execSync(
216
- `chown ${systemUser}:${systemUser} ${paths.stateDir} ${paths.logDir}`
217
- );
218
- console.log(`Created ${paths.stateDir} and ${paths.logDir}`);
219
- const envLines = [`BOT=${botId}`, `DESKFREE_INSTANCE_NAME=${name2}`];
220
- if (stage) envLines.push(`STAGE=${stage}`);
221
- writeFileSync(paths.envFile, envLines.join("\n") + "\n", { mode: 384 });
222
- chmodSync(paths.envFile, 384);
223
- console.log(`Wrote ${paths.envFile}`);
224
- const unit = `[Unit]
225
- Description=DeskFree Agent (${name2})
207
+ console.log(`Created ${paths.stateDir} and ${paths.logDir}`);
208
+ const envLines = [`BOT=${botId}`];
209
+ if (stage) envLines.push(`STAGE=${stage}`);
210
+ writeFileSync(paths.envFile, envLines.join("\n") + "\n", { mode: 384 });
211
+ chmodSync(paths.envFile, 384);
212
+ console.log(`Wrote ${paths.envFile}`);
213
+ const unit = `[Unit]
214
+ Description=DeskFree Agent (${botId})
226
215
  After=network-online.target
227
216
  Wants=network-online.target
228
217
 
@@ -233,7 +222,7 @@ Group=${systemUser}
233
222
  WorkingDirectory=${paths.stateDir}
234
223
  Environment=PATH=${nodeBinDir}:/usr/local/bin:/usr/bin:/bin
235
224
  ExecStartPre=+${npmPath} install -g ${PACKAGE}
236
- ExecStart=${nodeBinDir}/deskfree start
225
+ ExecStart=${nodeBinDir}/deskfree run ${botId}
237
226
  EnvironmentFile=${paths.envFile}
238
227
  Environment=NODE_ENV=production
239
228
  Environment=DESKFREE_STATE_DIR=${paths.stateDir}
@@ -246,42 +235,98 @@ StandardError=append:${paths.logDir}/stderr.log
246
235
  [Install]
247
236
  WantedBy=multi-user.target
248
237
  `;
249
- writeFileSync(paths.serviceFile, unit);
250
- console.log(`Wrote ${paths.serviceFile}`);
251
- execSync("systemctl daemon-reload");
252
- execSync(`systemctl enable ${serviceName}`);
238
+ writeFileSync(paths.serviceFile, unit);
239
+ console.log(`Wrote ${paths.serviceFile}`);
240
+ execSync("systemctl daemon-reload");
241
+ execSync(`systemctl enable ${serviceName}`);
242
+ }
253
243
  execSync(`systemctl start ${serviceName}`);
254
- console.log(`
255
- Service ${serviceName} installed and started.`);
256
- console.log(`Check status: systemctl status ${serviceName}`);
244
+ if (isInstalled) {
245
+ console.log(`Bot ${botId} started.`);
246
+ } else {
247
+ console.log(`
248
+ Bot ${botId} installed and started.`);
249
+ }
257
250
  console.log(`Logs: tail -f ${paths.logDir}/stdout.log`);
258
251
  }
259
- function install(botId, name2, stage) {
252
+ function start(botId, stage) {
260
253
  if (process.platform === "darwin") {
261
- installMac(botId, name2, stage);
254
+ startMac(botId, stage);
262
255
  } else if (process.platform === "linux") {
263
- installLinux(botId, name2, stage);
256
+ startLinux(botId, stage);
264
257
  } else {
265
258
  console.error(`Unsupported platform: ${process.platform}`);
266
259
  process.exit(1);
267
260
  }
268
261
  }
269
262
  var PACKAGE;
270
- var init_install = __esm({
271
- "src/cli/install.ts"() {
263
+ var init_start = __esm({
264
+ "src/cli/start.ts"() {
272
265
  init_paths();
273
266
  PACKAGE = "@questionbase/deskfree@latest";
274
267
  }
275
268
  });
276
269
 
270
+ // src/cli/stop.ts
271
+ var stop_exports = {};
272
+ __export(stop_exports, {
273
+ stop: () => stop
274
+ });
275
+ function stopMac(botId) {
276
+ const paths = getMacPaths(botId);
277
+ if (!existsSync(paths.plist)) {
278
+ console.error(`Bot ${botId} is not installed.`);
279
+ console.error(`Run: deskfree start ${botId}`);
280
+ process.exit(1);
281
+ }
282
+ try {
283
+ execSync(`launchctl bootout gui/$(id -u) ${paths.plist}`, {
284
+ stdio: "ignore"
285
+ });
286
+ console.log(`Bot ${botId} stopped.`);
287
+ } catch {
288
+ console.log(`Bot ${botId} is not running.`);
289
+ }
290
+ }
291
+ function stopLinux(botId) {
292
+ const paths = getLinuxPaths(botId);
293
+ const serviceName = getServiceName(botId);
294
+ if (!existsSync(paths.serviceFile)) {
295
+ console.error(`Bot ${botId} is not installed.`);
296
+ console.error(`Run: deskfree start ${botId}`);
297
+ process.exit(1);
298
+ }
299
+ try {
300
+ execSync(`systemctl stop ${serviceName}`, { stdio: "inherit" });
301
+ console.log(`Bot ${botId} stopped.`);
302
+ } catch {
303
+ console.log(`Bot ${botId} is not running.`);
304
+ }
305
+ }
306
+ function stop(botId) {
307
+ if (process.platform === "darwin") {
308
+ stopMac(botId);
309
+ } else if (process.platform === "linux") {
310
+ stopLinux(botId);
311
+ } else {
312
+ console.error(`Unsupported platform: ${process.platform}`);
313
+ process.exit(1);
314
+ }
315
+ }
316
+ var init_stop = __esm({
317
+ "src/cli/stop.ts"() {
318
+ init_paths();
319
+ }
320
+ });
321
+
277
322
  // src/cli/uninstall.ts
278
323
  var uninstall_exports = {};
279
324
  __export(uninstall_exports, {
280
325
  uninstall: () => uninstall
281
326
  });
282
- function uninstallMac(name2) {
283
- const paths = getMacPaths(name2);
284
- const plistLabel = getPlistLabel(name2);
327
+ function uninstallMac(botId) {
328
+ const paths = getMacPaths(botId);
329
+ const plistLabel = getPlistLabel(botId);
285
330
  try {
286
331
  execSync(`launchctl bootout gui/$(id -u) ${paths.plist}`, {
287
332
  stdio: "ignore"
@@ -294,18 +339,18 @@ function uninstallMac(name2) {
294
339
  console.log(`Removed ${file}`);
295
340
  }
296
341
  }
297
- console.log(`Service ${plistLabel} uninstalled.`);
342
+ console.log(`Bot ${botId} (${plistLabel}) uninstalled.`);
298
343
  console.log(
299
344
  `Note: logs and state in ${paths.deskfreeDir} were preserved. Remove manually if desired.`
300
345
  );
301
346
  }
302
- function uninstallLinux(name2) {
347
+ function uninstallLinux(botId) {
303
348
  if (process.getuid?.() !== 0) {
304
349
  console.error("Error: uninstall must be run as root (use sudo)");
305
350
  process.exit(1);
306
351
  }
307
- const paths = getLinuxPaths(name2);
308
- const serviceName = getServiceName(name2);
352
+ const paths = getLinuxPaths(botId);
353
+ const serviceName = getServiceName(botId);
309
354
  try {
310
355
  execSync(`systemctl stop ${serviceName}`, { stdio: "ignore" });
311
356
  } catch {
@@ -323,13 +368,13 @@ function uninstallLinux(name2) {
323
368
  console.log(`Removed ${paths.envFile}`);
324
369
  }
325
370
  execSync("systemctl daemon-reload");
326
- console.log(`Service ${serviceName} uninstalled.`);
371
+ console.log(`Bot ${botId} (${serviceName}) uninstalled.`);
327
372
  }
328
- function uninstall(name2) {
373
+ function uninstall(botId) {
329
374
  if (process.platform === "darwin") {
330
- uninstallMac(name2);
375
+ uninstallMac(botId);
331
376
  } else if (process.platform === "linux") {
332
- uninstallLinux(name2);
377
+ uninstallLinux(botId);
333
378
  } else {
334
379
  console.error(`Unsupported platform: ${process.platform}`);
335
380
  process.exit(1);
@@ -346,15 +391,15 @@ var status_exports = {};
346
391
  __export(status_exports, {
347
392
  status: () => status
348
393
  });
349
- function statusMac(name2) {
350
- const paths = getMacPaths(name2);
351
- const plistLabel = getPlistLabel(name2);
394
+ function statusMac(botId) {
395
+ const paths = getMacPaths(botId);
396
+ const plistLabel = getPlistLabel(botId);
352
397
  if (!existsSync(paths.plist)) {
353
- console.log(`DeskFree Agent "${name2}" is not installed.`);
354
- console.log(`Run: deskfree install <token> --name ${name2}`);
398
+ console.log(`Bot ${botId} is not installed.`);
399
+ console.log(`Run: deskfree start ${botId}`);
355
400
  return;
356
401
  }
357
- console.log(`DeskFree Agent "${name2}" (macOS LaunchAgent)
402
+ console.log(`Bot ${botId} (macOS LaunchAgent)
358
403
  `);
359
404
  try {
360
405
  const output = execSync(`launchctl print gui/$(id -u)/${plistLabel} 2>&1`, {
@@ -370,17 +415,15 @@ function statusMac(name2) {
370
415
  console.log(" Status: not running (service may be unloaded)");
371
416
  }
372
417
  }
373
- function statusLinux(name2) {
374
- const paths = getLinuxPaths(name2);
375
- const serviceName = getServiceName(name2);
418
+ function statusLinux(botId) {
419
+ const paths = getLinuxPaths(botId);
420
+ const serviceName = getServiceName(botId);
376
421
  if (!existsSync(paths.serviceFile)) {
377
- console.log(`DeskFree Agent "${name2}" is not installed.`);
378
- console.log(
379
- `Run: sudo npx @questionbase/deskfree@latest install <token> --name ${name2}`
380
- );
422
+ console.log(`Bot ${botId} is not installed.`);
423
+ console.log(`Run: sudo deskfree start ${botId}`);
381
424
  return;
382
425
  }
383
- console.log(`DeskFree Agent "${name2}" (systemd service)
426
+ console.log(`Bot ${botId} (systemd service)
384
427
  `);
385
428
  try {
386
429
  const output = execSync(`systemctl status ${serviceName} --no-pager 2>&1`, {
@@ -396,11 +439,11 @@ function statusLinux(name2) {
396
439
  }
397
440
  console.log(` Logs: ${paths.logDir}/stdout.log`);
398
441
  }
399
- function status(name2) {
442
+ function status(botId) {
400
443
  if (process.platform === "darwin") {
401
- statusMac(name2);
444
+ statusMac(botId);
402
445
  } else if (process.platform === "linux") {
403
- statusLinux(name2);
446
+ statusLinux(botId);
404
447
  } else {
405
448
  console.error(`Unsupported platform: ${process.platform}`);
406
449
  process.exit(1);
@@ -417,11 +460,11 @@ var restart_exports = {};
417
460
  __export(restart_exports, {
418
461
  restart: () => restart
419
462
  });
420
- function restartMac(name2) {
421
- const paths = getMacPaths(name2);
463
+ function restartMac(botId) {
464
+ const paths = getMacPaths(botId);
422
465
  if (!existsSync(paths.plist)) {
423
- console.error(`DeskFree Agent "${name2}" is not installed.`);
424
- console.error(`Run: deskfree install <token> --name ${name2}`);
466
+ console.error(`Bot ${botId} is not installed.`);
467
+ console.error(`Run: deskfree start ${botId}`);
425
468
  process.exit(1);
426
469
  }
427
470
  try {
@@ -431,28 +474,26 @@ function restartMac(name2) {
431
474
  } catch {
432
475
  }
433
476
  execSync(`launchctl bootstrap gui/$(id -u) ${paths.plist}`);
434
- console.log(`DeskFree Agent "${name2}" restarted.`);
477
+ console.log(`Bot ${botId} restarted.`);
435
478
  console.log(`Logs: tail -f ${paths.logDir}/stdout.log`);
436
479
  }
437
- function restartLinux(name2) {
438
- const paths = getLinuxPaths(name2);
439
- const serviceName = getServiceName(name2);
480
+ function restartLinux(botId) {
481
+ const paths = getLinuxPaths(botId);
482
+ const serviceName = getServiceName(botId);
440
483
  if (!existsSync(paths.serviceFile)) {
441
- console.error(`DeskFree Agent "${name2}" is not installed.`);
442
- console.error(
443
- `Run: sudo npx @questionbase/deskfree@latest install <token> --name ${name2}`
444
- );
484
+ console.error(`Bot ${botId} is not installed.`);
485
+ console.error(`Run: sudo deskfree start ${botId}`);
445
486
  process.exit(1);
446
487
  }
447
488
  execSync(`systemctl restart ${serviceName}`, { stdio: "inherit" });
448
- console.log(`DeskFree Agent "${name2}" restarted.`);
489
+ console.log(`Bot ${botId} restarted.`);
449
490
  console.log(`Logs: tail -f ${paths.logDir}/stdout.log`);
450
491
  }
451
- function restart(name2) {
492
+ function restart(botId) {
452
493
  if (process.platform === "darwin") {
453
- restartMac(name2);
494
+ restartMac(botId);
454
495
  } else if (process.platform === "linux") {
455
- restartLinux(name2);
496
+ restartLinux(botId);
456
497
  } else {
457
498
  console.error(`Unsupported platform: ${process.platform}`);
458
499
  process.exit(1);
@@ -469,30 +510,30 @@ var logs_exports = {};
469
510
  __export(logs_exports, {
470
511
  logs: () => logs
471
512
  });
472
- function getLogPath(name2) {
513
+ function getLogPath(botId) {
473
514
  if (process.platform === "darwin") {
474
- const logFile = join(getMacPaths(name2).logDir, "stdout.log");
515
+ const logFile = join(getMacPaths(botId).logDir, "stdout.log");
475
516
  return existsSync(logFile) ? logFile : null;
476
517
  } else if (process.platform === "linux") {
477
- const logFile = join(getLinuxPaths(name2).logDir, "stdout.log");
518
+ const logFile = join(getLinuxPaths(botId).logDir, "stdout.log");
478
519
  return existsSync(logFile) ? logFile : null;
479
520
  }
480
521
  return null;
481
522
  }
482
- function logs(follow, name2) {
523
+ function logs(follow, botId) {
483
524
  if (process.platform !== "darwin" && process.platform !== "linux") {
484
525
  console.error(`Unsupported platform: ${process.platform}`);
485
526
  process.exit(1);
486
527
  }
487
- const logPath = getLogPath(name2);
528
+ const logPath = getLogPath(botId);
488
529
  if (!logPath) {
489
530
  console.error(
490
- `No log file found for "${name2}". Is DeskFree Agent installed with --name ${name2}?`
531
+ `No log file found for bot ${botId}. Is it installed? Run: deskfree start ${botId}`
491
532
  );
492
533
  process.exit(1);
493
534
  }
494
- const args = follow ? ["-f", "-n", "50", logPath] : ["-n", "50", logPath];
495
- const child = spawn("tail", args, { stdio: "inherit" });
535
+ const args2 = follow ? ["-f", "-n", "50", logPath] : ["-n", "50", logPath];
536
+ const child = spawn("tail", args2, { stdio: "inherit" });
496
537
  child.on("error", (err) => {
497
538
  console.error(`Failed to read logs: ${err.message}`);
498
539
  process.exit(1);
@@ -1098,7 +1139,7 @@ function IsPrecedenceAnd(pattern) {
1098
1139
  return false;
1099
1140
  }
1100
1141
  function Or(pattern) {
1101
- let [count, start] = [0, 0];
1142
+ let [count, start2] = [0, 0];
1102
1143
  const expressions = [];
1103
1144
  for (let index = 0; index < pattern.length; index++) {
1104
1145
  if (IsOpenParen(pattern, index))
@@ -1106,13 +1147,13 @@ function Or(pattern) {
1106
1147
  if (IsCloseParen(pattern, index))
1107
1148
  count -= 1;
1108
1149
  if (IsSeparator(pattern, index) && count === 0) {
1109
- const range2 = pattern.slice(start, index);
1150
+ const range2 = pattern.slice(start2, index);
1110
1151
  if (range2.length > 0)
1111
1152
  expressions.push(TemplateLiteralParse(range2));
1112
- start = index + 1;
1153
+ start2 = index + 1;
1113
1154
  }
1114
1155
  }
1115
- const range = pattern.slice(start);
1156
+ const range = pattern.slice(start2);
1116
1157
  if (range.length > 0)
1117
1158
  expressions.push(TemplateLiteralParse(range));
1118
1159
  if (expressions.length === 0)
@@ -1146,13 +1187,13 @@ function And(pattern) {
1146
1187
  const expressions = [];
1147
1188
  for (let index = 0; index < pattern.length; index++) {
1148
1189
  if (IsOpenParen(pattern, index)) {
1149
- const [start, end] = Group(pattern, index);
1150
- const range = pattern.slice(start, end + 1);
1190
+ const [start2, end] = Group(pattern, index);
1191
+ const range = pattern.slice(start2, end + 1);
1151
1192
  expressions.push(TemplateLiteralParse(range));
1152
1193
  index = end;
1153
1194
  } else {
1154
- const [start, end] = Range(pattern, index);
1155
- const range = pattern.slice(start, end);
1195
+ const [start2, end] = Range(pattern, index);
1196
+ const range = pattern.slice(start2, end);
1156
1197
  if (range.length > 0)
1157
1198
  expressions.push(TemplateLiteralParse(range));
1158
1199
  index = end - 1;
@@ -1534,8 +1575,8 @@ function Intersect(types, options) {
1534
1575
  throw new Error("Cannot intersect transform types");
1535
1576
  return IntersectCreate(types, options);
1536
1577
  }
1537
- function Ref(...args) {
1538
- const [$ref, options] = typeof args[0] === "string" ? [args[0], args[1]] : [args[0].$id, args[1]];
1578
+ function Ref(...args2) {
1579
+ const [$ref, options] = typeof args2[0] === "string" ? [args2[0], args2[1]] : [args2[0].$id, args2[1]];
1539
1580
  if (typeof $ref !== "string")
1540
1581
  throw new TypeBoxError("Ref: $ref must be a string");
1541
1582
  return CreateType({ [Kind]: "Ref", $ref }, options);
@@ -2094,78 +2135,78 @@ function RecordKey2(type) {
2094
2135
  function RecordValue2(type) {
2095
2136
  return type.patternProperties[RecordPattern(type)];
2096
2137
  }
2097
- function FromConstructor2(args, type) {
2098
- type.parameters = FromTypes(args, type.parameters);
2099
- type.returns = FromType(args, type.returns);
2138
+ function FromConstructor2(args2, type) {
2139
+ type.parameters = FromTypes(args2, type.parameters);
2140
+ type.returns = FromType(args2, type.returns);
2100
2141
  return type;
2101
2142
  }
2102
- function FromFunction2(args, type) {
2103
- type.parameters = FromTypes(args, type.parameters);
2104
- type.returns = FromType(args, type.returns);
2143
+ function FromFunction2(args2, type) {
2144
+ type.parameters = FromTypes(args2, type.parameters);
2145
+ type.returns = FromType(args2, type.returns);
2105
2146
  return type;
2106
2147
  }
2107
- function FromIntersect5(args, type) {
2108
- type.allOf = FromTypes(args, type.allOf);
2148
+ function FromIntersect5(args2, type) {
2149
+ type.allOf = FromTypes(args2, type.allOf);
2109
2150
  return type;
2110
2151
  }
2111
- function FromUnion7(args, type) {
2112
- type.anyOf = FromTypes(args, type.anyOf);
2152
+ function FromUnion7(args2, type) {
2153
+ type.anyOf = FromTypes(args2, type.anyOf);
2113
2154
  return type;
2114
2155
  }
2115
- function FromTuple4(args, type) {
2156
+ function FromTuple4(args2, type) {
2116
2157
  if (IsUndefined(type.items))
2117
2158
  return type;
2118
- type.items = FromTypes(args, type.items);
2159
+ type.items = FromTypes(args2, type.items);
2119
2160
  return type;
2120
2161
  }
2121
- function FromArray5(args, type) {
2122
- type.items = FromType(args, type.items);
2162
+ function FromArray5(args2, type) {
2163
+ type.items = FromType(args2, type.items);
2123
2164
  return type;
2124
2165
  }
2125
- function FromAsyncIterator2(args, type) {
2126
- type.items = FromType(args, type.items);
2166
+ function FromAsyncIterator2(args2, type) {
2167
+ type.items = FromType(args2, type.items);
2127
2168
  return type;
2128
2169
  }
2129
- function FromIterator2(args, type) {
2130
- type.items = FromType(args, type.items);
2170
+ function FromIterator2(args2, type) {
2171
+ type.items = FromType(args2, type.items);
2131
2172
  return type;
2132
2173
  }
2133
- function FromPromise3(args, type) {
2134
- type.item = FromType(args, type.item);
2174
+ function FromPromise3(args2, type) {
2175
+ type.item = FromType(args2, type.item);
2135
2176
  return type;
2136
2177
  }
2137
- function FromObject2(args, type) {
2138
- const mappedProperties = FromProperties11(args, type.properties);
2178
+ function FromObject2(args2, type) {
2179
+ const mappedProperties = FromProperties11(args2, type.properties);
2139
2180
  return { ...type, ...Object2(mappedProperties) };
2140
2181
  }
2141
- function FromRecord2(args, type) {
2142
- const mappedKey = FromType(args, RecordKey2(type));
2143
- const mappedValue = FromType(args, RecordValue2(type));
2182
+ function FromRecord2(args2, type) {
2183
+ const mappedKey = FromType(args2, RecordKey2(type));
2184
+ const mappedValue = FromType(args2, RecordValue2(type));
2144
2185
  const result = Record(mappedKey, mappedValue);
2145
2186
  return { ...type, ...result };
2146
2187
  }
2147
- function FromArgument(args, argument) {
2148
- return argument.index in args ? args[argument.index] : Unknown();
2188
+ function FromArgument(args2, argument) {
2189
+ return argument.index in args2 ? args2[argument.index] : Unknown();
2149
2190
  }
2150
- function FromProperty2(args, type) {
2191
+ function FromProperty2(args2, type) {
2151
2192
  const isReadonly = IsReadonly(type);
2152
2193
  const isOptional = IsOptional(type);
2153
- const mapped = FromType(args, type);
2194
+ const mapped = FromType(args2, type);
2154
2195
  return isReadonly && isOptional ? ReadonlyOptional(mapped) : isReadonly && !isOptional ? Readonly(mapped) : !isReadonly && isOptional ? Optional(mapped) : mapped;
2155
2196
  }
2156
- function FromProperties11(args, properties) {
2197
+ function FromProperties11(args2, properties) {
2157
2198
  return globalThis.Object.getOwnPropertyNames(properties).reduce((result, key) => {
2158
- return { ...result, [key]: FromProperty2(args, properties[key]) };
2199
+ return { ...result, [key]: FromProperty2(args2, properties[key]) };
2159
2200
  }, {});
2160
2201
  }
2161
- function FromTypes(args, types) {
2162
- return types.map((type) => FromType(args, type));
2202
+ function FromTypes(args2, types) {
2203
+ return types.map((type) => FromType(args2, type));
2163
2204
  }
2164
- function FromType(args, type) {
2165
- return IsConstructor(type) ? FromConstructor2(args, type) : IsFunction2(type) ? FromFunction2(args, type) : IsIntersect(type) ? FromIntersect5(args, type) : IsUnion(type) ? FromUnion7(args, type) : IsTuple(type) ? FromTuple4(args, type) : IsArray3(type) ? FromArray5(args, type) : IsAsyncIterator2(type) ? FromAsyncIterator2(args, type) : IsIterator2(type) ? FromIterator2(args, type) : IsPromise(type) ? FromPromise3(args, type) : IsObject3(type) ? FromObject2(args, type) : IsRecord(type) ? FromRecord2(args, type) : IsArgument(type) ? FromArgument(args, type) : type;
2205
+ function FromType(args2, type) {
2206
+ return IsConstructor(type) ? FromConstructor2(args2, type) : IsFunction2(type) ? FromFunction2(args2, type) : IsIntersect(type) ? FromIntersect5(args2, type) : IsUnion(type) ? FromUnion7(args2, type) : IsTuple(type) ? FromTuple4(args2, type) : IsArray3(type) ? FromArray5(args2, type) : IsAsyncIterator2(type) ? FromAsyncIterator2(args2, type) : IsIterator2(type) ? FromIterator2(args2, type) : IsPromise(type) ? FromPromise3(args2, type) : IsObject3(type) ? FromObject2(args2, type) : IsRecord(type) ? FromRecord2(args2, type) : IsArgument(type) ? FromArgument(args2, type) : type;
2166
2207
  }
2167
- function Instantiate(type, args) {
2168
- return FromType(args, CloneType(type));
2208
+ function Instantiate(type, args2) {
2209
+ return FromType(args2, CloneType(type));
2169
2210
  }
2170
2211
  function Integer(options) {
2171
2212
  return CreateType({ [Kind]: "Integer", type: "integer" }, options);
@@ -2917,7 +2958,7 @@ function createWorkerTools(client, options) {
2917
2958
  }),
2918
2959
  createTool(WORKER_TOOLS.CREATE_FILE, async (params) => {
2919
2960
  try {
2920
- const name2 = validateStringParam(params, "name", true);
2961
+ const name = validateStringParam(params, "name", true);
2921
2962
  const description = validateStringParam(params, "description", false);
2922
2963
  const content = validateStringParam(params, "content", false);
2923
2964
  const contentFormat = validateEnumParam(
@@ -2928,7 +2969,7 @@ function createWorkerTools(client, options) {
2928
2969
  );
2929
2970
  const taskId = validateStringParam(params, "taskId", false);
2930
2971
  const result = await client.createFile({
2931
- name: name2,
2972
+ name,
2932
2973
  description,
2933
2974
  content,
2934
2975
  contentFormat,
@@ -3583,18 +3624,18 @@ function saveCursor(ctx, cursor, storagePath, log) {
3583
3624
  }
3584
3625
  }
3585
3626
  function validateField(opts) {
3586
- const { value, name: name2, minLength, maxLength, pattern, patternMessage } = opts;
3587
- if (!value) return `${name2} is required`;
3588
- if (typeof value !== "string") return `${name2} must be a string`;
3627
+ const { value, name, minLength, maxLength, pattern, patternMessage } = opts;
3628
+ if (!value) return `${name} is required`;
3629
+ if (typeof value !== "string") return `${name} must be a string`;
3589
3630
  const trimmed = value.trim();
3590
3631
  if (trimmed !== value)
3591
- return `${name2} must not have leading or trailing whitespace`;
3632
+ return `${name} must not have leading or trailing whitespace`;
3592
3633
  if (minLength !== void 0 && trimmed.length < minLength)
3593
- return `${name2} appears to be incomplete (minimum ${minLength} characters expected)`;
3634
+ return `${name} appears to be incomplete (minimum ${minLength} characters expected)`;
3594
3635
  if (maxLength !== void 0 && trimmed.length > maxLength)
3595
- return `${name2} appears to be invalid (maximum ${maxLength} characters expected)`;
3636
+ return `${name} appears to be invalid (maximum ${maxLength} characters expected)`;
3596
3637
  if (pattern !== void 0 && !pattern.test(trimmed))
3597
- return patternMessage ?? `${name2} contains invalid characters`;
3638
+ return patternMessage ?? `${name} contains invalid characters`;
3598
3639
  return null;
3599
3640
  }
3600
3641
  function isLocalDevelopmentHost(hostname2) {
@@ -3618,8 +3659,8 @@ function validateBotId(value) {
3618
3659
  if (patternError) return patternError;
3619
3660
  return null;
3620
3661
  }
3621
- function validateUrl(value, name2, allowedProtocols, protocolError) {
3622
- const fieldError = validateField({ value, name: name2 });
3662
+ function validateUrl(value, name, allowedProtocols, protocolError) {
3663
+ const fieldError = validateField({ value, name });
3623
3664
  if (fieldError) return fieldError;
3624
3665
  const trimmed = value.trim();
3625
3666
  let url;
@@ -3627,21 +3668,21 @@ function validateUrl(value, name2, allowedProtocols, protocolError) {
3627
3668
  url = new URL(trimmed);
3628
3669
  } catch (err) {
3629
3670
  const message = err instanceof Error ? err.message : "Invalid URL format";
3630
- return `${name2} must be a valid URL: ${message}`;
3671
+ return `${name} must be a valid URL: ${message}`;
3631
3672
  }
3632
3673
  if (!allowedProtocols.includes(url.protocol)) {
3633
3674
  return protocolError;
3634
3675
  }
3635
3676
  if (!url.hostname) {
3636
- return `${name2} must have a valid hostname`;
3677
+ return `${name} must have a valid hostname`;
3637
3678
  }
3638
3679
  if (isLocalDevelopmentHost(url.hostname)) {
3639
3680
  if (process.env.NODE_ENV === "production") {
3640
- return `${name2} cannot use localhost or private IP addresses in production. Please use a publicly accessible URL.`;
3681
+ return `${name} cannot use localhost or private IP addresses in production. Please use a publicly accessible URL.`;
3641
3682
  }
3642
3683
  }
3643
3684
  if (url.hostname.includes("..") || url.hostname.startsWith(".")) {
3644
- return `${name2} hostname appears to be malformed. Please check for typos.`;
3685
+ return `${name} hostname appears to be malformed. Please check for typos.`;
3645
3686
  }
3646
3687
  return null;
3647
3688
  }
@@ -3673,8 +3714,8 @@ var init_dist = __esm({
3673
3714
  return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
3674
3715
  };
3675
3716
  __export2 = (target, all) => {
3676
- for (var name2 in all)
3677
- __defProp2(target, name2, { get: all[name2], enumerable: true });
3717
+ for (var name in all)
3718
+ __defProp2(target, name, { get: all[name], enumerable: true });
3678
3719
  };
3679
3720
  __copyProps2 = (to, from, except, desc) => {
3680
3721
  if (from && typeof from === "object" || typeof from === "function") {
@@ -5712,9 +5753,9 @@ var init_dist = __esm({
5712
5753
  require_extension = __commonJS2({
5713
5754
  "../../node_modules/ws/lib/extension.js"(exports$1, module) {
5714
5755
  var { tokenChars } = require_validation();
5715
- function push(dest, name2, elem) {
5716
- if (dest[name2] === void 0) dest[name2] = [elem];
5717
- else dest[name2].push(elem);
5756
+ function push(dest, name, elem) {
5757
+ if (dest[name] === void 0) dest[name] = [elem];
5758
+ else dest[name].push(elem);
5718
5759
  }
5719
5760
  function parse(header) {
5720
5761
  const offers = /* @__PURE__ */ Object.create(null);
@@ -5724,7 +5765,7 @@ var init_dist = __esm({
5724
5765
  let inQuotes = false;
5725
5766
  let extensionName;
5726
5767
  let paramName;
5727
- let start = -1;
5768
+ let start2 = -1;
5728
5769
  let code = -1;
5729
5770
  let end = -1;
5730
5771
  let i = 0;
@@ -5732,45 +5773,45 @@ var init_dist = __esm({
5732
5773
  code = header.charCodeAt(i);
5733
5774
  if (extensionName === void 0) {
5734
5775
  if (end === -1 && tokenChars[code] === 1) {
5735
- if (start === -1) start = i;
5776
+ if (start2 === -1) start2 = i;
5736
5777
  } else if (i !== 0 && (code === 32 || code === 9)) {
5737
- if (end === -1 && start !== -1) end = i;
5778
+ if (end === -1 && start2 !== -1) end = i;
5738
5779
  } else if (code === 59 || code === 44) {
5739
- if (start === -1) {
5780
+ if (start2 === -1) {
5740
5781
  throw new SyntaxError(`Unexpected character at index ${i}`);
5741
5782
  }
5742
5783
  if (end === -1) end = i;
5743
- const name2 = header.slice(start, end);
5784
+ const name = header.slice(start2, end);
5744
5785
  if (code === 44) {
5745
- push(offers, name2, params);
5786
+ push(offers, name, params);
5746
5787
  params = /* @__PURE__ */ Object.create(null);
5747
5788
  } else {
5748
- extensionName = name2;
5789
+ extensionName = name;
5749
5790
  }
5750
- start = end = -1;
5791
+ start2 = end = -1;
5751
5792
  } else {
5752
5793
  throw new SyntaxError(`Unexpected character at index ${i}`);
5753
5794
  }
5754
5795
  } else if (paramName === void 0) {
5755
5796
  if (end === -1 && tokenChars[code] === 1) {
5756
- if (start === -1) start = i;
5797
+ if (start2 === -1) start2 = i;
5757
5798
  } else if (code === 32 || code === 9) {
5758
- if (end === -1 && start !== -1) end = i;
5799
+ if (end === -1 && start2 !== -1) end = i;
5759
5800
  } else if (code === 59 || code === 44) {
5760
- if (start === -1) {
5801
+ if (start2 === -1) {
5761
5802
  throw new SyntaxError(`Unexpected character at index ${i}`);
5762
5803
  }
5763
5804
  if (end === -1) end = i;
5764
- push(params, header.slice(start, end), true);
5805
+ push(params, header.slice(start2, end), true);
5765
5806
  if (code === 44) {
5766
5807
  push(offers, extensionName, params);
5767
5808
  params = /* @__PURE__ */ Object.create(null);
5768
5809
  extensionName = void 0;
5769
5810
  }
5770
- start = end = -1;
5771
- } else if (code === 61 && start !== -1 && end === -1) {
5772
- paramName = header.slice(start, i);
5773
- start = end = -1;
5811
+ start2 = end = -1;
5812
+ } else if (code === 61 && start2 !== -1 && end === -1) {
5813
+ paramName = header.slice(start2, i);
5814
+ start2 = end = -1;
5774
5815
  } else {
5775
5816
  throw new SyntaxError(`Unexpected character at index ${i}`);
5776
5817
  }
@@ -5779,13 +5820,13 @@ var init_dist = __esm({
5779
5820
  if (tokenChars[code] !== 1) {
5780
5821
  throw new SyntaxError(`Unexpected character at index ${i}`);
5781
5822
  }
5782
- if (start === -1) start = i;
5823
+ if (start2 === -1) start2 = i;
5783
5824
  else if (!mustUnescape) mustUnescape = true;
5784
5825
  isEscaping = false;
5785
5826
  } else if (inQuotes) {
5786
5827
  if (tokenChars[code] === 1) {
5787
- if (start === -1) start = i;
5788
- } else if (code === 34 && start !== -1) {
5828
+ if (start2 === -1) start2 = i;
5829
+ } else if (code === 34 && start2 !== -1) {
5789
5830
  inQuotes = false;
5790
5831
  end = i;
5791
5832
  } else if (code === 92) {
@@ -5796,15 +5837,15 @@ var init_dist = __esm({
5796
5837
  } else if (code === 34 && header.charCodeAt(i - 1) === 61) {
5797
5838
  inQuotes = true;
5798
5839
  } else if (end === -1 && tokenChars[code] === 1) {
5799
- if (start === -1) start = i;
5800
- } else if (start !== -1 && (code === 32 || code === 9)) {
5840
+ if (start2 === -1) start2 = i;
5841
+ } else if (start2 !== -1 && (code === 32 || code === 9)) {
5801
5842
  if (end === -1) end = i;
5802
5843
  } else if (code === 59 || code === 44) {
5803
- if (start === -1) {
5844
+ if (start2 === -1) {
5804
5845
  throw new SyntaxError(`Unexpected character at index ${i}`);
5805
5846
  }
5806
5847
  if (end === -1) end = i;
5807
- let value = header.slice(start, end);
5848
+ let value = header.slice(start2, end);
5808
5849
  if (mustUnescape) {
5809
5850
  value = value.replace(/\\/g, "");
5810
5851
  mustUnescape = false;
@@ -5816,17 +5857,17 @@ var init_dist = __esm({
5816
5857
  extensionName = void 0;
5817
5858
  }
5818
5859
  paramName = void 0;
5819
- start = end = -1;
5860
+ start2 = end = -1;
5820
5861
  } else {
5821
5862
  throw new SyntaxError(`Unexpected character at index ${i}`);
5822
5863
  }
5823
5864
  }
5824
5865
  }
5825
- if (start === -1 || inQuotes || code === 32 || code === 9) {
5866
+ if (start2 === -1 || inQuotes || code === 32 || code === 9) {
5826
5867
  throw new SyntaxError("Unexpected end of input");
5827
5868
  }
5828
5869
  if (end === -1) end = i;
5829
- const token = header.slice(start, end);
5870
+ const token = header.slice(start2, end);
5830
5871
  if (extensionName === void 0) {
5831
5872
  push(offers, token, params);
5832
5873
  } else {
@@ -6842,34 +6883,34 @@ var init_dist = __esm({
6842
6883
  var { tokenChars } = require_validation();
6843
6884
  function parse(header) {
6844
6885
  const protocols = /* @__PURE__ */ new Set();
6845
- let start = -1;
6886
+ let start2 = -1;
6846
6887
  let end = -1;
6847
6888
  let i = 0;
6848
6889
  for (i; i < header.length; i++) {
6849
6890
  const code = header.charCodeAt(i);
6850
6891
  if (end === -1 && tokenChars[code] === 1) {
6851
- if (start === -1) start = i;
6892
+ if (start2 === -1) start2 = i;
6852
6893
  } else if (i !== 0 && (code === 32 || code === 9)) {
6853
- if (end === -1 && start !== -1) end = i;
6894
+ if (end === -1 && start2 !== -1) end = i;
6854
6895
  } else if (code === 44) {
6855
- if (start === -1) {
6896
+ if (start2 === -1) {
6856
6897
  throw new SyntaxError(`Unexpected character at index ${i}`);
6857
6898
  }
6858
6899
  if (end === -1) end = i;
6859
- const protocol2 = header.slice(start, end);
6900
+ const protocol2 = header.slice(start2, end);
6860
6901
  if (protocols.has(protocol2)) {
6861
6902
  throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
6862
6903
  }
6863
6904
  protocols.add(protocol2);
6864
- start = end = -1;
6905
+ start2 = end = -1;
6865
6906
  } else {
6866
6907
  throw new SyntaxError(`Unexpected character at index ${i}`);
6867
6908
  }
6868
6909
  }
6869
- if (start === -1 || end !== -1) {
6910
+ if (start2 === -1 || end !== -1) {
6870
6911
  throw new SyntaxError("Unexpected end of input");
6871
6912
  }
6872
- const protocol = header.slice(start, i);
6913
+ const protocol = header.slice(start2, i);
6873
6914
  if (protocols.has(protocol)) {
6874
6915
  throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
6875
6916
  }
@@ -7455,14 +7496,14 @@ var init_dist = __esm({
7455
7496
  * Validates that a string parameter is non-empty.
7456
7497
  * Catches invalid inputs before they hit the network.
7457
7498
  */
7458
- requireNonEmpty(value, name2, caller) {
7499
+ requireNonEmpty(value, name, caller) {
7459
7500
  if (!value || value.trim() === "") {
7460
7501
  const ctx = caller ? ` (in ${caller})` : "";
7461
7502
  throw new DeskFreeError(
7462
7503
  "client",
7463
- name2,
7464
- `${name2} is required and cannot be empty${ctx}`,
7465
- `Missing required parameter: ${name2}. Please provide a valid value.`
7504
+ name,
7505
+ `${name} is required and cannot be empty${ctx}`,
7506
+ `Missing required parameter: ${name}. Please provide a valid value.`
7466
7507
  );
7467
7508
  }
7468
7509
  }
@@ -8785,18 +8826,8 @@ var init_config = __esm({
8785
8826
  init_dist();
8786
8827
  isDocker = process.env["DOCKER"] === "1" || existsSync("/.dockerenv");
8787
8828
  DEFAULTS = {
8788
- stateDir: isDocker ? "/app/state" : join(
8789
- homedir(),
8790
- ".deskfree",
8791
- process.env["DESKFREE_INSTANCE_NAME"] ?? "main",
8792
- "state"
8793
- ),
8794
- toolsDir: isDocker ? "/app/tools" : join(
8795
- homedir(),
8796
- ".deskfree",
8797
- process.env["DESKFREE_INSTANCE_NAME"] ?? "main",
8798
- "tools"
8799
- ),
8829
+ stateDir: isDocker ? "/app/state" : join(homedir(), ".deskfree", process.env["BOT"] ?? "default", "state"),
8830
+ toolsDir: isDocker ? "/app/tools" : join(homedir(), ".deskfree", process.env["BOT"] ?? "default", "tools"),
8800
8831
  logLevel: "info",
8801
8832
  healthPort: 3100
8802
8833
  };
@@ -11048,9 +11079,9 @@ var require_event_target2 = __commonJS({
11048
11079
  var require_extension2 = __commonJS({
11049
11080
  "../../node_modules/ws/lib/extension.js"(exports$1, module) {
11050
11081
  var { tokenChars } = require_validation2();
11051
- function push(dest, name2, elem) {
11052
- if (dest[name2] === void 0) dest[name2] = [elem];
11053
- else dest[name2].push(elem);
11082
+ function push(dest, name, elem) {
11083
+ if (dest[name] === void 0) dest[name] = [elem];
11084
+ else dest[name].push(elem);
11054
11085
  }
11055
11086
  function parse(header) {
11056
11087
  const offers = /* @__PURE__ */ Object.create(null);
@@ -11060,7 +11091,7 @@ var require_extension2 = __commonJS({
11060
11091
  let inQuotes = false;
11061
11092
  let extensionName;
11062
11093
  let paramName;
11063
- let start = -1;
11094
+ let start2 = -1;
11064
11095
  let code = -1;
11065
11096
  let end = -1;
11066
11097
  let i = 0;
@@ -11068,45 +11099,45 @@ var require_extension2 = __commonJS({
11068
11099
  code = header.charCodeAt(i);
11069
11100
  if (extensionName === void 0) {
11070
11101
  if (end === -1 && tokenChars[code] === 1) {
11071
- if (start === -1) start = i;
11102
+ if (start2 === -1) start2 = i;
11072
11103
  } else if (i !== 0 && (code === 32 || code === 9)) {
11073
- if (end === -1 && start !== -1) end = i;
11104
+ if (end === -1 && start2 !== -1) end = i;
11074
11105
  } else if (code === 59 || code === 44) {
11075
- if (start === -1) {
11106
+ if (start2 === -1) {
11076
11107
  throw new SyntaxError(`Unexpected character at index ${i}`);
11077
11108
  }
11078
11109
  if (end === -1) end = i;
11079
- const name2 = header.slice(start, end);
11110
+ const name = header.slice(start2, end);
11080
11111
  if (code === 44) {
11081
- push(offers, name2, params);
11112
+ push(offers, name, params);
11082
11113
  params = /* @__PURE__ */ Object.create(null);
11083
11114
  } else {
11084
- extensionName = name2;
11115
+ extensionName = name;
11085
11116
  }
11086
- start = end = -1;
11117
+ start2 = end = -1;
11087
11118
  } else {
11088
11119
  throw new SyntaxError(`Unexpected character at index ${i}`);
11089
11120
  }
11090
11121
  } else if (paramName === void 0) {
11091
11122
  if (end === -1 && tokenChars[code] === 1) {
11092
- if (start === -1) start = i;
11123
+ if (start2 === -1) start2 = i;
11093
11124
  } else if (code === 32 || code === 9) {
11094
- if (end === -1 && start !== -1) end = i;
11125
+ if (end === -1 && start2 !== -1) end = i;
11095
11126
  } else if (code === 59 || code === 44) {
11096
- if (start === -1) {
11127
+ if (start2 === -1) {
11097
11128
  throw new SyntaxError(`Unexpected character at index ${i}`);
11098
11129
  }
11099
11130
  if (end === -1) end = i;
11100
- push(params, header.slice(start, end), true);
11131
+ push(params, header.slice(start2, end), true);
11101
11132
  if (code === 44) {
11102
11133
  push(offers, extensionName, params);
11103
11134
  params = /* @__PURE__ */ Object.create(null);
11104
11135
  extensionName = void 0;
11105
11136
  }
11106
- start = end = -1;
11107
- } else if (code === 61 && start !== -1 && end === -1) {
11108
- paramName = header.slice(start, i);
11109
- start = end = -1;
11137
+ start2 = end = -1;
11138
+ } else if (code === 61 && start2 !== -1 && end === -1) {
11139
+ paramName = header.slice(start2, i);
11140
+ start2 = end = -1;
11110
11141
  } else {
11111
11142
  throw new SyntaxError(`Unexpected character at index ${i}`);
11112
11143
  }
@@ -11115,13 +11146,13 @@ var require_extension2 = __commonJS({
11115
11146
  if (tokenChars[code] !== 1) {
11116
11147
  throw new SyntaxError(`Unexpected character at index ${i}`);
11117
11148
  }
11118
- if (start === -1) start = i;
11149
+ if (start2 === -1) start2 = i;
11119
11150
  else if (!mustUnescape) mustUnescape = true;
11120
11151
  isEscaping = false;
11121
11152
  } else if (inQuotes) {
11122
11153
  if (tokenChars[code] === 1) {
11123
- if (start === -1) start = i;
11124
- } else if (code === 34 && start !== -1) {
11154
+ if (start2 === -1) start2 = i;
11155
+ } else if (code === 34 && start2 !== -1) {
11125
11156
  inQuotes = false;
11126
11157
  end = i;
11127
11158
  } else if (code === 92) {
@@ -11132,15 +11163,15 @@ var require_extension2 = __commonJS({
11132
11163
  } else if (code === 34 && header.charCodeAt(i - 1) === 61) {
11133
11164
  inQuotes = true;
11134
11165
  } else if (end === -1 && tokenChars[code] === 1) {
11135
- if (start === -1) start = i;
11136
- } else if (start !== -1 && (code === 32 || code === 9)) {
11166
+ if (start2 === -1) start2 = i;
11167
+ } else if (start2 !== -1 && (code === 32 || code === 9)) {
11137
11168
  if (end === -1) end = i;
11138
11169
  } else if (code === 59 || code === 44) {
11139
- if (start === -1) {
11170
+ if (start2 === -1) {
11140
11171
  throw new SyntaxError(`Unexpected character at index ${i}`);
11141
11172
  }
11142
11173
  if (end === -1) end = i;
11143
- let value = header.slice(start, end);
11174
+ let value = header.slice(start2, end);
11144
11175
  if (mustUnescape) {
11145
11176
  value = value.replace(/\\/g, "");
11146
11177
  mustUnescape = false;
@@ -11152,17 +11183,17 @@ var require_extension2 = __commonJS({
11152
11183
  extensionName = void 0;
11153
11184
  }
11154
11185
  paramName = void 0;
11155
- start = end = -1;
11186
+ start2 = end = -1;
11156
11187
  } else {
11157
11188
  throw new SyntaxError(`Unexpected character at index ${i}`);
11158
11189
  }
11159
11190
  }
11160
11191
  }
11161
- if (start === -1 || inQuotes || code === 32 || code === 9) {
11192
+ if (start2 === -1 || inQuotes || code === 32 || code === 9) {
11162
11193
  throw new SyntaxError("Unexpected end of input");
11163
11194
  }
11164
11195
  if (end === -1) end = i;
11165
- const token = header.slice(start, end);
11196
+ const token = header.slice(start2, end);
11166
11197
  if (extensionName === void 0) {
11167
11198
  push(offers, token, params);
11168
11199
  } else {
@@ -12184,34 +12215,34 @@ var require_subprotocol2 = __commonJS({
12184
12215
  var { tokenChars } = require_validation2();
12185
12216
  function parse(header) {
12186
12217
  const protocols = /* @__PURE__ */ new Set();
12187
- let start = -1;
12218
+ let start2 = -1;
12188
12219
  let end = -1;
12189
12220
  let i = 0;
12190
12221
  for (i; i < header.length; i++) {
12191
12222
  const code = header.charCodeAt(i);
12192
12223
  if (end === -1 && tokenChars[code] === 1) {
12193
- if (start === -1) start = i;
12224
+ if (start2 === -1) start2 = i;
12194
12225
  } else if (i !== 0 && (code === 32 || code === 9)) {
12195
- if (end === -1 && start !== -1) end = i;
12226
+ if (end === -1 && start2 !== -1) end = i;
12196
12227
  } else if (code === 44) {
12197
- if (start === -1) {
12228
+ if (start2 === -1) {
12198
12229
  throw new SyntaxError(`Unexpected character at index ${i}`);
12199
12230
  }
12200
12231
  if (end === -1) end = i;
12201
- const protocol2 = header.slice(start, end);
12232
+ const protocol2 = header.slice(start2, end);
12202
12233
  if (protocols.has(protocol2)) {
12203
12234
  throw new SyntaxError(`The "${protocol2}" subprotocol is duplicated`);
12204
12235
  }
12205
12236
  protocols.add(protocol2);
12206
- start = end = -1;
12237
+ start2 = end = -1;
12207
12238
  } else {
12208
12239
  throw new SyntaxError(`Unexpected character at index ${i}`);
12209
12240
  }
12210
12241
  }
12211
- if (start === -1 || end !== -1) {
12242
+ if (start2 === -1 || end !== -1) {
12212
12243
  throw new SyntaxError("Unexpected end of input");
12213
12244
  }
12214
- const protocol = header.slice(start, i);
12245
+ const protocol = header.slice(start2, i);
12215
12246
  if (protocols.has(protocol)) {
12216
12247
  throw new SyntaxError(`The "${protocol}" subprotocol is duplicated`);
12217
12248
  }
@@ -13249,9 +13280,9 @@ function adaptTool(deskfreeTool) {
13249
13280
  deskfreeTool.name,
13250
13281
  deskfreeTool.description,
13251
13282
  zodShape,
13252
- async (args) => {
13283
+ async (args2) => {
13253
13284
  const result = await deskfreeTool.execute(
13254
- args
13285
+ args2
13255
13286
  );
13256
13287
  return {
13257
13288
  content: result.content,
@@ -13350,15 +13381,15 @@ function containsInjectionPattern(content) {
13350
13381
  return INJECTION_PATTERNS.some((pattern) => pattern.test(content));
13351
13382
  }
13352
13383
  function withContentScan(execute, extractContent, scanner) {
13353
- return async (args) => {
13354
- const content = extractContent(args);
13384
+ return async (args2) => {
13385
+ const content = extractContent(args2);
13355
13386
  if (content) {
13356
13387
  const result = await scanner.scan(content);
13357
13388
  if (!result.safe) {
13358
13389
  return `Security check failed: ${result.reason ?? "content rejected"}. File not updated.`;
13359
13390
  }
13360
13391
  }
13361
- return execute(args);
13392
+ return execute(args2);
13362
13393
  };
13363
13394
  }
13364
13395
  function validateDownloadUrl(url) {
@@ -13488,7 +13519,7 @@ function createWorkerMcpServer(client, customTools = [], contentScanner) {
13488
13519
  if ((t.name === "deskfree_update_file" || t.name === "deskfree_create_file") && contentScanner) {
13489
13520
  const wrappedExecute = withContentScan(
13490
13521
  t.execute,
13491
- (args) => typeof args["content"] === "string" ? args["content"] : null,
13522
+ (args2) => typeof args2["content"] === "string" ? args2["content"] : null,
13492
13523
  contentScanner
13493
13524
  );
13494
13525
  return {
@@ -13818,17 +13849,17 @@ async function buildContextualPrompt(message, task, mediaPaths, log) {
13818
13849
  const imageBlocks = [];
13819
13850
  for (const filePath of mediaPaths) {
13820
13851
  const ext = extname(filePath).toLowerCase();
13821
- const name2 = basename(filePath);
13852
+ const name = basename(filePath);
13822
13853
  try {
13823
13854
  if (TEXT_EXTENSIONS.has(ext)) {
13824
13855
  const buf = await readFile(filePath);
13825
13856
  if (buf.length <= MAX_INLINE_TEXT_SIZE) {
13826
13857
  attachmentTexts.push(
13827
- `<attachment name="${name2}">${buf.toString("utf-8")}</attachment>`
13858
+ `<attachment name="${name}">${buf.toString("utf-8")}</attachment>`
13828
13859
  );
13829
13860
  } else {
13830
13861
  attachmentTexts.push(
13831
- `<attachment name="${name2}">[File too large to inline: ${buf.length} bytes]</attachment>`
13862
+ `<attachment name="${name}">[File too large to inline: ${buf.length} bytes]</attachment>`
13832
13863
  );
13833
13864
  }
13834
13865
  } else if (IMAGE_EXTENSIONS.has(ext)) {
@@ -13843,7 +13874,7 @@ async function buildContextualPrompt(message, task, mediaPaths, log) {
13843
13874
  });
13844
13875
  } else {
13845
13876
  attachmentTexts.push(
13846
- `<attachment name="${name2}" contentType="${ext}">File attached but content not previewable inline.</attachment>`
13877
+ `<attachment name="${name}" contentType="${ext}">File attached but content not previewable inline.</attachment>`
13847
13878
  );
13848
13879
  }
13849
13880
  } catch (err) {
@@ -15006,7 +15037,7 @@ async function startAgent(opts) {
15006
15037
  log.info("DeskFree Agent Runtime starting...");
15007
15038
  const { getRotationToken: getRotationToken2, setInitialRotationToken: setInitialRotationToken2 } = await Promise.resolve().then(() => (init_ws_gateway(), ws_gateway_exports));
15008
15039
  const { collectFingerprint: collectFingerprint2 } = await Promise.resolve().then(() => (init_fingerprint(), fingerprint_exports));
15009
- const runtimeVersion = "0.6.10";
15040
+ const runtimeVersion = "0.7.1";
15010
15041
  const fingerprint = collectFingerprint2(localConfig.stateDir, runtimeVersion);
15011
15042
  log.info("Connecting to DeskFree...", { wsUrl: localConfig.wsUrl });
15012
15043
  const connectResult = await initialConnect({
@@ -15051,7 +15082,7 @@ async function startAgent(opts) {
15051
15082
  runtimeVersion,
15052
15083
  maxConcurrentWorkers: 5,
15053
15084
  // updated after WorkerManager is created
15054
- instanceName: process.env["DESKFREE_INSTANCE_NAME"] || void 0
15085
+ instanceName: process.env["BOT"] || void 0
15055
15086
  };
15056
15087
  mkdirSync(config.stateDir, { recursive: true });
15057
15088
  mkdirSync(config.toolsDir, { recursive: true });
@@ -15352,60 +15383,55 @@ var init_entrypoint = __esm({
15352
15383
  });
15353
15384
 
15354
15385
  // src/bin.ts
15355
- init_paths();
15356
- var [name, cleanArgs] = parseName(process.argv.slice(2));
15357
- var command = cleanArgs[0];
15358
- if (command === "install") {
15359
- const stageIdx = cleanArgs.indexOf("--stage");
15360
- let stage;
15361
- let installArgs = cleanArgs.slice(1);
15362
- if (stageIdx !== -1) {
15363
- stage = cleanArgs[stageIdx + 1];
15364
- if (!stage || stage.startsWith("-")) {
15365
- console.error("Error: --stage requires a value (e.g. --stage charlie)");
15366
- process.exit(1);
15367
- }
15368
- installArgs = installArgs.filter(
15369
- (_, i) => i !== stageIdx - 1 && i !== stageIdx
15370
- );
15371
- }
15372
- let botId = installArgs[0];
15373
- if (!botId) {
15374
- const { createInterface } = await import('readline');
15375
- const rl = createInterface({
15376
- input: process.stdin,
15377
- output: process.stdout
15378
- });
15379
- botId = await new Promise((resolve) => {
15380
- rl.question(
15381
- "Paste your bot ID (from the DeskFree dashboard):\n> ",
15382
- (answer) => {
15383
- rl.close();
15384
- resolve(answer.trim());
15385
- }
15386
- );
15387
- });
15388
- if (!botId) {
15389
- console.error("No bot ID provided.");
15390
- process.exit(1);
15391
- }
15386
+ var args = process.argv.slice(2);
15387
+ var command = args[0];
15388
+ function requireBotId(args2) {
15389
+ for (const arg of args2) {
15390
+ if (!arg.startsWith("-") && /^B[A-Z0-9]+$/i.test(arg)) return arg;
15391
+ }
15392
+ console.error(
15393
+ "Error: bot ID required.\n\nUsage: deskfree <command> <botId>\n\nExample:\n deskfree start BABCDE12345"
15394
+ );
15395
+ process.exit(1);
15396
+ }
15397
+ function parseStage(args2) {
15398
+ const idx = args2.indexOf("--stage");
15399
+ if (idx === -1) return void 0;
15400
+ const stage = args2[idx + 1];
15401
+ if (!stage || stage.startsWith("-")) {
15402
+ console.error("Error: --stage requires a value (e.g. --stage charlie)");
15403
+ process.exit(1);
15392
15404
  }
15393
- const { install: install2 } = await Promise.resolve().then(() => (init_install(), install_exports));
15394
- install2(botId, name, stage);
15405
+ return stage;
15406
+ }
15407
+ if (command === "start") {
15408
+ const cmdArgs = args.slice(1);
15409
+ const botId = requireBotId(cmdArgs);
15410
+ const stage = parseStage(cmdArgs);
15411
+ const { start: start2 } = await Promise.resolve().then(() => (init_start(), start_exports));
15412
+ start2(botId, stage);
15413
+ } else if (command === "stop") {
15414
+ const botId = requireBotId(args.slice(1));
15415
+ const { stop: stop2 } = await Promise.resolve().then(() => (init_stop(), stop_exports));
15416
+ stop2(botId);
15395
15417
  } else if (command === "uninstall") {
15418
+ const botId = requireBotId(args.slice(1));
15396
15419
  const { uninstall: uninstall2 } = await Promise.resolve().then(() => (init_uninstall(), uninstall_exports));
15397
- uninstall2(name);
15420
+ uninstall2(botId);
15398
15421
  } else if (command === "status") {
15422
+ const botId = requireBotId(args.slice(1));
15399
15423
  const { status: status2 } = await Promise.resolve().then(() => (init_status(), status_exports));
15400
- status2(name);
15424
+ status2(botId);
15401
15425
  } else if (command === "restart") {
15426
+ const botId = requireBotId(args.slice(1));
15402
15427
  const { restart: restart2 } = await Promise.resolve().then(() => (init_restart(), restart_exports));
15403
- restart2(name);
15428
+ restart2(botId);
15404
15429
  } else if (command === "logs") {
15405
- const follow = cleanArgs.includes("-f") || cleanArgs.includes("--follow");
15430
+ const botId = requireBotId(args.slice(1));
15431
+ const follow = args.includes("-f") || args.includes("--follow");
15406
15432
  const { logs: logs2 } = await Promise.resolve().then(() => (init_logs(), logs_exports));
15407
- logs2(follow, name);
15408
- } else {
15433
+ logs2(follow, botId);
15434
+ } else if (command === "run") {
15409
15435
  let handleShutdown = function(signal) {
15410
15436
  log.info(`Received ${signal} \u2014 shutting down...`);
15411
15437
  if (dispose) {
@@ -15417,12 +15443,20 @@ if (command === "install") {
15417
15443
  process.exit(1);
15418
15444
  }, 5e3).unref();
15419
15445
  };
15420
- const startArgs = command === "start" ? cleanArgs.slice(1) : cleanArgs;
15421
- if (startArgs.length >= 2) {
15422
- process.env["STAGE"] = startArgs[0];
15423
- process.env["BOT"] = startArgs[1];
15424
- } else if (startArgs.length === 1) {
15425
- process.env["BOT"] = startArgs[0];
15446
+ const runArgs = args.slice(1);
15447
+ const stage = parseStage(runArgs);
15448
+ const positionals = runArgs.filter((a) => !a.startsWith("-") && a !== stage);
15449
+ if (positionals.length >= 2) {
15450
+ process.env["STAGE"] = positionals[0];
15451
+ process.env["BOT"] = positionals[1];
15452
+ } else if (positionals.length === 1) {
15453
+ process.env["BOT"] = positionals[0];
15454
+ if (stage) process.env["STAGE"] = stage;
15455
+ } else {
15456
+ console.error(
15457
+ "Error: bot ID required.\n\nUsage: deskfree run <botId> [--stage <stage>]"
15458
+ );
15459
+ process.exit(1);
15426
15460
  }
15427
15461
  const { startAgent: startAgent2 } = await Promise.resolve().then(() => (init_entrypoint(), entrypoint_exports));
15428
15462
  const { createLogger: createLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
@@ -15447,6 +15481,99 @@ if (command === "install") {
15447
15481
  log.error(`Fatal: failed to start agent: ${msg}`);
15448
15482
  process.exit(1);
15449
15483
  });
15484
+ } else {
15485
+ if (args.length >= 2 && args[0] && !args[0].startsWith("-")) {
15486
+ let handleShutdown = function(signal) {
15487
+ log.info(`Received ${signal} \u2014 shutting down...`);
15488
+ if (dispose) {
15489
+ dispose();
15490
+ dispose = null;
15491
+ }
15492
+ setTimeout(() => {
15493
+ log.warn("Cleanup timeout \u2014 forcing exit");
15494
+ process.exit(1);
15495
+ }, 5e3).unref();
15496
+ };
15497
+ process.env["STAGE"] = args[0];
15498
+ process.env["BOT"] = args[1];
15499
+ const { startAgent: startAgent2 } = await Promise.resolve().then(() => (init_entrypoint(), entrypoint_exports));
15500
+ const { createLogger: createLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
15501
+ const log = createLogger2("bin");
15502
+ let dispose = null;
15503
+ process.on("SIGTERM", () => handleShutdown("SIGTERM"));
15504
+ process.on("SIGINT", () => handleShutdown("SIGINT"));
15505
+ process.on("uncaughtException", (err) => {
15506
+ log.error(`Uncaught exception: ${err.message}`);
15507
+ log.error(err.stack ?? "");
15508
+ process.exit(1);
15509
+ });
15510
+ process.on("unhandledRejection", (reason) => {
15511
+ const msg = reason instanceof Error ? reason.message : String(reason);
15512
+ log.error(`Unhandled rejection: ${msg}`);
15513
+ process.exit(1);
15514
+ });
15515
+ startAgent2({ log }).then((d) => {
15516
+ dispose = d;
15517
+ }).catch((err) => {
15518
+ const msg = err instanceof Error ? err.message : String(err);
15519
+ log.error(`Fatal: failed to start agent: ${msg}`);
15520
+ process.exit(1);
15521
+ });
15522
+ } else if (process.env["BOT"]) {
15523
+ let handleShutdown = function(signal) {
15524
+ log.info(`Received ${signal} \u2014 shutting down...`);
15525
+ if (dispose) {
15526
+ dispose();
15527
+ dispose = null;
15528
+ }
15529
+ setTimeout(() => {
15530
+ log.warn("Cleanup timeout \u2014 forcing exit");
15531
+ process.exit(1);
15532
+ }, 5e3).unref();
15533
+ };
15534
+ const { startAgent: startAgent2 } = await Promise.resolve().then(() => (init_entrypoint(), entrypoint_exports));
15535
+ const { createLogger: createLogger2 } = await Promise.resolve().then(() => (init_logger(), logger_exports));
15536
+ const log = createLogger2("bin");
15537
+ let dispose = null;
15538
+ process.on("SIGTERM", () => handleShutdown("SIGTERM"));
15539
+ process.on("SIGINT", () => handleShutdown("SIGINT"));
15540
+ process.on("uncaughtException", (err) => {
15541
+ log.error(`Uncaught exception: ${err.message}`);
15542
+ log.error(err.stack ?? "");
15543
+ process.exit(1);
15544
+ });
15545
+ process.on("unhandledRejection", (reason) => {
15546
+ const msg = reason instanceof Error ? reason.message : String(reason);
15547
+ log.error(`Unhandled rejection: ${msg}`);
15548
+ process.exit(1);
15549
+ });
15550
+ startAgent2({ log }).then((d) => {
15551
+ dispose = d;
15552
+ }).catch((err) => {
15553
+ const msg = err instanceof Error ? err.message : String(err);
15554
+ log.error(`Fatal: failed to start agent: ${msg}`);
15555
+ process.exit(1);
15556
+ });
15557
+ } else {
15558
+ console.log(`DeskFree Agent CLI
15559
+
15560
+ Usage: deskfree <command> <botId> [options]
15561
+
15562
+ Commands:
15563
+ start <botId> [--stage <stage>] Install as service and start
15564
+ stop <botId> Stop the service
15565
+ restart <botId> Restart the service
15566
+ status <botId> Check service status
15567
+ logs <botId> [-f] View logs
15568
+ uninstall <botId> Remove the service
15569
+ run <botId> [--stage <stage>] Run in foreground (no service)
15570
+
15571
+ Examples:
15572
+ deskfree start BABCDE12345
15573
+ deskfree start BABCDE12345 --stage charlie
15574
+ deskfree stop BABCDE12345
15575
+ deskfree logs BABCDE12345 -f`);
15576
+ }
15450
15577
  }
15451
15578
  //# sourceMappingURL=bin.js.map
15452
15579
  //# sourceMappingURL=bin.js.map