botapp-cli 0.2.2 → 0.2.3

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/index.js CHANGED
@@ -1602,7 +1602,7 @@ Invalid ACP stdout: ${line}`;
1602
1602
  clientInfo: {
1603
1603
  name: "botapp-daemon",
1604
1604
  title: "botapp daemon",
1605
- version: "0.2.2"
1605
+ version: "0.2.3"
1606
1606
  }
1607
1607
  });
1608
1608
  const session = await request2("session/new", {
@@ -1753,9 +1753,9 @@ async function waitForChild(child, timeoutMs, label) {
1753
1753
  // src/commands/launch.ts
1754
1754
  import { Command as Command4 } from "commander";
1755
1755
  import { spawn as spawn4 } from "child_process";
1756
- import { resolve as resolve4, join as join4 } from "path";
1757
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, openSync, unlinkSync, writeFileSync as writeFileSync3, readFileSync as readFileSync4 } from "fs";
1758
- import { homedir as homedir4 } from "os";
1756
+ import { resolve as resolve4, join as join5 } from "path";
1757
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, openSync, writeFileSync as writeFileSync3 } from "fs";
1758
+ import { homedir as homedir5 } from "os";
1759
1759
  import { createInterface as createInterface3 } from "readline";
1760
1760
  import { hostname } from "os";
1761
1761
  import pc5 from "picocolors";
@@ -2022,6 +2022,41 @@ function openUrl(url) {
2022
2022
  }
2023
2023
  }
2024
2024
 
2025
+ // src/commands/daemon-supervisor.ts
2026
+ import { existsSync as existsSync5, readFileSync as readFileSync4, unlinkSync } from "fs";
2027
+ import { homedir as homedir4 } from "os";
2028
+ import { join as join4 } from "path";
2029
+ function daemonPidFile() {
2030
+ return join4(homedir4(), ".botapp", "daemon.pid");
2031
+ }
2032
+ function isDaemonRunningLocally(pidFile = daemonPidFile()) {
2033
+ if (!existsSync5(pidFile)) return false;
2034
+ try {
2035
+ const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2036
+ if (!Number.isInteger(pid) || pid <= 0) return false;
2037
+ process.kill(pid, 0);
2038
+ return true;
2039
+ } catch {
2040
+ return false;
2041
+ }
2042
+ }
2043
+ function stopExistingDaemon(pidFile = daemonPidFile()) {
2044
+ try {
2045
+ const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2046
+ if (Number.isInteger(pid) && pid > 0) {
2047
+ try {
2048
+ process.kill(pid, "SIGTERM");
2049
+ } catch {
2050
+ }
2051
+ }
2052
+ } catch {
2053
+ }
2054
+ try {
2055
+ unlinkSync(pidFile);
2056
+ } catch {
2057
+ }
2058
+ }
2059
+
2025
2060
  // src/commands/launch.ts
2026
2061
  var DEFAULT_SERVER_URL = "https://api.botapp.ai";
2027
2062
  var DEFAULT_APP_URL = "https://botapp.ai";
@@ -2163,15 +2198,15 @@ async function autoStartDaemon(opts, serverUrl, daemonId) {
2163
2198
  Next: run \`bot daemon run\` to bring this machine online.`));
2164
2199
  return;
2165
2200
  }
2166
- const dir = join4(homedir4(), ".botapp");
2167
- const pidFile = join4(dir, "daemon.pid");
2168
- const logFile = join4(dir, "daemon.log");
2201
+ const dir = join5(homedir5(), ".botapp");
2202
+ const pidFile = join5(dir, "daemon.pid");
2203
+ const logFile = join5(dir, "daemon.log");
2169
2204
  mkdirSync3(dir, { recursive: true });
2170
2205
  if (isDaemonRunningLocally(pidFile)) {
2171
2206
  stopExistingDaemon(pidFile);
2172
2207
  }
2173
2208
  const botBin = process.argv[1];
2174
- if (!botBin || !existsSync5(botBin)) {
2209
+ if (!botBin || !existsSync6(botBin)) {
2175
2210
  console.log(pc5.yellow(` Running: cannot resolve \`bot\` binary \u2014 run \`bot daemon run\` manually`));
2176
2211
  return;
2177
2212
  }
@@ -2203,33 +2238,6 @@ Next: run \`bot daemon run\` to bring this machine online.`));
2203
2238
  );
