claude-yes 1.154.0 → 1.155.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.
- package/default.config.yaml +10 -0
- package/dist/{SUPPORTED_CLIS-Dam11bMz.js → SUPPORTED_CLIS-5mRGfioE.js} +2 -2
- package/dist/SUPPORTED_CLIS-BNoM41LQ.js +8 -0
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{schedule-BPFBe7R5.js → schedule-TJEVE-qs.js} +4 -4
- package/dist/{serve-BYc2J-2F.js → serve-CqTdebcG.js} +39 -8
- package/dist/{setup-D9emVJYz.js → setup-B3Vf8zfq.js} +2 -2
- package/dist/{subcommands-DLvC6kto.js → subcommands-BmxH2HjH.js} +1 -1
- package/dist/{subcommands-C4tMi9NX.js → subcommands-DKL_x1ZC.js} +4 -4
- package/dist/{ts-U3AE4u72.js → ts-CQZuynAm.js} +2 -2
- package/dist/{versionChecker-B-ToHoJ2.js → versionChecker-DGqHb9YC.js} +2 -2
- package/lab/ui/index.html +52 -9
- package/package.json +1 -1
- package/ts/serve.ts +46 -2
- package/dist/SUPPORTED_CLIS-CmM_zBrM.js +0 -8
package/default.config.yaml
CHANGED
|
@@ -74,6 +74,16 @@ clis:
|
|
|
74
74
|
# gap across a line-wrap; `\s+`/`\s*` tolerate wraps inside the phrase.
|
|
75
75
|
- pattern: 'API Error:[\s\S]{0,40}Response\s+stalled\s+mid-\s*stream'
|
|
76
76
|
flags: i
|
|
77
|
+
# "API Error: Connection closed mid-response. The response above may be
|
|
78
|
+
# incomplete." — the HTTP/SSE connection dropped before the response
|
|
79
|
+
# finished. Same class as the stalled-mid-stream case (transient, the
|
|
80
|
+
# partial answer is already on screen), so retry with backoff instead of
|
|
81
|
+
# wedging. Same "API Error:" chrome anchor keeps an agent merely
|
|
82
|
+
# *discussing* a dropped connection from self-triggering a retry;
|
|
83
|
+
# `[\s\S]{0,40}` spans the prefix→phrase gap across a line-wrap and
|
|
84
|
+
# `\s+`/`\s*` tolerate wraps inside the phrase.
|
|
85
|
+
- pattern: 'API Error:[\s\S]{0,40}Connection\s+closed\s+mid-\s*response'
|
|
86
|
+
flags: i
|
|
77
87
|
# Any 5xx API error (e.g. "API Error: 529 Overloaded", "API Error: 503 …",
|
|
78
88
|
# or a 529 rendered as a raw JSON error blob) is server-side + transient —
|
|
79
89
|
# retry with backoff regardless of the wording. Anchored to "API Error" so
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-CQZuynAm.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-
|
|
8
|
+
//# sourceMappingURL=SUPPORTED_CLIS-5mRGfioE.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-CQZuynAm.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-DGqHb9YC.js";
|
|
4
|
+
import "./pidStore-fqXqTKkh.js";
|
|
5
|
+
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5mRGfioE.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
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-
|
|
4
|
+
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-DGqHb9YC.js";
|
|
5
5
|
import { argv } from "process";
|
|
6
6
|
import { execFileSync, spawn } from "child_process";
|
|
7
7
|
import ms from "ms";
|
|
@@ -481,7 +481,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
481
481
|
const rawArg = process.argv[2];
|
|
482
482
|
const managerCommands = !invokedCliName(process.argv);
|
|
483
483
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
484
|
-
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-
|
|
484
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-BmxH2HjH.js");
|
|
485
485
|
if (isHelpFlag && process.argv.length === 3) {
|
|
486
486
|
cmdHelp(managerCommands);
|
|
487
487
|
process.exit(0);
|
|
@@ -514,7 +514,7 @@ if (config.useRust) {
|
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
516
|
if (rustBinary) {
|
|
517
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
517
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BNoM41LQ.js");
|
|
518
518
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
519
519
|
if (config.verbose) {
|
|
520
520
|
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-
|
|
1
|
+
import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-CQZuynAm.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DGqHb9YC.js";
|
|
4
4
|
import "./pidStore-fqXqTKkh.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
6
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CQZuynAm.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DGqHb9YC.js";
|
|
4
4
|
import "./pidStore-fqXqTKkh.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5mRGfioE.js";
|
|
7
7
|
import { i as resolveSpawnCwd } from "./workspaceConfig-DT3cCBZK.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-
|
|
144
|
+
//# sourceMappingURL=schedule-TJEVE-qs.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CQZuynAm.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-DGqHb9YC.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-CEyhl0WH.js";
|
|
8
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
8
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-5mRGfioE.js";
|
|
9
9
|
import "./e2e-Bfw7qL9O.js";
|
|
10
10
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
11
11
|
import "./remotes-DBCvpp3B.js";
|
|
12
12
|
import { i as resolveSpawnCwd, r as isProvisionAllowed, t as getProvisionRoot } from "./workspaceConfig-DT3cCBZK.js";
|
|
13
|
-
import { E 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, w as snapshotStatus } from "./subcommands-
|
|
13
|
+
import { E 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, w as snapshotStatus } from "./subcommands-DKL_x1ZC.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";
|
|
@@ -985,6 +985,36 @@ Options:
|
|
|
985
985
|
return new Response(e.message, { status: 404 });
|
|
986
986
|
}
|
|
987
987
|
}
|
|
988
|
+
if (req.method === "POST" && p === "/api/restart") {
|
|
989
|
+
let body;
|
|
990
|
+
try {
|
|
991
|
+
body = await req.json();
|
|
992
|
+
} catch {
|
|
993
|
+
return new Response("invalid JSON body", { status: 400 });
|
|
994
|
+
}
|
|
995
|
+
const keyword = body.keyword;
|
|
996
|
+
if (!keyword || typeof keyword !== "string") return new Response("missing keyword", { status: 400 });
|
|
997
|
+
try {
|
|
998
|
+
const record = await resolveOne(keyword, defaultOpts({ all: true }));
|
|
999
|
+
const args = ["restart", String(record.pid)];
|
|
1000
|
+
if (body.fresh) args.push("--fresh");
|
|
1001
|
+
Bun.spawn(["agent-yes", ...args], {
|
|
1002
|
+
cwd: record.cwd,
|
|
1003
|
+
detached: true,
|
|
1004
|
+
stdio: [
|
|
1005
|
+
"ignore",
|
|
1006
|
+
"ignore",
|
|
1007
|
+
"ignore"
|
|
1008
|
+
]
|
|
1009
|
+
}).unref();
|
|
1010
|
+
return Response.json({
|
|
1011
|
+
ok: true,
|
|
1012
|
+
pid: record.pid
|
|
1013
|
+
});
|
|
1014
|
+
} catch (e) {
|
|
1015
|
+
return new Response(e.message, { status: 404 });
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
988
1018
|
const resizeM = /^\/api\/resize\/(.+)$/.exec(p);
|
|
989
1019
|
if (req.method === "POST" && resizeM) {
|
|
990
1020
|
const keyword = decodeURIComponent(resizeM[1]);
|
|
@@ -1055,10 +1085,11 @@ Options:
|
|
|
1055
1085
|
const prompt = String(body.prompt ?? "");
|
|
1056
1086
|
let cwd;
|
|
1057
1087
|
let provisioned = null;
|
|
1058
|
-
const fork = body.fork && typeof body.fork.fromCwd === "string" && typeof body.fork.branch === "string" ? {
|
|
1059
|
-
fromCwd: body.fork.fromCwd,
|
|
1060
|
-
branch: body.fork.branch
|
|
1088
|
+
const fork = body.fork && typeof body.fork.fromCwd === "string" && body.fork.fromCwd.trim() && typeof body.fork.branch === "string" && body.fork.branch.trim() ? {
|
|
1089
|
+
fromCwd: body.fork.fromCwd.trim(),
|
|
1090
|
+
branch: body.fork.branch.trim()
|
|
1061
1091
|
} : null;
|
|
1092
|
+
if (body.fork != null && !fork) return new Response("fork requires a non-empty fromCwd and branch", { status: 400 });
|
|
1062
1093
|
const from = typeof body.from === "string" ? body.from.trim() : "";
|
|
1063
1094
|
if (fork) {
|
|
1064
1095
|
let prov;
|
|
@@ -1272,4 +1303,4 @@ Options:
|
|
|
1272
1303
|
|
|
1273
1304
|
//#endregion
|
|
1274
1305
|
export { cmdServe };
|
|
1275
|
-
//# sourceMappingURL=serve-
|
|
1306
|
+
//# sourceMappingURL=serve-CqTdebcG.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-
|
|
35
|
+
const { cmdServe } = await import("./serve-CqTdebcG.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-
|
|
45
|
+
//# sourceMappingURL=setup-B3Vf8zfq.js.map
|
|
@@ -4,6 +4,6 @@ import "./configShared-CEyhl0WH.js";
|
|
|
4
4
|
import "./e2e-Bfw7qL9O.js";
|
|
5
5
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
6
6
|
import "./remotes-DBCvpp3B.js";
|
|
7
|
-
import { C as runSubcommand, E as writeToIpc, S as resolveResumeArgs, T as stopTipForCli, _ 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 snapshotStatus, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-
|
|
7
|
+
import { C as runSubcommand, E as writeToIpc, S as resolveResumeArgs, T as stopTipForCli, _ 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 snapshotStatus, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-DKL_x1ZC.js";
|
|
8
8
|
|
|
9
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-
|
|
557
|
+
const { cmdServe } = await import("./serve-CqTdebcG.js");
|
|
558
558
|
return cmdServe(rest);
|
|
559
559
|
}
|
|
560
560
|
case "setup": {
|
|
561
|
-
const { cmdSetup } = await import("./setup-
|
|
561
|
+
const { cmdSetup } = await import("./setup-B3Vf8zfq.js");
|
|
562
562
|
return cmdSetup(rest);
|
|
563
563
|
}
|
|
564
564
|
case "schedule": {
|
|
565
|
-
const { cmdSchedule } = await import("./schedule-
|
|
565
|
+
const { cmdSchedule } = await import("./schedule-TJEVE-qs.js");
|
|
566
566
|
return cmdSchedule(rest);
|
|
567
567
|
}
|
|
568
568
|
case "remote": {
|
|
@@ -2710,4 +2710,4 @@ async function cmdResultSet(rest) {
|
|
|
2710
2710
|
|
|
2711
2711
|
//#endregion
|
|
2712
2712
|
export { runSubcommand as C, writeToIpc as E, resolveResumeArgs as S, stopTipForCli 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, snapshotStatus as w, resolveReadWindow as x, renderRawLogLines as y };
|
|
2713
|
-
//# sourceMappingURL=subcommands-
|
|
2713
|
+
//# sourceMappingURL=subcommands-DKL_x1ZC.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-
|
|
2
|
+
import { r as getInstalledPackage } from "./versionChecker-DGqHb9YC.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";
|
|
@@ -1802,4 +1802,4 @@ function sleep(ms) {
|
|
|
1802
1802
|
|
|
1803
1803
|
//#endregion
|
|
1804
1804
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1805
|
-
//# sourceMappingURL=ts-
|
|
1805
|
+
//# sourceMappingURL=ts-CQZuynAm.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.
|
|
10
|
+
var version = "1.155.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-
|
|
218
|
+
//# sourceMappingURL=versionChecker-DGqHb9YC.js.map
|
package/lab/ui/index.html
CHANGED
|
@@ -1386,6 +1386,9 @@
|
|
|
1386
1386
|
>
|
|
1387
1387
|
<div class="rmenusep"></div>
|
|
1388
1388
|
<button class="rmenuitem rmenuact" id="stopAgent" type="button">⏹ Stop agent</button>
|
|
1389
|
+
<button class="rmenuitem rmenuact" id="restartAgent" type="button">
|
|
1390
|
+
↻ Restart (resume)
|
|
1391
|
+
</button>
|
|
1389
1392
|
<button class="rmenuitem rmenuact danger" id="killAgent" type="button">
|
|
1390
1393
|
✕ Force-kill (SIGKILL)
|
|
1391
1394
|
</button>
|
|
@@ -2803,6 +2806,20 @@
|
|
|
2803
2806
|
await send("\r");
|
|
2804
2807
|
}
|
|
2805
2808
|
|
|
2809
|
+
// Restart — stop (if live) + relaunch resuming the session, server-side via
|
|
2810
|
+
// POST /api/restart (the `ay restart` flow). The server runs it detached, so
|
|
2811
|
+
// it's decoupled from this agent's lifecycle — no prompt typed into the agent.
|
|
2812
|
+
async function restartAgent() {
|
|
2813
|
+
const e = sel ? entries.find((x) => x._key === sel) : null;
|
|
2814
|
+
if (!e) return;
|
|
2815
|
+
const who = `pid ${e.pid} ${cliLabel(e) || ident(e) || ""}`.trim();
|
|
2816
|
+
if (!confirm(`Restart ${who}?\nStops it (if live) and relaunches resuming the session.`))
|
|
2817
|
+
return;
|
|
2818
|
+
txFor(e)
|
|
2819
|
+
.post("/api/restart", { keyword: String(e.pid) })
|
|
2820
|
+
.catch(() => {});
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2806
2823
|
// ---- On-screen key bar (mobile) -------------------------------------
|
|
2807
2824
|
// A phone keyboard has no Esc/Tab/Ctrl/arrows, so agent TUIs (claude,
|
|
2808
2825
|
// codex, vim…) are otherwise undriveable. The bar posts raw byte
|
|
@@ -2994,6 +3011,7 @@
|
|
|
2994
3011
|
}
|
|
2995
3012
|
if (cb) cb.addEventListener("change", () => setPerfHud(cb.checked));
|
|
2996
3013
|
$("stopAgent")?.addEventListener("click", () => (closePanel(), stopAgent(false)));
|
|
3014
|
+
$("restartAgent")?.addEventListener("click", () => (closePanel(), restartAgent()));
|
|
2997
3015
|
$("killAgent")?.addEventListener("click", () => (closePanel(), stopAgent(true)));
|
|
2998
3016
|
// Font stepper — stays open so you can tap repeatedly; persists + refits.
|
|
2999
3017
|
$("fontDown")?.addEventListener("click", () => setTermFontSize(termFontSize - 1));
|
|
@@ -3766,6 +3784,18 @@
|
|
|
3766
3784
|
return first ? first.entry : null;
|
|
3767
3785
|
}
|
|
3768
3786
|
|
|
3787
|
+
// The fork SOURCE — strictly the agent that was open when the omnibox
|
|
3788
|
+
// launched, never the top-result fallback that omniAnchor() uses. "Fork
|
|
3789
|
+
// current branch" is meaningless without a concrete current branch: forking
|
|
3790
|
+
// whatever happens to rank first silently forks an unrelated agent (often the
|
|
3791
|
+
// console's own repo), landing the worktree in the wrong tree. So a fork is
|
|
3792
|
+
// offered ONLY when a real agent is selected AND it has live git info
|
|
3793
|
+
// (forkWorktree needs a worktree with a branch/origin).
|
|
3794
|
+
function omniForkSource() {
|
|
3795
|
+
const cur = omniReturnSel ? entries.find((x) => x._key === omniReturnSel) : null;
|
|
3796
|
+
return cur && cur.cwd && cur.git && cur.git.branch ? cur : null;
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3769
3799
|
// Which agent the highlighted candidate should preview in the background: an
|
|
3770
3800
|
// agent row → that agent; the spawn row / an empty list → the launch-time
|
|
3771
3801
|
// agent (so the backdrop shows the spawn target's cwd).
|
|
@@ -3840,8 +3870,8 @@
|
|
|
3840
3870
|
return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
|
|
3841
3871
|
<span class="dot active"></span>
|
|
3842
3872
|
<div class="omni-main">
|
|
3843
|
-
<div class="omni-title">⑂ Fork
|
|
3844
|
-
<div class="omni-sub">${esc(
|
|
3873
|
+
<div class="omni-title">⑂ Fork <b>${esc(r.srcBranch)}</b> & run <span style="opacity:.55">(carries uncommitted work)</span></div>
|
|
3874
|
+
<div class="omni-sub">${esc(r.fromCwd)} → new branch <b>${esc(r.branch)}</b> · ⏎ to edit & launch</div>
|
|
3845
3875
|
</div></div>`;
|
|
3846
3876
|
}
|
|
3847
3877
|
if (r.kind === "spawncwd") {
|
|
@@ -3882,9 +3912,19 @@
|
|
|
3882
3912
|
omniRows = hits.map((entry) => ({ kind: "agent", entry }));
|
|
3883
3913
|
if (q) {
|
|
3884
3914
|
omniRows.push({ kind: "spawn" });
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3915
|
+
// Fork is pinned to the open agent (omniForkSource), and the row carries
|
|
3916
|
+
// the exact source it will fork — cwd, branch, cli, room — so the launch
|
|
3917
|
+
// can't drift to a different anchor between render and activate.
|
|
3918
|
+
const forkSrc = omniForkSource();
|
|
3919
|
+
if (forkSrc)
|
|
3920
|
+
omniRows.push({
|
|
3921
|
+
kind: "fork",
|
|
3922
|
+
branch: forkSlug(q, forkSrc.git.branch),
|
|
3923
|
+
srcBranch: forkSrc.git.branch,
|
|
3924
|
+
fromCwd: forkSrc.cwd,
|
|
3925
|
+
cli: forkSrc.cli,
|
|
3926
|
+
room: forkSrc._room,
|
|
3927
|
+
});
|
|
3888
3928
|
omniRows.push({ kind: "spawncwd" });
|
|
3889
3929
|
}
|
|
3890
3930
|
omniIdx = 0;
|
|
@@ -3962,7 +4002,10 @@
|
|
|
3962
4002
|
return;
|
|
3963
4003
|
}
|
|
3964
4004
|
if (row && row.kind === "fork") {
|
|
3965
|
-
// Editable at launch (auto-slug is the default); carries the
|
|
4005
|
+
// Editable at launch (auto-slug is the default); carries the source's WIP.
|
|
4006
|
+
// Fork from the source PINNED on the row (row.fromCwd), not a freshly
|
|
4007
|
+
// re-resolved anchor — the anchor can drift as the list refreshes, but the
|
|
4008
|
+
// branch we fork from must be the one the row was built for.
|
|
3966
4009
|
const branch = prompt(
|
|
3967
4010
|
"Fork to a new branch (carries your uncommitted work):",
|
|
3968
4011
|
row.branch,
|
|
@@ -3971,11 +4014,11 @@
|
|
|
3971
4014
|
closeOmni(false);
|
|
3972
4015
|
await spawnAndSelect(
|
|
3973
4016
|
{
|
|
3974
|
-
cli:
|
|
4017
|
+
cli: row.cli || "claude",
|
|
3975
4018
|
prompt: q || undefined,
|
|
3976
|
-
fork: { fromCwd:
|
|
4019
|
+
fork: { fromCwd: row.fromCwd, branch: branch.trim() },
|
|
3977
4020
|
},
|
|
3978
|
-
|
|
4021
|
+
row.room,
|
|
3979
4022
|
);
|
|
3980
4023
|
return;
|
|
3981
4024
|
}
|
package/package.json
CHANGED
package/ts/serve.ts
CHANGED
|
@@ -1414,6 +1414,39 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1414
1414
|
}
|
|
1415
1415
|
}
|
|
1416
1416
|
|
|
1417
|
+
// POST /api/restart body {keyword, fresh?} — the console-native `ay restart`:
|
|
1418
|
+
// stop the agent (if live) then relaunch it RESUMING its session. Restart is a
|
|
1419
|
+
// multi-second flow (graceful /exit → wait for exit → relaunch) that must
|
|
1420
|
+
// OUTLIVE this request and must NOT be a child of the agent it restarts — so we
|
|
1421
|
+
// kick it off as a detached `agent-yes restart` and return immediately; the
|
|
1422
|
+
// console sees the old→new pid swap over /api/ls/subscribe. This is why restart
|
|
1423
|
+
// is a real server action and not a prompt typed into the agent.
|
|
1424
|
+
if (req.method === "POST" && p === "/api/restart") {
|
|
1425
|
+
let body: { keyword?: string; fresh?: boolean };
|
|
1426
|
+
try {
|
|
1427
|
+
body = (await req.json()) as typeof body;
|
|
1428
|
+
} catch {
|
|
1429
|
+
return new Response("invalid JSON body", { status: 400 });
|
|
1430
|
+
}
|
|
1431
|
+
const keyword = body.keyword;
|
|
1432
|
+
if (!keyword || typeof keyword !== "string")
|
|
1433
|
+
return new Response("missing keyword", { status: 400 });
|
|
1434
|
+
try {
|
|
1435
|
+
const record = await resolveOne(keyword, defaultOpts({ all: true }));
|
|
1436
|
+
const args = ["restart", String(record.pid)];
|
|
1437
|
+
if (body.fresh) args.push("--fresh");
|
|
1438
|
+
const child = Bun.spawn(["agent-yes", ...args], {
|
|
1439
|
+
cwd: record.cwd,
|
|
1440
|
+
detached: true,
|
|
1441
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
1442
|
+
});
|
|
1443
|
+
child.unref();
|
|
1444
|
+
return Response.json({ ok: true, pid: record.pid });
|
|
1445
|
+
} catch (e) {
|
|
1446
|
+
return new Response((e as Error).message, { status: 404 });
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1417
1450
|
// POST /api/resize/:keyword body {cols, rows} — drive the agent's PTY size.
|
|
1418
1451
|
// Mirrors `ay attach`: write ~/.agent-yes/winsize/<pid> then SIGWINCH; the
|
|
1419
1452
|
// agent's resize listener picks it up and reflows its TUI to that width.
|
|
@@ -1518,9 +1551,20 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1518
1551
|
let cwd: string;
|
|
1519
1552
|
let provisioned: { action: string; folder: string } | null = null;
|
|
1520
1553
|
const fork =
|
|
1521
|
-
body.fork &&
|
|
1522
|
-
|
|
1554
|
+
body.fork &&
|
|
1555
|
+
typeof body.fork.fromCwd === "string" &&
|
|
1556
|
+
body.fork.fromCwd.trim() &&
|
|
1557
|
+
typeof body.fork.branch === "string" &&
|
|
1558
|
+
body.fork.branch.trim()
|
|
1559
|
+
? { fromCwd: body.fork.fromCwd.trim(), branch: body.fork.branch.trim() }
|
|
1523
1560
|
: null;
|
|
1561
|
+
// A fork request that didn't resolve to a valid source must fail LOUDLY, not
|
|
1562
|
+
// silently fall through to the plain-`cwd` branch below — that would spawn
|
|
1563
|
+
// the agent in the workspace root (≈ where `ay serve` runs) instead of a
|
|
1564
|
+
// worktree off the intended branch, which looks like the agent "ignoring"
|
|
1565
|
+
// the fork. An empty/garbled fork object is a client bug; surface it as 400.
|
|
1566
|
+
if (body.fork != null && !fork)
|
|
1567
|
+
return new Response("fork requires a non-empty fromCwd and branch", { status: 400 });
|
|
1524
1568
|
const from = typeof body.from === "string" ? body.from.trim() : "";
|
|
1525
1569
|
if (fork) {
|
|
1526
1570
|
// Fork the anchor agent's branch (carrying its WIP) into a new sibling
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-U3AE4u72.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-B-ToHoJ2.js";
|
|
4
|
-
import "./pidStore-fqXqTKkh.js";
|
|
5
|
-
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Dam11bMz.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|