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/bin/bot.js CHANGED
@@ -1592,7 +1592,7 @@ Invalid ACP stdout: ${line}`;
1592
1592
  clientInfo: {
1593
1593
  name: "botapp-daemon",
1594
1594
  title: "botapp daemon",
1595
- version: "0.2.2"
1595
+ version: "0.2.3"
1596
1596
  }
1597
1597
  });
1598
1598
  const session = await request2("session/new", {
@@ -1743,9 +1743,9 @@ async function waitForChild(child, timeoutMs, label) {
1743
1743
  // src/commands/launch.ts
1744
1744
  import { Command as Command4 } from "commander";
1745
1745
  import { spawn as spawn4 } from "child_process";
1746
- import { resolve as resolve4, join as join4 } from "path";
1747
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, openSync, unlinkSync, writeFileSync as writeFileSync3, readFileSync as readFileSync4 } from "fs";
1748
- import { homedir as homedir4 } from "os";
1746
+ import { resolve as resolve4, join as join5 } from "path";
1747
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, openSync, writeFileSync as writeFileSync3 } from "fs";
1748
+ import { homedir as homedir5 } from "os";
1749
1749
  import { createInterface as createInterface3 } from "readline";
1750
1750
  import { hostname } from "os";
1751
1751
  import pc5 from "picocolors";
@@ -2012,6 +2012,41 @@ function openUrl(url) {
2012
2012
  }
2013
2013
  }
2014
2014
 
2015
+ // src/commands/daemon-supervisor.ts
2016
+ import { existsSync as existsSync5, readFileSync as readFileSync4, unlinkSync } from "fs";
2017
+ import { homedir as homedir4 } from "os";
2018
+ import { join as join4 } from "path";
2019
+ function daemonPidFile() {
2020
+ return join4(homedir4(), ".botapp", "daemon.pid");
2021
+ }
2022
+ function isDaemonRunningLocally(pidFile = daemonPidFile()) {
2023
+ if (!existsSync5(pidFile)) return false;
2024
+ try {
2025
+ const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2026
+ if (!Number.isInteger(pid) || pid <= 0) return false;
2027
+ process.kill(pid, 0);
2028
+ return true;
2029
+ } catch {
2030
+ return false;
2031
+ }
2032
+ }
2033
+ function stopExistingDaemon(pidFile = daemonPidFile()) {
2034
+ try {
2035
+ const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2036
+ if (Number.isInteger(pid) && pid > 0) {
2037
+ try {
2038
+ process.kill(pid, "SIGTERM");
2039
+ } catch {
2040
+ }
2041
+ }
2042
+ } catch {
2043
+ }
2044
+ try {
2045
+ unlinkSync(pidFile);
2046
+ } catch {
2047
+ }
2048
+ }
2049
+
2015
2050
  // src/commands/launch.ts
2016
2051
  var DEFAULT_SERVER_URL = "https://api.botapp.ai";
2017
2052
  var DEFAULT_APP_URL = "https://botapp.ai";
@@ -2153,15 +2188,15 @@ async function autoStartDaemon(opts, serverUrl, daemonId) {
2153
2188
  Next: run \`bot daemon run\` to bring this machine online.`));
2154
2189
  return;
2155
2190
  }
2156
- const dir = join4(homedir4(), ".botapp");
2157
- const pidFile = join4(dir, "daemon.pid");
2158
- const logFile = join4(dir, "daemon.log");
2191
+ const dir = join5(homedir5(), ".botapp");
2192
+ const pidFile = join5(dir, "daemon.pid");
2193
+ const logFile = join5(dir, "daemon.log");
2159
2194
  mkdirSync3(dir, { recursive: true });
2160
2195
  if (isDaemonRunningLocally(pidFile)) {
2161
2196
  stopExistingDaemon(pidFile);
2162
2197
  }
2163
2198
  const botBin = process.argv[1];
