agent-yes 1.258.3 → 1.259.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-DD6bhkyI.js → SUPPORTED_CLIS-BBeIFAZD.js} +2 -2
- package/dist/SUPPORTED_CLIS-BRgPb6Pz.js +11 -0
- package/dist/{agentShare-CoI7IHeq.js → agentShare-90Y_SFqK.js} +4 -4
- package/dist/{callback-CbdkyTRw.js → callback-CLzRxjEn.js} +3 -3
- package/dist/{callback-DNI__ASS.js → callback-DYQ2jQi2.js} +4 -4
- package/dist/cli.js +11 -11
- package/dist/{cwdConflictWarn-DZTxTGXq.js → cwdConflictWarn-B_047KCF.js} +2 -2
- package/dist/{forkNested-CgJ1rTnT.js → forkNested-CBdhC852.js} +2 -2
- package/dist/globalPidIndex-CHA__9Xf.js +4 -0
- package/dist/{globalPidIndex-Dq4KY2IV.js → globalPidIndex-pwp7Vb7o.js} +8 -2
- package/dist/index.js +4 -4
- package/dist/{notifyDaemon-BQ6_UbJS.js → notifyDaemon-D5RtFwMq.js} +4 -4
- package/dist/pidStore-1PQ4ARnh.js +6 -0
- package/dist/{pidStore-Cmcc8Oej.js → pidStore-DfSm1jog.js} +7 -4
- package/dist/{remotes-Dy4Rg8Yp.js → remotes-Cn-wszbK.js} +2 -2
- package/dist/{remotes-CNe85Icx.js → remotes-lOhHSoSS.js} +1 -1
- package/dist/{rustBinary-orhBmTNo.js → rustBinary-BEscpLLP.js} +2 -2
- package/dist/{schedule-BQy6gXYk.js → schedule-Cw5nW_di.js} +6 -6
- package/dist/{serve-C2mQMjUR.js → serve-DctJ7tY-.js} +19 -19
- package/dist/{setup-EEF1vfhi.js → setup-BA9D1ExO.js} +10 -2
- package/dist/{spawnGate-D0E1uRP7.js → spawnGate-D-68B907.js} +2 -2
- package/dist/spawnGate-DbSHnfqA.js +5 -0
- package/dist/{subcommands-CiX7J7hA.js → subcommands-D_cPHm34.js} +93 -24
- package/dist/{subcommands-S7uULM_d.js → subcommands-Dg7KkEi6.js} +3 -3
- package/dist/systemPathLink-DTAhFXFx.js +91 -0
- package/dist/{terminal-i7IimD_R.js → terminal-CB5K4Jjh.js} +2 -2
- package/dist/{todoCli-B2kqgqPh.js → todoCli-DNOk38lq.js} +2 -2
- package/dist/{tray-CgkwxtG6.js → tray-wWMvGWeY.js} +1 -1
- package/dist/trayApp-B1OhYfj3.js +5 -0
- package/dist/{trayApp-4sZgxxP-.js → trayApp-Ck3kWM-7.js} +2 -2
- package/dist/{ts-D-E4xqpA.js → ts-Bd_7sgVu.js} +5 -4
- package/dist/{versionChecker-YDl8a9il.js → versionChecker-DRijpksb.js} +2 -2
- package/dist/{webrtcRemote-C3OlHYSt.js → webrtcRemote-BkZcA5yq.js} +1 -1
- package/dist/{widget-7j9RrYZR.js → widget-DiRKbtng.js} +3 -3
- package/dist/{ws-DjyQ20AD.js → ws-Bp8eOEoV.js} +2 -2
- package/dist/{ws-Clem1WQ-.js → ws-Cqn8mxsS.js} +4 -4
- package/package.json +1 -1
- package/ts/globalPidIndex.spec.ts +36 -0
- package/ts/globalPidIndex.ts +19 -1
- package/ts/hist.spec.ts +219 -0
- package/ts/hist.ts +136 -0
- package/ts/histStore.spec.ts +351 -0
- package/ts/histStore.ts +494 -0
- package/ts/index.ts +4 -0
- package/ts/messageLog.ts +2 -0
- package/ts/pidStore.spec.ts +26 -0
- package/ts/pidStore.ts +10 -0
- package/ts/setup.ts +17 -0
- package/ts/subcommands.spec.ts +180 -0
- package/ts/subcommands.ts +103 -3
- package/ts/systemPathLink.spec.ts +69 -0
- package/ts/systemPathLink.ts +134 -0
- package/dist/SUPPORTED_CLIS-D1BoydrZ.js +0 -11
- package/dist/globalPidIndex-CQX_0JSB.js +0 -4
- package/dist/pidStore-BbKqQOS8.js +0 -6
- package/dist/spawnGate-DqKBA07k.js +0 -5
- package/dist/trayApp-C35IkXnz.js +0 -5
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
|
|
2
2
|
import { n as logger } from "./logger-CDIsZ-Pp.js";
|
|
3
3
|
import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
|
|
4
|
-
import { a as
|
|
4
|
+
import { a as sanitizeRole, i as readGlobalPids, o as updateGlobalPidStatus } from "./globalPidIndex-pwp7Vb7o.js";
|
|
5
5
|
import { a as recordOutbox, i as recordMessage, n as readMailbox, t as partyMatches } from "./messageLog-BYFwioFY.js";
|
|
6
6
|
import { t as loadSharedCliDefaults } from "./configShared-DtHMBCl7.js";
|
|
7
7
|
import { n as isWebrtcSpec } from "./webrtcLink-CS4D-3G1.js";
|
|
8
|
-
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-
|
|
8
|
+
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-Cn-wszbK.js";
|
|
9
9
|
import ms from "ms";
|
|
10
10
|
import yargs from "yargs";
|
|
11
11
|
import { appendFile, mkdir, open, readFile, readdir, rename, rm, stat, writeFile } from "fs/promises";
|
|
@@ -1211,6 +1211,7 @@ async function cmdWhoami(rest) {
|
|
|
1211
1211
|
const ageMin = Math.max(0, Math.round((Date.now() - self.started_at) / 6e4));
|
|
1212
1212
|
const lines = [
|
|
1213
1213
|
`agent ${self.cli} #${self.pid}${self.agent_id ? ` (agent_id ${self.agent_id})` : ""}`,
|
|
1214
|
+
`role ${self.role ?? "- (set with: ay role <name>)"}`,
|
|
1214
1215
|
`state ${state}${question ? ` — ${question}` : ""}`,
|
|
1215
1216
|
`cwd ${self.cwd}`,
|
|
1216
1217
|
`started ${new Date(self.started_at).toISOString()} (${ageMin}m ago)`,
|
|
@@ -1218,7 +1219,7 @@ async function cmdWhoami(rest) {
|
|
|
1218
1219
|
`log ${self.log_file ?? "-"}`,
|
|
1219
1220
|
`fifo ${self.fifo_file ?? "-"}`,
|
|
1220
1221
|
`reply ${reply} "..."`,
|
|
1221
|
-
`envelope <ay-msg from ${self.cli} #${self.pid} @ ${self.cwd} — reply: ${reply} "...">…</ay-msg>`
|
|
1222
|
+
`envelope <ay-msg from ${self.cli} #${self.pid}${self.role ? ` (${self.role})` : ""} @ ${self.cwd} — reply: ${reply} "...">…</ay-msg>`
|
|
1222
1223
|
];
|
|
1223
1224
|
process.stdout.write(lines.join("\n") + "\n");
|
|
1224
1225
|
return 0;
|
|
@@ -1264,7 +1265,8 @@ async function readLocalTsPids(cwd) {
|
|
|
1264
1265
|
status: d.status ?? "active",
|
|
1265
1266
|
exit_code: d.exitCode ?? null,
|
|
1266
1267
|
exit_reason: d.exitReason ?? null,
|
|
1267
|
-
started_at: d.startedAt ?? 0
|
|
1268
|
+
started_at: d.startedAt ?? 0,
|
|
1269
|
+
role: d.role ?? null
|
|
1268
1270
|
}));
|
|
1269
1271
|
}
|
|
1270
1272
|
/** Merge by pid; later entries (typically from the global file) win. */
|
|
@@ -1294,6 +1296,7 @@ const SUBCOMMANDS = new Set([
|
|
|
1294
1296
|
"head",
|
|
1295
1297
|
"send",
|
|
1296
1298
|
"msgs",
|
|
1299
|
+
"role",
|
|
1297
1300
|
"key",
|
|
1298
1301
|
"select",
|
|
1299
1302
|
"spawn",
|
|
@@ -1380,6 +1383,7 @@ async function runSubcommand(argv) {
|
|
|
1380
1383
|
case "head": return await cmdRead(rest, { mode: "head" });
|
|
1381
1384
|
case "send": return await cmdSend(rest);
|
|
1382
1385
|
case "msgs": return await cmdMsgs(rest);
|
|
1386
|
+
case "role": return await cmdRole(rest);
|
|
1383
1387
|
case "key": return await cmdKey(rest);
|
|
1384
1388
|
case "select": return await cmdSelect(rest);
|
|
1385
1389
|
case "spawn": return await cmdSpawn(rest);
|
|
@@ -1389,7 +1393,7 @@ async function runSubcommand(argv) {
|
|
|
1389
1393
|
case "restart": return await cmdRestart(rest);
|
|
1390
1394
|
case "note": return await cmdNote(rest);
|
|
1391
1395
|
case "todo": {
|
|
1392
|
-
const { runTodoSubcommand } = await import("./todoCli-
|
|
1396
|
+
const { runTodoSubcommand } = await import("./todoCli-DNOk38lq.js");
|
|
1393
1397
|
return runTodoSubcommand(rest);
|
|
1394
1398
|
}
|
|
1395
1399
|
case "ch":
|
|
@@ -1398,39 +1402,39 @@ async function runSubcommand(argv) {
|
|
|
1398
1402
|
return cmdCh(rest);
|
|
1399
1403
|
}
|
|
1400
1404
|
case "term": {
|
|
1401
|
-
const { cmdTerm } = await import("./terminal-
|
|
1405
|
+
const { cmdTerm } = await import("./terminal-CB5K4Jjh.js");
|
|
1402
1406
|
return cmdTerm(rest);
|
|
1403
1407
|
}
|
|
1404
1408
|
case "widget": {
|
|
1405
|
-
const { cmdWidget } = await import("./widget-
|
|
1409
|
+
const { cmdWidget } = await import("./widget-DiRKbtng.js");
|
|
1406
1410
|
return cmdWidget(rest);
|
|
1407
1411
|
}
|
|
1408
1412
|
case "mint": {
|
|
1409
|
-
const { cmdMint } = await import("./widget-
|
|
1413
|
+
const { cmdMint } = await import("./widget-DiRKbtng.js");
|
|
1410
1414
|
return cmdMint(rest);
|
|
1411
1415
|
}
|
|
1412
1416
|
case "serve": {
|
|
1413
|
-
const { cmdServe } = await import("./serve-
|
|
1417
|
+
const { cmdServe } = await import("./serve-DctJ7tY-.js");
|
|
1414
1418
|
return cmdServe(rest);
|
|
1415
1419
|
}
|
|
1416
1420
|
case "tray": {
|
|
1417
|
-
const { cmdTray } = await import("./trayApp-
|
|
1421
|
+
const { cmdTray } = await import("./trayApp-B1OhYfj3.js");
|
|
1418
1422
|
return cmdTray(rest);
|
|
1419
1423
|
}
|
|
1420
1424
|
case "setup": {
|
|
1421
|
-
const { cmdSetup } = await import("./setup-
|
|
1425
|
+
const { cmdSetup } = await import("./setup-BA9D1ExO.js");
|
|
1422
1426
|
return cmdSetup(rest);
|
|
1423
1427
|
}
|
|
1424
1428
|
case "ws": {
|
|
1425
|
-
const { cmdWs } = await import("./ws-
|
|
1429
|
+
const { cmdWs } = await import("./ws-Cqn8mxsS.js");
|
|
1426
1430
|
return cmdWs(rest);
|
|
1427
1431
|
}
|
|
1428
1432
|
case "schedule": {
|
|
1429
|
-
const { cmdSchedule } = await import("./schedule-
|
|
1433
|
+
const { cmdSchedule } = await import("./schedule-Cw5nW_di.js");
|
|
1430
1434
|
return cmdSchedule(rest);
|
|
1431
1435
|
}
|
|
1432
1436
|
case "remote": {
|
|
1433
|
-
const { cmdRemote } = await import("./remotes-
|
|
1437
|
+
const { cmdRemote } = await import("./remotes-lOhHSoSS.js");
|
|
1434
1438
|
return cmdRemote(rest);
|
|
1435
1439
|
}
|
|
1436
1440
|
case "expose": {
|
|
@@ -1438,7 +1442,7 @@ async function runSubcommand(argv) {
|
|
|
1438
1442
|
return cmdExpose(rest);
|
|
1439
1443
|
}
|
|
1440
1444
|
case "callback": {
|
|
1441
|
-
const { cmdCallback } = await import("./callback-
|
|
1445
|
+
const { cmdCallback } = await import("./callback-DYQ2jQi2.js");
|
|
1442
1446
|
return cmdCallback(rest);
|
|
1443
1447
|
}
|
|
1444
1448
|
case "reap":
|
|
@@ -1476,7 +1480,7 @@ async function cmdHelp(managerCommands = true) {
|
|
|
1476
1480
|
const wsLines = managerCommands ? " ay ws ls [--status] list <owner>/<repo>/tree/<branch> workspaces\n ay ws new <owner>/<repo>[@branch] clone/refresh a workspace (ay ws help for more)\n" : ``;
|
|
1477
1481
|
const self = process.env.AGENT_YES_PID ? await resolveSender() : null;
|
|
1478
1482
|
const agentSection = self ? await buildAgentContextSection(self) : "";
|
|
1479
|
-
process.stdout.write(agentSection + "ay - agent-yes CLI\n\nManagement:\n ay ls [keyword] list running agents\n ay tail [-f] [-n N] <keyword> last N lines (96), -f to follow\n ay read <keyword> [page opts] paginate: --last/--head N, --range A:B,\n --before-line L [--limit N]\n ay cat <keyword> full log\n ay head <keyword> first N lines\n ay send <keyword> <msg> send a message (keyword '.' = agent in this cwd)\n ay msgs [keyword] [--in|--out] inter-agent message log (sent + received)\n ay ch mk|join|send|read|tail <topic> local-first E2E channels: AI ↔ humans on a topic (ay ch help)\n ay term embed <pid> <script> to embed a live read-only agent terminal in a page (ay term help)\n ay widget ls | read selection|dom read an opted-in page widget's context (selection/DOM) (ay widget help)\n ay mint <target> --caps ... mint a scoped, short-TTL capability token (embeddable in a page)\n ay key <keyword> <key...> send raw keystrokes (down/up/enter/esc/…) — drives menus\n ay select <keyword> <N> pick option N of a needs_input selection menu\n ay attach <keyword> interactive attach (detach: Ctrl-\\)\n ay stop <keyword> graceful shutdown (/exit for claude/codex)\n ay exit <keyword> [reason] graceful shutdown, recording who/why (= 'ay send <kw> exit')\n ay restart <keyword> [--fresh] stop (if live) + relaunch resuming the session; --fresh replays the prompt\n ay status <keyword> agent status snapshot\n ay whoami [--json] (inside an agent) your own registry identity + reply address\n ay result <keyword> [--wait] pull an agent's structured result envelope\n ay result set '<json>' (inside an agent) deposit your result envelope\n ay reap kill process groups leaked by dead agents\n" + wsLines + "\nRemote:\n" + setupLine + " ay schedule <when> <cli> -- <msg> run an agent on a schedule (HH:MM or cron)\n ay serve [--port N] start HTTP API server (prints token)\n ay serve status show serve daemon/server status\n ay remote add <alias> http://<token>@<host>:<port>\n ay remote ls / rm <alias> manage saved remotes\n ay expose <port> share localhost:<port> at https://<id>.agent-yes.com (private link)\n ay callback --expires 7d mint an embeddable message-me widget for one agent\n ay ls <token>@<host>:<port> connect inline (no alias needed)\n ay send <token>@<host>:<port>:<kw> <msg>\n\nRun an agent:\n ay [claude|codex|gemini|...] [options] -- [prompt]\n ay claude -- \"fix the bug in auth.ts\"\n ay claude --help full agent-runner options\n\nLabs (examples at https://github.com/snomiao/agent-yes/tree/main/lab):\n local-role-play/ designer + builder on one machine\n http-remote/ ay serve remote access demo\n p2p-pairing/ libp2p P2P (needs: cargo build --features swarm)\n");
|
|
1483
|
+
process.stdout.write(agentSection + "ay - agent-yes CLI\n\nManagement:\n ay ls [keyword] list running agents\n ay tail [-f] [-n N] <keyword> last N lines (96), -f to follow\n ay read <keyword> [page opts] paginate: --last/--head N, --range A:B,\n --before-line L [--limit N]\n ay cat <keyword> full log\n ay head <keyword> first N lines\n ay send <keyword> <msg> send a message (keyword '.' = agent in this cwd)\n ay msgs [keyword] [--in|--out] inter-agent message log (sent + received)\n ay role [name] | ay role <kw> <name> lane/role name shown in the send envelope\n ay ch mk|join|send|read|tail <topic> local-first E2E channels: AI ↔ humans on a topic (ay ch help)\n ay term embed <pid> <script> to embed a live read-only agent terminal in a page (ay term help)\n ay widget ls | read selection|dom read an opted-in page widget's context (selection/DOM) (ay widget help)\n ay mint <target> --caps ... mint a scoped, short-TTL capability token (embeddable in a page)\n ay key <keyword> <key...> send raw keystrokes (down/up/enter/esc/…) — drives menus\n ay select <keyword> <N> pick option N of a needs_input selection menu\n ay attach <keyword> interactive attach (detach: Ctrl-\\)\n ay stop <keyword> graceful shutdown (/exit for claude/codex)\n ay exit <keyword> [reason] graceful shutdown, recording who/why (= 'ay send <kw> exit')\n ay restart <keyword> [--fresh] stop (if live) + relaunch resuming the session; --fresh replays the prompt\n ay status <keyword> agent status snapshot\n ay whoami [--json] (inside an agent) your own registry identity + reply address\n ay result <keyword> [--wait] pull an agent's structured result envelope\n ay result set '<json>' (inside an agent) deposit your result envelope\n ay reap kill process groups leaked by dead agents\n" + wsLines + "\nRemote:\n" + setupLine + " ay schedule <when> <cli> -- <msg> run an agent on a schedule (HH:MM or cron)\n ay serve [--port N] start HTTP API server (prints token)\n ay serve status show serve daemon/server status\n ay remote add <alias> http://<token>@<host>:<port>\n ay remote ls / rm <alias> manage saved remotes\n ay expose <port> share localhost:<port> at https://<id>.agent-yes.com (private link)\n ay callback --expires 7d mint an embeddable message-me widget for one agent\n ay ls <token>@<host>:<port> connect inline (no alias needed)\n ay send <token>@<host>:<port>:<kw> <msg>\n\nRun an agent:\n ay [claude|codex|gemini|...] [options] -- [prompt]\n ay claude -- \"fix the bug in auth.ts\"\n ay claude --help full agent-runner options\n\nLabs (examples at https://github.com/snomiao/agent-yes/tree/main/lab):\n local-role-play/ designer + builder on one machine\n http-remote/ ay serve remote access demo\n p2p-pairing/ libp2p P2P (needs: cargo build --features swarm)\n");
|
|
1480
1484
|
return 0;
|
|
1481
1485
|
}
|
|
1482
1486
|
function matchKeyword(record, keyword) {
|
|
@@ -1856,7 +1860,7 @@ async function fetchRemoteRecordsRaw(url, token, opts) {
|
|
|
1856
1860
|
let base = url;
|
|
1857
1861
|
let bearer = token;
|
|
1858
1862
|
if (isWebrtcSpec(url)) {
|
|
1859
|
-
const { startWebrtcBridge } = await import("./webrtcRemote-
|
|
1863
|
+
const { startWebrtcBridge } = await import("./webrtcRemote-BkZcA5yq.js");
|
|
1860
1864
|
bridge = await startWebrtcBridge(url);
|
|
1861
1865
|
base = bridge.baseUrl;
|
|
1862
1866
|
bearer = bridge.token;
|
|
@@ -3294,7 +3298,9 @@ async function cmdSend(rest) {
|
|
|
3294
3298
|
let nonce;
|
|
3295
3299
|
if (sender.agent && !isSlashCommand(body) && !raw) {
|
|
3296
3300
|
nonce = randomBytes$1(4).toString("hex");
|
|
3297
|
-
|
|
3301
|
+
const senderRole = sanitizeRole(sender.agent.role);
|
|
3302
|
+
const roleTag = senderRole ? ` (${senderRole})` : "";
|
|
3303
|
+
prefix = `<ay-msg ${nonce} from ${sender.agent.cli} #${sender.agent.pid}${roleTag} @ ${shortenPath(sender.agent.cwd)} — reply: ay send ${replyTarget} "...">\n`;
|
|
3298
3304
|
suffix = `\n</ay-msg ${nonce}>`;
|
|
3299
3305
|
if (/^\s*<ay-msg\s/.test(body)) process.stderr.write("warning: body already starts with an <ay-msg …> header — ay send adds the envelope automatically, so the recipient will see a DOUBLE wrapper. Send the bare body instead (or pass --raw if you really mean to deliver a pre-built envelope verbatim; forwarding a quoted message inside a plain body is fine).\n");
|
|
3300
3306
|
}
|
|
@@ -3328,13 +3334,15 @@ async function cmdSend(rest) {
|
|
|
3328
3334
|
pid: sender.agent.pid,
|
|
3329
3335
|
cli: sender.agent.cli,
|
|
3330
3336
|
cwd: sender.agent.cwd,
|
|
3331
|
-
agent_id: sender.agent.agent_id
|
|
3337
|
+
agent_id: sender.agent.agent_id,
|
|
3338
|
+
role: sender.agent.role ?? void 0
|
|
3332
3339
|
} : null,
|
|
3333
3340
|
to: {
|
|
3334
3341
|
pid: record.pid,
|
|
3335
3342
|
cli: record.cli,
|
|
3336
3343
|
cwd: record.cwd,
|
|
3337
|
-
agent_id: record.agent_id
|
|
3344
|
+
agent_id: record.agent_id,
|
|
3345
|
+
role: record.role ?? void 0
|
|
3338
3346
|
},
|
|
3339
3347
|
body,
|
|
3340
3348
|
code: trailing === "\r" ? void 0 : codeName,
|
|
@@ -3455,6 +3463,67 @@ async function cmdMsgs(rest) {
|
|
|
3455
3463
|
}
|
|
3456
3464
|
return 0;
|
|
3457
3465
|
}
|
|
3466
|
+
/**
|
|
3467
|
+
* `ay role [name]` / `ay role <keyword> <name>` — read or set an agent's
|
|
3468
|
+
* self-declared lane/role name ("pm", "crm", …). The role rides in the
|
|
3469
|
+
* `ay send` envelope header (`from claude #123 (pm) @ …`) so recipients don't
|
|
3470
|
+
* translate cwd/pid into a lane by hand — the emergent `[pm→qa]` body prefixes
|
|
3471
|
+
* exist exactly because the envelope lacked this. With no args: print the
|
|
3472
|
+
* calling agent's role. With one arg: set the calling agent's role (requires
|
|
3473
|
+
* agent context). With two args: resolve the keyword and set that agent's role.
|
|
3474
|
+
* `--clear` removes it. Roles are clamped by sanitizeRole (they render into the
|
|
3475
|
+
* non-nonce-protected open tag).
|
|
3476
|
+
*/
|
|
3477
|
+
const ROLE_RESOLVE_OPTS = {
|
|
3478
|
+
all: false,
|
|
3479
|
+
active: false,
|
|
3480
|
+
cwdScope: null,
|
|
3481
|
+
latest: false,
|
|
3482
|
+
json: false
|
|
3483
|
+
};
|
|
3484
|
+
async function cmdRole(rest) {
|
|
3485
|
+
const argv = await yargs(rest).usage("Usage: ay role [name] | ay role <keyword> <name> | ay role [keyword] --clear").option("clear", {
|
|
3486
|
+
type: "boolean",
|
|
3487
|
+
default: false,
|
|
3488
|
+
description: "Remove the role"
|
|
3489
|
+
}).help(false).version(false).exitProcess(false).parseAsync();
|
|
3490
|
+
const args = argv._.slice(0).map(String);
|
|
3491
|
+
let target = null;
|
|
3492
|
+
let newRole;
|
|
3493
|
+
if (args.length === 2) {
|
|
3494
|
+
target = await resolveOne(args[0], ROLE_RESOLVE_OPTS);
|
|
3495
|
+
newRole = args[1];
|
|
3496
|
+
} else if (args.length === 1 && argv.clear) target = await resolveOne(args[0], ROLE_RESOLVE_OPTS);
|
|
3497
|
+
else if (args.length === 1) {
|
|
3498
|
+
target = await resolveSender();
|
|
3499
|
+
if (!target) {
|
|
3500
|
+
process.stderr.write("ay role: no agent context (AGENT_YES_PID unset or unregistered) — from a human shell, name the agent: ay role <keyword> <name>\n");
|
|
3501
|
+
return 1;
|
|
3502
|
+
}
|
|
3503
|
+
newRole = args[0];
|
|
3504
|
+
} else {
|
|
3505
|
+
target = await resolveSender();
|
|
3506
|
+
if (!target) {
|
|
3507
|
+
process.stderr.write("ay role: no agent context — from a human shell, name the agent: ay role <keyword> [<name>|--clear]\n");
|
|
3508
|
+
return 1;
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
if (newRole === void 0 && !argv.clear) {
|
|
3512
|
+
process.stdout.write(`${target.role ?? ""}\n`);
|
|
3513
|
+
return 0;
|
|
3514
|
+
}
|
|
3515
|
+
let role = null;
|
|
3516
|
+
if (!argv.clear) {
|
|
3517
|
+
role = sanitizeRole(newRole);
|
|
3518
|
+
if (!role) {
|
|
3519
|
+
process.stderr.write(`ay role: invalid role ${JSON.stringify(newRole)} — use 1-32 chars of [A-Za-z0-9._-]\n`);
|
|
3520
|
+
return 1;
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
await updateGlobalPidStatus(target.pid, { role });
|
|
3524
|
+
process.stdout.write(role ? `pid ${target.pid} (${target.cli}): role set to "${role}" — envelopes now read: from ${target.cli} #${target.pid} (${role}) @ ${shortenPath(target.cwd)}\n` : `pid ${target.pid} (${target.cli}): role cleared\n`);
|
|
3525
|
+
return 0;
|
|
3526
|
+
}
|
|
3458
3527
|
async function resolveWritableAgent(keyword, opts) {
|
|
3459
3528
|
const record = await resolveOne(keyword, opts);
|
|
3460
3529
|
if (!record.fifo_file) throw new Error(`pid ${record.pid}: no fifo_file recorded — this agent didn't register a stdin FIFO (an older agent, or one not started with --stdpush). Restarting it (ay restart ${record.pid}) re-registers one.`);
|
|
@@ -3887,7 +3956,7 @@ async function cmdAttach(rest) {
|
|
|
3887
3956
|
const winsizeDir = path.join(ayHome, "winsize");
|
|
3888
3957
|
await mkdir(winsizeDir, { recursive: true });
|
|
3889
3958
|
const winsizePath = path.join(winsizeDir, String(record.pid));
|
|
3890
|
-
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-
|
|
3959
|
+
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-DctJ7tY-.js");
|
|
3891
3960
|
const daemonBase = await resolveDaemonHttpBase().catch(() => null);
|
|
3892
3961
|
const daemonToken = daemonBase ? await loadTokenReadOnly().catch(() => null) ?? "" : "";
|
|
3893
3962
|
const capViewer = `attach:${process.pid}`;
|
|
@@ -4597,7 +4666,7 @@ async function cmdNotify(rest) {
|
|
|
4597
4666
|
}
|
|
4598
4667
|
const ensure = async () => {
|
|
4599
4668
|
if (!argv["ensure-daemon"]) return;
|
|
4600
|
-
const { ensureDaemon } = await import("./notifyDaemon-
|
|
4669
|
+
const { ensureDaemon } = await import("./notifyDaemon-D5RtFwMq.js");
|
|
4601
4670
|
await ensureDaemon().catch(() => null);
|
|
4602
4671
|
};
|
|
4603
4672
|
await heartbeatWatcher(parent, selfStartedAt);
|
|
@@ -4671,7 +4740,7 @@ async function cmdNotifyCursor(args) {
|
|
|
4671
4740
|
}
|
|
4672
4741
|
async function cmdNotifyd(rest) {
|
|
4673
4742
|
const sub = rest[0] ?? "status";
|
|
4674
|
-
const daemon = await import("./notifyDaemon-
|
|
4743
|
+
const daemon = await import("./notifyDaemon-D5RtFwMq.js");
|
|
4675
4744
|
switch (sub) {
|
|
4676
4745
|
case "run": return daemon.runDaemon();
|
|
4677
4746
|
case "once": return daemon.runDaemon({ once: true });
|
|
@@ -4698,4 +4767,4 @@ async function cmdNotifyd(rest) {
|
|
|
4698
4767
|
|
|
4699
4768
|
//#endregion
|
|
4700
4769
|
export { liveWatchers as $, readPtysize as A, runSubcommand as B, lastStdinAt as C, readAgentPtysize as D, menuSelectKeys as E, renderRawLogLines as F, waitForLogQuiet as G, stdinActivityPath as H, resolveOne as I, appendEvent as J, writeKeysPaced as K, resolveReadWindow as L, recentReadEdges as M, renderLogTailLines as N, readLogForRender as O, renderRawLog as P, listInboxParents as Q, resolveResumeArgs as R, isUserTyping as S, matchKeyword as T, stopTipForCli as U, snapshotStatus as V, submitAndConfirm as W, hostId as X, gcInboxes as Y, isTransientLockMkdirError as Z, isExitRequest as _, backoffWhileTyping as a, TYPING_BADGE as at, isSubcommand as b, cursorAbs as c, extractBadges as d, readInbox as et, extractMenu as f, isAgentStuck as g, finalizedLines as h, TYPING_WINDOW_MS as i, notifyDir as it, recentMessageEdges as j, readNotes as k, deriveLiveState as l, extractTaskCounts as m, MAX_RENDER_BYTES as n, daemonLockDir as nt, cmdHelp as o, extractNeedsInput as p, writeToIpc as q, READ_PAGE_DEFAULT as r, daemonLockOwnerPath as rt, controlCodeFromName as s, GRACEFUL_EXIT_COMMANDS as t, shouldStealLock as tt, deriveLiveStatus as u, isPidAlive as v, listRecords as w, isUnknownManagerToken as x, isSlashCommand as y, restartHintLines as z };
|
|
4701
|
-
//# sourceMappingURL=subcommands-
|
|
4770
|
+
//# sourceMappingURL=subcommands-D_cPHm34.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./globalPidIndex-
|
|
2
|
+
import "./globalPidIndex-pwp7Vb7o.js";
|
|
3
3
|
import "./messageLog-BYFwioFY.js";
|
|
4
4
|
import "./e2e-CUMZC53I.js";
|
|
5
5
|
import "./configShared-DtHMBCl7.js";
|
|
6
|
-
import { A as readPtysize, B as runSubcommand, C as lastStdinAt, D as readAgentPtysize, E as menuSelectKeys, F as renderRawLogLines, G as waitForLogQuiet, H as stdinActivityPath, I as resolveOne, K as writeKeysPaced, L as resolveReadWindow, M as recentReadEdges, N as renderLogTailLines, O as readLogForRender, P as renderRawLog, R as resolveResumeArgs, S as isUserTyping, T as matchKeyword, U as stopTipForCli, V as snapshotStatus, W as submitAndConfirm, _ as isExitRequest, a as backoffWhileTyping, b as isSubcommand, c as cursorAbs, d as extractBadges, f as extractMenu, g as isAgentStuck, h as finalizedLines, i as TYPING_WINDOW_MS, j as recentMessageEdges, k as readNotes, l as deriveLiveState, m as extractTaskCounts, n as MAX_RENDER_BYTES, o as cmdHelp, p as extractNeedsInput, q as writeToIpc, r as READ_PAGE_DEFAULT, s as controlCodeFromName, t as GRACEFUL_EXIT_COMMANDS, u as deriveLiveStatus, v as isPidAlive, w as listRecords, x as isUnknownManagerToken, y as isSlashCommand, z as restartHintLines } from "./subcommands-
|
|
6
|
+
import { A as readPtysize, B as runSubcommand, C as lastStdinAt, D as readAgentPtysize, E as menuSelectKeys, F as renderRawLogLines, G as waitForLogQuiet, H as stdinActivityPath, I as resolveOne, K as writeKeysPaced, L as resolveReadWindow, M as recentReadEdges, N as renderLogTailLines, O as readLogForRender, P as renderRawLog, R as resolveResumeArgs, S as isUserTyping, T as matchKeyword, U as stopTipForCli, V as snapshotStatus, W as submitAndConfirm, _ as isExitRequest, a as backoffWhileTyping, b as isSubcommand, c as cursorAbs, d as extractBadges, f as extractMenu, g as isAgentStuck, h as finalizedLines, i as TYPING_WINDOW_MS, j as recentMessageEdges, k as readNotes, l as deriveLiveState, m as extractTaskCounts, n as MAX_RENDER_BYTES, o as cmdHelp, p as extractNeedsInput, q as writeToIpc, r as READ_PAGE_DEFAULT, s as controlCodeFromName, t as GRACEFUL_EXIT_COMMANDS, u as deriveLiveStatus, v as isPidAlive, w as listRecords, x as isUnknownManagerToken, y as isSlashCommand, z as restartHintLines } from "./subcommands-D_cPHm34.js";
|
|
7
7
|
import "./webrtcLink-CS4D-3G1.js";
|
|
8
|
-
import "./remotes-
|
|
8
|
+
import "./remotes-Cn-wszbK.js";
|
|
9
9
|
|
|
10
10
|
export { cmdHelp, isSubcommand, isUnknownManagerToken, runSubcommand };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { existsSync, lstatSync, mkdirSync, readdirSync, readlinkSync, symlinkSync, unlinkSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
|
|
5
|
+
//#region ts/systemPathLink.ts
|
|
6
|
+
/** Did a (now-dangling) symlink at `linkPath` point into `dir`? Used to adopt
|
|
7
|
+
* only stale links we previously created, never a foreign broken link. */
|
|
8
|
+
function danglingPointsInto(linkPath, dir) {
|
|
9
|
+
try {
|
|
10
|
+
const oldTarget = path.resolve(path.dirname(linkPath), readlinkSync(linkPath));
|
|
11
|
+
return path.resolve(path.dirname(oldTarget)) === path.resolve(dir);
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** The directory bun installs global binaries into, or null if absent. */
|
|
17
|
+
function bunBinDir(env = process.env) {
|
|
18
|
+
const install = env.BUN_INSTALL || path.join(homedir(), ".bun");
|
|
19
|
+
const dir = path.join(install, "bin");
|
|
20
|
+
return existsSync(dir) ? dir : null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Symlink each entry of the bun-global bin dir into `target` (default
|
|
24
|
+
* /usr/local/bin). Skips a name that already exists UNLESS it's a symlink we
|
|
25
|
+
* previously created into the same bun dir (those we refresh, so a rebuilt/moved
|
|
26
|
+
* bun bin stays valid). Returns null on an unsupported platform or when neither
|
|
27
|
+
* the bun dir nor the target is usable. Never throws.
|
|
28
|
+
*/
|
|
29
|
+
function linkBunBinsToSystemPath(opts) {
|
|
30
|
+
if (process.platform === "win32") return null;
|
|
31
|
+
const env = opts?.env ?? process.env;
|
|
32
|
+
const bunDir = opts?.bunDir ?? bunBinDir(env);
|
|
33
|
+
if (!bunDir) return null;
|
|
34
|
+
const target = opts?.target ?? "/usr/local/bin";
|
|
35
|
+
try {
|
|
36
|
+
if (!existsSync(target)) mkdirSync(target, { recursive: true });
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const result = {
|
|
41
|
+
target,
|
|
42
|
+
linked: [],
|
|
43
|
+
skipped: [],
|
|
44
|
+
refreshed: []
|
|
45
|
+
};
|
|
46
|
+
let entries;
|
|
47
|
+
try {
|
|
48
|
+
entries = readdirSync(bunDir);
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
for (const name of entries) {
|
|
53
|
+
const src = path.join(bunDir, name);
|
|
54
|
+
const dest = path.join(target, name);
|
|
55
|
+
let existing = null;
|
|
56
|
+
try {
|
|
57
|
+
existing = lstatSync(dest);
|
|
58
|
+
} catch {
|
|
59
|
+
existing = null;
|
|
60
|
+
}
|
|
61
|
+
if (existing) {
|
|
62
|
+
let ours = false;
|
|
63
|
+
if (existing.isSymbolicLink()) try {
|
|
64
|
+
ours = path.resolve(target, readlinkSync(dest)) === src;
|
|
65
|
+
} catch {
|
|
66
|
+
ours = false;
|
|
67
|
+
}
|
|
68
|
+
if (ours) result.skipped.push(name);
|
|
69
|
+
else if (existing.isSymbolicLink() && !existsSync(dest) && danglingPointsInto(dest, bunDir)) try {
|
|
70
|
+
unlinkSync(dest);
|
|
71
|
+
symlinkSync(src, dest);
|
|
72
|
+
result.refreshed.push(name);
|
|
73
|
+
} catch {
|
|
74
|
+
result.skipped.push(name);
|
|
75
|
+
}
|
|
76
|
+
else result.skipped.push(name);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
symlinkSync(src, dest);
|
|
81
|
+
result.linked.push(name);
|
|
82
|
+
} catch {
|
|
83
|
+
result.skipped.push(name);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
export { linkBunBinsToSystemPath };
|
|
91
|
+
//# sourceMappingURL=systemPathLink-DTAhFXFx.js.map
|
|
@@ -98,7 +98,7 @@ async function cmdTermMint(args) {
|
|
|
98
98
|
if (flags.ro && flags.interactive) throw new Error("--ro and --interactive are mutually exclusive");
|
|
99
99
|
const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
|
|
100
100
|
const canSend = flags.interactive === true;
|
|
101
|
-
const { mintScopedTermToken } = await import("./serve-
|
|
101
|
+
const { mintScopedTermToken } = await import("./serve-DctJ7tY-.js");
|
|
102
102
|
const r = await mintScopedTermToken(pid, {
|
|
103
103
|
ttlSec,
|
|
104
104
|
canSend
|
|
@@ -135,4 +135,4 @@ async function cmdTerm(args) {
|
|
|
135
135
|
|
|
136
136
|
//#endregion
|
|
137
137
|
export { cmdTerm };
|
|
138
|
-
//# sourceMappingURL=terminal-
|
|
138
|
+
//# sourceMappingURL=terminal-CB5K4Jjh.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
2
|
import { _ as isKnownKind, a as renderTree, d as openStore, i as renderDigest, l as CycleError, n as buildTreeJSON, o as unblockedTasks, p as LIFECYCLES, s as describeBlock, t as reconcileTodos, x as removeControlCharacters } from "./todoAutomation-BQRW614S.js";
|
|
3
3
|
import "./JsonlStore-CPGIR0Wy.js";
|
|
4
|
-
import { i as readGlobalPids } from "./globalPidIndex-
|
|
4
|
+
import { i as readGlobalPids } from "./globalPidIndex-pwp7Vb7o.js";
|
|
5
5
|
import yargs from "yargs";
|
|
6
6
|
|
|
7
7
|
//#region ts/todoCli.ts
|
|
@@ -456,4 +456,4 @@ async function runTodoSubcommand(rest0) {
|
|
|
456
456
|
|
|
457
457
|
//#endregion
|
|
458
458
|
export { runTodoSubcommand };
|
|
459
|
-
//# sourceMappingURL=todoCli-
|
|
459
|
+
//# sourceMappingURL=todoCli-DNOk38lq.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as findTrayLauncher } from "./rustBinary-
|
|
1
|
+
import { n as findTrayLauncher } from "./rustBinary-BEscpLLP.js";
|
|
2
2
|
import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -97,4 +97,4 @@ async function cmdTray(args) {
|
|
|
97
97
|
|
|
98
98
|
//#endregion
|
|
99
99
|
export { trayHiddenMarker as a, launchTray as i, hasDesktop as n, isTrayHidden as r, cmdTray as t };
|
|
100
|
-
//# sourceMappingURL=trayApp-
|
|
100
|
+
//# sourceMappingURL=trayApp-Ck3kWM-7.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as __esmMin, r as __exportAll } from "./chunk-cZBX9HZv.js";
|
|
2
2
|
import { n as logger, t as addTransport } from "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-DRijpksb.js";
|
|
4
4
|
import { t as agentYesHome } from "./agentYesHome-CtmsY6I-.js";
|
|
5
5
|
import { d as openStore, p as LIFECYCLES, x as removeControlCharacters } from "./todoAutomation-BQRW614S.js";
|
|
6
6
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-DBoONoM-.js";
|
|
7
|
-
import { i as readGlobalPids } from "./globalPidIndex-
|
|
8
|
-
import { t as PidStore } from "./pidStore-
|
|
7
|
+
import { i as readGlobalPids } from "./globalPidIndex-pwp7Vb7o.js";
|
|
8
|
+
import { t as PidStore } from "./pidStore-DfSm1jog.js";
|
|
9
9
|
import { r as recordInbox } from "./messageLog-BYFwioFY.js";
|
|
10
10
|
import { n as register, r as sweep } from "./reaper-C4BvNylH.js";
|
|
11
11
|
import { arch, platform } from "process";
|
|
@@ -1569,6 +1569,7 @@ async function agentYes({ cli, cliArgs = [], skipPermissions = false, prompt, ro
|
|
|
1569
1569
|
const parentPid = Number.isInteger(inheritedAyPid) && inheritedAyPid > 0 ? inheritedAyPid : void 0;
|
|
1570
1570
|
ptyEnv.AGENT_YES_PID = String(process.pid);
|
|
1571
1571
|
delete ptyEnv.AGENT_YES_AGENT_ID;
|
|
1572
|
+
delete ptyEnv.AGENT_YES_ROLE;
|
|
1572
1573
|
stripClaudeSessionPin(ptyEnv);
|
|
1573
1574
|
if (cliConf?.env) for (const [key, raw] of Object.entries(cliConf.env)) {
|
|
1574
1575
|
let unresolved = false;
|
|
@@ -2180,4 +2181,4 @@ function sleep(ms) {
|
|
|
2180
2181
|
|
|
2181
2182
|
//#endregion
|
|
2182
2183
|
export { hasTodoStore as a, permissionBadge as c, answerAsk as i, AgentContext as l, agentYes as n, listAsks as o, config as r, listAsksForProject as s, CLIS_CONFIG as t, CLAUDE_SESSION_PIN_ENV as u };
|
|
2183
|
-
//# sourceMappingURL=ts-
|
|
2184
|
+
//# sourceMappingURL=ts-Bd_7sgVu.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.259.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-DRijpksb.js.map
|
|
@@ -28,7 +28,7 @@ function parseFlags(args, known) {
|
|
|
28
28
|
}
|
|
29
29
|
/** Resolve the local daemon base URL + token (flags override discovery). */
|
|
30
30
|
async function daemonTarget(flags) {
|
|
31
|
-
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-
|
|
31
|
+
const { resolveDaemonHttpBase, loadTokenReadOnly } = await import("./serve-DctJ7tY-.js");
|
|
32
32
|
const base = typeof flags.base === "string" ? flags.base : await resolveDaemonHttpBase();
|
|
33
33
|
if (!base) throw new Error("no running ay serve daemon found — start `ay serve` or pass --base <url> (e.g. http://127.0.0.1:PORT)");
|
|
34
34
|
const token = typeof flags.token === "string" ? flags.token : await loadTokenReadOnly() ?? "";
|
|
@@ -186,7 +186,7 @@ async function cmdMint(args) {
|
|
|
186
186
|
const bad = caps.filter((c) => !KNOWN_CAPS.has(c));
|
|
187
187
|
if (bad.length) throw new Error(`unknown cap(s): ${bad.join(", ")} (valid: ${[...KNOWN_CAPS].join(", ")})`);
|
|
188
188
|
const ttlSec = parseTtlSec(typeof flags.ttl === "string" ? flags.ttl : "15m");
|
|
189
|
-
const { mintScopedTermToken } = await import("./serve-
|
|
189
|
+
const { mintScopedTermToken } = await import("./serve-DctJ7tY-.js");
|
|
190
190
|
const r = await mintScopedTermToken(target, {
|
|
191
191
|
ttlSec,
|
|
192
192
|
caps
|
|
@@ -202,4 +202,4 @@ async function cmdMint(args) {
|
|
|
202
202
|
|
|
203
203
|
//#endregion
|
|
204
204
|
export { cmdMint, cmdWidget };
|
|
205
|
-
//# sourceMappingURL=widget-
|
|
205
|
+
//# sourceMappingURL=widget-DiRKbtng.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { w as listRecords } from "./subcommands-
|
|
1
|
+
import { w as listRecords } from "./subcommands-D_cPHm34.js";
|
|
2
2
|
import { a as getProvisionRoot } from "./workspaceConfig-Bxuk_MOq.js";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
4
|
import { lstat, opendir } from "fs/promises";
|
|
@@ -426,4 +426,4 @@ async function cmdWs(args) {
|
|
|
426
426
|
|
|
427
427
|
//#endregion
|
|
428
428
|
export { isPathInside as a, walkWorkspaces as c, importProvisionModule as i, workspaceStatus as l, cmdWs as n, loadProvision as o, collectWorkspaces as r, resolveOperand as s, WS_JSON_SCHEMA as t };
|
|
429
|
-
//# sourceMappingURL=ws-
|
|
429
|
+
//# sourceMappingURL=ws-Bp8eOEoV.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "./logger-CDIsZ-Pp.js";
|
|
2
|
-
import "./globalPidIndex-
|
|
2
|
+
import "./globalPidIndex-pwp7Vb7o.js";
|
|
3
3
|
import "./messageLog-BYFwioFY.js";
|
|
4
4
|
import "./e2e-CUMZC53I.js";
|
|
5
5
|
import "./configShared-DtHMBCl7.js";
|
|
6
|
-
import "./subcommands-
|
|
6
|
+
import "./subcommands-D_cPHm34.js";
|
|
7
7
|
import "./webrtcLink-CS4D-3G1.js";
|
|
8
|
-
import "./remotes-
|
|
9
|
-
import { a as isPathInside, c as walkWorkspaces, i as importProvisionModule, l as workspaceStatus, n as cmdWs, o as loadProvision, r as collectWorkspaces, s as resolveOperand, t as WS_JSON_SCHEMA } from "./ws-
|
|
8
|
+
import "./remotes-Cn-wszbK.js";
|
|
9
|
+
import { a as isPathInside, c as walkWorkspaces, i as importProvisionModule, l as workspaceStatus, n as cmdWs, o as loadProvision, r as collectWorkspaces, s as resolveOperand, t as WS_JSON_SCHEMA } from "./ws-Bp8eOEoV.js";
|
|
10
10
|
|
|
11
11
|
export { WS_JSON_SCHEMA, cmdWs, collectWorkspaces, isPathInside, loadProvision, workspaceStatus };
|
package/package.json
CHANGED
|
@@ -158,6 +158,42 @@ describe("globalPidIndex", () => {
|
|
|
158
158
|
expect(records).toEqual([]);
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
+
it("sanitizeRole accepts safe lane names and rejects header-forging values", async () => {
|
|
162
|
+
const mod = await loadModule();
|
|
163
|
+
expect(mod.sanitizeRole("pm")).toBe("pm");
|
|
164
|
+
expect(mod.sanitizeRole(" release-console ")).toBe("release-console");
|
|
165
|
+
expect(mod.sanitizeRole("crm_v2.a")).toBe("crm_v2.a");
|
|
166
|
+
// Anything that could forge the (non-nonce-protected) open tag is rejected:
|
|
167
|
+
expect(mod.sanitizeRole('x") @ /fake — reply: ay send 1 "')).toBeNull();
|
|
168
|
+
expect(mod.sanitizeRole("a b")).toBeNull();
|
|
169
|
+
expect(mod.sanitizeRole("a>b")).toBeNull();
|
|
170
|
+
expect(mod.sanitizeRole("a\nb")).toBeNull();
|
|
171
|
+
expect(mod.sanitizeRole("")).toBeNull();
|
|
172
|
+
expect(mod.sanitizeRole("x".repeat(33))).toBeNull();
|
|
173
|
+
expect(mod.sanitizeRole(undefined)).toBeNull();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("updateGlobalPidStatus can set and clear role", async () => {
|
|
177
|
+
const mod = await loadModule();
|
|
178
|
+
await mod.appendGlobalPid({
|
|
179
|
+
pid: 4242,
|
|
180
|
+
cli: "claude",
|
|
181
|
+
prompt: null,
|
|
182
|
+
cwd: "/repo",
|
|
183
|
+
log_file: null,
|
|
184
|
+
status: "active",
|
|
185
|
+
exit_code: null,
|
|
186
|
+
exit_reason: null,
|
|
187
|
+
started_at: Date.now(),
|
|
188
|
+
});
|
|
189
|
+
await mod.updateGlobalPidStatus(4242, { role: "pm" });
|
|
190
|
+
let rec = (await mod.readGlobalPids()).find((r: any) => r.pid === 4242);
|
|
191
|
+
expect(rec?.role).toBe("pm");
|
|
192
|
+
await mod.updateGlobalPidStatus(4242, { role: null });
|
|
193
|
+
rec = (await mod.readGlobalPids()).find((r: any) => r.pid === 4242);
|
|
194
|
+
expect(rec?.role).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
|
|
161
197
|
it("updateGlobalPidStatus is a no-op for unknown pids", async () => {
|
|
162
198
|
const mod = await loadModule();
|
|
163
199
|
await mod.updateGlobalPidStatus(7777, { status: "exited" });
|
package/ts/globalPidIndex.ts
CHANGED
|
@@ -65,6 +65,24 @@ export interface GlobalPidRecord {
|
|
|
65
65
|
// permission checks off?" is unanswerable after the fact. See
|
|
66
66
|
// ts/agentPermissions.ts (mirrored in rs/src/agent_permissions.rs).
|
|
67
67
|
permissions?: AgentPermissions | null;
|
|
68
|
+
// Self-declared lane/role name (e.g. "pm", "crm", "release-console"), shown in
|
|
69
|
+
// the `ay send` envelope so recipients don't have to translate cwd/pid into a
|
|
70
|
+
// role by hand. Set via $AGENT_YES_ROLE at spawn or `ay role <name>` later.
|
|
71
|
+
// Mirrors Rust's `role`; must pass sanitizeRole (it is rendered into the
|
|
72
|
+
// envelope header line, so an unconstrained value could forge header syntax).
|
|
73
|
+
role?: string | null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Roles render verbatim into the `<ay-msg …>` header line, whose OPEN tag is not
|
|
77
|
+
// nonce-protected (only the close tag is) — whitespace, ">", or control chars in
|
|
78
|
+
// a role could forge header structure. Clamp at every entry point (env pickup,
|
|
79
|
+
// `ay role`), not at render time, so stored records stay clean.
|
|
80
|
+
const ROLE_RE = /^[A-Za-z0-9._-]{1,32}$/;
|
|
81
|
+
|
|
82
|
+
/** Validate a role name; returns the trimmed role or null when unusable. */
|
|
83
|
+
export function sanitizeRole(raw: string | undefined | null): string | null {
|
|
84
|
+
const trimmed = raw?.trim();
|
|
85
|
+
return trimmed && ROLE_RE.test(trimmed) ? trimmed : null;
|
|
68
86
|
}
|
|
69
87
|
|
|
70
88
|
/**
|
|
@@ -118,7 +136,7 @@ export async function appendGlobalPid(record: GlobalPidRecord): Promise<void> {
|
|
|
118
136
|
/** Append a partial update by pid (status, exit_code, exit_reason, log_file). */
|
|
119
137
|
export async function updateGlobalPidStatus(
|
|
120
138
|
pid: number,
|
|
121
|
-
patch: Partial<Pick<GlobalPidRecord, "status" | "exit_code" | "exit_reason" | "log_file">>,
|
|
139
|
+
patch: Partial<Pick<GlobalPidRecord, "status" | "exit_code" | "exit_reason" | "log_file" | "role">>,
|
|
122
140
|
): Promise<void> {
|
|
123
141
|
const file = resolveGlobalFile(); // capture at call time (see withLock)
|
|
124
142
|
try {
|