claude-yes 1.166.0 → 1.167.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-Xem8nliL.js → SUPPORTED_CLIS-DFBATC85.js} +2 -2
- package/dist/SUPPORTED_CLIS-DLFqRE8W.js +8 -0
- package/dist/cli.js +4 -4
- package/dist/index.js +2 -2
- package/dist/{schedule-CwAX3y8s.js → schedule-C2RMA3qm.js} +4 -4
- package/dist/{serve-DeJBMba0.js → serve-mLqsRwfR.js} +5 -5
- package/dist/{setup-hWG3ZBG3.js → setup-BtqKZx3q.js} +2 -2
- package/dist/{subcommands-BnsjTNpy.js → subcommands-B-WoBVhk.js} +1 -1
- package/dist/{subcommands-BY0mIDo9.js → subcommands-DWeo7ZLc.js} +26 -6
- package/dist/{ts-CXxZiZKE.js → ts-s3wYccKf.js} +2 -2
- package/dist/{versionChecker-Dv5DhRs3.js → versionChecker-BvR6tV3u.js} +2 -2
- package/package.json +1 -1
- package/ts/cli.ts +1 -1
- package/ts/subcommands.spec.ts +127 -18
- package/ts/subcommands.ts +65 -2
- package/dist/SUPPORTED_CLIS-ClQgRKQu.js +0 -8
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-s3wYccKf.js";
|
|
2
2
|
|
|
3
3
|
//#region ts/SUPPORTED_CLIS.ts
|
|
4
4
|
const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
5
5
|
|
|
6
6
|
//#endregion
|
|
7
7
|
export { SUPPORTED_CLIS as t };
|
|
8
|
-
//# sourceMappingURL=SUPPORTED_CLIS-
|
|
8
|
+
//# sourceMappingURL=SUPPORTED_CLIS-DFBATC85.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-s3wYccKf.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-BvR6tV3u.js";
|
|
4
|
+
import "./pidStore-BfoBWUjc.js";
|
|
5
|
+
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DFBATC85.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { t as invokedCliName } from "./invokedCli-uqM2YYA7.js";
|
|
3
3
|
import { n as logger } from "./logger-CDIsZ-Pp.js";
|
|
4
|
-
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-
|
|
4
|
+
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-BvR6tV3u.js";
|
|
5
5
|
import { argv } from "process";
|
|
6
6
|
import { execFileSync, spawn } from "child_process";
|
|
7
7
|
import ms from "ms";
|
|
@@ -481,9 +481,9 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
481
481
|
const rawArg = process.argv[2];
|
|
482
482
|
const managerCommands = !invokedCliName(process.argv);
|
|
483
483
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
484
|
-
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-
|
|
484
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-B-WoBVhk.js");
|
|
485
485
|
if (isHelpFlag && process.argv.length === 3) {
|
|
486
|
-
cmdHelp(managerCommands);
|
|
486
|
+
await cmdHelp(managerCommands);
|
|
487
487
|
process.exit(0);
|
|
488
488
|
}
|
|
489
489
|
if (isSubcommand(rawArg, managerCommands)) {
|
|
@@ -523,7 +523,7 @@ if (config.useRust) {
|
|
|
523
523
|
}
|
|
524
524
|
}
|
|
525
525
|
if (rustBinary) {
|
|
526
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
526
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DLFqRE8W.js");
|
|
527
527
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
528
528
|
if (config.verbose) {
|
|
529
529
|
console.log(`[rust] Using binary: ${rustBinary}`);
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-s3wYccKf.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-BvR6tV3u.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
6
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-s3wYccKf.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-BvR6tV3u.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DFBATC85.js";
|
|
7
7
|
import { l as resolveSpawnCwd } from "./workspaceConfig-D3OH7and.js";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
|
|
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
|
|
|
141
141
|
|
|
142
142
|
//#endregion
|
|
143
143
|
export { cmdSchedule };
|
|
144
|
-
//# sourceMappingURL=schedule-
|
|
144
|
+
//# sourceMappingURL=schedule-C2RMA3qm.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-s3wYccKf.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-BvR6tV3u.js";
|
|
4
4
|
import "./pidStore-BfoBWUjc.js";
|
|
5
5
|
import { a as updateGlobalPidStatus } from "./globalPidIndex-DlmmJlO8.js";
|
|
6
6
|
import { t as pgidForWrapper } from "./reaper-C-eWAxIj.js";
|
|
7
7
|
import "./configShared-CEyhl0WH.js";
|
|
8
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
8
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DFBATC85.js";
|
|
9
9
|
import "./e2e-Bfw7qL9O.js";
|
|
10
10
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
11
11
|
import "./remotes-T6nf0t3K.js";
|
|
12
12
|
import { c as isProvisionAllowed, i as getSpawnHook, l as resolveSpawnCwd, r as getProvisionRoot, s as hasSpawnHook } from "./workspaceConfig-D3OH7and.js";
|
|
13
|
-
import { A as writeToIpc, D as snapshotStatus, S as resolveOne, b as renderRawLog, c as extractNeedsInput, h as listRecords, i as controlCodeFromName, l as extractTaskCounts, o as deriveLiveStatus, v as readNotes, y as readPtysize } from "./subcommands-
|
|
13
|
+
import { A as writeToIpc, D as snapshotStatus, S as resolveOne, b as renderRawLog, c as extractNeedsInput, h as listRecords, i as controlCodeFromName, l as extractTaskCounts, o as deriveLiveStatus, v as readNotes, y as readPtysize } from "./subcommands-DWeo7ZLc.js";
|
|
14
14
|
import { r as spawnRejectionReason } from "./spawnGate-B_VDMXYL.js";
|
|
15
15
|
import yargs from "yargs";
|
|
16
16
|
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
@@ -1445,4 +1445,4 @@ Options:
|
|
|
1445
1445
|
|
|
1446
1446
|
//#endregion
|
|
1447
1447
|
export { cmdServe };
|
|
1448
|
-
//# sourceMappingURL=serve-
|
|
1448
|
+
//# sourceMappingURL=serve-mLqsRwfR.js.map
|
|
@@ -32,7 +32,7 @@ async function cmdSetup(rest) {
|
|
|
32
32
|
if (!existsSync(abs)) process.stderr.write(` note: that directory doesn't exist yet — create it, or agents spawned there will fail\n`);
|
|
33
33
|
if (noShare) return 0;
|
|
34
34
|
process.stdout.write(`\nsharing this machine to agent-yes.com…\n`);
|
|
35
|
-
const { cmdServe } = await import("./serve-
|
|
35
|
+
const { cmdServe } = await import("./serve-mLqsRwfR.js");
|
|
36
36
|
return cmdServe([
|
|
37
37
|
"install",
|
|
38
38
|
"--share",
|
|
@@ -42,4 +42,4 @@ async function cmdSetup(rest) {
|
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
44
|
export { cmdSetup };
|
|
45
|
-
//# sourceMappingURL=setup-
|
|
45
|
+
//# sourceMappingURL=setup-BtqKZx3q.js.map
|
|
@@ -4,6 +4,6 @@ import "./configShared-CEyhl0WH.js";
|
|
|
4
4
|
import "./e2e-Bfw7qL9O.js";
|
|
5
5
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
6
6
|
import "./remotes-T6nf0t3K.js";
|
|
7
|
-
import { A as writeToIpc, C as resolveReadWindow, D as snapshotStatus, E as runSubcommand, O as stopTipForCli, S as resolveOne, T as restartHintLines, _ as menuSelectKeys, a as cursorAbs, b as renderRawLog, c as extractNeedsInput, d as isAgentStuck, f as isExitRequest, g as matchKeyword, h as listRecords, i as controlCodeFromName, k as writeKeysPaced, l as extractTaskCounts, m as isSubcommand, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isPidAlive, r as cmdHelp, s as extractMenu, t as GRACEFUL_EXIT_COMMANDS, u as finalizedLines, v as readNotes, w as resolveResumeArgs, x as renderRawLogLines, y as readPtysize } from "./subcommands-
|
|
7
|
+
import { A as writeToIpc, C as resolveReadWindow, D as snapshotStatus, E as runSubcommand, O as stopTipForCli, S as resolveOne, T as restartHintLines, _ as menuSelectKeys, a as cursorAbs, b as renderRawLog, c as extractNeedsInput, d as isAgentStuck, f as isExitRequest, g as matchKeyword, h as listRecords, i as controlCodeFromName, k as writeKeysPaced, l as extractTaskCounts, m as isSubcommand, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isPidAlive, r as cmdHelp, s as extractMenu, t as GRACEFUL_EXIT_COMMANDS, u as finalizedLines, v as readNotes, w as resolveResumeArgs, x as renderRawLogLines, y as readPtysize } from "./subcommands-DWeo7ZLc.js";
|
|
8
8
|
|
|
9
9
|
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -597,15 +597,15 @@ async function runSubcommand(argv) {
|
|
|
597
597
|
case "restart": return await cmdRestart(rest);
|
|
598
598
|
case "note": return await cmdNote(rest);
|
|
599
599
|
case "serve": {
|
|
600
|
-
const { cmdServe } = await import("./serve-
|
|
600
|
+
const { cmdServe } = await import("./serve-mLqsRwfR.js");
|
|
601
601
|
return cmdServe(rest);
|
|
602
602
|
}
|
|
603
603
|
case "setup": {
|
|
604
|
-
const { cmdSetup } = await import("./setup-
|
|
604
|
+
const { cmdSetup } = await import("./setup-BtqKZx3q.js");
|
|
605
605
|
return cmdSetup(rest);
|
|
606
606
|
}
|
|
607
607
|
case "schedule": {
|
|
608
|
-
const { cmdSchedule } = await import("./schedule-
|
|
608
|
+
const { cmdSchedule } = await import("./schedule-C2RMA3qm.js");
|
|
609
609
|
return cmdSchedule(rest);
|
|
610
610
|
}
|
|
611
611
|
case "remote": {
|
|
@@ -624,9 +624,29 @@ async function runSubcommand(argv) {
|
|
|
624
624
|
return 1;
|
|
625
625
|
}
|
|
626
626
|
}
|
|
627
|
-
|
|
627
|
+
/**
|
|
628
|
+
* The banner shown by `ay help` / `ay -h` when this process is itself running
|
|
629
|
+
* inside an agent (`AGENT_YES_PID` set — see resolveSender). Answers the three
|
|
630
|
+
* things a nested agent actually needs: who am I, who spawned me, and how do I
|
|
631
|
+
* drive sub-agents of my own — so it doesn't have to rediscover the fan-out
|
|
632
|
+
* primitives (spawn / ay ls forest / ay ls --watch) from scratch every session.
|
|
633
|
+
*/
|
|
634
|
+
async function buildAgentContextSection(self) {
|
|
635
|
+
const hasParentPid = typeof self.parent_pid === "number" && self.parent_pid > 0;
|
|
636
|
+
const parent = hasParentPid ? (await listRecords(void 0, {
|
|
637
|
+
all: true,
|
|
638
|
+
active: false,
|
|
639
|
+
json: false,
|
|
640
|
+
latest: false,
|
|
641
|
+
cwdScope: null
|
|
642
|
+
})).find((r) => r.wrapper_pid === self.parent_pid) : void 0;
|
|
643
|
+
return `You are running inside an agent:\n ${`You are agent pid ${self.pid} (${self.cli}) in ${shortenPath(self.cwd)}.`}\n ${!hasParentPid ? `Top-level agent — no parent (started from a human shell or scheduler).` : parent ? `Spawned by agent pid ${parent.pid} (${parent.cli}) in ${shortenPath(parent.cwd)}.` : `Nested under a parent (wrapper pid ${self.parent_pid}) whose record isn't in the local registry.`}\n\nAs an agent, you can:\n Spawn a sub-agent:\n ay <cli> -- "<prompt>" auto-links as your child\n ay claude --model sonnet --advisor opus -- "<prompt>" routine task\n ay claude --model opus --advisor fable -- "<prompt>" complex task\n (pick --model by task complexity so easy tasks don't cost like hard ones;\n --advisor is a claude-cli flag — only takes effect for claude/cy)\n List agents (your children nest under your own pid in the tree):\n ay ls --cwd ${shortenPath(self.cwd)}\n Watch agent state changes, scoped to your workspace:\n ay ls --watch --cwd ${shortenPath(self.cwd)}\n (NDJSON stream of state changes across every matched agent — one watcher\n for the whole fan-out instead of N \`ay status --watch\`es)\n Read one sub-agent's output:\n ay tail -f <pid> follow live output (no single command tails\n many agents' content at once yet — loop\n \`ay ls --json\` pids into per-pid \`ay tail\`)\n\n`;
|
|
644
|
+
}
|
|
645
|
+
async function cmdHelp(managerCommands = true) {
|
|
628
646
|
const setupLine = managerCommands ? ` ay setup guided setup: pick a workspace, share to agent-yes.com\n` : ``;
|
|
629
|
-
|
|
647
|
+
const self = process.env.AGENT_YES_PID ? await resolveSender() : null;
|
|
648
|
+
const agentSection = self ? await buildAgentContextSection(self) : "";
|
|
649
|
+
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\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 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\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 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");
|
|
630
650
|
return 0;
|
|
631
651
|
}
|
|
632
652
|
function matchKeyword(record, keyword) {
|
|
@@ -3005,4 +3025,4 @@ async function cmdResultSet(rest) {
|
|
|
3005
3025
|
|
|
3006
3026
|
//#endregion
|
|
3007
3027
|
export { writeToIpc as A, resolveReadWindow as C, snapshotStatus as D, runSubcommand as E, stopTipForCli as O, resolveOne as S, restartHintLines as T, menuSelectKeys as _, cursorAbs as a, renderRawLog as b, extractNeedsInput as c, isAgentStuck as d, isExitRequest as f, matchKeyword as g, listRecords as h, controlCodeFromName as i, writeKeysPaced as k, extractTaskCounts as l, isSubcommand as m, READ_PAGE_DEFAULT as n, deriveLiveStatus as o, isPidAlive as p, cmdHelp as r, extractMenu as s, GRACEFUL_EXIT_COMMANDS as t, finalizedLines as u, readNotes as v, resolveResumeArgs as w, renderRawLogLines as x, readPtysize as y };
|
|
3008
|
-
//# sourceMappingURL=subcommands-
|
|
3028
|
+
//# sourceMappingURL=subcommands-DWeo7ZLc.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-BvR6tV3u.js";
|
|
3
3
|
import { t as agentYesHome } from "./agentYesHome-_eJa3DaX.js";
|
|
4
4
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-V4qvXgAw.js";
|
|
5
5
|
import { t as PidStore } from "./pidStore-BfoBWUjc.js";
|
|
@@ -1803,4 +1803,4 @@ function sleep(ms) {
|
|
|
1803
1803
|
|
|
1804
1804
|
//#endregion
|
|
1805
1805
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1806
|
-
//# sourceMappingURL=ts-
|
|
1806
|
+
//# sourceMappingURL=ts-s3wYccKf.js.map
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
|
|
8
8
|
//#region package.json
|
|
9
9
|
var name = "claude-yes";
|
|
10
|
-
var version = "1.
|
|
10
|
+
var version = "1.167.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-BvR6tV3u.js.map
|
package/package.json
CHANGED
package/ts/cli.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { buildRustArgs } from "./buildRustArgs.ts";
|
|
|
30
30
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
31
31
|
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands.ts");
|
|
32
32
|
if (isHelpFlag && process.argv.length === 3) {
|
|
33
|
-
cmdHelp(managerCommands);
|
|
33
|
+
await cmdHelp(managerCommands);
|
|
34
34
|
process.exit(0);
|
|
35
35
|
}
|
|
36
36
|
if (isSubcommand(rawArg, managerCommands)) {
|
package/ts/subcommands.spec.ts
CHANGED
|
@@ -113,25 +113,134 @@ describe("subcommands.isSubcommand", () => {
|
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
describe("subcommands.cmdHelp", () => {
|
|
116
|
-
|
|
116
|
+
const capture = async (managerCommands?: boolean) => {
|
|
117
117
|
const { cmdHelp } = await loadModule();
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
expect(capture()).toContain("ay setup"); //
|
|
133
|
-
expect(capture(
|
|
134
|
-
expect(capture(false)).toContain("ay
|
|
118
|
+
let out = "";
|
|
119
|
+
const spy = vi.spyOn(process.stdout, "write").mockImplementation((s: unknown) => {
|
|
120
|
+
out += String(s);
|
|
121
|
+
return true;
|
|
122
|
+
});
|
|
123
|
+
try {
|
|
124
|
+
await cmdHelp(managerCommands);
|
|
125
|
+
} finally {
|
|
126
|
+
spy.mockRestore();
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
it("hides the manager-only `setup` line for cli-bound aliases", async () => {
|
|
132
|
+
expect(await capture(true)).toContain("ay setup"); // manager
|
|
133
|
+
expect(await capture()).toContain("ay setup"); // default = manager
|
|
134
|
+
expect(await capture(false)).not.toContain("ay setup"); // cli-bound alias (cy)
|
|
135
|
+
expect(await capture(false)).toContain("ay ls"); // universal commands still shown
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("stays plain for a human shell (no AGENT_YES_PID)", async () => {
|
|
139
|
+
const out = await capture();
|
|
140
|
+
expect(out).not.toContain("You are running inside an agent");
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("prints self + parent identity and sub-agent guidance when nested in an agent", async () => {
|
|
144
|
+
const { appendGlobalPid } = await import("./globalPidIndex.ts");
|
|
145
|
+
const parentWrapperPid = 555001;
|
|
146
|
+
const selfWrapperPid = 555002;
|
|
147
|
+
await appendGlobalPid({
|
|
148
|
+
pid: 900001,
|
|
149
|
+
cli: "codex",
|
|
150
|
+
prompt: "orchestrate the migration",
|
|
151
|
+
cwd: "/work/parent",
|
|
152
|
+
log_file: null,
|
|
153
|
+
fifo_file: null,
|
|
154
|
+
status: "active",
|
|
155
|
+
exit_code: null,
|
|
156
|
+
exit_reason: null,
|
|
157
|
+
started_at: Date.now(),
|
|
158
|
+
wrapper_pid: parentWrapperPid,
|
|
159
|
+
});
|
|
160
|
+
await appendGlobalPid({
|
|
161
|
+
pid: process.pid,
|
|
162
|
+
cli: "claude",
|
|
163
|
+
prompt: "fix the failing test",
|
|
164
|
+
cwd: "/work/parent/child",
|
|
165
|
+
log_file: null,
|
|
166
|
+
fifo_file: null,
|
|
167
|
+
status: "active",
|
|
168
|
+
exit_code: null,
|
|
169
|
+
exit_reason: null,
|
|
170
|
+
started_at: Date.now(),
|
|
171
|
+
wrapper_pid: selfWrapperPid,
|
|
172
|
+
parent_pid: parentWrapperPid,
|
|
173
|
+
});
|
|
174
|
+
const saved = process.env.AGENT_YES_PID;
|
|
175
|
+
process.env.AGENT_YES_PID = String(selfWrapperPid);
|
|
176
|
+
try {
|
|
177
|
+
const out = await capture();
|
|
178
|
+
expect(out).toContain("You are running inside an agent");
|
|
179
|
+
expect(out).toContain(`You are agent pid ${process.pid} (claude)`);
|
|
180
|
+
expect(out).toContain(`Spawned by agent pid 900001 (codex)`);
|
|
181
|
+
expect(out).toContain("Spawn a sub-agent");
|
|
182
|
+
expect(out).toContain(`ay ls --cwd /work/parent/child`);
|
|
183
|
+
expect(out).toContain(`ay ls --watch --cwd /work/parent/child`);
|
|
184
|
+
} finally {
|
|
185
|
+
if (saved === undefined) delete process.env.AGENT_YES_PID;
|
|
186
|
+
else process.env.AGENT_YES_PID = saved;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("reports a nested-but-unresolved parent distinctly from top-level", async () => {
|
|
191
|
+
const { appendGlobalPid } = await import("./globalPidIndex.ts");
|
|
192
|
+
const selfWrapperPid = 555004;
|
|
193
|
+
await appendGlobalPid({
|
|
194
|
+
pid: process.pid,
|
|
195
|
+
cli: "claude",
|
|
196
|
+
prompt: null,
|
|
197
|
+
cwd: process.cwd(),
|
|
198
|
+
log_file: null,
|
|
199
|
+
fifo_file: null,
|
|
200
|
+
status: "active",
|
|
201
|
+
exit_code: null,
|
|
202
|
+
exit_reason: null,
|
|
203
|
+
started_at: Date.now(),
|
|
204
|
+
wrapper_pid: selfWrapperPid,
|
|
205
|
+
parent_pid: 999999999, // no record ever registered for this wrapper pid
|
|
206
|
+
});
|
|
207
|
+
const saved = process.env.AGENT_YES_PID;
|
|
208
|
+
process.env.AGENT_YES_PID = String(selfWrapperPid);
|
|
209
|
+
try {
|
|
210
|
+
const out = await capture();
|
|
211
|
+
expect(out).not.toContain("Top-level agent");
|
|
212
|
+
expect(out).toContain("Nested under a parent (wrapper pid 999999999)");
|
|
213
|
+
} finally {
|
|
214
|
+
if (saved === undefined) delete process.env.AGENT_YES_PID;
|
|
215
|
+
else process.env.AGENT_YES_PID = saved;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("reports top-level (no parent) when parent_pid is absent", async () => {
|
|
220
|
+
const { appendGlobalPid } = await import("./globalPidIndex.ts");
|
|
221
|
+
const selfWrapperPid = 555003;
|
|
222
|
+
await appendGlobalPid({
|
|
223
|
+
pid: process.pid,
|
|
224
|
+
cli: "claude",
|
|
225
|
+
prompt: null,
|
|
226
|
+
cwd: process.cwd(),
|
|
227
|
+
log_file: null,
|
|
228
|
+
fifo_file: null,
|
|
229
|
+
status: "active",
|
|
230
|
+
exit_code: null,
|
|
231
|
+
exit_reason: null,
|
|
232
|
+
started_at: Date.now(),
|
|
233
|
+
wrapper_pid: selfWrapperPid,
|
|
234
|
+
});
|
|
235
|
+
const saved = process.env.AGENT_YES_PID;
|
|
236
|
+
process.env.AGENT_YES_PID = String(selfWrapperPid);
|
|
237
|
+
try {
|
|
238
|
+
const out = await capture();
|
|
239
|
+
expect(out).toContain("Top-level agent");
|
|
240
|
+
} finally {
|
|
241
|
+
if (saved === undefined) delete process.env.AGENT_YES_PID;
|
|
242
|
+
else process.env.AGENT_YES_PID = saved;
|
|
243
|
+
}
|
|
135
244
|
});
|
|
136
245
|
});
|
|
137
246
|
|
package/ts/subcommands.ts
CHANGED
|
@@ -387,14 +387,77 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
387
387
|
// ay help
|
|
388
388
|
// ---------------------------------------------------------------------------
|
|
389
389
|
|
|
390
|
-
|
|
390
|
+
/**
|
|
391
|
+
* The banner shown by `ay help` / `ay -h` when this process is itself running
|
|
392
|
+
* inside an agent (`AGENT_YES_PID` set — see resolveSender). Answers the three
|
|
393
|
+
* things a nested agent actually needs: who am I, who spawned me, and how do I
|
|
394
|
+
* drive sub-agents of my own — so it doesn't have to rediscover the fan-out
|
|
395
|
+
* primitives (spawn / ay ls forest / ay ls --watch) from scratch every session.
|
|
396
|
+
*/
|
|
397
|
+
async function buildAgentContextSection(self: GlobalPidRecord): Promise<string> {
|
|
398
|
+
const hasParentPid = typeof self.parent_pid === "number" && self.parent_pid > 0;
|
|
399
|
+
const parent = hasParentPid
|
|
400
|
+
? (
|
|
401
|
+
await listRecords(undefined, {
|
|
402
|
+
all: true,
|
|
403
|
+
active: false,
|
|
404
|
+
json: false,
|
|
405
|
+
latest: false,
|
|
406
|
+
cwdScope: null,
|
|
407
|
+
})
|
|
408
|
+
).find((r) => r.wrapper_pid === self.parent_pid)
|
|
409
|
+
: undefined;
|
|
410
|
+
|
|
411
|
+
const whoAmI = `You are agent pid ${self.pid} (${self.cli}) in ${shortenPath(self.cwd)}.`;
|
|
412
|
+
// Three distinct states: no parent at all (top-level); a parent_pid whose
|
|
413
|
+
// record we can resolve; or a parent_pid we can't resolve (its record aged
|
|
414
|
+
// out / lives on a remote) — that last case is still nested, just unknown,
|
|
415
|
+
// so it must not collapse into the "top-level" line.
|
|
416
|
+
const parentLine = !hasParentPid
|
|
417
|
+
? `Top-level agent — no parent (started from a human shell or scheduler).`
|
|
418
|
+
: parent
|
|
419
|
+
? `Spawned by agent pid ${parent.pid} (${parent.cli}) in ${shortenPath(parent.cwd)}.`
|
|
420
|
+
: `Nested under a parent (wrapper pid ${self.parent_pid}) whose record isn't in the local registry.`;
|
|
421
|
+
|
|
422
|
+
return (
|
|
423
|
+
`You are running inside an agent:\n` +
|
|
424
|
+
` ${whoAmI}\n` +
|
|
425
|
+
` ${parentLine}\n` +
|
|
426
|
+
`\n` +
|
|
427
|
+
`As an agent, you can:\n` +
|
|
428
|
+
` Spawn a sub-agent:\n` +
|
|
429
|
+
` ay <cli> -- "<prompt>" auto-links as your child\n` +
|
|
430
|
+
` ay claude --model sonnet --advisor opus -- "<prompt>" routine task\n` +
|
|
431
|
+
` ay claude --model opus --advisor fable -- "<prompt>" complex task\n` +
|
|
432
|
+
` (pick --model by task complexity so easy tasks don't cost like hard ones;\n` +
|
|
433
|
+
` --advisor is a claude-cli flag — only takes effect for claude/cy)\n` +
|
|
434
|
+
` List agents (your children nest under your own pid in the tree):\n` +
|
|
435
|
+
` ay ls --cwd ${shortenPath(self.cwd)}\n` +
|
|
436
|
+
` Watch agent state changes, scoped to your workspace:\n` +
|
|
437
|
+
` ay ls --watch --cwd ${shortenPath(self.cwd)}\n` +
|
|
438
|
+
` (NDJSON stream of state changes across every matched agent — one watcher\n` +
|
|
439
|
+
` for the whole fan-out instead of N \`ay status --watch\`es)\n` +
|
|
440
|
+
` Read one sub-agent's output:\n` +
|
|
441
|
+
` ay tail -f <pid> follow live output (no single command tails\n` +
|
|
442
|
+
` many agents' content at once yet — loop\n` +
|
|
443
|
+
` \`ay ls --json\` pids into per-pid \`ay tail\`)\n` +
|
|
444
|
+
`\n`
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export async function cmdHelp(managerCommands = true): Promise<number> {
|
|
391
449
|
// `setup` is manager-only — hide it when invoked through a cli-bound alias
|
|
392
450
|
// (cy/claude-yes/…), where `cy setup` runs the agent instead of managing the host.
|
|
393
451
|
const setupLine = managerCommands
|
|
394
452
|
? ` ay setup guided setup: pick a workspace, share to agent-yes.com\n`
|
|
395
453
|
: ``;
|
|
454
|
+
// Only agents carry AGENT_YES_PID — a human shell never sets it — so this
|
|
455
|
+
// section is skipped entirely (no async work at all) for interactive use.
|
|
456
|
+
const self = process.env.AGENT_YES_PID ? await resolveSender() : null;
|
|
457
|
+
const agentSection = self ? await buildAgentContextSection(self) : "";
|
|
396
458
|
process.stdout.write(
|
|
397
|
-
|
|
459
|
+
agentSection +
|
|
460
|
+
`ay - agent-yes CLI\n` +
|
|
398
461
|
`\n` +
|
|
399
462
|
`Management:\n` +
|
|
400
463
|
` ay ls [keyword] list running agents\n` +
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-CXxZiZKE.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-Dv5DhRs3.js";
|
|
4
|
-
import "./pidStore-BfoBWUjc.js";
|
|
5
|
-
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-Xem8nliL.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|