2164
- if (!botBin || !existsSync5(botBin)) {
2199
+ if (!botBin || !existsSync6(botBin)) {
2165
2200
  console.log(pc5.yellow(` Running: cannot resolve \`bot\` binary \u2014 run \`bot daemon run\` manually`));
2166
2201
  return;
2167
2202
  }
@@ -2193,33 +2228,6 @@ Next: run \`bot daemon run\` to bring this machine online.`));
2193
2228
  );
2194
2229
  }
2195
2230
  }
2196
- function isDaemonRunningLocally(pidFile) {
2197
- if (!existsSync5(pidFile)) return false;
2198
- try {
2199
- const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2200
- if (!Number.isInteger(pid) || pid <= 0) return false;
2201
- process.kill(pid, 0);
2202
- return true;
2203
- } catch {
2204
- return false;
2205
- }
2206
- }
2207
- function stopExistingDaemon(pidFile) {
2208
- try {
2209
- const pid = parseInt(readFileSync4(pidFile, "utf-8").trim(), 10);
2210
- if (Number.isInteger(pid) && pid > 0) {
2211
- try {
2212
- process.kill(pid, "SIGTERM");
2213
- } catch {
2214
- }
2215
- }
2216
- } catch {
2217
- }
2218
- try {
2219
- unlinkSync(pidFile);
2220
- } catch {
2221
- }
2222
- }
2223
2231
  async function isDaemonOnline(serverUrl, daemonId) {
2224
2232
  try {
2225
2233
  const res = await fetch(`${serverUrl}/api/daemons`, {
@@ -2320,7 +2328,7 @@ function findServerEntry2() {
2320
2328
  resolve4(process.cwd(), "../../packages/server/src/index.ts")
2321
2329
  ];
2322
2330
  for (const c of candidates) {
2323
- if (existsSync5(c)) return c;
2331
+ if (existsSync6(c)) return c;
2324
2332
  }
2325
2333
  return null;
2326
2334
  }
@@ -2523,20 +2531,20 @@ var loginCommand = new Command7("login").description("Login to a botapp server")
2523
2531
  // src/commands/install.ts
2524
2532
  import { Command as Command8 } from "commander";
2525
2533
  import { resolve as resolve5, basename } from "path";
2526
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, symlinkSync, cpSync, readFileSync as readFileSync5 } from "fs";
2527
- import { homedir as homedir5 } from "os";
2528
- import { join as join5 } from "path";
2534
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, symlinkSync, cpSync, readFileSync as readFileSync5 } from "fs";
2535
+ import { homedir as homedir6 } from "os";
2536
+ import { join as join6 } from "path";
2529
2537
  import pc9 from "picocolors";
2530
- var APPS_DIR = join5(homedir5(), ".botapp", "apps");
2538
+ var APPS_DIR = join6(homedir6(), ".botapp", "apps");
2531
2539
  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) => {
2532
2540
  const absPath = resolve5(appPath);
2533
- if (!existsSync6(absPath)) {
2541
+ if (!existsSync7(absPath)) {
2534
2542
  console.error(pc9.red(`Path not found: ${absPath}`));
2535
2543
  process.exitCode = 1;
2536
2544
  return;
2537
2545
  }
2538
- const manifestPath = join5(absPath, "botapp.app.json");
2539
- if (!existsSync6(manifestPath)) {
2546
+ const manifestPath = join6(absPath, "botapp.app.json");
2547
+ if (!existsSync7(manifestPath)) {
2540
2548
  console.error(pc9.red(`No botapp.app.json found in ${absPath}`));
2541
2549
  process.exitCode = 1;
2542
2550
  return;
@@ -2550,9 +2558,9 @@ var installCommand = new Command8("install").description("Install an app from a
2550
2558
  return;
2551
2559
  }
2552
2560
  const appName = manifest.name || basename(absPath);
2553
- const targetDir = join5(APPS_DIR, appName);
2561
+ const targetDir = join6(APPS_DIR, appName);
2554
2562
  mkdirSync4(APPS_DIR, { recursive: true });
2555
- if (existsSync6(targetDir)) {
2563
+ if (existsSync7(targetDir)) {
2556
2564
  console.log(pc9.yellow(`App "${appName}" is already installed. Reinstalling...`));
2557
2565
  const { rmSync: rmSync2 } = await import("fs");
2558
2566
  rmSync2(targetDir, { recursive: true, force: true });
@@ -2571,14 +2579,14 @@ var installCommand = new Command8("install").description("Install an app from a
2571
2579
 
2572
2580
  // src/commands/uninstall.ts
2573
2581
  import { Command as Command9 } from "commander";
2574
- import { existsSync as existsSync7, rmSync } from "fs";
2575
- import { homedir as homedir6 } from "os";
2576
- import { join as join6 } from "path";
2582
+ import { existsSync as existsSync8, rmSync } from "fs";
2583
+ import { homedir as homedir7 } from "os";
2584
+ import { join as join7 } from "path";
2577
2585
  import pc10 from "picocolors";
2578
- var APPS_DIR2 = join6(homedir6(), ".botapp", "apps");
2586
+ var APPS_DIR2 = join7(homedir7(), ".botapp", "apps");
2579
2587
  var uninstallCommand = new Command9("uninstall").description("Uninstall an app").argument("<name>", "App name to uninstall").action(async (name) => {
2580
- const targetDir = join6(APPS_DIR2, name);
2581
- if (!existsSync7(targetDir)) {
2588
+ const targetDir = join7(APPS_DIR2, name);
2589
+ if (!existsSync8(targetDir)) {
2582
2590
  console.error(pc10.red(`App "${name}" is not installed`));
2583
2591
  process.exitCode = 1;
2584
2592
  return;
@@ -2590,21 +2598,21 @@ var uninstallCommand = new Command9("uninstall").description("Uninstall an app")
2590
2598
 
2591
2599
  // src/commands/dev.ts
2592
2600
  import { Command as Command10 } from "commander";
2593
- import { resolve as resolve6, basename as basename2, join as join7 } from "path";
2594
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, symlinkSync as symlinkSync2, readFileSync as readFileSync6, lstatSync } from "fs";
2595
- import { homedir as homedir7 } from "os";
2601
+ import { resolve as resolve6, basename as basename2, join as join8 } from "path";
2602
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, symlinkSync as symlinkSync2, readFileSync as readFileSync6, lstatSync } from "fs";
2603
+ import { homedir as homedir8 } from "os";
2596
2604
  import { spawn as spawn5 } from "child_process";
2597
2605
  import pc11 from "picocolors";
2598
- var APPS_DIR3 = join7(homedir7(), ".botapp", "apps");
2606
+ var APPS_DIR3 = join8(homedir8(), ".botapp", "apps");
2599
2607
  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) => {
2600
2608
  const absPath = resolve6(appPath);
2601
- if (!existsSync8(absPath)) {
2609
+ if (!existsSync9(absPath)) {
2602
2610
  console.error(pc11.red(`Path not found: ${absPath}`));
2603
2611
  process.exitCode = 1;
2604
2612
  return;
2605
2613
  }
2606
- const manifestPath = join7(absPath, "botapp.app.json");
2607
- if (!existsSync8(manifestPath)) {
2614
+ const manifestPath = join8(absPath, "botapp.app.json");
2615
+ if (!existsSync9(manifestPath)) {
2608
2616
  console.error(pc11.red(`No botapp.app.json found in ${absPath}`));
2609
2617
  process.exitCode = 1;
2610
2618
  return;
@@ -2618,9 +2626,9 @@ var devCommand = new Command10("dev").description("Start development mode for an
2618
2626
  return;
2619
2627
  }
2620
2628
  const appName = manifest.name || basename2(absPath);
2621
- const targetDir = join7(APPS_DIR3, appName);
2629
+ const targetDir = join8(APPS_DIR3, appName);
2622
2630
  mkdirSync5(APPS_DIR3, { recursive: true });
2623
- if (!existsSync8(targetDir)) {
2631
+ if (!existsSync9(targetDir)) {
2624
2632
  symlinkSync2(absPath, targetDir, "dir");
2625
2633
  console.log(pc11.blue(`Linked ${pc11.bold(appName)} \u2192 ${pc11.dim(absPath)}`));
2626
2634
  } else {
@@ -2671,7 +2679,7 @@ function findServerEntry3() {
2671
2679
  resolve6(process.cwd(), "../server/src/index.ts")
2672
2680
  ];
2673
2681
  for (const c of candidates) {
2674
- if (existsSync8(c)) return c;
2682
+ if (existsSync9(c)) return c;
2675
2683
  }
2676
2684
  return null;
2677
2685
  }
@@ -2905,13 +2913,13 @@ All agents:`);
2905
2913
 
2906
2914
  // src/commands/register.ts
2907
2915
  import { Command as Command14 } from "commander";
2908
- import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
2916
+ import { readFileSync as readFileSync7, existsSync as existsSync10 } from "fs";
2909
2917
  import pc15 from "picocolors";
2910
2918
  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) => {
2911
2919
  const globalOpts = cmd.parent?.opts() ?? {};
2912
2920
  const serverUrl = resolveServerUrl(globalOpts.server);
2913
2921
  const token = resolveToken(globalOpts.token);
2914
- if (!existsSync9(manifestPath)) {
2922
+ if (!existsSync10(manifestPath)) {
2915
2923
  console.error(pc15.red(`Error: Manifest not found: ${manifestPath}`));
2916
2924
  process.exitCode = 1;
2917
2925
  return;
@@ -2948,13 +2956,13 @@ var registerCommand = new Command14("register").description("Register an externa
2948
2956
 
2949
2957
  // src/commands/wrap.ts
2950
2958
  import { Command as Command15 } from "commander";
2951
- import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
2959
+ import { readFileSync as readFileSync8, existsSync as existsSync11 } from "fs";
2952
2960
  import pc16 from "picocolors";
2953
2961
  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) => {
2954
2962
  const globalOpts = cmd.parent?.opts() ?? {};
2955
2963
  const serverUrl = resolveServerUrl(globalOpts.server);
2956
2964
  const token = resolveToken(globalOpts.token);
2957
- if (!existsSync10(manifestPath)) {
2965
+ if (!existsSync11(manifestPath)) {
2958
2966
  console.error(pc16.red(`Error: Manifest not found: ${manifestPath}`));
2959
2967
  process.exitCode = 1;
2960
2968
  return;
@@ -3210,6 +3218,10 @@ var pairingCommand = new Command18("pairing").alias("pair").description("Pair th
3210
3218
  process.exitCode = 1;
3211
3219
  return;
3212
3220
  }
3221
+ const stoppedExistingDaemon = isDaemonRunningLocally();
3222
+ if (stoppedExistingDaemon) {
3223
+ stopExistingDaemon();
3224
+ }
3213
3225
  const savedProfile = saveDaemonProfile({
3214
3226
  server: serverUrl,
3215
3227
  daemonId: data.daemon.id,
@@ -3220,6 +3232,9 @@ var pairingCommand = new Command18("pairing").alias("pair").description("Pair th
3220
3232
  console.log(` ID: ${data.daemon.id}`);
3221
3233
  console.log(` Server: ${serverUrl}`);
3222
3234
  console.log(` Profile: ${savedProfile.alias}`);
3235
+ if (stoppedExistingDaemon) {
3236
+ console.log(pc19.dim(" Note: stopped the existing background daemon (was holding the old token)."));
3237
+ }
3223
3238
  if (opts.run) {
3224
3239
  await runDaemonConnectionLoop(savedProfile);
3225
3240
  return;
@@ -3329,7 +3344,7 @@ function updateCommandFor(manager) {
3329
3344
  }
3330
3345
 
3331
3346
  // src/index.ts
3332
- var version = "0.2.2";
3347
+ var version = "0.2.3";
3333
3348
  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");
3334
3349
  program.addCommand(launchCommand);
3335
3350
  program.addCommand(runCommand);