2204
2239
  }
2205
2240
  }
2206
- function isDaemonRunningLocally(pidFile) {
2207
- if (!existsSync5(pidFile)) return false;
2208
- try {
2209
- const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2210
- if (!Number.isInteger(pid) || pid <= 0) return false;
2211
- process.kill(pid, 0);
2212
- return true;
2213
- } catch {
2214
- return false;
2215
- }
2216
- }
2217
- function stopExistingDaemon(pidFile) {
2218
- try {
2219
- const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2220
- if (Number.isInteger(pid) && pid > 0) {
2221
- try {
2222
- process.kill(pid, "SIGTERM");
2223
- } catch {
2224
- }
2225
- }
2226
- } catch {
2227
- }
2228
- try {
2229
- unlinkSync(pidFile);
2230
- } catch {
2231
- }
2232
- }
2233
2241
  async function isDaemonOnline(serverUrl, daemonId) {
2234
2242
  try {
2235
2243
  const res = await fetch(`${serverUrl}/api/daemons`, {
@@ -2330,7 +2338,7 @@ function findServerEntry2() {
2330
2338
  resolve4(process.cwd(), "../../packages/server/src/index.ts")
2331
2339
  ];
2332
2340
  for (const c of candidates) {
2333
- if (existsSync5(c)) return c;
2341
+ if (existsSync6(c)) return c;
2334
2342
  }
2335
2343
  return null;
2336
2344
  }
@@ -2533,20 +2541,20 @@ var loginCommand = new Command7("login").description("Login to a botapp server")
2533
2541
  // src/commands/install.ts
2534
2542
  import { Command as Command8 } from "commander";
2535
2543
  import { resolve as resolve5, basename } from "path";
2536
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, symlinkSync, cpSync, readFileSync as readFileSync5 } from "fs";
2537
- import { homedir as homedir5 } from "os";
2538
- import { join as join5 } from "path";
2544
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, symlinkSync, cpSync, readFileSync as readFileSync5 } from "fs";
2545
+ import { homedir as homedir6 } from "os";
2546
+ import { join as join6 } from "path";
2539
2547
  import pc9 from "picocolors";
2540
- var APPS_DIR = join5(homedir5(), ".botapp", "apps");
2548
+ var APPS_DIR = join6(homedir6(), ".botapp", "apps");
2541
2549
  var installCommand = new Command8("install").description("Install an app from a local path").argument("<path>", "Path to the app directory").option("--dev", "Install in dev mode (symlink)").action(async (appPath, opts) => {
2542
2550
  const absPath = resolve5(appPath);
2543
- if (!existsSync6(absPath)) {
2551
+ if (!existsSync7(absPath)) {
2544
2552
  console.error(pc9.red(`Path not found: ${absPath}`));
2545
2553
  process.exitCode = 1;
2546
2554
  return;
2547
2555
  }
2548
- const manifestPath = join5(absPath, "botapp.app.json");
2549
- if (!existsSync6(manifestPath)) {
2556
+ const manifestPath = join6(absPath, "botapp.app.json");
2557
+ if (!existsSync7(manifestPath)) {
2550
2558
  console.error(pc9.red(`No botapp.app.json found in ${absPath}`));
2551
2559
  process.exitCode = 1;
2552
2560
  return;
@@ -2560,9 +2568,9 @@ var installCommand = new Command8("install").description("Install an app from a
2560
2568
  return;
2561
2569
  }
2562
2570
  const appName = manifest.name || basename(absPath);
2563
- const targetDir = join5(APPS_DIR, appName);
2571
+ const targetDir = join6(APPS_DIR, appName);
2564
2572
  mkdirSync4(APPS_DIR, { recursive: true });
2565
- if (existsSync6(targetDir)) {
2573
+ if (existsSync7(targetDir)) {
2566
2574
  console.log(pc9.yellow(`App "${appName}" is already installed. Reinstalling...`));
2567
2575
  const { rmSync: rmSync2 } = await import("fs");
2568
2576
  rmSync2(targetDir, { recursive: true, force: true });
@@ -2581,14 +2589,14 @@ var installCommand = new Command8("install").description("Install an app from a
2581
2589
 
2582
2590
  // src/commands/uninstall.ts
2583
2591
  import { Command as Command9 } from "commander";
2584
- import { existsSync as existsSync7, rmSync } from "fs";
2585
- import { homedir as homedir6 } from "os";
2586
- import { join as join6 } from "path";
2592
+ import { existsSync as existsSync8, rmSync } from "fs";
2593
+ import { homedir as homedir7 } from "os";
2594
+ import { join as join7 } from "path";
2587
2595
  import pc10 from "picocolors";
2588
- var APPS_DIR2 = join6(homedir6(), ".botapp", "apps");
2596
+ var APPS_DIR2 = join7(homedir7(), ".botapp", "apps");
2589
2597
  var uninstallCommand = new Command9("uninstall").description("Uninstall an app").argument("<name>", "App name to uninstall").action(async (name) => {
2590
- const targetDir = join6(APPS_DIR2, name);
2591
- if (!existsSync7(targetDir)) {
2598
+ const targetDir = join7(APPS_DIR2, name);
2599
+ if (!existsSync8(targetDir)) {
2592
2600
  console.error(pc10.red(`App "${name}" is not installed`));
2593
2601
  process.exitCode = 1;
2594
2602
  return;
@@ -2600,21 +2608,21 @@ var uninstallCommand = new Command9("uninstall").description("Uninstall an app")
2600
2608
 
2601
2609
  // src/commands/dev.ts
2602
2610
  import { Command as Command10 } from "commander";
2603
- import { resolve as resolve6, basename as basename2, join as join7 } from "path";
2604
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, symlinkSync as symlinkSync2, readFileSync as readFileSync6, lstatSync } from "fs";
2605
- import { homedir as homedir7 } from "os";
2611
+ import { resolve as resolve6, basename as basename2, join as join8 } from "path";
2612
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, symlinkSync as symlinkSync2, readFileSync as readFileSync6, lstatSync } from "fs";
2613
+ import { homedir as homedir8 } from "os";
2606
2614
  import { spawn as spawn5 } from "child_process";
2607
2615
  import pc11 from "picocolors";
2608
- var APPS_DIR3 = join7(homedir7(), ".botapp", "apps");
2616
+ var APPS_DIR3 = join8(homedir8(), ".botapp", "apps");
2609
2617
  var devCommand = new Command10("dev").description("Start development mode for an app").argument("[path]", "Path to the app directory", ".").option("-p, --port <port>", "Server port", "7100").action(async (appPath, opts) => {
2610
2618
  const absPath = resolve6(appPath);
2611
- if (!existsSync8(absPath)) {
2619
+ if (!existsSync9(absPath)) {
2612
2620
  console.error(pc11.red(`Path not found: ${absPath}`));
2613
2621
  process.exitCode = 1;
2614
2622
  return;
2615
2623
  }
2616
- const manifestPath = join7(absPath, "botapp.app.json");
2617
- if (!existsSync8(manifestPath)) {
2624
+ const manifestPath = join8(absPath, "botapp.app.json");
2625
+ if (!existsSync9(manifestPath)) {
2618
2626
  console.error(pc11.red(`No botapp.app.json found in ${absPath}`));
2619
2627
  process.exitCode = 1;
2620
2628
  return;
@@ -2628,9 +2636,9 @@ var devCommand = new Command10("dev").description("Start development mode for an
2628
2636
  return;
2629
2637
  }
2630
2638
  const appName = manifest.name || basename2(absPath);
2631
- const targetDir = join7(APPS_DIR3, appName);
2639
+ const targetDir = join8(APPS_DIR3, appName);
2632
2640
  mkdirSync5(APPS_DIR3, { recursive: true });
2633
- if (!existsSync8(targetDir)) {
2641
+ if (!existsSync9(targetDir)) {
2634
2642
  symlinkSync2(absPath, targetDir, "dir");
2635
2643
  console.log(pc11.blue(`Linked ${pc11.bold(appName)} \u2192 ${pc11.dim(absPath)}`));
2636
2644
  } else {
@@ -2681,7 +2689,7 @@ function findServerEntry3() {
2681
2689
  resolve6(process.cwd(), "../server/src/index.ts")
2682
2690
  ];
2683
2691
  for (const c of candidates) {
2684
- if (existsSync8(c)) return c;
2692
+ if (existsSync9(c)) return c;
2685
2693
  }
2686
2694
  return null;
2687
2695
  }
@@ -2915,13 +2923,13 @@ All agents:`);
2915
2923
 
2916
2924
  // src/commands/register.ts
2917
2925
  import { Command as Command14 } from "commander";
2918
- import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
2926
+ import { readFileSync as readFileSync7, existsSync as existsSync10 } from "fs";
2919
2927
  import pc15 from "picocolors";
2920
2928
  var registerCommand = new Command14("register").description("Register an external app via HTTP bridge manifest").argument("<manifest>", "Path to YAML manifest file").option("--adapter <url>", "Override base URL from manifest").action(async (manifestPath, opts, cmd) => {
2921
2929
  const globalOpts = cmd.parent?.opts() ?? {};
2922
2930
  const serverUrl = resolveServerUrl(globalOpts.server);
2923
2931
  const token = resolveToken(globalOpts.token);
2924
- if (!existsSync9(manifestPath)) {
2932
+ if (!existsSync10(manifestPath)) {
2925
2933
  console.error(pc15.red(`Error: Manifest not found: ${manifestPath}`));
2926
2934
  process.exitCode = 1;
2927
2935
  return;
@@ -2958,13 +2966,13 @@ var registerCommand = new Command14("register").description("Register an externa
2958
2966
 
2959
2967
  // src/commands/wrap.ts
2960
2968
  import { Command as Command15 } from "commander";
2961
- import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
2969
+ import { readFileSync as readFileSync8, existsSync as existsSync11 } from "fs";
2962
2970
  import pc16 from "picocolors";
2963
2971
  var wrapCommand = new Command15("wrap").description("Register CLI tool as app commands via YAML manifest").argument("<manifest>", "Path to CLI wrapper YAML manifest").action(async (manifestPath, _opts, cmd) => {
2964
2972
  const globalOpts = cmd.parent?.opts() ?? {};
2965
2973
  const serverUrl = resolveServerUrl(globalOpts.server);
2966
2974
  const token = resolveToken(globalOpts.token);
2967
- if (!existsSync10(manifestPath)) {
2975
+ if (!existsSync11(manifestPath)) {
2968
2976
  console.error(pc16.red(`Error: Manifest not found: ${manifestPath}`));
2969
2977
  process.exitCode = 1;
2970
2978
  return;
@@ -3220,6 +3228,10 @@ var pairingCommand = new Command18("pairing").alias("pair").description("Pair th
3220
3228
  process.exitCode = 1;
3221
3229
  return;
3222
3230
  }
3231
+ const stoppedExistingDaemon = isDaemonRunningLocally();
3232
+ if (stoppedExistingDaemon) {
3233
+ stopExistingDaemon();
3234
+ }
3223
3235
  const savedProfile = saveDaemonProfile({
3224
3236
  server: serverUrl,
3225
3237
  daemonId: data.daemon.id,
@@ -3230,6 +3242,9 @@ var pairingCommand = new Command18("pairing").alias("pair").description("Pair th
3230
3242
  console.log(` ID: ${data.daemon.id}`);
3231
3243
  console.log(` Server: ${serverUrl}`);
3232
3244
  console.log(` Profile: ${savedProfile.alias}`);
3245
+ if (stoppedExistingDaemon) {
3246
+ console.log(pc19.dim(" Note: stopped the existing background daemon (was holding the old token)."));
3247
+ }
3233
3248
  if (opts.run) {
3234
3249
  await runDaemonConnectionLoop(savedProfile);
3235
3250
  return;
@@ -3339,7 +3354,7 @@ function updateCommandFor(manager) {
3339
3354
  }
3340
3355
 
3341
3356
  // src/index.ts
3342
- var version = "0.2.2";
3357
+ var version = "0.2.3";
3343
3358
  var program = new Command20().name("bot").description("botapp CLI \u2014 operate apps from the command line").version(version).enablePositionalOptions(true).option("--json", "Output as JSON").option("-s, --server <url>", "Server URL override").option("-t, --token <token>", "Auth token override").option("-v, --verbose", "Verbose output");
3344
3359
  program.addCommand(launchCommand);
3345
3360
  program.addCommand(runCommand);