botapp-cli 0.2.8 → 0.2.10

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
@@ -953,32 +953,38 @@ async function ptyKill(params) {
953
953
  async function openPty(opts) {
954
954
  const nodePty = await loadNodePty();
955
955
  if (nodePty) {
956
- const proc2 = nodePty.spawn(opts.command, opts.args, {
957
- name: "xterm-256color",
958
- cols: opts.cols,
959
- rows: opts.rows,
960
- cwd: opts.cwd,
961
- env: opts.env
962
- });
963
- const ptyId2 = randomUUID();
964
- proc2.onData((data) => {
965
- opts.ctx.pushChunk({ kind: "data", data });
966
- });
967
- const exited2 = new Promise((resolve11) => {
968
- proc2.onExit(({ exitCode }) => {
969
- resolve11(exitCode);
956
+ try {
957
+ const proc2 = nodePty.spawn(opts.command, opts.args, {
958
+ name: "xterm-256color",
959
+ cols: opts.cols,
960
+ rows: opts.rows,
961
+ cwd: opts.cwd,
962
+ env: opts.env
970
963
  });
971
- });
972
- return {
973
- mode: "pty",
974
- exited: exited2,
975
- handle: {
976
- ptyId: ptyId2,
977
- resize: (cols, rows) => proc2.resize(cols, rows),
978
- write: (data) => proc2.write(data),
979
- kill: (signal) => proc2.kill(signal)
980
- }
981
- };
964
+ const ptyId2 = randomUUID();
965
+ proc2.onData((data) => {
966
+ opts.ctx.pushChunk({ kind: "data", data });
967
+ });
968
+ const exited2 = new Promise((resolve11) => {
969
+ proc2.onExit(({ exitCode }) => {
970
+ resolve11(exitCode);
971
+ });
972
+ });
973
+ return {
974
+ mode: "pty",
975
+ exited: exited2,
976
+ handle: {
977
+ ptyId: ptyId2,
978
+ resize: (cols, rows) => proc2.resize(cols, rows),
979
+ write: (data) => proc2.write(data),
980
+ kill: (signal) => proc2.kill(signal)
981
+ }
982
+ };
983
+ } catch (e) {
984
+ console.warn(
985
+ `[pty] node-pty spawn failed (${e?.message ?? e}); falling back to line-oriented pipe mode`
986
+ );
987
+ }
982
988
  }
983
989
  const proc = spawn2(
984
990
  opts.command,
@@ -997,7 +1003,23 @@ async function openPty(opts) {
997
1003
  opts.ctx.pushChunk({ kind: "data", data: chunk.toString("utf8") });
998
1004
  });
999
1005
  const exited = new Promise((resolve11) => {
1000
- proc.on("close", (code) => resolve11(code));
1006
+ let settled = false;
1007
+ proc.on("close", (code) => {
1008
+ if (settled) return;
1009
+ settled = true;
1010
+ resolve11(code);
1011
+ });
1012
+ proc.on("error", (err) => {
1013
+ opts.ctx.pushChunk({
1014
+ kind: "data",
1015
+ data: `\r
1016
+ [shell failed to start: ${err.message}]\r
1017
+ `
1018
+ });
1019
+ if (settled) return;
1020
+ settled = true;
1021
+ resolve11(1);
1022
+ });
1001
1023
  });
1002
1024
  return {
1003
1025
  mode: "pipe",
@@ -1361,7 +1383,7 @@ async function runShellAgent(job) {
1361
1383
  child.stderr.on("data", (chunk) => {
1362
1384
  stderr += chunk.toString();
1363
1385
  });
1364
- const code = await new Promise((resolve11) => child.on("close", resolve11));
1386
+ const code = await awaitChildClose(child, job.agent.command);
1365
1387
  if (code !== 0) {
1366
1388
  throw new Error(stderr.trim() || `Agent exited with code ${code}`);
1367
1389
  }
@@ -1449,7 +1471,7 @@ async function runCodexAgent(job, update) {
1449
1471
  }
1450
1472
  const rl = createInterface2({ input: child.stdout });
1451
1473
  rl.on("line", processLine);
1452
- const code = await new Promise((resolve11) => child.on("close", resolve11));
1474
+ const code = await awaitChildClose(child, job.agent.command);
1453
1475
  if (code !== 0) {
1454
1476
  throw new Error(errors.at(-1) ?? (stderr.trim() || `Codex exited with code ${code}`));
1455
1477
  }
@@ -1584,7 +1606,7 @@ async function runClaudeCodeAgent(job, update) {
1584
1606
  }
1585
1607
  const rl = createInterface2({ input: child.stdout });
1586
1608
  rl.on("line", processLine);
1587
- const code = await new Promise((resolve11) => child.on("close", resolve11));
1609
+ const code = await awaitChildClose(child, job.agent.command);
1588
1610
  if (code !== 0) {
1589
1611
  const parts = [];
1590
1612
  if (stderr.trim()) parts.push(stderr.trim());
@@ -1721,7 +1743,7 @@ ${job.query}`;
1721
1743
  }
1722
1744
  const rl = createInterface2({ input: child.stdout });
1723
1745
  rl.on("line", processLine);
1724
- const code = await new Promise((resolve11) => child.on("close", resolve11));
1746
+ const code = await awaitChildClose(child, job.agent.command);
1725
1747
  const resumeMatch = stderr.match(/To resume this session:\s*kimi\s+-r\s+([A-Za-z0-9_-]+)/);
1726
1748
  if (resumeMatch) result.sessionId = resumeMatch[1];
1727
1749
  if (code !== 0) {
@@ -2385,7 +2407,7 @@ Invalid ACP stdout: ${line}`;
2385
2407
  clientInfo: {
2386
2408
  name: "botapp-daemon",
2387
2409
  title: "botapp daemon",
2388
- version: "0.2.8"
2410
+ version: "0.2.10"
2389
2411
  }
2390
2412
  });
2391
2413
  const session = await request2("session/new", {
@@ -2512,6 +2534,20 @@ function parseMaybeJson(value) {
2512
2534
  function sleep(ms) {
2513
2535
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
2514
2536
  }
2537
+ function awaitChildClose(child, commandLabel) {
2538
+ return new Promise((resolveClose, reject) => {
2539
+ child.once("error", (err) => {
2540
+ if (err.code === "ENOENT") {
2541
+ reject(new Error(
2542
+ `Agent CLI "${commandLabel}" not found on PATH for the daemon process. Install it, or re-register the agent with an absolute path (\`bot daemon agent remove ${commandLabel}\` then \`bot daemon config\`).`
2543
+ ));
2544
+ } else {
2545
+ reject(err);
2546
+ }
2547
+ });
2548
+ child.once("close", resolveClose);
2549
+ });
2550
+ }
2515
2551
  async function waitForChild(child, timeoutMs, label) {
2516
2552
  return new Promise((resolveWait, reject) => {
2517
2553
  const timeout = setTimeout(() => {
@@ -5039,7 +5075,7 @@ function die(msg) {
5039
5075
  }
5040
5076
 
5041
5077
  // src/index.ts
5042
- var version = "0.2.8";
5078
+ var version = "0.2.10";
5043
5079
  var program = new Command25().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");
5044
5080
  program.addCommand(launchCommand);
5045
5081
  program.addCommand(runCommand);