claude-yes 1.149.1 → 1.150.0

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.
@@ -0,0 +1,8 @@
1
+ import "./ts-Cng1o5fC.js";
2
+ import "./logger-CDIsZ-Pp.js";
3
+ import "./versionChecker-CeVZzVQB.js";
4
+ import "./pidStore-fqXqTKkh.js";
5
+ import "./globalPidIndex-DlmmJlO8.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D8mK1P78.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-C21nFgXQ.js";
1
+ import { t as CLIS_CONFIG } from "./ts-Cng1o5fC.js";
2
2
 
3
3
  //#region ts/SUPPORTED_CLIS.ts
4
4
  const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
5
5
 
6
6
  //#endregion
7
7
  export { SUPPORTED_CLIS as t };
8
- //# sourceMappingURL=SUPPORTED_CLIS-DyQjQODe.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-D8mK1P78.js.map
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
3
3
  import { n as logger } from "./logger-CDIsZ-Pp.js";
4
- import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-C-JJk14E.js";
4
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-CeVZzVQB.js";
5
5
  import { argv } from "process";
6
6
  import { execFileSync, spawn } from "child_process";
7
7
  import ms from "ms";
@@ -480,7 +480,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
480
480
  const rawArg = process.argv[2];
481
481
  const managerCommands = !invokedCliName(process.argv);
482
482
  const isHelpFlag = rawArg === "-h" || rawArg === "--help";
483
- const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-Bv7xJq9E.js");
483
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-BDftiFrp.js");
484
484
  if (isHelpFlag && process.argv.length === 3) {
485
485
  cmdHelp(managerCommands);
486
486
  process.exit(0);
@@ -513,7 +513,7 @@ if (config.useRust) {
513
513
  }
514
514
  }
