claude-yes 1.162.0 → 1.164.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/dist/{SUPPORTED_CLIS-BNLYYzBZ.js → SUPPORTED_CLIS-C_J_okdw.js} +2 -2
- package/dist/SUPPORTED_CLIS-CmJam_wA.js +8 -0
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{schedule-DzFEVEoq.js → schedule-B-Ncgklt.js} +4 -4
- package/dist/{serve-BFnjq7JW.js → serve-yVh9Y6ot.js} +60 -14
- package/dist/{setup-BmUQ_Zbt.js → setup-BmYrvUsz.js} +2 -2
- package/dist/{subcommands-CKMEWv6U.js → subcommands-BbKngO7F.js} +4 -4
- package/dist/{subcommands-DeW-4FGU.js → subcommands-C-aCmtre.js} +1 -1
- package/dist/{ts--UKFJGU-.js → ts-BzyVSzo1.js} +2 -2
- package/dist/{versionChecker-DJObC8O_.js → versionChecker-CCHuozmQ.js} +2 -2
- package/lab/ui/console-logic.js +22 -6
- package/lab/ui/index.html +25 -10
- package/package.json +1 -1
- package/ts/serve.ts +119 -27
- package/dist/SUPPORTED_CLIS-C9TQK7ME.js +0 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-BzyVSzo1.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-C_J_okdw.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-BzyVSzo1.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-CCHuozmQ.js";
|
|
4
|
+
import "./pidStore-BfoBWUjc.js";
|
|
5
|
+
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-C_J_okdw.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-CCHuozmQ.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-C-aCmtre.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-CmJam_wA.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-BzyVSzo1.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CCHuozmQ.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
6
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts
|
|
1
|
+
import "./ts-BzyVSzo1.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CCHuozmQ.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.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-C_J_okdw.js";
|
|
7
7
|
import { o as resolveSpawnCwd } from "./workspaceConfig-B0Q9-q2B.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-B-Ncgklt.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import "./ts
|
|
1
|
+
import "./ts-BzyVSzo1.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-CCHuozmQ.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.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-C_J_okdw.js";
|
|
9
9
|
import "./e2e-Bfw7qL9O.js";
|
|
10
10
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
11
11
|
import "./remotes-DBCvpp3B.js";
|
|
12
12
|
import { a as isProvisionAllowed, i as hasSpawnHook, n as getSpawnHook, o as resolveSpawnCwd, t as getProvisionRoot } from "./workspaceConfig-B0Q9-q2B.js";
|
|
13
|
-
import { D as writeToIpc, T as snapshotStatus, _ 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-
|
|
13
|
+
import { D as writeToIpc, T as snapshotStatus, _ as readPtysize, b as resolveOne, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, s as extractNeedsInput, v as renderRawLog } from "./subcommands-BbKngO7F.js";
|
|
14
14
|
import yargs from "yargs";
|
|
15
15
|
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
16
16
|
import { homedir, hostname, userInfo } from "os";
|
|
@@ -625,6 +625,24 @@ Options:
|
|
|
625
625
|
return null;
|
|
626
626
|
}
|
|
627
627
|
};
|
|
628
|
+
const niCache = /* @__PURE__ */ new Map();
|
|
629
|
+
const logNeedsInput = async (logFile, cli) => {
|
|
630
|
+
if (!logFile) return null;
|
|
631
|
+
try {
|
|
632
|
+
const { size, mtimeMs } = await stat(logFile);
|
|
633
|
+
const hit = niCache.get(logFile);
|
|
634
|
+
if (hit && hit.size === size && hit.mtimeMs === mtimeMs) return hit.question;
|
|
635
|
+
const question = (await extractNeedsInput(logFile, cli))?.question ?? null;
|
|
636
|
+
niCache.set(logFile, {
|
|
637
|
+
size,
|
|
638
|
+
mtimeMs,
|
|
639
|
+
question
|
|
640
|
+
});
|
|
641
|
+
return question;
|
|
642
|
+
} catch {
|
|
643
|
+
return null;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
628
646
|
const GIT_DEBOUNCE_MS = 800;
|
|
629
647
|
const GIT_SAFETY_MS = 6e4;
|
|
630
648
|
const runGit = async (args, cwd) => {
|
|
@@ -643,17 +661,43 @@ Options:
|
|
|
643
661
|
}
|
|
644
662
|
};
|
|
645
663
|
const parseGitStatus = (out) => {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const
|
|
664
|
+
let branch = null;
|
|
665
|
+
let ahead = 0;
|
|
666
|
+
let behind = 0;
|
|
667
|
+
let changed = 0;
|
|
668
|
+
let pins = 0;
|
|
669
|
+
let subDirty = 0;
|
|
670
|
+
for (const line of out.split("\n")) {
|
|
671
|
+
if (line.length === 0) continue;
|
|
672
|
+
if (line[0] === "#") {
|
|
673
|
+
const head = /^# branch\.head (.+)$/.exec(line);
|
|
674
|
+
if (head) {
|
|
675
|
+
branch = head[1] === "(detached)" ? null : head[1];
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
const ab = /^# branch\.ab \+(\d+) -(\d+)/.exec(line);
|
|
679
|
+
if (ab) {
|
|
680
|
+
ahead = Number(ab[1]);
|
|
681
|
+
behind = Number(ab[2]);
|
|
682
|
+
}
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
const type = line[0];
|
|
686
|
+
if (type === "?") changed++;
|
|
687
|
+
else if (type === "u") changed++;
|
|
688
|
+
else if (type === "1" || type === "2") {
|
|
689
|
+
const sub = line.split(" ")[2] ?? "N...";
|
|
690
|
+
if (sub[0] === "S") if (sub[1] === "C") pins++;
|
|
691
|
+
else subDirty++;
|
|
692
|
+
else changed++;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
653
695
|
return {
|
|
654
696
|
branch,
|
|
655
697
|
dirty: changed > 0,
|
|
656
698
|
changed,
|
|
699
|
+
pins,
|
|
700
|
+
subDirty,
|
|
657
701
|
ahead,
|
|
658
702
|
behind
|
|
659
703
|
};
|
|
@@ -676,7 +720,7 @@ Options:
|
|
|
676
720
|
try {
|
|
677
721
|
const out = await runGit([
|
|
678
722
|
"status",
|
|
679
|
-
"--porcelain",
|
|
723
|
+
"--porcelain=v2",
|
|
680
724
|
"--branch"
|
|
681
725
|
], root);
|
|
682
726
|
if (out != null) rw.val = parseGitStatus(out);
|
|
@@ -717,9 +761,11 @@ Options:
|
|
|
717
761
|
};
|
|
718
762
|
const withMeta = async (r) => {
|
|
719
763
|
const status = await deriveLiveStatus(r);
|
|
764
|
+
const question = status !== "exited" && !r.unresponsive ? await logNeedsInput(r.log_file, r.cli) : null;
|
|
720
765
|
return {
|
|
721
766
|
...r,
|
|
722
|
-
status: status
|
|
767
|
+
status: status === "exited" ? status : r.unresponsive ? "stuck" : question ? "needs_input" : status,
|
|
768
|
+
question,
|
|
723
769
|
title: await logTitle(r.log_file),
|
|
724
770
|
git: status === "exited" ? null : await gitStatus(r.cwd),
|
|
725
771
|
tasks: status === "exited" ? null : await logTasks(r.log_file)
|
|
@@ -1396,4 +1442,4 @@ Options:
|
|
|
1396
1442
|
|
|
1397
1443
|
//#endregion
|
|
1398
1444
|
export { cmdServe };
|
|
1399
|
-
//# sourceMappingURL=serve-
|
|
1445
|
+
//# sourceMappingURL=serve-yVh9Y6ot.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-yVh9Y6ot.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-BmYrvUsz.js.map
|
|
@@ -556,15 +556,15 @@ async function runSubcommand(argv) {
|
|
|
556
556
|
case "restart": return await cmdRestart(rest);
|
|
557
557
|
case "note": return await cmdNote(rest);
|
|
558
558
|
case "serve": {
|
|
559
|
-
const { cmdServe } = await import("./serve-
|
|
559
|
+
const { cmdServe } = await import("./serve-yVh9Y6ot.js");
|
|
560
560
|
return cmdServe(rest);
|
|
561
561
|
}
|
|
562
562
|
case "setup": {
|
|
563
|
-
const { cmdSetup } = await import("./setup-
|
|
563
|
+
const { cmdSetup } = await import("./setup-BmYrvUsz.js");
|
|
564
564
|
return cmdSetup(rest);
|
|
565
565
|
}
|
|
566
566
|
case "schedule": {
|
|
567
|
-
const { cmdSchedule } = await import("./schedule-
|
|
567
|
+
const { cmdSchedule } = await import("./schedule-B-Ncgklt.js");
|
|
568
568
|
return cmdSchedule(rest);
|
|
569
569
|
}
|
|
570
570
|
case "remote": {
|
|
@@ -2795,4 +2795,4 @@ async function cmdResultSet(rest) {
|
|
|
2795
2795
|
|
|
2796
2796
|
//#endregion
|
|
2797
2797
|
export { restartHintLines as C, writeToIpc as D, stopTipForCli as E, resolveResumeArgs as S, snapshotStatus 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, runSubcommand as w, resolveReadWindow as x, renderRawLogLines as y };
|
|
2798
|
-
//# sourceMappingURL=subcommands-
|
|
2798
|
+
//# sourceMappingURL=subcommands-BbKngO7F.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 restartHintLines, D as writeToIpc, E as stopTipForCli, S as resolveResumeArgs, T as snapshotStatus, _ 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 runSubcommand, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-
|
|
7
|
+
import { C as restartHintLines, D as writeToIpc, E as stopTipForCli, S as resolveResumeArgs, T as snapshotStatus, _ 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 runSubcommand, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-BbKngO7F.js";
|
|
8
8
|
|
|
9
9
|
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -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-CCHuozmQ.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-BfoBWUjc.js";
|
|
@@ -1803,4 +1803,4 @@ function sleep(ms) {
|
|
|
1803
1803
|
|
|
1804
1804
|
//#endregion
|
|
1805
1805
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1806
|
-
//# sourceMappingURL=ts
|
|
1806
|
+
//# sourceMappingURL=ts-BzyVSzo1.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.164.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-CCHuozmQ.js.map
|
package/lab/ui/console-logic.js
CHANGED
|
@@ -153,14 +153,19 @@ export function tagsFor(e) {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// Compact git indicator from the record's `git` snapshot (server-side
|
|
156
|
-
// `git status --porcelain --branch`): "±3" changed files, "
|
|
157
|
-
//
|
|
158
|
-
//
|
|
156
|
+
// `git status --porcelain=v2 --branch`): "±3" real changed files, "⑂2"
|
|
157
|
+
// submodule pin-bumps, "⊙1" submodule internal dirt, "↑1" ahead, "↓2" behind.
|
|
158
|
+
// Pins/sub-dirt are split out of "±" so submodule drift (constant in a repo with
|
|
159
|
+
// many submodules) never buries the real file edits. Returns "" when there's no
|
|
160
|
+
// git info or the tree is clean and in sync, so a tidy repo adds no noise. Branch
|
|
161
|
+
// itself is shown via the path identity.
|
|
159
162
|
export function gitLabel(e) {
|
|
160
163
|
const g = e.git;
|
|
161
164
|
if (!g) return "";
|
|
162
165
|
const parts = [];
|
|
163
166
|
if (g.changed > 0) parts.push("±" + g.changed);
|
|
167
|
+
if (g.pins > 0) parts.push("⑂" + g.pins);
|
|
168
|
+
if (g.subDirty > 0) parts.push("⊙" + g.subDirty);
|
|
164
169
|
if (g.ahead > 0) parts.push("↑" + g.ahead);
|
|
165
170
|
if (g.behind > 0) parts.push("↓" + g.behind);
|
|
166
171
|
return parts.join(" ");
|
|
@@ -521,10 +526,21 @@ export function fitTransform(gridW, gridH, paneW, paneH) {
|
|
|
521
526
|
|
|
522
527
|
// Browser-tab title: "<glyph> <selected agent title> - agent-yes", or the bare
|
|
523
528
|
// console title when nothing is selected (blank/whitespace name). The leading
|
|
524
|
-
// glyph mirrors the agent's status dot —
|
|
525
|
-
// shows liveness at a glance
|
|
529
|
+
// glyph mirrors the agent's status dot — ⌨ needs_input ("your turn"), ⚠ stuck,
|
|
530
|
+
// ● active, ○ idle, ✗ exited — so the tab shows liveness at a glance even in a
|
|
531
|
+
// background tab; an unknown status adds no glyph.
|
|
526
532
|
export function statusGlyph(status) {
|
|
527
|
-
return status === "
|
|
533
|
+
return status === "needs_input"
|
|
534
|
+
? "⌨"
|
|
535
|
+
: status === "stuck"
|
|
536
|
+
? "⚠"
|
|
537
|
+
: status === "active"
|
|
538
|
+
? "●"
|
|
539
|
+
: status === "idle"
|
|
540
|
+
? "○"
|
|
541
|
+
: status === "exited"
|
|
542
|
+
? "✗"
|
|
543
|
+
: "";
|
|
528
544
|
}
|
|
529
545
|
export function docTitle(name, status) {
|
|
530
546
|
const n = name && String(name).trim();
|
package/lab/ui/index.html
CHANGED
|
@@ -891,6 +891,11 @@
|
|
|
891
891
|
color: var(--green);
|
|
892
892
|
border-color: #2a3a2a;
|
|
893
893
|
}
|
|
894
|
+
/* The pending question when an agent needs_input — blue accent to match the
|
|
895
|
+
needs_input dot, reading as "your turn / here's what it's asking". */
|
|
896
|
+
.detail.ask {
|
|
897
|
+
color: var(--accent);
|
|
898
|
+
}
|
|
894
899
|
.detail {
|
|
895
900
|
color: var(--muted);
|
|
896
901
|
font-size: 12.5px;
|
|
@@ -3187,13 +3192,19 @@
|
|
|
3187
3192
|
);
|
|
3188
3193
|
}
|
|
3189
3194
|
|
|
3190
|
-
// A small git chip (±changed ↑ahead ↓behind) for a row,
|
|
3191
|
-
//
|
|
3195
|
+
// A small git chip (±changed ⑂pins ⊙sub-dirty ↑ahead ↓behind) for a row,
|
|
3196
|
+
// amber when the tree has real file changes. Submodule pin-drift shows as a
|
|
3197
|
+
// muted "⑂" that never turns the chip amber, so it can't bury real edits.
|
|
3198
|
+
// Empty for clean/in-sync repos and non-git cwds — no noise.
|
|
3192
3199
|
function gitChipHtml(e) {
|
|
3193
3200
|
const label = gitLabel(e);
|
|
3194
3201
|
if (!label) return "";
|
|
3195
3202
|
const g = e.git || {};
|
|
3196
|
-
const tip =
|
|
3203
|
+
const tip =
|
|
3204
|
+
`git: ${g.changed || 0} changed file${(g.changed || 0) === 1 ? "" : "s"}` +
|
|
3205
|
+
(g.pins ? ` · ${g.pins} submodule pin-bump${g.pins === 1 ? "" : "s"}` : "") +
|
|
3206
|
+
(g.subDirty ? ` · ${g.subDirty} submodule dirty` : "") +
|
|
3207
|
+
` · ${g.ahead || 0} ahead · ${g.behind || 0} behind`;
|
|
3197
3208
|
return `<span class="git${g.dirty ? " dirty" : ""}" title="${esc(tip)}">${esc(label)}</span>`;
|
|
3198
3209
|
}
|
|
3199
3210
|
|
|
@@ -3285,7 +3296,13 @@
|
|
|
3285
3296
|
${gitChipHtml(e)}
|
|
3286
3297
|
<span class="age">${age(e)}</span></div>
|
|
3287
3298
|
${e.title ? `<div class="rowtitle" title="${esc(e.title)}">${esc(e.title)}</div>` : ""}
|
|
3288
|
-
${
|
|
3299
|
+
${
|
|
3300
|
+
e.status === "needs_input" && e.question
|
|
3301
|
+
? `<div class="detail ask" title="${esc(e.question)}">⌨ ${esc(e.question)}</div>`
|
|
3302
|
+
: e.prompt
|
|
3303
|
+
? `<div class="detail" title="${esc(e.prompt)}">${esc(e.prompt)}</div>`
|
|
3304
|
+
: ""
|
|
3305
|
+
}
|
|
3289
3306
|
<div class="rowtags">${tags}</div>
|
|
3290
3307
|
</div>`;
|
|
3291
3308
|
})
|
|
@@ -3918,7 +3935,7 @@
|
|
|
3918
3935
|
return `<div class="omni-row omni-spawn${sc}" data-i="${i}">
|
|
3919
3936
|
<span class="dot active"></span>
|
|
3920
3937
|
<div class="omni-main">
|
|
3921
|
-
<div class="omni-title">⑂ Fork <b>${esc(r.srcBranch)}</b> & run <span style="opacity:.55">(
|
|
3938
|
+
<div class="omni-title">⑂ Fork <b>${esc(r.srcBranch)}</b> & run <span style="opacity:.55">(clean — committed work only)</span></div>
|
|
3922
3939
|
<div class="omni-sub">${esc(r.fromCwd)} → new branch <b>${esc(r.branch)}</b> · ⏎ to edit & launch</div>
|
|
3923
3940
|
</div></div>`;
|
|
3924
3941
|
}
|
|
@@ -4050,14 +4067,12 @@
|
|
|
4050
4067
|
return;
|
|
4051
4068
|
}
|
|
4052
4069
|
if (row && row.kind === "fork") {
|
|
4053
|
-
// Editable at launch (auto-slug is the default)
|
|
4070
|
+
// Editable at launch (auto-slug is the default). The fork is clean —
|
|
4071
|
+
// committed work only, the source's uncommitted changes stay put.
|
|
4054
4072
|
// Fork from the source PINNED on the row (row.fromCwd), not a freshly
|
|
4055
4073
|
// re-resolved anchor — the anchor can drift as the list refreshes, but the
|
|
4056
4074
|
// branch we fork from must be the one the row was built for.
|
|
4057
|
-
const branch = prompt(
|
|
4058
|
-
"Fork to a new branch (carries your uncommitted work):",
|
|
4059
|
-
row.branch,
|
|
4060
|
-
);
|
|
4075
|
+
const branch = prompt("Fork to a new branch (clean — committed work only):", row.branch);
|
|
4061
4076
|
if (!branch || !branch.trim()) return; // cancelled — leave the omnibox open
|
|
4062
4077
|
closeOmni(false);
|
|
4063
4078
|
await spawnAndSelect(
|
package/package.json
CHANGED
package/ts/serve.ts
CHANGED
|
@@ -9,6 +9,7 @@ import yargs from "yargs";
|
|
|
9
9
|
import {
|
|
10
10
|
controlCodeFromName,
|
|
11
11
|
deriveLiveStatus,
|
|
12
|
+
extractNeedsInput,
|
|
12
13
|
extractTaskCounts,
|
|
13
14
|
listRecords,
|
|
14
15
|
readNotes,
|
|
@@ -172,12 +173,15 @@ function loginShellEnv(): Record<string, string> | null {
|
|
|
172
173
|
// Delimiters fence off the env dump from any banner/prompt noise the rc files
|
|
173
174
|
// print to stdout; `env -0` is NUL-separated so values with newlines survive.
|
|
174
175
|
const delim = "_AY_SHELL_ENV_DELIM_";
|
|
175
|
-
const res = Bun.spawnSync(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
176
|
+
const res = Bun.spawnSync(
|
|
177
|
+
[shell, "-ilc", `printf %s "${delim}"; env -0; printf %s "${delim}"`],
|
|
178
|
+
{
|
|
179
|
+
stdin: "ignore",
|
|
180
|
+
stderr: "ignore",
|
|
181
|
+
timeout: 5_000,
|
|
182
|
+
env: process.env as Record<string, string>,
|
|
183
|
+
},
|
|
184
|
+
);
|
|
181
185
|
const out = res.stdout?.toString() ?? "";
|
|
182
186
|
const start = out.indexOf(delim);
|
|
183
187
|
const end = out.lastIndexOf(delim);
|
|
@@ -930,8 +934,37 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
930
934
|
}
|
|
931
935
|
};
|
|
932
936
|
|
|
937
|
+
// Per-agent "waiting on you" detection: the agent is parked on an interactive
|
|
938
|
+
// menu it did NOT auto-resolve (config `needsInput` patterns). Same source and
|
|
939
|
+
// classifier as `ay ls` / `ay status`, so the console's dot matches the CLI's
|
|
940
|
+
// needs_input. Cached per (size, mtime) exactly like logTitle/logTasks — each
|
|
941
|
+
// miss renders a log window through xterm, so the 1s list tick stays cheap on
|
|
942
|
+
// an idle fleet. Returns the pending question text (surfaced in the UI), or
|
|
943
|
+
// null when the agent isn't blocked.
|
|
944
|
+
const niCache = new Map<string, { size: number; mtimeMs: number; question: string | null }>();
|
|
945
|
+
const logNeedsInput = async (
|
|
946
|
+
logFile: string | null | undefined,
|
|
947
|
+
cli: string,
|
|
948
|
+
): Promise<string | null> => {
|
|
949
|
+
if (!logFile) return null;
|
|
950
|
+
try {
|
|
951
|
+
const { size, mtimeMs } = await stat(logFile);
|
|
952
|
+
const hit = niCache.get(logFile);
|
|
953
|
+
if (hit && hit.size === size && hit.mtimeMs === mtimeMs) return hit.question;
|
|
954
|
+
const ni = await extractNeedsInput(logFile, cli);
|
|
955
|
+
const question = ni?.question ?? null;
|
|
956
|
+
niCache.set(logFile, { size, mtimeMs, question });
|
|
957
|
+
return question;
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
|
|
933
963
|
// Per-repo git snapshot for the list (branch + dirty/changed + ahead/behind, from
|
|
934
|
-
// one `git status --porcelain --branch`).
|
|
964
|
+
// one `git status --porcelain=v2 --branch`). v2 (not v1) so the submodule field
|
|
965
|
+
// lets us split real file changes from submodule pin-drift, which would otherwise
|
|
966
|
+
// inflate `changed` — in a superproject with many submodules the constant gitlink
|
|
967
|
+
// drift buries the real edits. WATCHER-INVALIDATED, not polled: a read
|
|
935
968
|
// returns the cached snapshot instantly and NEVER spawns `git status` on the
|
|
936
969
|
// request path. A per-repo-root fs watcher recomputes (debounced) only when the
|
|
937
970
|
// repo actually changes, so an idle fleet costs ~0 git processes. The old design
|
|
@@ -942,7 +975,9 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
942
975
|
interface GitInfo {
|
|
943
976
|
branch: string | null;
|
|
944
977
|
dirty: boolean;
|
|
945
|
-
changed: number;
|
|
978
|
+
changed: number; // real file changes (excludes submodule pin-bumps & internal dirt)
|
|
979
|
+
pins: number; // submodule gitlinks pointing at new commit(s) — pin-bump/drift
|
|
980
|
+
subDirty: number; // submodule has internal changes but its recorded pin is unchanged
|
|
946
981
|
ahead: number;
|
|
947
982
|
behind: number;
|
|
948
983
|
}
|
|
@@ -964,16 +999,55 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
964
999
|
}
|
|
965
1000
|
};
|
|
966
1001
|
const parseGitStatus = (out: string): GitInfo => {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
1002
|
+
// porcelain=v2 --branch: "# branch.*" headers then one line per changed entry.
|
|
1003
|
+
let branch: string | null = null;
|
|
1004
|
+
let ahead = 0;
|
|
1005
|
+
let behind = 0;
|
|
1006
|
+
let changed = 0; // real file changes
|
|
1007
|
+
let pins = 0; // submodule pin-bumps (gitlink → new commit)
|
|
1008
|
+
let subDirty = 0; // submodule internal dirt, recorded pin unchanged
|
|
1009
|
+
for (const line of out.split("\n")) {
|
|
1010
|
+
if (line.length === 0) continue;
|
|
1011
|
+
if (line[0] === "#") {
|
|
1012
|
+
// "# branch.head <name|(detached)>" and "# branch.ab +A -B" (ab absent
|
|
1013
|
+
// when there's no upstream). branch.head carries the name even on an
|
|
1014
|
+
// unborn branch, so no special-casing needed.
|
|
1015
|
+
const head = /^# branch\.head (.+)$/.exec(line);
|
|
1016
|
+
if (head) {
|
|
1017
|
+
branch = head[1] === "(detached)" ? null : head[1]!;
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
const ab = /^# branch\.ab \+(\d+) -(\d+)/.exec(line);
|
|
1021
|
+
if (ab) {
|
|
1022
|
+
ahead = Number(ab[1]);
|
|
1023
|
+
behind = Number(ab[2]);
|
|
1024
|
+
}
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
// Changed-entry lines. Untracked ("?") and unmerged ("u") are always real
|
|
1028
|
+
// work; ignored ("!") never appears (we don't pass --ignored). For ordinary
|
|
1029
|
+
// ("1") / renamed ("2") entries the 3rd space-delimited token is the
|
|
1030
|
+
// submodule field <sub>: "N..." for a normal path, or "S<c><m><u>" for a
|
|
1031
|
+
// submodule where c=C means its gitlink moved to new commit(s) (pin-bump),
|
|
1032
|
+
// and m/u flag internal dirty/untracked with the recorded pin unchanged.
|
|
1033
|
+
// Paths (which may contain spaces) come after token 2, so counting by token
|
|
1034
|
+
// index is robust without -z.
|
|
1035
|
+
const type = line[0];
|
|
1036
|
+
if (type === "?") {
|
|
1037
|
+
changed++;
|
|
1038
|
+
} else if (type === "u") {
|
|
1039
|
+
changed++;
|
|
1040
|
+
} else if (type === "1" || type === "2") {
|
|
1041
|
+
const sub = line.split(" ")[2] ?? "N...";
|
|
1042
|
+
if (sub[0] === "S") {
|
|
1043
|
+
if (sub[1] === "C") pins++;
|
|
1044
|
+
else subDirty++;
|
|
1045
|
+
} else {
|
|
1046
|
+
changed++;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return { branch, dirty: changed > 0, changed, pins, subDirty, ahead, behind };
|
|
977
1051
|
};
|
|
978
1052
|
// cwd -> repo root ("" = resolved, not a repo). Resolved once per cwd via a cheap
|
|
979
1053
|
// `git rev-parse --show-toplevel` (no tree scan) and cached, so many agents in the
|
|
@@ -999,7 +1073,7 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
999
1073
|
if (rw.busy) return void recompute(root, rw); // re-arm if one is in flight
|
|
1000
1074
|
rw.busy = true;
|
|
1001
1075
|
try {
|
|
1002
|
-
const out = await runGit(["status", "--porcelain", "--branch"], root);
|
|
1076
|
+
const out = await runGit(["status", "--porcelain=v2", "--branch"], root);
|
|
1003
1077
|
if (out != null) rw.val = parseGitStatus(out);
|
|
1004
1078
|
} finally {
|
|
1005
1079
|
rw.busy = false;
|
|
@@ -1051,12 +1125,23 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1051
1125
|
// the LIVE status here — same liveness+log-mtime basis as `ay ls` — so the
|
|
1052
1126
|
// console's dot (and the browser tab glyph) flips to idle in step with `ay ls`.
|
|
1053
1127
|
const status = await deriveLiveStatus(r);
|
|
1128
|
+
// "Waiting on you": alive, quiet, but parked on an unanswered menu. Checked
|
|
1129
|
+
// only for live agents, and skipped when unresponsive (the Rust wedge signal
|
|
1130
|
+
// wins) — mirroring deriveLiveState's precedence in `ay ls` so the console's
|
|
1131
|
+
// dot and the CLI agree.
|
|
1132
|
+
const question =
|
|
1133
|
+
status !== "exited" && !r.unresponsive ? await logNeedsInput(r.log_file, r.cli) : null;
|
|
1054
1134
|
return {
|
|
1055
1135
|
...r,
|
|
1056
|
-
//
|
|
1057
|
-
//
|
|
1058
|
-
//
|
|
1059
|
-
|
|
1136
|
+
// Precedence: exited stays exited; the Rust supervisor's unresponsive flag is
|
|
1137
|
+
// an authoritative wedge signal (`stuck`); then a blocked menu (`needs_input`);
|
|
1138
|
+
// else the base live status — so the console's dot matches `ay ls`. (A dead
|
|
1139
|
+
// agent is never unresponsive — Rust clears the flag on exit.)
|
|
1140
|
+
status:
|
|
1141
|
+
status === "exited" ? status : r.unresponsive ? "stuck" : question ? "needs_input" : status,
|
|
1142
|
+
// The pending menu/question text when needs_input, for the console to show
|
|
1143
|
+
// WHAT the agent is waiting on. Null otherwise.
|
|
1144
|
+
question,
|
|
1060
1145
|
title: await logTitle(r.log_file),
|
|
1061
1146
|
git: status === "exited" ? null : await gitStatus(r.cwd),
|
|
1062
1147
|
// Task progress from the rendered todo block (null when none detected → no
|
|
@@ -1642,9 +1727,11 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1642
1727
|
return new Response("fork requires a non-empty fromCwd and branch", { status: 400 });
|
|
1643
1728
|
const from = typeof body.from === "string" ? body.from.trim() : "";
|
|
1644
1729
|
if (fork) {
|
|
1645
|
-
// Fork the anchor agent's branch
|
|
1646
|
-
//
|
|
1647
|
-
//
|
|
1730
|
+
// Fork the anchor agent's branch into a new sibling worktree via
|
|
1731
|
+
// codehost/provision (git worktree off HEAD, no clone), then spawn the
|
|
1732
|
+
// agent there. The fork is clean — committed work only; the source's
|
|
1733
|
+
// uncommitted changes stay put (codehost forkWorktree defaults wip:false,
|
|
1734
|
+
// and we don't opt in).
|
|
1648
1735
|
let prov: {
|
|
1649
1736
|
forkWorktree: (o: { fromCwd: string; branch: string; wsRoot?: string }) => Promise<{
|
|
1650
1737
|
ok: boolean;
|
|
@@ -1800,7 +1887,12 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
1800
1887
|
const child = Bun.spawn([shell, "-c", script, "ay-spawn", ...agentArgv], {
|
|
1801
1888
|
cwd,
|
|
1802
1889
|
detached: true,
|
|
1803
|
-
env: {
|
|
1890
|
+
env: {
|
|
1891
|
+
...agentEnv,
|
|
1892
|
+
AGENT_YES_CWD: cwd,
|
|
1893
|
+
AGENT_YES_CLI: cli,
|
|
1894
|
+
AGENT_YES_AGENT_ID: agentId,
|
|
1895
|
+
},
|
|
1804
1896
|
stdin: "ignore",
|
|
1805
1897
|
stdout: "ignore",
|
|
1806
1898
|
stderr: Bun.file(errPath),
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts--UKFJGU-.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-DJObC8O_.js";
|
|
4
|
-
import "./pidStore-BfoBWUjc.js";
|
|
5
|
-
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BNLYYzBZ.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|