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 +81 -66
- package/dist/bin/bot.js.map +1 -1
- package/dist/index.js +81 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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
|
|
1747
|
-
import { existsSync as
|
|
1748
|
-
import { homedir as
|
|
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 =
|
|
2157
|
-
const pidFile =
|
|
2158
|
-
const logFile =
|
|
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 || !
|
|
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 (
|
|
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
|
|
2527
|
-
import { homedir as
|
|
2528
|
-
import { join as
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
2539
|
-
if (!
|
|
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 =
|
|
2561
|
+
const targetDir = join6(APPS_DIR, appName);
|
|
2554
2562
|
mkdirSync4(APPS_DIR, { recursive: true });
|
|
2555
|
-
if (
|
|
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
|
|
2575
|
-
import { homedir as
|
|
2576
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
2581
|
-
if (!
|
|
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
|
|
2594
|
-
import { existsSync as
|
|
2595
|
-
import { homedir as
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
2607
|
-
if (!
|
|
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 =
|
|
2629
|
+
const targetDir = join8(APPS_DIR3, appName);
|
|
2622
2630
|
mkdirSync5(APPS_DIR3, { recursive: true });
|
|
2623
|
-
if (!
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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.
|
|
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);
|