agent-yes 1.205.0 → 1.206.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/README.md +2 -0
- package/dist/SUPPORTED_CLIS-CQ6e94ln.js +9 -0
- package/dist/{SUPPORTED_CLIS-C8-qh98a.js → SUPPORTED_CLIS-DQSgURGW.js} +2 -2
- package/dist/{agentShare-99IGGOkv.js → agentShare-k8224qiZ.js} +3 -3
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{notifyDaemon-DK1HOMjj.js → notifyDaemon-BbVnNvlo.js} +2 -2
- package/dist/{rustBinary-Tgn948GR.js → rustBinary-BjRvvEs8.js} +2 -2
- package/dist/{schedule-CBoM67Vy.js → schedule-DJ-v4yVa.js} +4 -4
- package/dist/{serve-IvOlaL-7.js → serve-crLypY_c.js} +162 -39
- package/dist/{setup-BaKdS-3i.js → setup-BPNkeSmY.js} +2 -2
- package/dist/{share-Ciw1mWVN.js → share-_QYjPN7q.js} +1 -1
- package/dist/{share-BfIU8t_h.js → share-vchIyVd8.js} +98 -5
- package/dist/{subcommands-DyDHZ5YI.js → subcommands-DCGZjr4t.js} +1 -1
- package/dist/{subcommands-Bs7wJRBB.js → subcommands-DkrMRVNh.js} +7 -7
- package/dist/{ts-Dm6jjLwC.js → ts-DnqRreF4.js} +2 -2
- package/dist/{versionChecker-BomfUpSo.js → versionChecker-d5c6_vgS.js} +2 -2
- package/dist/{ws-CSkP2mkD.js → ws-BmHpWaG_.js} +2 -2
- package/lab/ui/console-logic.js +3 -1
- package/lab/ui/index.html +39 -5
- package/package.json +1 -1
- package/ts/serve.spec.ts +13 -1
- package/ts/serve.ts +158 -28
- package/ts/share.ts +80 -1
- package/ts/statusText.spec.ts +17 -0
- package/ts/statusText.ts +19 -0
- package/dist/SUPPORTED_CLIS-D3XTFfS7.js +0 -9
|
@@ -16,7 +16,29 @@ const MAX_PEER_JOIN_QUEUE = 50;
|
|
|
16
16
|
const IDLE_RESTART_UPTIME_MS = 25 * 6e4;
|
|
17
17
|
const HARD_RESTART_UPTIME_MS = 45 * 6e4;
|
|
18
18
|
const IDLE_RESTART_CHECK_MS = 6e4;
|
|
19
|
+
const PERF_SLOW_MS = Number(process.env.AGENT_YES_WEBRTC_PERF_SLOW_MS) || 750;
|
|
20
|
+
const PERF_BUFFERED_BYTES = Number(process.env.AGENT_YES_WEBRTC_PERF_BUFFERED_BYTES) || 1e6;
|
|
21
|
+
const PERF_VERBOSE = process.env.AGENT_YES_WEBRTC_PERF === "1";
|
|
19
22
|
const STUN = [{ urls: "stun:stun.l.google.com:19302" }];
|
|
23
|
+
function perfLog(event, data, force = false) {
|
|
24
|
+
if (!force && !PERF_VERBOSE) return;
|
|
25
|
+
process.stderr.write(`[share:perf] ${JSON.stringify({
|
|
26
|
+
t: Date.now(),
|
|
27
|
+
event,
|
|
28
|
+
...data
|
|
29
|
+
})}\n`);
|
|
30
|
+
}
|
|
31
|
+
function maybeSlow(event, startedAt, data = {}) {
|
|
32
|
+
const ms = Math.round(performance.now() - startedAt);
|
|
33
|
+
perfLog(event, {
|
|
34
|
+
ms,
|
|
35
|
+
...data
|
|
36
|
+
}, ms >= PERF_SLOW_MS);
|
|
37
|
+
}
|
|
38
|
+
function dcBufferedAmount(dc) {
|
|
39
|
+
const n = Number(dc?.bufferedAmount ?? 0);
|
|
40
|
+
return Number.isFinite(n) ? n : 0;
|
|
41
|
+
}
|
|
20
42
|
let iceCache = null;
|
|
21
43
|
async function getIceServers() {
|
|
22
44
|
const keyId = process.env.CF_TURN_KEY_ID;
|
|
@@ -222,6 +244,7 @@ async function startShare(opts) {
|
|
|
222
244
|
if (closed) return;
|
|
223
245
|
const ws = new WebSocket(`${wsScheme}://${host}/${room}`, [SUB]);
|
|
224
246
|
currentWs = ws;
|
|
247
|
+
const signalStartedAt = performance.now();
|
|
225
248
|
let ready = false;
|
|
226
249
|
let lastRecv = Date.now();
|
|
227
250
|
let hb;
|
|
@@ -237,6 +260,10 @@ async function startShare(opts) {
|
|
|
237
260
|
}
|
|
238
261
|
};
|
|
239
262
|
ws.onopen = () => {
|
|
263
|
+
maybeSlow("signal.open", signalStartedAt, {
|
|
264
|
+
room,
|
|
265
|
+
host
|
|
266
|
+
});
|
|
240
267
|
ws.send(JSON.stringify({
|
|
241
268
|
type: "hello",
|
|
242
269
|
role: "host",
|
|
@@ -271,6 +298,12 @@ async function startShare(opts) {
|
|
|
271
298
|
const m = JSON.parse(ev.data);
|
|
272
299
|
if (m.type === "pong") return;
|
|
273
300
|
if (m.type === "peer-join") {
|
|
301
|
+
perfLog("peer.join", {
|
|
302
|
+
room,
|
|
303
|
+
peer: String(m.peer),
|
|
304
|
+
queue: peerJoinQueue.length,
|
|
305
|
+
peers: peers.size
|
|
306
|
+
});
|
|
274
307
|
const pid = String(m.peer);
|
|
275
308
|
if (!peers.has(pid) && !peerJoinQueue.includes(pid) && peerJoinQueue.length < MAX_PEER_JOIN_QUEUE) {
|
|
276
309
|
peerJoinQueue.push(pid);
|
|
@@ -317,6 +350,7 @@ async function startShare(opts) {
|
|
|
317
350
|
return ws;
|
|
318
351
|
};
|
|
319
352
|
async function startPeer(ws, peerId) {
|
|
353
|
+
const startedAt = performance.now();
|
|
320
354
|
const iceServers = await getIceServers();
|
|
321
355
|
const pc = new RTCPeerConnection({ iceServers });
|
|
322
356
|
let resolveKeys;
|
|
@@ -354,6 +388,11 @@ async function startShare(opts) {
|
|
|
354
388
|
dc.binaryType = "arraybuffer";
|
|
355
389
|
dc.onopen = async () => {
|
|
356
390
|
try {
|
|
391
|
+
maybeSlow("peer.dc_open", startedAt, {
|
|
392
|
+
room,
|
|
393
|
+
peer: peerId,
|
|
394
|
+
buffered: dcBufferedAmount(dc)
|
|
395
|
+
});
|
|
357
396
|
await peer.keysReady;
|
|
358
397
|
enqueueSeal(peerId, dc, peer, FLAG_CONFIRM, {
|
|
359
398
|
t: "confirm",
|
|
@@ -387,6 +426,11 @@ async function startShare(opts) {
|
|
|
387
426
|
sdp: pc.localDescription.sdp,
|
|
388
427
|
iceServers
|
|
389
428
|
}));
|
|
429
|
+
maybeSlow("peer.offer", startedAt, {
|
|
430
|
+
room,
|
|
431
|
+
peer: peerId,
|
|
432
|
+
iceServers: iceServers.length
|
|
433
|
+
});
|
|
390
434
|
}
|
|
391
435
|
function closePeer(peerId) {
|
|
392
436
|
const p = peers.get(peerId);
|
|
@@ -399,8 +443,10 @@ async function startShare(opts) {
|
|
|
399
443
|
peers.delete(peerId);
|
|
400
444
|
}
|
|
401
445
|
function enqueueSeal(peerId, dc, peer, flags, obj) {
|
|
446
|
+
const queuedAt = performance.now();
|
|
402
447
|
peer.sendChain = peer.sendChain.then(async () => {
|
|
403
448
|
if (dc.readyState !== "open" || !peer.keyH2C || !peer.th) return;
|
|
449
|
+
const queuedMs = Math.round(performance.now() - queuedAt);
|
|
404
450
|
let frame;
|
|
405
451
|
try {
|
|
406
452
|
frame = await seal(peer.keyH2C, peer.send, flags, peer.th, packEnvelope(obj));
|
|
@@ -410,6 +456,15 @@ async function startShare(opts) {
|
|
|
410
456
|
}
|
|
411
457
|
try {
|
|
412
458
|
dc.send(frame);
|
|
459
|
+
const buffered = dcBufferedAmount(dc);
|
|
460
|
+
perfLog("send", {
|
|
461
|
+
room,
|
|
462
|
+
peer: peerId,
|
|
463
|
+
kind: obj?.t,
|
|
464
|
+
queuedMs,
|
|
465
|
+
buffered,
|
|
466
|
+
bytes: frame.byteLength
|
|
467
|
+
}, queuedMs >= PERF_SLOW_MS || buffered >= PERF_BUFFERED_BYTES);
|
|
413
468
|
} catch {}
|
|
414
469
|
});
|
|
415
470
|
return peer.sendChain;
|
|
@@ -452,6 +507,14 @@ async function startShare(opts) {
|
|
|
452
507
|
}
|
|
453
508
|
if (req.t !== "req") return;
|
|
454
509
|
const { id, method, path: p, body } = req;
|
|
510
|
+
const startedAt = performance.now();
|
|
511
|
+
perfLog("req.start", {
|
|
512
|
+
room,
|
|
513
|
+
peer: peerId,
|
|
514
|
+
id,
|
|
515
|
+
method,
|
|
516
|
+
path: p
|
|
517
|
+
});
|
|
455
518
|
const ac = new AbortController();
|
|
456
519
|
peer.aborts.set(id, ac);
|
|
457
520
|
try {
|
|
@@ -464,6 +527,14 @@ async function startShare(opts) {
|
|
|
464
527
|
body: body ?? void 0,
|
|
465
528
|
signal: ac.signal
|
|
466
529
|
}));
|
|
530
|
+
maybeSlow("req.head", startedAt, {
|
|
531
|
+
room,
|
|
532
|
+
peer: peerId,
|
|
533
|
+
id,
|
|
534
|
+
method,
|
|
535
|
+
path: p,
|
|
536
|
+
status: res.status
|
|
537
|
+
});
|
|
467
538
|
enqueueSeal(peerId, dc, peer, 0, {
|
|
468
539
|
t: "res",
|
|
469
540
|
id,
|
|
@@ -473,9 +544,11 @@ async function startShare(opts) {
|
|
|
473
544
|
const reader = res.body.getReader();
|
|
474
545
|
const dec = new TextDecoder();
|
|
475
546
|
let seq = 0;
|
|
547
|
+
let bytes = 0;
|
|
476
548
|
for (;;) {
|
|
477
549
|
const { done, value } = await reader.read();
|
|
478
550
|
if (done) break;
|
|
551
|
+
bytes += value.byteLength;
|
|
479
552
|
const text = dec.decode(value, { stream: true });
|
|
480
553
|
for (let i = 0; i < text.length; i += MAX_CHUNK) enqueueSeal(peerId, dc, peer, 0, {
|
|
481
554
|
t: "data",
|
|
@@ -489,12 +562,32 @@ async function startShare(opts) {
|
|
|
489
562
|
id,
|
|
490
563
|
seq
|
|
491
564
|
});
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
565
|
+
maybeSlow("req.end", startedAt, {
|
|
566
|
+
room,
|
|
567
|
+
peer: peerId,
|
|
495
568
|
id,
|
|
496
|
-
|
|
569
|
+
method,
|
|
570
|
+
path: p,
|
|
571
|
+
status: res.status,
|
|
572
|
+
chunks: seq,
|
|
573
|
+
bytes
|
|
497
574
|
});
|
|
575
|
+
} catch (e) {
|
|
576
|
+
if (e.name !== "AbortError") {
|
|
577
|
+
maybeSlow("req.error", startedAt, {
|
|
578
|
+
room,
|
|
579
|
+
peer: peerId,
|
|
580
|
+
id,
|
|
581
|
+
method,
|
|
582
|
+
path: p,
|
|
583
|
+
error: String(e.message ?? e)
|
|
584
|
+
});
|
|
585
|
+
enqueueSeal(peerId, dc, peer, 0, {
|
|
586
|
+
t: "end",
|
|
587
|
+
id,
|
|
588
|
+
error: String(e.message ?? e)
|
|
589
|
+
});
|
|
590
|
+
}
|
|
498
591
|
} finally {
|
|
499
592
|
peer.aborts.delete(id);
|
|
500
593
|
}
|
|
@@ -534,4 +627,4 @@ async function startShare(opts) {
|
|
|
534
627
|
|
|
535
628
|
//#endregion
|
|
536
629
|
export { shareLinkFromRoomUrl as n, startShare as r, loadOrCreateShareRoom as t };
|
|
537
|
-
//# sourceMappingURL=share-
|
|
630
|
+
//# sourceMappingURL=share-vchIyVd8.js.map
|
|
@@ -2,7 +2,7 @@ import "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { A as renderRawLog, B as submitAndConfirm, C as matchKeyword, D as recentMessageEdges, E as readPtysize, F as restartHintLines, H as writeKeysPaced, I as runSubcommand, L as snapshotStatus, M as resolveOne, N as resolveReadWindow, O as recentReadEdges, P as resolveResumeArgs, R as stdinActivityPath, S as listRecords, T as readNotes, U as writeToIpc, V as waitForLogQuiet, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as renderRawLogLines, k as renderLogTailLines, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as stopTipForCli } from "./subcommands-
|
|
5
|
+
import { A as renderRawLog, B as submitAndConfirm, C as matchKeyword, D as recentMessageEdges, E as readPtysize, F as restartHintLines, H as writeKeysPaced, I as runSubcommand, L as snapshotStatus, M as resolveOne, N as resolveReadWindow, O as recentReadEdges, P as resolveResumeArgs, R as stdinActivityPath, S as listRecords, T as readNotes, U as writeToIpc, V as waitForLogQuiet, _ as isPidAlive, a as cmdHelp, b as isUserTyping, c as deriveLiveState, d as extractMenu, f as extractNeedsInput, g as isExitRequest, h as isAgentStuck, i as backoffWhileTyping, j as renderRawLogLines, k as renderLogTailLines, l as deriveLiveStatus, m as finalizedLines, n as READ_PAGE_DEFAULT, o as controlCodeFromName, p as extractTaskCounts, r as TYPING_WINDOW_MS, s as cursorAbs, t as GRACEFUL_EXIT_COMMANDS, u as extractBadges, v as isSlashCommand, w as menuSelectKeys, x as lastStdinAt, y as isSubcommand, z as stopTipForCli } from "./subcommands-DkrMRVNh.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -1237,19 +1237,19 @@ async function runSubcommand(argv) {
|
|
|
1237
1237
|
case "restart": return await cmdRestart(rest);
|
|
1238
1238
|
case "note": return await cmdNote(rest);
|
|
1239
1239
|
case "serve": {
|
|
1240
|
-
const { cmdServe } = await import("./serve-
|
|
1240
|
+
const { cmdServe } = await import("./serve-crLypY_c.js");
|
|
1241
1241
|
return cmdServe(rest);
|
|
1242
1242
|
}
|
|
1243
1243
|
case "setup": {
|
|
1244
|
-
const { cmdSetup } = await import("./setup-
|
|
1244
|
+
const { cmdSetup } = await import("./setup-BPNkeSmY.js");
|
|
1245
1245
|
return cmdSetup(rest);
|
|
1246
1246
|
}
|
|
1247
1247
|
case "ws": {
|
|
1248
|
-
const { cmdWs } = await import("./ws-
|
|
1248
|
+
const { cmdWs } = await import("./ws-BmHpWaG_.js");
|
|
1249
1249
|
return cmdWs(rest);
|
|
1250
1250
|
}
|
|
1251
1251
|
case "schedule": {
|
|
1252
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1252
|
+
const { cmdSchedule } = await import("./schedule-DJ-v4yVa.js");
|
|
1253
1253
|
return cmdSchedule(rest);
|
|
1254
1254
|
}
|
|
1255
1255
|
case "remote": {
|
|
@@ -4269,7 +4269,7 @@ async function cmdNotify(rest) {
|
|
|
4269
4269
|
}
|
|
4270
4270
|
const ensure = async () => {
|
|
4271
4271
|
if (!argv["ensure-daemon"]) return;
|
|
4272
|
-
const { ensureDaemon } = await import("./notifyDaemon-
|
|
4272
|
+
const { ensureDaemon } = await import("./notifyDaemon-BbVnNvlo.js");
|
|
4273
4273
|
await ensureDaemon().catch(() => null);
|
|
4274
4274
|
};
|
|
4275
4275
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4343,7 +4343,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4343
4343
|
}
|
|
4344
4344
|
async function cmdNotifyd(rest) {
|
|
4345
4345
|
const sub = rest[0] ?? "status";
|
|
4346
|
-
const daemon = await import("./notifyDaemon-
|
|
4346
|
+
const daemon = await import("./notifyDaemon-BbVnNvlo.js");
|
|
4347
4347
|
switch (sub) {
|
|
4348
4348
|
case "run": return daemon.runDaemon();
|
|
4349
4349
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4370,4 +4370,4 @@ async function cmdNotifyd(rest) {
|
|
|
4370
4370
|
|
|
4371
4371
|
//#endregion
|
|
4372
4372
|
export { daemonLockOwnerPath as $, renderRawLog as A, submitAndConfirm as B, matchKeyword as C, recentMessageEdges as D, readPtysize as E, restartHintLines as F, gcInboxes as G, writeKeysPaced as H, runSubcommand as I, listInboxParents as J, hostId as K, snapshotStatus as L, resolveOne as M, resolveReadWindow as N, recentReadEdges as O, resolveResumeArgs as P, daemonLockDir as Q, stdinActivityPath as R, listRecords as S, readNotes as T, writeToIpc as U, waitForLogQuiet as V, appendEvent as W, readInbox as X, liveWatchers as Y, shouldStealLock as Z, isPidAlive as _, cmdHelp as a, isUserTyping as b, deriveLiveState as c, extractMenu as d, notifyDir as et, extractNeedsInput as f, isExitRequest as g, isAgentStuck as h, backoffWhileTyping as i, renderRawLogLines as j, renderLogTailLines as k, deriveLiveStatus as l, finalizedLines as m, READ_PAGE_DEFAULT as n, controlCodeFromName as o, extractTaskCounts as p, isTransientLockMkdirError as q, TYPING_WINDOW_MS as r, cursorAbs as s, GRACEFUL_EXIT_COMMANDS as t, TYPING_BADGE as tt, extractBadges as u, isSlashCommand as v, menuSelectKeys as w, lastStdinAt as x, isSubcommand as y, stopTipForCli as z };
|
|
4373
|
-
//# sourceMappingURL=subcommands-
|
|
4373
|
+
//# sourceMappingURL=subcommands-DkrMRVNh.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-d5c6_vgS.js";
|
|
3
3
|
import { t as agentYesHome } from "./agentYesHome-CtHb5b71.js";
|
|
4
4
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-CNMl13dC.js";
|
|
5
5
|
import { t as PidStore } from "./pidStore-BIvsBQ8X.js";
|
|
@@ -1901,4 +1901,4 @@ function sleep(ms) {
|
|
|
1901
1901
|
|
|
1902
1902
|
//#endregion
|
|
1903
1903
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1904
|
-
//# sourceMappingURL=ts-
|
|
1904
|
+
//# sourceMappingURL=ts-DnqRreF4.js.map
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
|
|
8
8
|
//#region package.json
|
|
9
9
|
var name = "agent-yes";
|
|
10
|
-
var version = "1.
|
|
10
|
+
var version = "1.206.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-d5c6_vgS.js.map
|
|
@@ -2,7 +2,7 @@ import "./logger-CDIsZ-Pp.js";
|
|
|
2
2
|
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
3
|
import "./messageLog-CxrKJj77.js";
|
|
4
4
|
import "./configShared-aKTg-sa5.js";
|
|
5
|
-
import { S as listRecords } from "./subcommands-
|
|
5
|
+
import { S as listRecords } from "./subcommands-DkrMRVNh.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -418,4 +418,4 @@ async function cmdWs(args) {
|
|
|
418
418
|
|
|
419
419
|
//#endregion
|
|
420
420
|
export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, workspaceStatus };
|
|
421
|
-
//# sourceMappingURL=ws-
|
|
421
|
+
//# sourceMappingURL=ws-BmHpWaG_.js.map
|
package/lab/ui/console-logic.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// `now` so age() is deterministic under test.
|
|
8
8
|
|
|
9
9
|
// An agent entry as surfaced by /api/ls (the fields this module reads):
|
|
10
|
-
// { cli, cwd, title, prompt, status, started_at, pid, _host }
|
|
10
|
+
// { cli, cwd, title, status_text, prompt, status, started_at, pid, _host }
|
|
11
11
|
|
|
12
12
|
// claude is the default CLI — show the cli name only when it differs, so the
|
|
13
13
|
// common case stays uncluttered and the identity (repo/branch) leads instead.
|
|
@@ -261,6 +261,8 @@ export function matches(e, toks) {
|
|
|
261
261
|
const hay =
|
|
262
262
|
(e.title || "") +
|
|
263
263
|
" " +
|
|
264
|
+
(e.status_text || "") +
|
|
265
|
+
" " +
|
|
264
266
|
(e.prompt || "") +
|
|
265
267
|
" " +
|
|
266
268
|
e.cli +
|
package/lab/ui/index.html
CHANGED
|
@@ -1325,6 +1325,14 @@
|
|
|
1325
1325
|
text-overflow: ellipsis;
|
|
1326
1326
|
white-space: nowrap;
|
|
1327
1327
|
}
|
|
1328
|
+
.statusline {
|
|
1329
|
+
color: var(--muted);
|
|
1330
|
+
font-size: 12.5px;
|
|
1331
|
+
margin-top: 4px;
|
|
1332
|
+
overflow: hidden;
|
|
1333
|
+
text-overflow: ellipsis;
|
|
1334
|
+
white-space: nowrap;
|
|
1335
|
+
}
|
|
1328
1336
|
/* compact view: one line per agent — dot + cli + live title (or prompt), age */
|
|
1329
1337
|
.row.crow {
|
|
1330
1338
|
display: flex;
|
|
@@ -1682,11 +1690,28 @@
|
|
|
1682
1690
|
h1 {
|
|
1683
1691
|
font-size: 17px;
|
|
1684
1692
|
}
|
|
1685
|
-
/* roomier tap targets for the header controls
|
|
1693
|
+
/* roomier tap targets for the header controls — min 44px square so
|
|
1694
|
+
touch users can hit them (WCAG 2.5.5). inline-flex keeps the glyph
|
|
1695
|
+
centered once min-height stretches the box past its text. */
|
|
1686
1696
|
.newbtn,
|
|
1687
1697
|
.viewbtn {
|
|
1688
1698
|
padding: 7px 12px;
|
|
1689
1699
|
font-size: 12.5px;
|
|
1700
|
+
min-height: 44px;
|
|
1701
|
+
min-width: 44px;
|
|
1702
|
+
display: inline-flex;
|
|
1703
|
+
align-items: center;
|
|
1704
|
+
justify-content: center;
|
|
1705
|
+
}
|
|
1706
|
+
/* the filter box is the primary control — give it a full-height touch
|
|
1707
|
+
target too, not the 38px it collapses to from text metrics alone.
|
|
1708
|
+
Stretch the input itself to the box height so a tap anywhere in the
|
|
1709
|
+
box lands on the field, not just its 17px text line. */
|
|
1710
|
+
.ibox {
|
|
1711
|
+
min-height: 44px;
|
|
1712
|
+
}
|
|
1713
|
+
#q {
|
|
1714
|
+
align-self: stretch;
|
|
1690
1715
|
}
|
|
1691
1716
|
.meta {
|
|
1692
1717
|
align-items: center;
|
|
@@ -1819,6 +1844,7 @@
|
|
|
1819
1844
|
<input
|
|
1820
1845
|
id="q"
|
|
1821
1846
|
placeholder="filter… repo:agent-yes claude (space = AND)"
|
|
1847
|
+
aria-label="Filter agents by repo, CLI, or title"
|
|
1822
1848
|
autocomplete="off"
|
|
1823
1849
|
autofocus
|
|
1824
1850
|
/>
|
|
@@ -1831,7 +1857,14 @@
|
|
|
1831
1857
|
<span class="metaright">
|
|
1832
1858
|
<button id="foldbtn" class="viewbtn" title="fold subagent trees">⊞ subs</button>
|
|
1833
1859
|
<button id="sortbtn" class="viewbtn" title="cycle sort order">⇅ state</button>
|
|
1834
|
-
<button
|
|
1860
|
+
<button
|
|
1861
|
+
id="viewbtn"
|
|
1862
|
+
class="viewbtn"
|
|
1863
|
+
title="toggle compact list"
|
|
1864
|
+
aria-label="Toggle compact list view"
|
|
1865
|
+
>
|
|
1866
|
+
☰
|
|
1867
|
+
</button>
|
|
1835
1868
|
<button id="portsbtn" class="viewbtn" title="manage exposed localhost ports">
|
|
1836
1869
|
⇄ ports
|
|
1837
1870
|
</button>
|
|
@@ -4832,7 +4865,7 @@
|
|
|
4832
4865
|
.map((r) => {
|
|
4833
4866
|
if (r.kind !== "agent") return headerHtml(r);
|
|
4834
4867
|
const e = r.entry;
|
|
4835
|
-
const t = e.title || e.prompt || "";
|
|
4868
|
+
const t = e.title || e.status_text || e.prompt || "";
|
|
4836
4869
|
const id = compactIdent(e, ctx, 3, r.parentEntry);
|
|
4837
4870
|
const cli = cliLabel(e);
|
|
4838
4871
|
return `<div class="row crow ${e._key === sel ? "sel" : ""}${rowFlags(e)}" data-key="${esc(e._key)}">
|
|
@@ -4875,9 +4908,10 @@
|
|
|
4875
4908
|
${taskChipHtml(e)}
|
|
4876
4909
|
${badgeChipsHtml(e)}
|
|
4877
4910
|
${gitChipHtml(e)}
|
|
4878
|
-
|
|
4879
|
-
|
|
4911
|
+
${peerChipHtml(e)}
|
|
4912
|
+
<span class="age">${age(e)}</span></div>
|
|
4880
4913
|
${e.title ? `<div class="rowtitle" title="${esc(e.title)}">${esc(e.title)}</div>` : ""}
|
|
4914
|
+
${e.status_text ? `<div class="statusline" title="${esc(e.status_text)}">${esc(e.status_text)}</div>` : ""}
|
|
4881
4915
|
${
|
|
4882
4916
|
e.status === "needs_input" && e.question
|
|
4883
4917
|
? `<div class="detail ask" title="${esc(e.question)}">⌨ ${esc(e.question)}</div>`
|
package/package.json
CHANGED
package/ts/serve.spec.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { readFile } from "fs/promises";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
installerArgv,
|
|
5
|
+
isNoNodeExecError,
|
|
6
|
+
oxmgrVersionHasWindowsFix,
|
|
7
|
+
portlessConsoleUrl,
|
|
8
|
+
} from "./serve.ts";
|
|
9
|
+
|
|
10
|
+
describe("portlessConsoleUrl", () => {
|
|
11
|
+
it("uses the stable local HTTPS hostname and keeps auth in the fragment", () => {
|
|
12
|
+
expect(portlessConsoleUrl()).toBe("https://agent-yes.localhost/");
|
|
13
|
+
expect(portlessConsoleUrl("a b")).toBe("https://agent-yes.localhost/#k=a%20b");
|
|
14
|
+
});
|
|
15
|
+
});
|
|
4
16
|
|
|
5
17
|
// Guards the Windows daemon-manager selection: on Windows we only PREFER oxmgr
|
|
6
18
|
// when the installed build carries the daemon-socket-inheritance fix. Stock
|