515
515
  if (rustBinary) {
516
- const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DhVolHXQ.js");
516
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BsjC_rd9.js");
517
517
  const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
518
518
  if (config.verbose) {
519
519
  console.log(`[rust] Using binary: ${rustBinary}`);
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-C21nFgXQ.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-Cng1o5fC.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-C-JJk14E.js";
3
+ import "./versionChecker-CeVZzVQB.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
6
 
@@ -1,9 +1,9 @@
1
- import "./ts-C21nFgXQ.js";
1
+ import "./ts-Cng1o5fC.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-C-JJk14E.js";
3
+ import "./versionChecker-CeVZzVQB.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import "./globalPidIndex-DlmmJlO8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DyQjQODe.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D8mK1P78.js";
7
7
  import { i as resolveSpawnCwd } from "./workspaceConfig-B9VX8tVO.js";
8
8
  import { createHash } from "node:crypto";
9
9
 
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
141
141
 
142
142
  //#endregion
143
143
  export { cmdSchedule };
144
- //# sourceMappingURL=schedule-BJk96cOy.js.map
144
+ //# sourceMappingURL=schedule-3FpLAXCx.js.map
@@ -1,16 +1,16 @@
1
- import "./ts-C21nFgXQ.js";
1
+ import "./ts-Cng1o5fC.js";
2
2
  import "./logger-CDIsZ-Pp.js";
3
- import { r as getInstalledPackage } from "./versionChecker-C-JJk14E.js";
3
+ import { r as getInstalledPackage } from "./versionChecker-CeVZzVQB.js";
4
4
  import "./pidStore-fqXqTKkh.js";
5
5
  import { a as updateGlobalPidStatus } from "./globalPidIndex-DlmmJlO8.js";
6
6
  import { t as pgidForWrapper } from "./reaper-C-eWAxIj.js";
7
7
  import "./configShared-C1C04bbq.js";
8
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DyQjQODe.js";
8
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D8mK1P78.js";
9
9
  import "./e2e-ClOI_aqV.js";
10
10
  import "./webrtcLink-BWhuA74k.js";
11
11
  import "./remotes-qK6uozO4.js";
12
12
  import { i as resolveSpawnCwd, r as isProvisionAllowed, t as getProvisionRoot } from "./workspaceConfig-B9VX8tVO.js";
13
- import { S as snapshotStatus, _ as renderRawLog, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, w as writeToIpc, y as resolveOne } from "./subcommands-OyK7Y447.js";
13
+ import { C as snapshotStatus, T as writeToIpc, _ as readPtysize, b as resolveOne, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, v as renderRawLog } from "./subcommands-BtUKGF4n.js";
14
14
  import yargs from "yargs";
15
15
  import { mkdir, open, readFile, stat, writeFile } from "fs/promises";
16
16
  import { homedir, hostname, userInfo } from "os";
@@ -802,9 +802,13 @@ Options:
802
802
  try {
803
803
  const record = await resolveOne(keyword, defaultOpts());
804
804
  if (!record.log_file) return new Response(`pid ${record.pid}: no log_file`, { status: 404 });
805
- const text = await renderRawLog(await readFile(record.log_file), {
805
+ const buf = await readFile(record.log_file);
806
+ const size = await readPtysize(record.pid);
807
+ const text = await renderRawLog(buf, {
806
808
  mode,
807
- n
809
+ n,
810
+ cols: size?.cols,
811
+ rows: size?.rows
808
812
  });
809
813
  return new Response(text, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
810
814
  } catch (e) {
@@ -816,20 +820,11 @@ Options:
816
820
  const keyword = decodeURIComponent(sizeM[1]);
817
821
  try {
818
822
  const record = await resolveOne(keyword, defaultOpts());
819
- const ayHome = process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes");
820
- let cols = null;
821
- let rows = null;
822
- try {
823
- const [c = 0, r = 0] = (await readFile(path.join(ayHome, "ptysize", String(record.pid)), "utf-8")).trim().split(/\s+/).map(Number);
824
- if (c > 0 && r > 0) {
825
- cols = c;
826
- rows = r;
827
- }
828
- } catch {}
823
+ const size = await readPtysize(record.pid);
829
824
  return Response.json({
830
825
  pid: record.pid,
831
- cols,
832
- rows
826
+ cols: size?.cols ?? null,
827
+ rows: size?.rows ?? null
833
828
  });
834
829
  } catch (e) {
835
830
  return new Response(e.message, { status: 404 });
@@ -1051,8 +1046,37 @@ Options:
1051
1046
  const prompt = String(body.prompt ?? "");
1052
1047
  let cwd;
1053
1048
  let provisioned = null;
1049
+ const fork = body.fork && typeof body.fork.fromCwd === "string" && typeof body.fork.branch === "string" ? {
1050
+ fromCwd: body.fork.fromCwd,
1051
+ branch: body.fork.branch
1052
+ } : null;
1054
1053
  const from = typeof body.from === "string" ? body.from.trim() : "";
1055
- if (from) {
1054
+ if (fork) {
1055
+ let prov;
1056
+ try {
1057
+ prov = await import("codehost/provision");
1058
+ } catch (e) {
1059
+ return new Response(`fork needs the 'codehost' package (codehost/provision) — install it (npm i -g codehost) or 'bun link' it for local dev: ${e.message}`, { status: 501 });
1060
+ }
1061
+ let result;
1062
+ try {
1063
+ const wsRoot = getProvisionRoot();
1064
+ result = await prov.forkWorktree({
1065
+ fromCwd: fork.fromCwd,
1066
+ branch: fork.branch,
1067
+ ...wsRoot ? { wsRoot } : {}
1068
+ });
1069
+ } catch (e) {
1070
+ return new Response(`fork failed: ${e.message}`, { status: 502 });
1071
+ }
1072
+ if (!result?.ok) return new Response(result?.error ?? "fork failed", { status: 502 });
1073
+ if (result.spec && !isProvisionAllowed(result.spec.owner, result.spec.repo)) return new Response(`forking '${result.spec.owner}/${result.spec.repo}' is not allowed — add the owner to provisionAllowlist in ~/.agent-yes/config.json (or "*" to allow all)`, { status: 403 });
1074
+ cwd = result.folder;
1075
+ provisioned = {
1076
+ action: result.action,
1077
+ folder: result.folder
1078
+ };
1079
+ } else if (from) {
1056
1080
  let prov;
1057
1081
  try {
1058
1082
  prov = await import("codehost/provision");
@@ -1088,7 +1112,7 @@ Options:
1088
1112
  return new Response(`cannot create cwd ${cwd}: ${e.message}`, { status: 500 });
1089
1113
  }
1090
1114
  }
1091
- process.stderr.write(`→ console spawned: ay ${cli}${prompt ? ` -- "${prompt.slice(0, 60)}"` : ""} (cwd: ${cwd}${provisioned ? `, ${provisioned.action} from ${from}` : ""})\n`);
1115
+ process.stderr.write(`→ console spawned: ay ${cli}${prompt ? ` -- "${prompt.slice(0, 60)}"` : ""} (cwd: ${cwd}${provisioned ? `, ${provisioned.action}` : ""})\n`);
1092
1116
  const ayBin = Bun.which("ay") ?? process.argv[1];
1093
1117
  const ayCmd = process.platform === "win32" && ayBin.toLowerCase().endsWith(".exe") ? [ayBin] : [process.execPath, ayBin];
1094
1118
  try {
@@ -1235,4 +1259,4 @@ Options:
1235
1259
 
1236
1260
  //#endregion
1237
1261
  export { cmdServe };
1238
- //# sourceMappingURL=serve-CaIDZfhy.js.map
1262
+ //# sourceMappingURL=serve-plR3NUPH.js.map
@@ -32,7 +32,7 @@ async function cmdSetup(rest) {
32
32
  if (!existsSync(abs)) process.stderr.write(` note: that directory doesn't exist yet — create it, or agents spawned there will fail\n`);
33
33
  if (noShare) return 0;
34
34
  process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
35
- const { cmdServe } = await import("./serve-CaIDZfhy.js");
35
+ const { cmdServe } = await import("./serve-plR3NUPH.js");
36
36
  return cmdServe([
37
37
  "install",
38
38
  "--share",
@@ -42,4 +42,4 @@ async function cmdSetup(rest) {
42
42
 
43
43
  //#endregion
44
44
  export { cmdSetup };
45
- //# sourceMappingURL=setup-B15dHEd1.js.map
45
+ //# sourceMappingURL=setup-BWGYyij8.js.map
@@ -0,0 +1,9 @@
1
+ import "./logger-CDIsZ-Pp.js";
2
+ import "./globalPidIndex-DlmmJlO8.js";
3
+ import "./configShared-C1C04bbq.js";
4
+ import "./e2e-ClOI_aqV.js";
5
+ import "./webrtcLink-BWhuA74k.js";
6
+ import "./remotes-qK6uozO4.js";
7
+ import { C as snapshotStatus, S as runSubcommand, T as writeToIpc, _ as readPtysize, a as cursorAbs, b as resolveOne, c as extractTaskCounts, d as isExitRequest, f as isPidAlive, g as readNotes, h as matchKeyword, i as controlCodeFromName, l as finalizedLines, m as listRecords, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isSubcommand, r as cmdHelp, s as extractNeedsInput, t as GRACEFUL_EXIT_COMMANDS, u as isAgentStuck, v as renderRawLog, w as stopTipForCli, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-BtUKGF4n.js";
8
+
9
+ export { cmdHelp, isSubcommand, runSubcommand };
@@ -554,15 +554,15 @@ async function runSubcommand(argv) {
554
554
  case "restart": return await cmdRestart(rest);
555
555
  case "note": return await cmdNote(rest);
556
556
  case "serve": {
557
- const { cmdServe } = await import("./serve-CaIDZfhy.js");
557
+ const { cmdServe } = await import("./serve-plR3NUPH.js");
558
558
  return cmdServe(rest);
559
559
  }
560
560
  case "setup": {
561
- const { cmdSetup } = await import("./setup-B15dHEd1.js");
561
+ const { cmdSetup } = await import("./setup-BWGYyij8.js");
562
562
  return cmdSetup(rest);
563
563
  }
564
564
  case "schedule": {
565
- const { cmdSchedule } = await import("./schedule-BJk96cOy.js");
565
+ const { cmdSchedule } = await import("./schedule-3FpLAXCx.js");
566
566
  return cmdSchedule(rest);
567
567
  }
568
568
  case "remote": {
@@ -1298,12 +1298,15 @@ async function cmdRead(rest, { mode }) {
1298
1298
  }
1299
1299
  if (!stats.isFile()) throw new Error(`pid ${record.pid}: log path is not a file: ${logPath}`);
1300
1300
  const buf = await readFile(logPath);
1301
+ const size = await readPtysize(record.pid);
1301
1302
  const noteLabel = (await readNotes()).get(record.pid);
1302
1303
  const header = noteLabel ? `[pid ${record.pid} ${shortenPath(record.cwd)} * ${noteLabel}]` : `[pid ${record.pid} ${shortenPath(record.cwd)}]`;
1303
1304
  if (follow) {
1304
1305
  const rendered = await renderRawLog(buf, {
1305
1306
  mode,
1306
- n
1307
+ n,
1308
+ cols: size?.cols,
1309
+ rows: size?.rows
1307
1310
  });
1308
1311
  process.stderr.write(header + "\n");
1309
1312
  process.stdout.write(rendered);
@@ -1311,7 +1314,10 @@ async function cmdRead(rest, { mode }) {
1311
1314
  setInterval(() => void recordRead(reader.key, record.pid), 3e4).unref?.();
1312
1315
  return plain ? followPlainLocal(logPath, buf) : followRawLocal(logPath, buf);
1313
1316
  }
1314
- const allLines = await renderRawLogLines(buf);
1317
+ const allLines = await renderRawLogLines(buf, {
1318
+ cols: size?.cols,
1319
+ rows: size?.rows
1320
+ });
1315
1321
  const total = allLines.length;
1316
1322
  const win = resolveReadWindow({
1317
1323
  total,
@@ -1493,11 +1499,31 @@ async function followPlainLocal(logPath, buf) {
1493
1499
  return 0;
1494
1500
  }
1495
1501
  /**
1502
+ * Read an agent's last-known PTY geometry from `~/.agent-yes/ptysize/<pid>`
1503
+ * (written by both runtimes — ts/index.ts and rs/src/pty_spawner.rs — as
1504
+ * "<cols> <rows>\n"). Returns null when there's no sidecar (older agent, or not
1505
+ * yet written).
1506
+ */
1507
+ async function readPtysize(pid) {
1508
+ const dir = process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes");
1509
+ try {
1510
+ const [c = 0, r = 0] = (await readFile(path.join(dir, "ptysize", String(pid)), "utf-8")).trim().split(/\s+/).map(Number);
1511
+ if (c > 0 && r > 0) return {
1512
+ cols: c,
1513
+ rows: r
1514
+ };
1515
+ } catch {}
1516
+ return null;
1517
+ }
1518
+ /**
1496
1519
  * Feed the raw PTY bytes through @xterm/headless and emit plain text.
1497
1520
  * Same approach as koho's renderTerminalBuffer + agent-yes's XtermProxy.
1498
1521
  */
1499
- async function renderRawLog(buf, { mode, n }) {
1500
- const lines = await renderRawLogLines(buf);
1522
+ async function renderRawLog(buf, { mode, n, cols, rows }) {
1523
+ const lines = await renderRawLogLines(buf, {
1524
+ cols,
1525
+ rows
1526
+ });
1501
1527
  if (mode === "cat") return lines.join("\n");
1502
1528
  if (mode === "tail") return lines.slice(Math.max(0, lines.length - n)).join("\n");
1503
1529
  return lines.slice(0, n).join("\n");
@@ -1510,9 +1536,9 @@ async function renderRawLog(buf, { mode, n }) {
1510
1536
  * cursor moves / clears / wraps), so we always render the whole buffer once and
1511
1537
  * window the resulting lines.
1512
1538
  */
1513
- async function renderRawLogLines(buf) {
1514
- const cols = 200;
1515
- const rows = 50;
1539
+ async function renderRawLogLines(buf, geom) {
1540
+ const cols = geom?.cols && geom.cols > 0 ? geom.cols : 200;
1541
+ const rows = geom?.rows && geom.rows > 0 ? geom.rows : 50;
1516
1542
  const scrollback = 5e4;
1517
1543
  try {
1518
1544
  const { Terminal } = await import("@xterm/headless");
@@ -2592,5 +2618,5 @@ async function cmdResultSet(rest) {
2592
2618
  }
2593
2619
 
2594
2620
  //#endregion
2595
- export { stopTipForCli as C, snapshotStatus as S, renderRawLog as _, cursorAbs as a, resolveReadWindow as b, extractTaskCounts as c, isExitRequest as d, isPidAlive as f, readNotes as g, matchKeyword as h, controlCodeFromName as i, finalizedLines as l, listRecords as m, READ_PAGE_DEFAULT as n, deriveLiveStatus as o, isSubcommand as p, cmdHelp as r, extractNeedsInput as s, GRACEFUL_EXIT_COMMANDS as t, isAgentStuck as u, renderRawLogLines as v, writeToIpc as w, runSubcommand as x, resolveOne as y };
2596
- //# sourceMappingURL=subcommands-OyK7Y447.js.map
2621
+ export { snapshotStatus as C, runSubcommand as S, writeToIpc as T, readPtysize as _, cursorAbs as a, resolveOne as b, extractTaskCounts as c, isExitRequest as d, isPidAlive as f, readNotes as g, matchKeyword as h, controlCodeFromName as i, finalizedLines as l, listRecords as m, READ_PAGE_DEFAULT as n, deriveLiveStatus as o, isSubcommand as p, cmdHelp as r, extractNeedsInput as s, GRACEFUL_EXIT_COMMANDS as t, isAgentStuck as u, renderRawLog as v, stopTipForCli as w, resolveReadWindow as x, renderRawLogLines as y };
2622
+ //# sourceMappingURL=subcommands-BtUKGF4n.js.map
@@ -1,5 +1,5 @@
1
1
  import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
2
- import { r as getInstalledPackage } from "./versionChecker-C-JJk14E.js";
2
+ import { r as getInstalledPackage } from "./versionChecker-CeVZzVQB.js";
3
3
  import { t as agentYesHome } from "./agentYesHome-_eJa3DaX.js";
4
4
  import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-V4qvXgAw.js";
5
5
  import { t as PidStore } from "./pidStore-fqXqTKkh.js";
@@ -1228,8 +1228,10 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
1228
1228
  if (unresolved) continue;
1229
1229
  ptyEnv[key] = value;
1230
1230
  }
1231
+ if (!ptyEnv.TERM) ptyEnv.TERM = "xterm-256color";
1232
+ if (!ptyEnv.COLORTERM) ptyEnv.COLORTERM = "truecolor";
1231
1233
  const ptyOptions = {
1232
- name: "xterm-color",
1234
+ name: ptyEnv.TERM,
1233
1235
  ...getTerminalDimensions(),
1234
1236
  cwd: cwd ?? process.cwd(),
1235
1237
  env: ptyEnv
@@ -1330,7 +1332,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
1330
1332
  let [bin, ...args] = [...parseCommandString(cliConf?.binary || cli), ...cliArgs.filter((arg) => !["--continue", "--resume"].includes(arg))];
1331
1333
  logger.info(`Restarting ${cli} ${JSON.stringify([bin, ...args])}`);
1332
1334
  const restartPtyOptions = {
1333
- name: "xterm-color",
1335
+ name: ptyEnv.TERM,
1334
1336
  ...getTerminalDimensions(),
1335
1337
  cwd: cwd ?? process.cwd(),
1336
1338
  env: ptyEnv
@@ -1414,7 +1416,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
1414
1416
  } else logger.debug(`restore|no stored session, using default restore args`);
1415
1417
  }
1416
1418
  const restorePtyOptions = {
1417
- name: "xterm-color",
1419
+ name: ptyEnv.TERM,
1418
1420
  ...getTerminalDimensions(),
1419
1421
  cwd: cwd ?? process.cwd(),
1420
1422
  env: ptyEnv
@@ -1800,4 +1802,4 @@ function sleep(ms) {
1800
1802
 
1801
1803
  //#endregion
1802
1804
  export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
1803
- //# sourceMappingURL=ts-C21nFgXQ.js.map
1805
+ //# sourceMappingURL=ts-Cng1o5fC.js.map
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
7
7
 
8
8
  //#region package.json
9
9
  var name = "claude-yes";
10
- var version = "1.149.1";
10
+ var version = "1.150.0";
11
11
 
12
12
  //#endregion
13
13
  //#region ts/versionChecker.ts
@@ -215,4 +215,4 @@ async function displayVersion() {
215
215
 
216
216
  //#endregion
217
217
  export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
218
- //# sourceMappingURL=versionChecker-C-JJk14E.js.map
218
+ //# sourceMappingURL=versionChecker-CeVZzVQB.js.map
package/lab/ui/index.html CHANGED
@@ -3794,6 +3794,18 @@
3794
3794
  }, 120);
3795
3795
  }
3796
3796
 
3797
+ // Auto-derive a branch name from the typed prompt for the Cmd+K fork action
3798
+ // (editable at launch). e.g. "fix the auth bug" → "fork/fix-the-auth-bug".
3799
+ function forkSlug(q) {
3800
+ const s = q
3801
+ .toLowerCase()
3802
+ .replace(/[^a-z0-9]+/g, "-")
3803
+ .replace(/^-+|-+$/g, "")
3804
+ .slice(0, 40)
3805
+ .replace(/-+$/, "");
3806
+ return "fork/" + (s || "wip");
3807
+ }
3808
+
3797
3809
  function renderOmni() {
3798
3810
  const q = $("omni-input").value.trim();
3799
3811
  if (omniIdx >= omniRows.length) omniIdx = Math.max(0, omniRows.length - 1);
@@ -3809,6 +3821,22 @@
3809
3821
  <div class="omni-sub">${esc(anchor?.cwd || "(host default)")} &nbsp;·&nbsp; prompt: ${esc(q || "(empty)")}</div>
3810
3822
  </div></div>`;
3811
3823
  }
3824
+ if (r.kind === "fork") {
3825
+ return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
3826
+ <span class="dot active"></span>
3827
+ <div class="omni-main">
3828
+ <div class="omni-title">⑂ Fork current branch &amp; run <span style="opacity:.55">(carries uncommitted work)</span></div>
3829
+ <div class="omni-sub">${esc(anchor?.cwd || "?")} &nbsp;→&nbsp; new branch <b>${esc(r.branch)}</b> &nbsp;·&nbsp; ⏎ to edit &amp; launch</div>
3830
+ </div></div>`;
3831
+ }
3832
+ if (r.kind === "spawncwd") {
3833
+ return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
3834
+ <span class="dot active"></span>
3835
+ <div class="omni-main">
3836
+ <div class="omni-title">⊕ Spawn new ${esc(anchor?.cli || "claude")} agent in a directory…</div>
3837
+ <div class="omni-sub">⏎ to choose a working dir &nbsp;·&nbsp; prompt: ${esc(q || "(empty)")}</div>
3838
+ </div></div>`;
3839
+ }
3812
3840
  const e = r.entry;
3813
3841
  const snip = r.snippet ? `<div class="omni-snip">…${r.snippet}…</div>` : "";
3814
3842
  return `<div class="omni-row${sc}" data-i="${i}">
@@ -3837,7 +3865,12 @@
3837
3865
  )
3838
3866
  .slice(0, 30);
3839
3867
  omniRows = hits.map((entry) => ({ kind: "agent", entry }));
3840
- if (q) omniRows.push({ kind: "spawn" });
3868
+ if (q) {
3869
+ omniRows.push({ kind: "spawn" });
3870
+ const anchor = omniAnchor();
3871
+ if (anchor?.cwd) omniRows.push({ kind: "fork", branch: forkSlug(q) });
3872
+ omniRows.push({ kind: "spawncwd" });
3873
+ }
3841
3874
  omniIdx = 0;
3842
3875
  renderOmni();
3843
3876
  // Tier 2 — debounced output (tail) search for alive agents not already shown.
@@ -3902,8 +3935,9 @@
3902
3935
  async function omniActivate(forceSpawn) {
3903
3936
  const q = $("omni-input").value.trim();
3904
3937
  const row = omniRows[omniIdx];
3938
+ const anchor = omniAnchor();
3939
+ // ⌘⏎ always = spawn-here (the fast default), regardless of the selected row.
3905
3940
  if (forceSpawn || (row && row.kind === "spawn")) {
3906
- const anchor = omniAnchor();
3907
3941
  closeOmni(false); // committing — keep the bg as-is, spawnAndSelect takes over
3908
3942
  await spawnAndSelect(
3909
3943
  { cli: anchor?.cli || "claude", cwd: anchor?.cwd || undefined, prompt: q || undefined },
@@ -3911,6 +3945,31 @@
3911
3945
  );
3912
3946
  return;
3913
3947
  }
3948
+ if (row && row.kind === "fork") {
3949
+ // Editable at launch (auto-slug is the default); carries the anchor's WIP.
3950
+ const branch = prompt("Fork to a new branch (carries your uncommitted work):", row.branch);
3951
+ if (!branch || !branch.trim()) return; // cancelled — leave the omnibox open
3952
+ closeOmni(false);
3953
+ await spawnAndSelect(
3954
+ {
3955
+ cli: anchor?.cli || "claude",
3956
+ prompt: q || undefined,
3957
+ fork: { fromCwd: anchor?.cwd, branch: branch.trim() },
3958
+ },
3959
+ anchor?._room,
3960
+ );
3961
+ return;
3962
+ }
3963
+ if (row && row.kind === "spawncwd") {
3964
+ const cwd = prompt("Spawn in which working directory?", anchor?.cwd || "");
3965
+ if (cwd == null) return; // cancelled
3966
+ closeOmni(false);
3967
+ await spawnAndSelect(
3968
+ { cli: anchor?.cli || "claude", cwd: cwd.trim() || undefined, prompt: q || undefined },
3969
+ anchor?._room,
3970
+ );
3971
+ return;
3972
+ }
3914
3973
  if (row && row.kind === "agent") {
3915
3974
  closeOmni(false); // committing the previewed agent — don't restore the original
3916
3975
  select(row.entry._key);
@@ -4335,6 +4394,7 @@
4335
4394
  const res = await target.tx.post("/api/spawn", {
4336
4395
  cli: spec.cli || "claude",
4337
4396
  from: spec.from || undefined,
4397
+ fork: spec.fork || undefined,
4338
4398
  cwd: spec.cwd || undefined,
4339
4399
  prompt: spec.prompt || undefined,
4340
4400
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.149.1",
3
+ "version": "1.150.0",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
package/ts/index.ts CHANGED
@@ -395,8 +395,17 @@ export default async function agentYes({
395
395
  ptyEnv[key] = value;
396
396
  }
397
397
  }
398
+ // The agent runs in a PTY (a real terminal), so advertise terminal
399
+ // capabilities. A console/daemon-spawned agent inherits an env with no TERM/
400
+ // COLORTERM: neither the daemon (no controlling terminal) nor the recovered
401
+ // login-shell env (captured without a tty) carries them — those vars are set
402
+ // by the terminal emulator, not by the shell. Without them the wrapped CLI
403
+ // renders colorless in the web console. Fill only when absent so a
404
+ // terminal-launched agent keeps its real values (e.g. xterm-256color, tmux).
405
+ if (!ptyEnv.TERM) ptyEnv.TERM = "xterm-256color";
406
+ if (!ptyEnv.COLORTERM) ptyEnv.COLORTERM = "truecolor";
398
407
  const ptyOptions = {
399
- name: "xterm-color",
408
+ name: ptyEnv.TERM,
400
409
  ...getTerminalDimensions(),
401
410
  cwd: cwd ?? process.cwd(),
402
411
  env: ptyEnv,
@@ -561,7 +570,7 @@ export default async function agentYes({
561
570
  logger.info(`Restarting ${cli} ${JSON.stringify([bin, ...args])}`);
562
571
 
563
572
  const restartPtyOptions = {
564
- name: "xterm-color",
573
+ name: ptyEnv.TERM,
565
574
  ...getTerminalDimensions(),
566
575
  cwd: cwd ?? process.cwd(),
567
576
  env: ptyEnv,
@@ -667,7 +676,7 @@ export default async function agentYes({
667
676
  }
668
677
 
669
678
  const restorePtyOptions = {
670
- name: "xterm-color",
679
+ name: ptyEnv.TERM,
671
680
  ...getTerminalDimensions(),
672
681
  cwd: cwd ?? process.cwd(),
673
682
  env: ptyEnv,
package/ts/serve.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  extractTaskCounts,
12
12
  listRecords,
13
13
  readNotes,
14
+ readPtysize,
14
15
  renderRawLog,
15
16
  resolveOne,
16
17
  snapshotStatus,
@@ -1163,7 +1164,8 @@ export async function cmdServe(rest: string[]): Promise<number> {
1163
1164
  if (!record.log_file)
1164
1165
  return new Response(`pid ${record.pid}: no log_file`, { status: 404 });
1165
1166
  const buf = await readFile(record.log_file);
1166
- const text = await renderRawLog(buf, { mode, n });
1167
+ const size = await readPtysize(record.pid);
1168
+ const text = await renderRawLog(buf, { mode, n, cols: size?.cols, rows: size?.rows });
1167
1169
  return new Response(text, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
1168
1170
  } catch (e) {
1169
1171
  return new Response((e as Error).message, { status: 404 });
@@ -1177,20 +1179,12 @@ export async function cmdServe(rest: string[]): Promise<number> {
1177
1179
  const keyword = decodeURIComponent(sizeM[1]!);
1178
1180
  try {
1179
1181
  const record = await resolveOne(keyword, defaultOpts());
1180
- const ayHome = process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes");
1181
- let cols: number | null = null;
1182
- let rows: number | null = null;
1183
- try {
1184
- const txt = await readFile(path.join(ayHome, "ptysize", String(record.pid)), "utf-8");
1185
- const [c = 0, r = 0] = txt.trim().split(/\s+/).map(Number);
1186
- if (c > 0 && r > 0) {
1187
- cols = c;
1188
- rows = r;
1189
- }
1190
- } catch {
1191
- /* no ptysize sidecar (older agent or not yet written) */
1192
- }
1193
- return Response.json({ pid: record.pid, cols, rows });
1182
+ const size = await readPtysize(record.pid);
1183
+ return Response.json({
1184
+ pid: record.pid,
1185
+ cols: size?.cols ?? null,
1186
+ rows: size?.rows ?? null,
1187
+ });
1194
1188
  } catch (e) {
1195
1189
  return new Response((e as Error).message, { status: 404 });
1196
1190
  }
@@ -1478,7 +1472,13 @@ export async function cmdServe(rest: string[]): Promise<number> {
1478
1472
  // standard); otherwise `cwd` is resolved against the workspace root and
1479
1473
  // created if missing (Layer-0 plain-dir provisioning — no more ENOENT 500).
1480
1474
  if (req.method === "POST" && p === "/api/spawn") {
1481
- let body: { cli?: string; cwd?: string; from?: string; prompt?: string };
1475
+ let body: {
1476
+ cli?: string;
1477
+ cwd?: string;
1478
+ from?: string;
1479
+ prompt?: string;
1480
+ fork?: { fromCwd?: string; branch?: string };
1481
+ };
1482
1482
  try {
1483
1483
  body = (await req.json()) as typeof body;
1484
1484
  } catch {
@@ -1494,8 +1494,61 @@ export async function cmdServe(rest: string[]): Promise<number> {
1494
1494
  // workspace root and mkdir-p'd so a missing dir no longer ENOENTs.
1495
1495
  let cwd: string;
1496
1496
  let provisioned: { action: string; folder: string } | null = null;
1497
+ const fork =
1498
+ body.fork && typeof body.fork.fromCwd === "string" && typeof body.fork.branch === "string"
1499
+ ? { fromCwd: body.fork.fromCwd, branch: body.fork.branch }
1500
+ : null;
1497
1501
  const from = typeof body.from === "string" ? body.from.trim() : "";
1498
- if (from) {
1502
+ if (fork) {
1503
+ // Fork the anchor agent's branch (carrying its WIP) into a new sibling
1504
+ // worktree via codehost/provision (git worktree off HEAD, no clone), then
1505
+ // spawn the agent there.
1506
+ let prov: {
1507
+ forkWorktree: (o: { fromCwd: string; branch: string; wsRoot?: string }) => Promise<{
1508
+ ok: boolean;
1509
+ folder: string;
1510
+ action: string;
1511
+ error?: string;
1512
+ spec?: { owner: string; repo: string };
1513
+ }>;
1514
+ };
1515
+ try {
1516
+ prov = (await import("codehost/provision")) as typeof prov;
1517
+ } catch (e) {
1518
+ return new Response(
1519
+ `fork needs the 'codehost' package (codehost/provision) — install it ` +
1520
+ `(npm i -g codehost) or 'bun link' it for local dev: ${(e as Error).message}`,
1521
+ { status: 501 },
1522
+ );
1523
+ }
1524
+ let result: {
1525
+ ok: boolean;
1526
+ folder: string;
1527
+ action: string;
1528
+ error?: string;
1529
+ spec?: { owner: string; repo: string };
1530
+ };
1531
+ try {
1532
+ const wsRoot = getProvisionRoot();
1533
+ result = await prov.forkWorktree({
1534
+ fromCwd: fork.fromCwd,
1535
+ branch: fork.branch,
1536
+ ...(wsRoot ? { wsRoot } : {}),
1537
+ });
1538
+ } catch (e) {
1539
+ return new Response(`fork failed: ${(e as Error).message}`, { status: 502 });
1540
+ }
1541
+ if (!result?.ok) return new Response(result?.error ?? "fork failed", { status: 502 });
1542
+ // Same allowlist gate as `from` — the fork runs setup-repo.sh (code exec).
1543
+ if (result.spec && !isProvisionAllowed(result.spec.owner, result.spec.repo))
1544
+ return new Response(
1545
+ `forking '${result.spec.owner}/${result.spec.repo}' is not allowed — add the owner ` +
1546
+ `to provisionAllowlist in ~/.agent-yes/config.json (or "*" to allow all)`,
1547
+ { status: 403 },
1548
+ );
1549
+ cwd = result.folder;
1550
+ provisioned = { action: result.action, folder: result.folder };
1551
+ } else if (from) {
1499
1552
  type Spec = { owner: string; repo: string; branch: string };
1500
1553
  let prov: {
1501
1554
  parseSource?: (s: string) => Spec | null;
@@ -1553,7 +1606,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
1553
1606
  }
1554
1607
  }
1555
1608
  process.stderr.write(
1556
- `→ console spawned: ay ${cli}${prompt ? ` -- "${prompt.slice(0, 60)}"` : ""} (cwd: ${cwd}${provisioned ? `, ${provisioned.action} from ${from}` : ""})\n`,
1609
+ `→ console spawned: ay ${cli}${prompt ? ` -- "${prompt.slice(0, 60)}"` : ""} (cwd: ${cwd}${provisioned ? `, ${provisioned.action}` : ""})\n`,
1557
1610
  );
1558
1611
  // Resolve `ay` to an absolute command. The detached daemon (oxmgr/launchd/
1559
1612
  // pm2) usually has a PATH WITHOUT ~/.bun/bin, so a bare "ay" fails with
@@ -1718,3 +1718,80 @@ describe("subcommands.isAgentStuck / stuck state", () => {
1718
1718
  }
1719
1719
  });
1720
1720
  });
1721
+
1722
+ // A CLI like Claude Code repaints by moving the cursor UP over the previous
1723
+ // frame and rewriting it. The up-count is the frame's height AT THE AGENT'S REAL
1724
+ // WIDTH. Replayed narrower, the body line wraps to an extra row, the up-count
1725
+ // undershoots, and every old frame strands below as a duplicate — the `ay tail`
1726
+ // stutter. `bodyLen` chars stay one row at the real width but wrap below it.
1727
+ function buildRedrawLog(frames: number, bodyLen: number): Buffer {
1728
+ const body = "BODY-" + "z".repeat(Math.max(0, bodyLen - 5));
1729
+ const frame = (i: number) => `HEADER-${i}\r\n${body}`;
1730
+ let bytes = frame(0) + "\r\n";
1731
+ for (let i = 1; i < frames; i++) bytes += `\x1b[2A\r` + frame(i) + "\r\n"; // up 2 = header+body at real width
1732
+ return Buffer.from(bytes);
1733
+ }
1734
+ const countHeaders = (s: string) => (s.match(/^HEADER-\d+/gm) ?? []).length;
1735
+
1736
+ describe("renderRawLog honors the agent's recorded PTY geometry", () => {
1737
+ it("collapses redraw frames at the recorded width but duplicates at a mismatched width", async () => {
1738
+ const { renderRawLog } = await loadModule();
1739
+ const buf = buildRedrawLog(6, 220); // one row at >=220 cols, two rows below that
1740
+
1741
+ // Replayed at the real width, each repaint lands on the prior frame: one header.
1742
+ const correct = await renderRawLog(buf, { mode: "cat", n: 0, cols: 240, rows: 50 });
1743
+ expect(countHeaders(correct)).toBe(1);
1744
+
1745
+ // Replayed narrower (the body wraps), repaints undershoot and pile up.
1746
+ const wrong = await renderRawLog(buf, { mode: "cat", n: 0, cols: 120, rows: 50 });
1747
+ expect(countHeaders(wrong)).toBeGreaterThan(1);
1748
+ });
1749
+ });
1750
+
1751
+ describe("subcommands.cmdRead replays at the ptysize sidecar geometry", () => {
1752
+ it("renders at the recorded geometry, not the 200-col fallback", async () => {
1753
+ const { runSubcommand } = await loadModule();
1754
+ const { appendGlobalPid } = await import("./globalPidIndex.ts");
1755
+ const tmp = await mkdtemp(path.join(tmpdir(), "ay-raw-log-"));
1756
+ try {
1757
+ const logPath = path.join(tmp, "wide.raw.log");
1758
+ // Authored for a 240-col terminal; at the 200-col fallback the body wraps
1759
+ // and the redraw duplicates (see buildRedrawLog / renderRawLogLines).
1760
+ await writeFile(logPath, buildRedrawLog(6, 220));
1761
+
1762
+ // ptysize sidecar lives under the (mocked) home: ~/.agent-yes/ptysize/<pid>.
1763
+ const ptDir = path.join(testHome, ".agent-yes", "ptysize");
1764
+ await mkdir(ptDir, { recursive: true });
1765
+ await writeFile(path.join(ptDir, String(process.pid)), "240 50\n");
1766
+
1767
+ await appendGlobalPid({
1768
+ pid: process.pid,
1769
+ cli: "claude",
1770
+ prompt: null,
1771
+ cwd: process.cwd(),
1772
+ log_file: logPath,
1773
+ status: "active" as const,
1774
+ exit_code: null,
1775
+ exit_reason: null,
1776
+ started_at: Date.now(),
1777
+ });
1778
+
1779
+ const stdout: string[] = [];
1780
+ const orig = process.stdout.write.bind(process.stdout);
1781
+ (process.stdout as any).write = (s: any) => {
1782
+ stdout.push(String(s));
1783
+ return true;
1784
+ };
1785
+ try {
1786
+ const code = await runSubcommand(["bun", "cli.js", "cat", String(process.pid)]);
1787
+ expect(code).toBe(0);
1788
+ } finally {
1789
+ process.stdout.write = orig;
1790
+ }
1791
+ // With the sidecar honored, the six repaints collapse to a single frame.
1792
+ expect(countHeaders(stdout.join(""))).toBe(1);
1793
+ } finally {
1794
+ await rm(tmp, { recursive: true, force: true }).catch(() => null);
1795
+ }
1796
+ });
1797
+ });
package/ts/subcommands.ts CHANGED
@@ -1406,6 +1406,7 @@ async function cmdRead(rest: string[], { mode }: ReadOpts): Promise<number> {
1406
1406
  }
1407
1407
 
1408
1408
  const buf = await readFile(logPath);
1409
+ const size = await readPtysize(record.pid);
1409
1410
  const notes = await readNotes();
1410
1411
  const noteLabel = notes.get(record.pid);
1411
1412
  const header = noteLabel
@@ -1414,7 +1415,7 @@ async function cmdRead(rest: string[], { mode }: ReadOpts): Promise<number> {
1414
1415
 
1415
1416
  if (follow) {
1416
1417
  // Follow mode ignores pagination: print the initial context, then stream deltas.
1417
- const rendered = await renderRawLog(buf, { mode, n });
1418
+ const rendered = await renderRawLog(buf, { mode, n, cols: size?.cols, rows: size?.rows });
1418
1419
  process.stderr.write(header + "\n");
1419
1420
  process.stdout.write(rendered);
1420
1421
  if (!rendered.endsWith("\n")) process.stdout.write("\n");
@@ -1427,7 +1428,7 @@ async function cmdRead(rest: string[], { mode }: ReadOpts): Promise<number> {
1427
1428
 
1428
1429
  // Static read: render the full log once, then window into the rendered lines
1429
1430
  // so line numbers (and the pagination cursor in the footer) are exact.
1430
- const allLines = await renderRawLogLines(buf);
1431
+ const allLines = await renderRawLogLines(buf, { cols: size?.cols, rows: size?.rows });
1431
1432
  const total = allLines.length;
1432
1433
  const win = resolveReadWindow({
1433
1434
  total,
@@ -1663,15 +1664,42 @@ async function followPlainLocal(logPath: string, buf: Uint8Array): Promise<numbe
1663
1664
  return 0;
1664
1665
  }
1665
1666
 
1667
+ /**
1668
+ * The agent's real PTY geometry (from readPtysize), passed to the renderers so
1669
+ * the raw log replays at the size it was authored for. Omitted → a wide 200x50
1670
+ * default; if the agent ran wider/taller than that its cursor-addressed redraw
1671
+ * frames undershoot on replay and strand into scrollback as duplicates (the
1672
+ * `ay tail` stutter this guards).
1673
+ */
1674
+ type RenderGeom = { cols?: number; rows?: number };
1675
+
1676
+ /**
1677
+ * Read an agent's last-known PTY geometry from `~/.agent-yes/ptysize/<pid>`
1678
+ * (written by both runtimes — ts/index.ts and rs/src/pty_spawner.rs — as
1679
+ * "<cols> <rows>\n"). Returns null when there's no sidecar (older agent, or not
1680
+ * yet written).
1681
+ */
1682
+ export async function readPtysize(pid: number): Promise<{ cols: number; rows: number } | null> {
1683
+ const dir = process.env.AGENT_YES_HOME ?? path.join(homedir(), ".agent-yes");
1684
+ try {
1685
+ const txt = await readFile(path.join(dir, "ptysize", String(pid)), "utf-8");
1686
+ const [c = 0, r = 0] = txt.trim().split(/\s+/).map(Number);
1687
+ if (c > 0 && r > 0) return { cols: c, rows: r };
1688
+ } catch {
1689
+ /* no ptysize sidecar */
1690
+ }
1691
+ return null;
1692
+ }
1693
+
1666
1694
  /**
1667
1695
  * Feed the raw PTY bytes through @xterm/headless and emit plain text.
1668
1696
  * Same approach as koho's renderTerminalBuffer + agent-yes's XtermProxy.
1669
1697
  */
1670
1698
  export async function renderRawLog(
1671
1699
  buf: Uint8Array,
1672
- { mode, n }: { mode: "cat" | "tail" | "head"; n: number },
1700
+ { mode, n, cols, rows }: { mode: "cat" | "tail" | "head"; n: number } & RenderGeom,
1673
1701
  ): Promise<string> {
1674
- const lines = await renderRawLogLines(buf);
1702
+ const lines = await renderRawLogLines(buf, { cols, rows });
1675
1703
  if (mode === "cat") return lines.join("\n");
1676
1704
  if (mode === "tail") return lines.slice(Math.max(0, lines.length - n)).join("\n");
1677
1705
  return lines.slice(0, n).join("\n");
@@ -1685,11 +1713,13 @@ export async function renderRawLog(
1685
1713
  * cursor moves / clears / wraps), so we always render the whole buffer once and
1686
1714
  * window the resulting lines.
1687
1715
  */
1688
- export async function renderRawLogLines(buf: Uint8Array): Promise<string[]> {
1689
- // Default screen geometry we don't know what the agent used, but
1690
- // 200x50 is a reasonable upper bound that won't truncate normal output.
1691
- const cols = 200;
1692
- const rows = 50;
1716
+ export async function renderRawLogLines(buf: Uint8Array, geom?: RenderGeom): Promise<string[]> {
1717
+ // Replay at the agent's real geometry when known (see RenderGeom / readPtysize);
1718
+ // otherwise fall back to a wide 200x50 a reasonable upper bound that won't
1719
+ // truncate normal output, though an agent wider/taller than it can still
1720
+ // duplicate on replay (which is why callers pass the recorded size).
1721
+ const cols = geom?.cols && geom.cols > 0 ? geom.cols : 200;
1722
+ const rows = geom?.rows && geom.rows > 0 ? geom.rows : 50;
1693
1723
  // Scrollback caps how far back pagination can reach; older lines are evicted.
1694
1724
  const scrollback = 50000;
1695
1725
 
@@ -1,8 +0,0 @@
1
- import "./ts-C21nFgXQ.js";
2
- import "./logger-CDIsZ-Pp.js";
3
- import "./versionChecker-C-JJk14E.js";
4
- import "./pidStore-fqXqTKkh.js";
5
- import "./globalPidIndex-DlmmJlO8.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DyQjQODe.js";
7
-
8
- export { SUPPORTED_CLIS };
@@ -1,9 +0,0 @@
1
- import "./logger-CDIsZ-Pp.js";
2
- import "./globalPidIndex-DlmmJlO8.js";
3
- import "./configShared-C1C04bbq.js";
4
- import "./e2e-ClOI_aqV.js";
5
- import "./webrtcLink-BWhuA74k.js";
6
- import "./remotes-qK6uozO4.js";
7
- import { C as stopTipForCli, S as snapshotStatus, _ as renderRawLog, a as cursorAbs, b as resolveReadWindow, c as extractTaskCounts, d as isExitRequest, f as isPidAlive, g as readNotes, h as matchKeyword, i as controlCodeFromName, l as finalizedLines, m as listRecords, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isSubcommand, r as cmdHelp, s as extractNeedsInput, t as GRACEFUL_EXIT_COMMANDS, u as isAgentStuck, v as renderRawLogLines, w as writeToIpc, x as runSubcommand, y as resolveOne } from "./subcommands-OyK7Y447.js";
8
-
9
- export { cmdHelp, isSubcommand, runSubcommand };