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/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.
|
|
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
|
|
1757
|
-
import { existsSync as
|
|
1758
|
-
import { homedir as
|
|
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 =
|
|
2167
|
-
const pidFile =
|
|
2168
|
-
const logFile =
|
|
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 || !
|
|
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 (
|
|
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
|
|
2537
|
-
import { homedir as
|
|
2538
|
-
import { join as
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
2549
|
-
if (!
|
|
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 =
|
|
2571
|
+
const targetDir = join6(APPS_DIR, appName);
|
|
2564
2572
|
mkdirSync4(APPS_DIR, { recursive: true });
|
|
2565
|
-
if (
|
|
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
|
|
2585
|
-
import { homedir as
|
|
2586
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
2591
|
-
if (!
|
|
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
|
|
2604
|
-
import { existsSync as
|
|
2605
|
-
import { homedir as
|
|
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 =
|
|
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 (!
|
|
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 =
|
|
2617
|
-
if (!
|
|
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 =
|
|
2639
|
+
const targetDir = join8(APPS_DIR3, appName);
|
|
2632
2640
|
mkdirSync5(APPS_DIR3, { recursive: true });
|
|
2633
|
-
if (!
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 (!
|
|
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.
|
|
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);
|