agent-yes 1.205.0 → 1.207.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-C8-qh98a.js → SUPPORTED_CLIS-B1CDJwYn.js} +2 -2
- package/dist/SUPPORTED_CLIS-vH8hvcZr.js +9 -0
- package/dist/{agentShare-99IGGOkv.js → agentShare-DdEbHtAn.js} +3 -3
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{notifyDaemon-DK1HOMjj.js → notifyDaemon-DivHVzZx.js} +2 -2
- package/dist/{rustBinary-Tgn948GR.js → rustBinary-CuBIr-zX.js} +2 -2
- package/dist/{schedule-CBoM67Vy.js → schedule-Bg_CDt2j.js} +4 -4
- package/dist/{serve-IvOlaL-7.js → serve-B-ZCy67S.js} +258 -41
- package/dist/{setup-BaKdS-3i.js → setup-D6UBzk4-.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-Bs7wJRBB.js → subcommands-6AQ8egRn.js} +7 -7
- package/dist/{subcommands-DyDHZ5YI.js → subcommands-CeRH9-_h.js} +1 -1
- package/dist/{ts-Dm6jjLwC.js → ts-DZWZvbLM.js} +2 -2
- package/dist/{versionChecker-BomfUpSo.js → versionChecker-C2CV9VOX.js} +2 -2
- package/dist/{ws-CSkP2mkD.js → ws-CGNmxCPD.js} +2 -2
- package/lab/ui/console-logic.js +23 -1
- package/lab/ui/index.html +188 -29
- package/package.json +1 -1
- package/ts/serve.spec.ts +13 -1
- package/ts/serve.ts +263 -34
- package/ts/serveLock.spec.ts +15 -14
- package/ts/share.ts +80 -1
- package/ts/sizeNego.spec.ts +61 -0
- package/ts/sizeNego.ts +59 -0
- package/ts/statusText.spec.ts +17 -0
- package/ts/statusText.ts +19 -0
- package/ts/ws.spec.ts +8 -10
- 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
|
|
@@ -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-B-ZCy67S.js");
|
|
1241
1241
|
return cmdServe(rest);
|
|
1242
1242
|
}
|
|
1243
1243
|
case "setup": {
|
|
1244
|
-
const { cmdSetup } = await import("./setup-
|
|
1244
|
+
const { cmdSetup } = await import("./setup-D6UBzk4-.js");
|
|
1245
1245
|
return cmdSetup(rest);
|
|
1246
1246
|
}
|
|
1247
1247
|
case "ws": {
|
|
1248
|
-
const { cmdWs } = await import("./ws-
|
|
1248
|
+
const { cmdWs } = await import("./ws-CGNmxCPD.js");
|
|
1249
1249
|
return cmdWs(rest);
|
|
1250
1250
|
}
|
|
1251
1251
|
case "schedule": {
|
|
1252
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1252
|
+
const { cmdSchedule } = await import("./schedule-Bg_CDt2j.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-DivHVzZx.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-DivHVzZx.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-6AQ8egRn.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-6AQ8egRn.js";
|
|
6
6
|
import "./e2e-jb0Hp43q.js";
|
|
7
7
|
import "./webrtcLink-B7REGtK2.js";
|
|
8
8
|
import "./remotes-Cim0dBU7.js";
|
|
@@ -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-C2CV9VOX.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-DZWZvbLM.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.207.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-C2CV9VOX.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-6AQ8egRn.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-CGNmxCPD.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 +
|
|
@@ -699,6 +701,26 @@ export function fitTransform(gridW, gridH, paneW, paneH) {
|
|
|
699
701
|
return s > 0.985 && s < 1.04 ? "none" : "scale(" + s.toFixed(4) + ")";
|
|
700
702
|
}
|
|
701
703
|
|
|
704
|
+
// Centered variant: same scale selection as fitTransform, plus a translate that
|
|
705
|
+
// centers the scaled grid in the pane (fit-width → vertically centered,
|
|
706
|
+
// fit-height → horizontally centered). transform-origin stays top-left, so the
|
|
707
|
+
// translate is in pane px and consumers mapping grid→screen coords (peer
|
|
708
|
+
// overlays) can read the offset back off this same object. "none" (the crisp
|
|
709
|
+
// driver path) never gets a translate — grid ≈ pane, nothing to center.
|
|
710
|
+
export function fitTransformCentered(gridW, gridH, paneW, paneH) {
|
|
711
|
+
const t = fitTransform(gridW, gridH, paneW, paneH);
|
|
712
|
+
if (t === "none") return { transform: "none", scale: 1, dx: 0, dy: 0 };
|
|
713
|
+
const s = Math.min(paneW / gridW, paneH / gridH);
|
|
714
|
+
const dx = Math.max(0, (paneW - gridW * s) / 2);
|
|
715
|
+
const dy = Math.max(0, (paneH - gridH * s) / 2);
|
|
716
|
+
return {
|
|
717
|
+
transform: `translate(${dx.toFixed(1)}px, ${dy.toFixed(1)}px) ` + t,
|
|
718
|
+
scale: s,
|
|
719
|
+
dx,
|
|
720
|
+
dy,
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
702
724
|
// Browser-tab title: "<glyph> <selected agent title> - agent-yes", or the bare
|
|
703
725
|
// console title when nothing is selected (blank/whitespace name). The leading
|
|
704
726
|
// glyph mirrors the agent's status dot — ⌨ needs_input ("your turn"), ⚠ stuck,
|