agent-yes 1.194.0 → 1.196.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-Ca2ffDRy.js +8 -0
- package/dist/{SUPPORTED_CLIS--WH2XfM2.js → SUPPORTED_CLIS-CxLCQtAU.js} +2 -2
- package/dist/{agentShare-BEXN8bNT.js → agentShare-Bi95Xy0S.js} +2 -2
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{notifyDaemon-Deisyrbn.js → notifyDaemon-BdOeFIVl.js} +2 -2
- package/dist/{rustBinary-cTIMKGQp.js → rustBinary-D_ifX2Vd.js} +2 -2
- package/dist/{schedule-MQZjDaY6.js → schedule-rvMgc0tA.js} +4 -4
- package/dist/{serve-hA23xPpg.js → serve-D0-LoTfw.js} +43 -13
- package/dist/{setup-C6grPf1R.js → setup-BC1VjTOf.js} +2 -2
- package/dist/subcommands-Cz8xpc5X.js +9 -0
- package/dist/{subcommands-Ba0V9EEH.js → subcommands-s74ViJcI.js} +305 -12
- package/dist/{ts-6JcbtJh1.js → ts-CP17kUI1.js} +2 -2
- package/dist/{versionChecker-DDNKcQRx.js → versionChecker-DTssk7cU.js} +2 -2
- package/lab/ui/index.html +292 -2
- package/lab/ui/room-client.js +544 -388
- package/lab/ui/sw.js +71 -19
- package/package.json +1 -1
- package/ts/messageLog.spec.ts +145 -0
- package/ts/messageLog.ts +147 -0
- package/ts/serve.ts +55 -8
- package/ts/subcommands.ts +270 -5
- package/dist/SUPPORTED_CLIS-NfXUfiWY.js +0 -8
- package/dist/subcommands-LP1Z8g-h.js +0 -9
package/ts/subcommands.ts
CHANGED
|
@@ -20,6 +20,14 @@ import { type GlobalPidRecord, readGlobalPids, updateGlobalPidStatus } from "./g
|
|
|
20
20
|
import { buildAgentForest, flattenForest } from "./agentTree.ts";
|
|
21
21
|
import { parseTaskCounts, type TaskCounts } from "./todoParse.ts";
|
|
22
22
|
import { agentYesHome } from "./agentYesHome.ts";
|
|
23
|
+
import {
|
|
24
|
+
type MailParty,
|
|
25
|
+
type MessageRecord,
|
|
26
|
+
partyMatches,
|
|
27
|
+
readMailbox,
|
|
28
|
+
recordMessage,
|
|
29
|
+
recordOutbox,
|
|
30
|
+
} from "./messageLog.ts";
|
|
23
31
|
import { badgeDef, matchBadges, TYPING_BADGE } from "./badges.ts";
|
|
24
32
|
import {
|
|
25
33
|
classifyNeedsInput,
|
|
@@ -195,6 +203,49 @@ export async function recentReadEdges(windowMs = READ_WINDOW_MS): Promise<ReadEd
|
|
|
195
203
|
return out;
|
|
196
204
|
}
|
|
197
205
|
|
|
206
|
+
/** Recent agent→agent MESSAGE edges (a delivered `ay send`/`key`/`select`), for
|
|
207
|
+
* the /rgui + /w wire view. Like {@link ReadEdge} but sourced from the per-cwd
|
|
208
|
+
* outbox logs and carrying the send `kind`. `by`/`target` are the sender/recipient
|
|
209
|
+
* pids AT SEND TIME (a restarted agent keeps a new pid — matched best-effort). */
|
|
210
|
+
export interface MessageEdge {
|
|
211
|
+
by: number;
|
|
212
|
+
target: number;
|
|
213
|
+
at: number;
|
|
214
|
+
kind?: "key" | "select";
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Scan every live agent's outbox for sends within `windowMs` and return them as
|
|
219
|
+
* directional edges (newest `at` per by→target pair wins). Bounded by the number
|
|
220
|
+
* of distinct agent cwds — the outbox is per-cwd, so each dir is read once.
|
|
221
|
+
*/
|
|
222
|
+
export async function recentMessageEdges(windowMs = READ_WINDOW_MS): Promise<MessageEdge[]> {
|
|
223
|
+
const now = Date.now();
|
|
224
|
+
const records = await listRecords(undefined, {
|
|
225
|
+
all: true,
|
|
226
|
+
active: false,
|
|
227
|
+
json: false,
|
|
228
|
+
latest: false,
|
|
229
|
+
cwdScope: null,
|
|
230
|
+
});
|
|
231
|
+
const cwds = [...new Set(records.map((r) => r.cwd).filter(Boolean))];
|
|
232
|
+
const best = new Map<string, MessageEdge>();
|
|
233
|
+
await Promise.all(
|
|
234
|
+
cwds.map(async (cwd) => {
|
|
235
|
+
for (const rec of await readMailbox(cwd, "outbox")) {
|
|
236
|
+
if (now - rec.at > windowMs) continue;
|
|
237
|
+
const by = rec.from?.pid;
|
|
238
|
+
const target = rec.to?.pid;
|
|
239
|
+
if (!by || !target || by === target) continue; // agent→agent only
|
|
240
|
+
const key = `${by}\0${target}`;
|
|
241
|
+
const prev = best.get(key);
|
|
242
|
+
if (!prev || rec.at > prev.at) best.set(key, { by, target, at: rec.at, kind: rec.kind });
|
|
243
|
+
}
|
|
244
|
+
}),
|
|
245
|
+
);
|
|
246
|
+
return [...best.values()];
|
|
247
|
+
}
|
|
248
|
+
|
|
198
249
|
// Identify the sender. An agent launched by `ay` inherits AGENT_YES_PID=<wrapper
|
|
199
250
|
// pid>; the registered agent record carries that same wrapper_pid, so we map the
|
|
200
251
|
// env value back to the agent's own canonical record. Falls back to a direct pid
|
|
@@ -296,6 +347,7 @@ const SUBCOMMANDS = new Set([
|
|
|
296
347
|
"tail",
|
|
297
348
|
"head",
|
|
298
349
|
"send",
|
|
350
|
+
"msgs",
|
|
299
351
|
"key",
|
|
300
352
|
"select",
|
|
301
353
|
"spawn",
|
|
@@ -397,6 +449,8 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
397
449
|
return await cmdRead(rest, { mode: "head" });
|
|
398
450
|
case "send":
|
|
399
451
|
return await cmdSend(rest);
|
|
452
|
+
case "msgs":
|
|
453
|
+
return await cmdMsgs(rest);
|
|
400
454
|
case "key":
|
|
401
455
|
return await cmdKey(rest);
|
|
402
456
|
case "select":
|
|
@@ -534,6 +588,7 @@ export async function cmdHelp(managerCommands = true): Promise<number> {
|
|
|
534
588
|
` ay cat <keyword> full log\n` +
|
|
535
589
|
` ay head <keyword> first N lines\n` +
|
|
536
590
|
` ay send <keyword> <msg> send a message\n` +
|
|
591
|
+
` ay msgs [keyword] [--in|--out] inter-agent message log (sent + received)\n` +
|
|
537
592
|
` ay key <keyword> <key...> send raw keystrokes (down/up/enter/esc/…) — drives menus\n` +
|
|
538
593
|
` ay select <keyword> <N> pick option N of a needs_input selection menu\n` +
|
|
539
594
|
` ay attach <keyword> interactive attach (detach: Ctrl-\\)\n` +
|
|
@@ -979,13 +1034,48 @@ async function runRemoteSend(remote: ResolvedRemote, msg: string, code: string):
|
|
|
979
1034
|
process.stderr.write("remote send requires a keyword (e.g. token@host:port:keyword)\n");
|
|
980
1035
|
return 1;
|
|
981
1036
|
}
|
|
982
|
-
|
|
1037
|
+
// Attribute the send so the remote can record its recipient's inbox with a real
|
|
1038
|
+
// sender (not an anonymous cross-wire write). Human shell → no `from`.
|
|
1039
|
+
const sender = await senderContext();
|
|
1040
|
+
const from = sender.agent
|
|
1041
|
+
? {
|
|
1042
|
+
pid: sender.agent.pid,
|
|
1043
|
+
cli: sender.agent.cli,
|
|
1044
|
+
cwd: sender.agent.cwd,
|
|
1045
|
+
agent_id: sender.agent.agent_id,
|
|
1046
|
+
}
|
|
1047
|
+
: null;
|
|
1048
|
+
const res = await remotePost(remote, "/api/send", { keyword, msg, code, from });
|
|
983
1049
|
if (!res.ok) {
|
|
984
1050
|
process.stderr.write(`remote error ${res.status}: ${await res.text()}\n`);
|
|
985
1051
|
return 1;
|
|
986
1052
|
}
|
|
987
|
-
const data = (await res.json()) as
|
|
1053
|
+
const data = (await res.json()) as {
|
|
1054
|
+
pid: number;
|
|
1055
|
+
cli?: string;
|
|
1056
|
+
cwd?: string;
|
|
1057
|
+
agentId?: string;
|
|
1058
|
+
};
|
|
988
1059
|
process.stdout.write(`sent to remote pid ${data.pid} (${remote.url} ${keyword})\n`);
|
|
1060
|
+
// Record the sender's half of the exchange locally (the recipient's inbox is
|
|
1061
|
+
// recorded on the remote host by its /api/send handler). Only real bodies.
|
|
1062
|
+
if (msg && msg !== "-") {
|
|
1063
|
+
await recordOutbox({
|
|
1064
|
+
at: Date.now(),
|
|
1065
|
+
from,
|
|
1066
|
+
to: {
|
|
1067
|
+
pid: data.pid,
|
|
1068
|
+
cli: data.cli ?? keyword,
|
|
1069
|
+
cwd: data.cwd ?? "",
|
|
1070
|
+
agent_id: data.agentId,
|
|
1071
|
+
},
|
|
1072
|
+
body: msg,
|
|
1073
|
+
code: code.toLowerCase() === "enter" ? undefined : code.toLowerCase(),
|
|
1074
|
+
confirmed: true,
|
|
1075
|
+
wrapped: false,
|
|
1076
|
+
remote: remote.url,
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
989
1079
|
return 0;
|
|
990
1080
|
}
|
|
991
1081
|
|
|
@@ -2975,8 +3065,9 @@ async function cmdSend(rest: string[]): Promise<number> {
|
|
|
2975
3065
|
const replyTarget = sender.agent?.agent_id || sender.agent?.pid;
|
|
2976
3066
|
let prefix = "";
|
|
2977
3067
|
let suffix = "";
|
|
3068
|
+
let nonce: string | undefined;
|
|
2978
3069
|
if (sender.agent && !isSlashCommand(body)) {
|
|
2979
|
-
|
|
3070
|
+
nonce = randomBytes(4).toString("hex");
|
|
2980
3071
|
prefix = `<ay-msg ${nonce} from ${sender.agent.cli} #${sender.agent.pid} @ ${shortenPath(sender.agent.cwd)} — reply: ay send ${replyTarget} "...">\n`;
|
|
2981
3072
|
suffix = `\n</ay-msg ${nonce}>`;
|
|
2982
3073
|
}
|
|
@@ -3031,6 +3122,35 @@ async function cmdSend(rest: string[]): Promise<number> {
|
|
|
3031
3122
|
process.stdout.write(
|
|
3032
3123
|
`${status} to pid ${record.pid} (${record.cli}): ${truncate(payload, 80)}\n`,
|
|
3033
3124
|
);
|
|
3125
|
+
|
|
3126
|
+
// Persist a durable record of the exchange from both ends' point of view (the
|
|
3127
|
+
// sender's outbox + the recipient's inbox). Only real message bodies are
|
|
3128
|
+
// logged — a bare control code (esc/ctrl-c with no body) isn't a "message".
|
|
3129
|
+
// Best-effort: recordMessage swallows its own errors so it never breaks send.
|
|
3130
|
+
if (body) {
|
|
3131
|
+
await recordMessage({
|
|
3132
|
+
at: Date.now(),
|
|
3133
|
+
nonce,
|
|
3134
|
+
from: sender.agent
|
|
3135
|
+
? {
|
|
3136
|
+
pid: sender.agent.pid,
|
|
3137
|
+
cli: sender.agent.cli,
|
|
3138
|
+
cwd: sender.agent.cwd,
|
|
3139
|
+
agent_id: sender.agent.agent_id,
|
|
3140
|
+
}
|
|
3141
|
+
: null,
|
|
3142
|
+
to: {
|
|
3143
|
+
pid: record.pid,
|
|
3144
|
+
cli: record.cli,
|
|
3145
|
+
cwd: record.cwd,
|
|
3146
|
+
agent_id: record.agent_id,
|
|
3147
|
+
},
|
|
3148
|
+
body,
|
|
3149
|
+
code: trailing === "\r" ? undefined : codeName,
|
|
3150
|
+
confirmed,
|
|
3151
|
+
wrapped: Boolean(nonce),
|
|
3152
|
+
});
|
|
3153
|
+
}
|
|
3034
3154
|
if (!confirmed) {
|
|
3035
3155
|
process.stderr.write(
|
|
3036
3156
|
`\nwarning: couldn't confirm the CLI acted on it after ${SEND_SUBMIT_MAX_RETRIES + 1} attempt(s) — ` +
|
|
@@ -3059,6 +3179,119 @@ async function cmdSend(rest: string[]): Promise<number> {
|
|
|
3059
3179
|
return confirmed ? 0 : 1;
|
|
3060
3180
|
}
|
|
3061
3181
|
|
|
3182
|
+
// ---------------------------------------------------------------------------
|
|
3183
|
+
// ay msgs — read the durable inter-agent message log
|
|
3184
|
+
// ---------------------------------------------------------------------------
|
|
3185
|
+
|
|
3186
|
+
/** A mailbox record annotated with the direction it takes from the owner's POV. */
|
|
3187
|
+
interface DirectedMessage {
|
|
3188
|
+
dir: "in" | "out";
|
|
3189
|
+
rec: MessageRecord;
|
|
3190
|
+
}
|
|
3191
|
+
|
|
3192
|
+
/**
|
|
3193
|
+
* `ay msgs [keyword]` — show the inter-agent messages an agent sent and
|
|
3194
|
+
* received. With no keyword it uses THIS caller's context (the agent running
|
|
3195
|
+
* `ay msgs`, or the human shell's cwd); with a keyword it resolves one agent and
|
|
3196
|
+
* reads that agent's mailboxes. Newest last, like a chat log.
|
|
3197
|
+
*/
|
|
3198
|
+
async function cmdMsgs(rest: string[]): Promise<number> {
|
|
3199
|
+
const y = yargs(rest)
|
|
3200
|
+
.usage("Usage: ay msgs [keyword] [--in|--out] [-n N] [--json]")
|
|
3201
|
+
.option("in", { type: "boolean", default: false, description: "Only received messages" })
|
|
3202
|
+
.option("out", { type: "boolean", default: false, description: "Only sent messages" })
|
|
3203
|
+
.option("n", { type: "number", description: "Show the last N messages (default 50)" })
|
|
3204
|
+
.option("json", { type: "boolean", default: false, description: "Emit raw JSONL records" })
|
|
3205
|
+
.option("all", { type: "boolean", default: false, description: "Include exited agents" })
|
|
3206
|
+
.option("latest", {
|
|
3207
|
+
type: "boolean",
|
|
3208
|
+
default: false,
|
|
3209
|
+
description: "Use most recent match when multiple match",
|
|
3210
|
+
})
|
|
3211
|
+
.option("cwd", { type: "string", description: "Restrict to agents under this dir" })
|
|
3212
|
+
.help(false)
|
|
3213
|
+
.version(false)
|
|
3214
|
+
.exitProcess(false);
|
|
3215
|
+
|
|
3216
|
+
const argv = await y.parseAsync();
|
|
3217
|
+
const keyword = argv._[0] !== undefined ? String(argv._[0]) : undefined;
|
|
3218
|
+
|
|
3219
|
+
// Whose mailbox: an explicit keyword names a target agent; otherwise the
|
|
3220
|
+
// calling agent (or, for a human shell, its own cwd with no agent filter).
|
|
3221
|
+
let ownerCwd: string;
|
|
3222
|
+
let ownerAgentId: string | null | undefined;
|
|
3223
|
+
let ownerPid: number | null | undefined;
|
|
3224
|
+
let ownerLabel: string;
|
|
3225
|
+
if (keyword) {
|
|
3226
|
+
const opts: CommonOpts = {
|
|
3227
|
+
all: argv.all,
|
|
3228
|
+
active: false,
|
|
3229
|
+
json: false,
|
|
3230
|
+
latest: argv.latest,
|
|
3231
|
+
cwdScope: typeof argv.cwd === "string" ? path.resolve(argv.cwd) : null,
|
|
3232
|
+
};
|
|
3233
|
+
const record = await resolveOne(keyword, opts);
|
|
3234
|
+
ownerCwd = record.cwd;
|
|
3235
|
+
ownerAgentId = record.agent_id;
|
|
3236
|
+
ownerPid = record.pid;
|
|
3237
|
+
ownerLabel = `pid ${record.pid} (${record.cli})`;
|
|
3238
|
+
} else {
|
|
3239
|
+
const sender = await senderContext();
|
|
3240
|
+
ownerCwd = sender.agent?.cwd ?? process.cwd();
|
|
3241
|
+
ownerAgentId = sender.agent?.agent_id;
|
|
3242
|
+
ownerPid = sender.agent?.pid;
|
|
3243
|
+
ownerLabel = sender.agent ? `pid ${sender.agent.pid} (${sender.agent.cli})` : "this shell";
|
|
3244
|
+
}
|
|
3245
|
+
|
|
3246
|
+
const isOwner = (party: MailParty | null): boolean =>
|
|
3247
|
+
// A human shell (no agent context) owns only the messages it sent, which
|
|
3248
|
+
// carry `from: null`; match those so `ay msgs` in a plain terminal works.
|
|
3249
|
+
ownerAgentId || ownerPid ? partyMatches(party, ownerAgentId, ownerPid) : party === null;
|
|
3250
|
+
|
|
3251
|
+
const messages: DirectedMessage[] = [];
|
|
3252
|
+
if (!argv.in) {
|
|
3253
|
+
for (const rec of await readMailbox(ownerCwd, "outbox")) {
|
|
3254
|
+
if (isOwner(rec.from)) messages.push({ dir: "out", rec });
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
if (!argv.out) {
|
|
3258
|
+
for (const rec of await readMailbox(ownerCwd, "inbox")) {
|
|
3259
|
+
if (isOwner(rec.to)) messages.push({ dir: "in", rec });
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
messages.sort((a, b) => a.rec.at - b.rec.at);
|
|
3263
|
+
|
|
3264
|
+
const limit =
|
|
3265
|
+
argv.n !== undefined && Number.isFinite(argv.n) && argv.n! > 0 ? Math.floor(argv.n!) : 50;
|
|
3266
|
+
const shown = messages.slice(-limit);
|
|
3267
|
+
|
|
3268
|
+
if (argv.json) {
|
|
3269
|
+
for (const { dir, rec } of shown) {
|
|
3270
|
+
process.stdout.write(JSON.stringify({ dir, ...rec }) + "\n");
|
|
3271
|
+
}
|
|
3272
|
+
return 0;
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
if (shown.length === 0) {
|
|
3276
|
+
process.stderr.write(`no messages for ${ownerLabel}.\n`);
|
|
3277
|
+
return 0;
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
for (const { dir, rec } of shown) {
|
|
3281
|
+
const when = new Date(rec.at).toLocaleTimeString();
|
|
3282
|
+
const peer =
|
|
3283
|
+
dir === "out"
|
|
3284
|
+
? `→ ${rec.to.cli} #${rec.to.pid}`
|
|
3285
|
+
: `← ${rec.from ? `${rec.from.cli} #${rec.from.pid}` : "human"}`;
|
|
3286
|
+
const via = rec.remote ? ` (via ${rec.remote})` : "";
|
|
3287
|
+
const flag = rec.confirmed === false ? " (unconfirmed)" : "";
|
|
3288
|
+
const tag = rec.kind ? `[${rec.kind}] ` : "";
|
|
3289
|
+
const line = tag + truncate(rec.body.replace(/\s+/g, " "), 100);
|
|
3290
|
+
process.stdout.write(`${when} ${peer.padEnd(20)}${via}${flag} ${line}\n`);
|
|
3291
|
+
}
|
|
3292
|
+
return 0;
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3062
3295
|
// Resolve a keyword to one agent and return it with a writable FIFO, or throw
|
|
3063
3296
|
// with the same guidance cmdSend gives. Shared by `ay key` / `ay select`.
|
|
3064
3297
|
async function resolveWritableAgent(keyword: string, opts: CommonOpts): Promise<GlobalPidRecord> {
|
|
@@ -3071,6 +3304,36 @@ async function resolveWritableAgent(keyword: string, opts: CommonOpts): Promise<
|
|
|
3071
3304
|
return record;
|
|
3072
3305
|
}
|
|
3073
3306
|
|
|
3307
|
+
/**
|
|
3308
|
+
* Record an `ay key` / `ay select` stdin write in the message log, same as a
|
|
3309
|
+
* text send but tagged with its `kind` (and `body` = the keystroke names /
|
|
3310
|
+
* chosen option). Key/select are local-only (no remote wire), so both mailboxes
|
|
3311
|
+
* are on this host — recordMessage writes both. Best-effort.
|
|
3312
|
+
*/
|
|
3313
|
+
async function recordKeyEvent(
|
|
3314
|
+
sender: { agent: GlobalPidRecord | null },
|
|
3315
|
+
record: GlobalPidRecord,
|
|
3316
|
+
kind: "key" | "select",
|
|
3317
|
+
body: string,
|
|
3318
|
+
): Promise<void> {
|
|
3319
|
+
await recordMessage({
|
|
3320
|
+
at: Date.now(),
|
|
3321
|
+
from: sender.agent
|
|
3322
|
+
? {
|
|
3323
|
+
pid: sender.agent.pid,
|
|
3324
|
+
cli: sender.agent.cli,
|
|
3325
|
+
cwd: sender.agent.cwd,
|
|
3326
|
+
agent_id: sender.agent.agent_id,
|
|
3327
|
+
}
|
|
3328
|
+
: null,
|
|
3329
|
+
to: { pid: record.pid, cli: record.cli, cwd: record.cwd, agent_id: record.agent_id },
|
|
3330
|
+
kind,
|
|
3331
|
+
body,
|
|
3332
|
+
confirmed: true,
|
|
3333
|
+
wrapped: false,
|
|
3334
|
+
});
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3074
3337
|
async function cmdKey(rest: string[]): Promise<number> {
|
|
3075
3338
|
const y = yargs(rest)
|
|
3076
3339
|
.usage(
|
|
@@ -3118,10 +3381,11 @@ async function cmdKey(rest: string[]): Promise<number> {
|
|
|
3118
3381
|
};
|
|
3119
3382
|
const record = await resolveWritableAgent(keyword, opts);
|
|
3120
3383
|
const force = Boolean(argv.force) || process.env.AGENT_YES_FORCE_SEND === "1";
|
|
3121
|
-
await enforceSendGuards(record, force);
|
|
3384
|
+
const sender = await enforceSendGuards(record, force);
|
|
3122
3385
|
|
|
3123
3386
|
await writeKeysPaced(record.fifo_file!, byteSeqs, Math.max(0, argv.pace));
|
|
3124
3387
|
process.stdout.write(`sent to pid ${record.pid} (${record.cli}): ${keyNames.join(" ")}\n`);
|
|
3388
|
+
await recordKeyEvent(sender, record, "key", keyNames.join(" "));
|
|
3125
3389
|
return 0;
|
|
3126
3390
|
}
|
|
3127
3391
|
|
|
@@ -3178,7 +3442,7 @@ async function cmdSelect(rest: string[]): Promise<number> {
|
|
|
3178
3442
|
);
|
|
3179
3443
|
}
|
|
3180
3444
|
const force = Boolean(argv.force) || process.env.AGENT_YES_FORCE_SEND === "1";
|
|
3181
|
-
await enforceSendGuards(record, force);
|
|
3445
|
+
const sender = await enforceSendGuards(record, force);
|
|
3182
3446
|
|
|
3183
3447
|
const menu = await extractMenu(record.log_file, record.cli);
|
|
3184
3448
|
if (!menu) {
|
|
@@ -3202,6 +3466,7 @@ async function cmdSelect(rest: string[]): Promise<number> {
|
|
|
3202
3466
|
process.stdout.write(
|
|
3203
3467
|
`pid ${record.pid} (${record.cli}): selected option ${n} (${moved} + enter)\n`,
|
|
3204
3468
|
);
|
|
3469
|
+
await recordKeyEvent(sender, record, "select", `option ${n}`);
|
|
3205
3470
|
|
|
3206
3471
|
if (argv.wait) {
|
|
3207
3472
|
const ok = await waitForNeedsInputClear(record, Math.max(1, argv.timeout) * 1000);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-6JcbtJh1.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-DDNKcQRx.js";
|
|
4
|
-
import "./pidStore-BIvsBQ8X.js";
|
|
5
|
-
import "./globalPidIndex-CoNr7tS8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS--WH2XfM2.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./globalPidIndex-CoNr7tS8.js";
|
|
3
|
-
import "./configShared-0MnIQ652.js";
|
|
4
|
-
import { A as renderRawLogLines, B as waitForLogQuiet, C as matchKeyword, D as recentReadEdges, E as readPtysize, F as runSubcommand, H as writeToIpc, I as snapshotStatus, L as stdinActivityPath, M as resolveReadWindow, N as resolveResumeArgs, O as renderLogTailLines, P as restartHintLines, R as stopTipForCli, S as listRecords, T as readNotes, V as writeKeysPaced, _ 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 resolveOne, k as renderRawLog, 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 submitAndConfirm } from "./subcommands-Ba0V9EEH.js";
|
|
5
|
-
import "./e2e-BeKjLhmO.js";
|
|
6
|
-
import "./webrtcLink-BG0Xc4-W.js";
|
|
7
|
-
import "./remotes-oSmwSYaV.js";
|
|
8
|
-
|
|
9
|
-
export { cmdHelp, isSubcommand, runSubcommand };
|