claude-yes 1.160.3 → 1.161.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-CHmQfHCh.js +8 -0
- package/dist/{SUPPORTED_CLIS-WcYvfnJQ.js → SUPPORTED_CLIS-DYTnLX8C.js} +2 -2
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{schedule-YIA3BrZV.js → schedule-CCvB7SCT.js} +4 -4
- package/dist/{serve-D3vy56FC.js → serve-BRARQjsC.js} +5 -5
- package/dist/{setup-B1meh4do.js → setup-Cx7jDKtC.js} +2 -2
- package/dist/{subcommands-BJ2xKtDu.js → subcommands-5AXvxB0S.js} +1 -1
- package/dist/{subcommands-Cz17HvuK.js → subcommands-DGkBxWS5.js} +81 -6
- package/dist/{ts-DcZvAsIp.js → ts-CRo3qQWb.js} +2 -2
- package/dist/{versionChecker-DOse329y.js → versionChecker-DrjR4P0K.js} +2 -2
- package/package.json +1 -1
- package/ts/subcommands.ts +137 -0
- package/dist/SUPPORTED_CLIS-pKjUYMIj.js +0 -8
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-CRo3qQWb.js";
|
|
2
|
+
import "./logger-CDIsZ-Pp.js";
|
|
3
|
+
import "./versionChecker-DrjR4P0K.js";
|
|
4
|
+
import "./pidStore-fqXqTKkh.js";
|
|
5
|
+
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-DYTnLX8C.js";
|
|
7
|
+
|
|
8
|
+
export { SUPPORTED_CLIS };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-CRo3qQWb.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-DYTnLX8C.js.map
|
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-DrjR4P0K.js";
|
|
5
5
|
import { argv } from "process";
|
|
6
6
|
import { execFileSync, spawn } from "child_process";
|
|
7
7
|
import ms from "ms";
|
|
@@ -481,7 +481,7 @@ 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-5AXvxB0S.js");
|
|
485
485
|
if (isHelpFlag && process.argv.length === 3) {
|
|
486
486
|
cmdHelp(managerCommands);
|
|
487
487
|
process.exit(0);
|
|
@@ -514,7 +514,7 @@ if (config.useRust) {
|
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
516
|
if (rustBinary) {
|
|
517
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
517
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-CHmQfHCh.js");
|
|
518
518
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
519
519
|
if (config.verbose) {
|
|
520
520
|
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-CRo3qQWb.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DrjR4P0K.js";
|
|
4
4
|
import "./pidStore-fqXqTKkh.js";
|
|
5
5
|
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
6
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CRo3qQWb.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-DrjR4P0K.js";
|
|
4
4
|
import "./pidStore-fqXqTKkh.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-DYTnLX8C.js";
|
|
7
7
|
import { o as resolveSpawnCwd } from "./workspaceConfig-B0Q9-q2B.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-CCvB7SCT.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-CRo3qQWb.js";
|
|
2
2
|
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import { r as getInstalledPackage } from "./versionChecker-
|
|
3
|
+
import { r as getInstalledPackage } from "./versionChecker-DrjR4P0K.js";
|
|
4
4
|
import "./pidStore-fqXqTKkh.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-DYTnLX8C.js";
|
|
9
9
|
import "./e2e-Bfw7qL9O.js";
|
|
10
10
|
import "./webrtcLink-CBZkZ-LT.js";
|
|
11
11
|
import "./remotes-DBCvpp3B.js";
|
|
12
12
|
import { a as isProvisionAllowed, i as hasSpawnHook, n as getSpawnHook, o as resolveSpawnCwd, t as getProvisionRoot } from "./workspaceConfig-B0Q9-q2B.js";
|
|
13
|
-
import { D as writeToIpc, T as snapshotStatus, _ as readPtysize, b as resolveOne, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, v as renderRawLog } from "./subcommands-
|
|
13
|
+
import { D as writeToIpc, T as snapshotStatus, _ as readPtysize, b as resolveOne, c as extractTaskCounts, g as readNotes, i as controlCodeFromName, m as listRecords, o as deriveLiveStatus, v as renderRawLog } from "./subcommands-DGkBxWS5.js";
|
|
14
14
|
import yargs from "yargs";
|
|
15
15
|
import { mkdir, open, readFile, stat, unlink, writeFile } from "fs/promises";
|
|
16
16
|
import { homedir, hostname, userInfo } from "os";
|
|
@@ -1389,4 +1389,4 @@ Options:
|
|
|
1389
1389
|
|
|
1390
1390
|
//#endregion
|
|
1391
1391
|
export { cmdServe };
|
|
1392
|
-
//# sourceMappingURL=serve-
|
|
1392
|
+
//# sourceMappingURL=serve-BRARQjsC.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-BRARQjsC.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-Cx7jDKtC.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-DBCvpp3B.js";
|
|
7
|
-
import { C as restartHintLines, D as writeToIpc, E as stopTipForCli, S as resolveResumeArgs, T as snapshotStatus, _ as readPtysize, a as cursorAbs, b as resolveOne, c as extractTaskCounts, d as isExitRequest, f as isPidAlive, g as readNotes, h as matchKeyword, i as controlCodeFromName, l as finalizedLines, m as listRecords, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isSubcommand, r as cmdHelp, s as extractNeedsInput, t as GRACEFUL_EXIT_COMMANDS, u as isAgentStuck, v as renderRawLog, w as runSubcommand, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-
|
|
7
|
+
import { C as restartHintLines, D as writeToIpc, E as stopTipForCli, S as resolveResumeArgs, T as snapshotStatus, _ as readPtysize, a as cursorAbs, b as resolveOne, c as extractTaskCounts, d as isExitRequest, f as isPidAlive, g as readNotes, h as matchKeyword, i as controlCodeFromName, l as finalizedLines, m as listRecords, n as READ_PAGE_DEFAULT, o as deriveLiveStatus, p as isSubcommand, r as cmdHelp, s as extractNeedsInput, t as GRACEFUL_EXIT_COMMANDS, u as isAgentStuck, v as renderRawLog, w as runSubcommand, x as resolveReadWindow, y as renderRawLogLines } from "./subcommands-DGkBxWS5.js";
|
|
8
8
|
|
|
9
9
|
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -500,6 +500,7 @@ const SUBCOMMANDS = new Set([
|
|
|
500
500
|
"tail",
|
|
501
501
|
"head",
|
|
502
502
|
"send",
|
|
503
|
+
"spawn",
|
|
503
504
|
"attach",
|
|
504
505
|
"stop",
|
|
505
506
|
"exit",
|
|
@@ -548,21 +549,22 @@ async function runSubcommand(argv) {
|
|
|
548
549
|
case "tail": return await cmdRead(rest, { mode: "tail" });
|
|
549
550
|
case "head": return await cmdRead(rest, { mode: "head" });
|
|
550
551
|
case "send": return await cmdSend(rest);
|
|
552
|
+
case "spawn": return await cmdSpawn(rest);
|
|
551
553
|
case "attach": return await cmdAttach(rest);
|
|
552
554
|
case "stop": return await cmdStop(rest);
|
|
553
555
|
case "exit": return await cmdExit(rest);
|
|
554
556
|
case "restart": return await cmdRestart(rest);
|
|
555
557
|
case "note": return await cmdNote(rest);
|
|
556
558
|
case "serve": {
|
|
557
|
-
const { cmdServe } = await import("./serve-
|
|
559
|
+
const { cmdServe } = await import("./serve-BRARQjsC.js");
|
|
558
560
|
return cmdServe(rest);
|
|
559
561
|
}
|
|
560
562
|
case "setup": {
|
|
561
|
-
const { cmdSetup } = await import("./setup-
|
|
563
|
+
const { cmdSetup } = await import("./setup-Cx7jDKtC.js");
|
|
562
564
|
return cmdSetup(rest);
|
|
563
565
|
}
|
|
564
566
|
case "schedule": {
|
|
565
|
-
const { cmdSchedule } = await import("./schedule-
|
|
567
|
+
const { cmdSchedule } = await import("./schedule-CCvB7SCT.js");
|
|
566
568
|
return cmdSchedule(rest);
|
|
567
569
|
}
|
|
568
570
|
case "remote": {
|
|
@@ -716,14 +718,15 @@ async function resolveOne(keyword, opts) {
|
|
|
716
718
|
async function remoteGet(remote, pathname) {
|
|
717
719
|
return fetch(`${remote.url}${pathname}`, { headers: { Authorization: `Bearer ${remote.token}` } });
|
|
718
720
|
}
|
|
719
|
-
async function remotePost(remote, pathname, body) {
|
|
721
|
+
async function remotePost(remote, pathname, body, signal) {
|
|
720
722
|
return fetch(`${remote.url}${pathname}`, {
|
|
721
723
|
method: "POST",
|
|
722
724
|
headers: {
|
|
723
725
|
Authorization: `Bearer ${remote.token}`,
|
|
724
726
|
"Content-Type": "application/json"
|
|
725
727
|
},
|
|
726
|
-
body: JSON.stringify(body)
|
|
728
|
+
body: JSON.stringify(body),
|
|
729
|
+
...signal ? { signal } : {}
|
|
727
730
|
});
|
|
728
731
|
}
|
|
729
732
|
async function runRemoteLs(remote, opts) {
|
|
@@ -875,6 +878,44 @@ async function runRemoteSend(remote, msg, code) {
|
|
|
875
878
|
process.stdout.write(`sent to remote pid ${data.pid} (${remote.url} ${keyword})\n`);
|
|
876
879
|
return 0;
|
|
877
880
|
}
|
|
881
|
+
/**
|
|
882
|
+
* Spawn an agent on a remote host by POSTing its existing `/api/spawn`. The
|
|
883
|
+
* remote applies ITS OWN spawn hook + provision allowlist server-side (the hook
|
|
884
|
+
* never crosses the wire). `hint` is the user-typed target (alias or
|
|
885
|
+
* token@host:port) so the printed follow-ups are copy-pasteable.
|
|
886
|
+
*
|
|
887
|
+
* NO retry: a POST that already spawned must never be re-sent (double-spawn). A
|
|
888
|
+
* generous timeout still bounds a half-open/stalled connection — on timeout the
|
|
889
|
+
* result is UNKNOWN, so we say so and point at `ay ls` rather than retrying.
|
|
890
|
+
*/
|
|
891
|
+
async function runRemoteSpawn(remote, hint, spec) {
|
|
892
|
+
const SPAWN_TIMEOUT_MS = Number(process.env.AGENT_YES_REMOTE_SPAWN_TIMEOUT_MS) || 12e4;
|
|
893
|
+
let res;
|
|
894
|
+
try {
|
|
895
|
+
res = await remotePost(remote, "/api/spawn", {
|
|
896
|
+
cli: spec.cli,
|
|
897
|
+
cwd: spec.cwd || void 0,
|
|
898
|
+
from: spec.from || void 0,
|
|
899
|
+
prompt: spec.prompt || void 0
|
|
900
|
+
}, AbortSignal.timeout(SPAWN_TIMEOUT_MS));
|
|
901
|
+
} catch (e) {
|
|
902
|
+
const name = e?.name;
|
|
903
|
+
if (name === "TimeoutError" || name === "AbortError") {
|
|
904
|
+
process.stderr.write(`remote spawn: no response from ${remote.url} within ${Math.round(SPAWN_TIMEOUT_MS / 1e3)}s — result UNKNOWN (not retried).\n ay ls ${hint} # check whether it started\n`);
|
|
905
|
+
return 2;
|
|
906
|
+
}
|
|
907
|
+
process.stderr.write(`remote spawn failed: ${e.message}\n`);
|
|
908
|
+
return 1;
|
|
909
|
+
}
|
|
910
|
+
if (!res.ok) {
|
|
911
|
+
process.stderr.write(`remote spawn failed ${res.status}: ${await res.text()}\n`);
|
|
912
|
+
return 1;
|
|
913
|
+
}
|
|
914
|
+
const r = await res.json();
|
|
915
|
+
process.stdout.write(`spawned ${r.cli} on ${remote.url} in ${r.cwd}${r.hook ? " (via spawn hook)" : ""}${r.provisioned ? ` (${r.provisioned.action})` : ""}\n`);
|
|
916
|
+
process.stderr.write(`\n ay ls ${hint} # the new ${r.cli} agent appears here\n`);
|
|
917
|
+
return 0;
|
|
918
|
+
}
|
|
878
919
|
async function runRemoteStatus(remote) {
|
|
879
920
|
const keyword = remote.keyword ?? "";
|
|
880
921
|
if (!keyword) {
|
|
@@ -1819,6 +1860,40 @@ function extractActivityFromLines(lines) {
|
|
|
1819
1860
|
}
|
|
1820
1861
|
return null;
|
|
1821
1862
|
}
|
|
1863
|
+
async function cmdSpawn(rest) {
|
|
1864
|
+
const argv = await yargs(rest).usage("Usage: ay spawn <remote> [--cli claude] [--cwd <dir>] [--from <src>] -- <prompt>").option("cli", {
|
|
1865
|
+
type: "string",
|
|
1866
|
+
default: "claude",
|
|
1867
|
+
description: "CLI to wrap (claude|codex|gemini|…)"
|
|
1868
|
+
}).option("cwd", {
|
|
1869
|
+
type: "string",
|
|
1870
|
+
description: "Working dir ON THE REMOTE (resolved against the remote's workspace root)"
|
|
1871
|
+
}).option("from", {
|
|
1872
|
+
type: "string",
|
|
1873
|
+
description: "Provision a worktree from a GitHub source (owner/repo@branch) on the remote"
|
|
1874
|
+
}).option("prompt", {
|
|
1875
|
+
type: "string",
|
|
1876
|
+
description: "Initial prompt (or pass it after `--`)"
|
|
1877
|
+
}).help(false).version(false).exitProcess(false).parseAsync();
|
|
1878
|
+
const target = argv._[0] !== void 0 ? String(argv._[0]) : void 0;
|
|
1879
|
+
if (!target) throw new Error("usage: ay spawn <remote> [--cli X] [--cwd D] [--from S] -- <prompt>");
|
|
1880
|
+
const prompt = String(argv.prompt ?? argv._.slice(1).map(String).join(" "));
|
|
1881
|
+
const remote = await resolveRemoteSpec(target);
|
|
1882
|
+
if (!remote) {
|
|
1883
|
+
process.stderr.write(`ay spawn: '${target}' is not a known remote (token@host:port or a saved alias).\n to spawn locally: ay ${argv.cli}${prompt ? ` -- "${prompt}"` : ""}\n to add a remote: ay remote add <alias> http://<token>@<host>:<port>\n`);
|
|
1884
|
+
return 1;
|
|
1885
|
+
}
|
|
1886
|
+
if (remote.keyword) {
|
|
1887
|
+
process.stderr.write(`ay spawn: target '${target}' carries a ':${remote.keyword}' keyword — spawn takes a remote, not an existing agent. Drop the ':${remote.keyword}'.\n`);
|
|
1888
|
+
return 1;
|
|
1889
|
+
}
|
|
1890
|
+
return runRemoteSpawn(remote, target, {
|
|
1891
|
+
cli: String(argv.cli || "claude"),
|
|
1892
|
+
cwd: argv.cwd ? String(argv.cwd) : void 0,
|
|
1893
|
+
from: argv.from ? String(argv.from) : void 0,
|
|
1894
|
+
prompt: prompt || void 0
|
|
1895
|
+
});
|
|
1896
|
+
}
|
|
1822
1897
|
async function cmdSend(rest) {
|
|
1823
1898
|
const argv = await yargs(rest).usage("Usage: ay send <keyword> <msg|-> [options]").option("code", {
|
|
1824
1899
|
type: "string",
|
|
@@ -2719,4 +2794,4 @@ async function cmdResultSet(rest) {
|
|
|
2719
2794
|
|
|
2720
2795
|
//#endregion
|
|
2721
2796
|
export { restartHintLines as C, writeToIpc as D, stopTipForCli as E, resolveResumeArgs as S, snapshotStatus as T, readPtysize as _, cursorAbs as a, resolveOne as b, extractTaskCounts as c, isExitRequest as d, isPidAlive as f, readNotes as g, matchKeyword as h, controlCodeFromName as i, finalizedLines as l, listRecords as m, READ_PAGE_DEFAULT as n, deriveLiveStatus as o, isSubcommand as p, cmdHelp as r, extractNeedsInput as s, GRACEFUL_EXIT_COMMANDS as t, isAgentStuck as u, renderRawLog as v, runSubcommand as w, resolveReadWindow as x, renderRawLogLines as y };
|
|
2722
|
-
//# sourceMappingURL=subcommands-
|
|
2797
|
+
//# sourceMappingURL=subcommands-DGkBxWS5.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-DrjR4P0K.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-fqXqTKkh.js";
|
|
@@ -1802,4 +1802,4 @@ function sleep(ms) {
|
|
|
1802
1802
|
|
|
1803
1803
|
//#endregion
|
|
1804
1804
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1805
|
-
//# sourceMappingURL=ts-
|
|
1805
|
+
//# sourceMappingURL=ts-CRo3qQWb.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.161.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-DrjR4P0K.js.map
|
package/package.json
CHANGED
package/ts/subcommands.ts
CHANGED
|
@@ -251,6 +251,7 @@ const SUBCOMMANDS = new Set([
|
|
|
251
251
|
"tail",
|
|
252
252
|
"head",
|
|
253
253
|
"send",
|
|
254
|
+
"spawn",
|
|
254
255
|
"attach",
|
|
255
256
|
"stop",
|
|
256
257
|
"exit",
|
|
@@ -325,6 +326,8 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
325
326
|
return await cmdRead(rest, { mode: "head" });
|
|
326
327
|
case "send":
|
|
327
328
|
return await cmdSend(rest);
|
|
329
|
+
case "spawn":
|
|
330
|
+
return await cmdSpawn(rest);
|
|
328
331
|
case "attach":
|
|
329
332
|
return await cmdAttach(rest);
|
|
330
333
|
case "stop":
|
|
@@ -648,11 +651,13 @@ async function remotePost(
|
|
|
648
651
|
remote: ResolvedRemote,
|
|
649
652
|
pathname: string,
|
|
650
653
|
body: unknown,
|
|
654
|
+
signal?: AbortSignal,
|
|
651
655
|
): Promise<Response> {
|
|
652
656
|
return fetch(`${remote.url}${pathname}`, {
|
|
653
657
|
method: "POST",
|
|
654
658
|
headers: { Authorization: `Bearer ${remote.token}`, "Content-Type": "application/json" },
|
|
655
659
|
body: JSON.stringify(body),
|
|
660
|
+
...(signal ? { signal } : {}),
|
|
656
661
|
});
|
|
657
662
|
}
|
|
658
663
|
|
|
@@ -839,6 +844,79 @@ async function runRemoteSend(remote: ResolvedRemote, msg: string, code: string):
|
|
|
839
844
|
return 0;
|
|
840
845
|
}
|
|
841
846
|
|
|
847
|
+
/**
|
|
848
|
+
* Spawn an agent on a remote host by POSTing its existing `/api/spawn`. The
|
|
849
|
+
* remote applies ITS OWN spawn hook + provision allowlist server-side (the hook
|
|
850
|
+
* never crosses the wire). `hint` is the user-typed target (alias or
|
|
851
|
+
* token@host:port) so the printed follow-ups are copy-pasteable.
|
|
852
|
+
*
|
|
853
|
+
* NO retry: a POST that already spawned must never be re-sent (double-spawn). A
|
|
854
|
+
* generous timeout still bounds a half-open/stalled connection — on timeout the
|
|
855
|
+
* result is UNKNOWN, so we say so and point at `ay ls` rather than retrying.
|
|
856
|
+
*/
|
|
857
|
+
async function runRemoteSpawn(
|
|
858
|
+
remote: ResolvedRemote,
|
|
859
|
+
hint: string,
|
|
860
|
+
spec: { cli: string; cwd?: string; from?: string; prompt?: string },
|
|
861
|
+
): Promise<number> {
|
|
862
|
+
// A hooked `/api/spawn` (#126) can legitimately block up to the remote's
|
|
863
|
+
// handshake window, so the timeout is generous; it only guards a dead/half-open
|
|
864
|
+
// connection that would otherwise hang the CLI forever.
|
|
865
|
+
const SPAWN_TIMEOUT_MS = Number(process.env.AGENT_YES_REMOTE_SPAWN_TIMEOUT_MS) || 120_000;
|
|
866
|
+
let res: Response;
|
|
867
|
+
try {
|
|
868
|
+
res = await remotePost(
|
|
869
|
+
remote,
|
|
870
|
+
"/api/spawn",
|
|
871
|
+
{
|
|
872
|
+
cli: spec.cli,
|
|
873
|
+
cwd: spec.cwd || undefined,
|
|
874
|
+
from: spec.from || undefined,
|
|
875
|
+
prompt: spec.prompt || undefined,
|
|
876
|
+
},
|
|
877
|
+
AbortSignal.timeout(SPAWN_TIMEOUT_MS),
|
|
878
|
+
);
|
|
879
|
+
} catch (e) {
|
|
880
|
+
const name = (e as Error)?.name;
|
|
881
|
+
if (name === "TimeoutError" || name === "AbortError") {
|
|
882
|
+
// The request may or may not have spawned — do NOT retry. Let the operator check.
|
|
883
|
+
process.stderr.write(
|
|
884
|
+
`remote spawn: no response from ${remote.url} within ${Math.round(SPAWN_TIMEOUT_MS / 1000)}s — ` +
|
|
885
|
+
`result UNKNOWN (not retried).\n ay ls ${hint} # check whether it started\n`,
|
|
886
|
+
);
|
|
887
|
+
return 2;
|
|
888
|
+
}
|
|
889
|
+
process.stderr.write(`remote spawn failed: ${(e as Error).message}\n`);
|
|
890
|
+
return 1;
|
|
891
|
+
}
|
|
892
|
+
if (!res.ok) {
|
|
893
|
+
process.stderr.write(`remote spawn failed ${res.status}: ${await res.text()}\n`);
|
|
894
|
+
return 1;
|
|
895
|
+
}
|
|
896
|
+
const r = (await res.json()) as {
|
|
897
|
+
pid: number;
|
|
898
|
+
cli: string;
|
|
899
|
+
cwd: string;
|
|
900
|
+
hook?: boolean;
|
|
901
|
+
provisioned?: { action: string };
|
|
902
|
+
};
|
|
903
|
+
process.stdout.write(
|
|
904
|
+
`spawned ${r.cli} on ${remote.url} in ${r.cwd}` +
|
|
905
|
+
`${r.hook ? " (via spawn hook)" : ""}` +
|
|
906
|
+
`${r.provisioned ? ` (${r.provisioned.action})` : ""}\n`,
|
|
907
|
+
);
|
|
908
|
+
// We deliberately do NOT print the agent's own pid. `/api/spawn` returns the
|
|
909
|
+
// `ay` LAUNCHER pid, which is not the agent's registered pid (the record's
|
|
910
|
+
// pid/wrapper_pid are the runtime process, not the launcher) — and picking the
|
|
911
|
+
// freshly-registered agent by "newest" would, under a concurrent spawn,
|
|
912
|
+
// surface a sibling's (or another user's) pid. Point at the remote's list,
|
|
913
|
+
// where the new agent reliably appears, instead of guessing.
|
|
914
|
+
// (A one-step `ay tail <remote>:<pid>` would need /api/spawn to return a
|
|
915
|
+
// correlatable agent id — a server change left for a follow-up.)
|
|
916
|
+
process.stderr.write(`\n ay ls ${hint} # the new ${r.cli} agent appears here\n`);
|
|
917
|
+
return 0;
|
|
918
|
+
}
|
|
919
|
+
|
|
842
920
|
async function runRemoteStatus(remote: ResolvedRemote): Promise<number> {
|
|
843
921
|
const keyword = remote.keyword ?? "";
|
|
844
922
|
if (!keyword) {
|
|
@@ -2072,6 +2150,65 @@ function extractActivityFromLines(lines: string[]): string | null {
|
|
|
2072
2150
|
return null;
|
|
2073
2151
|
}
|
|
2074
2152
|
|
|
2153
|
+
// ---------------------------------------------------------------------------
|
|
2154
|
+
// ay spawn — launch an agent on a REMOTE host (POSTs the remote's /api/spawn)
|
|
2155
|
+
// ---------------------------------------------------------------------------
|
|
2156
|
+
|
|
2157
|
+
async function cmdSpawn(rest: string[]): Promise<number> {
|
|
2158
|
+
const y = yargs(rest)
|
|
2159
|
+
.usage("Usage: ay spawn <remote> [--cli claude] [--cwd <dir>] [--from <src>] -- <prompt>")
|
|
2160
|
+
.option("cli", {
|
|
2161
|
+
type: "string",
|
|
2162
|
+
default: "claude",
|
|
2163
|
+
description: "CLI to wrap (claude|codex|gemini|…)",
|
|
2164
|
+
})
|
|
2165
|
+
.option("cwd", {
|
|
2166
|
+
type: "string",
|
|
2167
|
+
description: "Working dir ON THE REMOTE (resolved against the remote's workspace root)",
|
|
2168
|
+
})
|
|
2169
|
+
.option("from", {
|
|
2170
|
+
type: "string",
|
|
2171
|
+
description: "Provision a worktree from a GitHub source (owner/repo@branch) on the remote",
|
|
2172
|
+
})
|
|
2173
|
+
.option("prompt", { type: "string", description: "Initial prompt (or pass it after `--`)" })
|
|
2174
|
+
.help(false)
|
|
2175
|
+
.version(false)
|
|
2176
|
+
.exitProcess(false);
|
|
2177
|
+
|
|
2178
|
+
const argv = await y.parseAsync();
|
|
2179
|
+
const target = argv._[0] !== undefined ? String(argv._[0]) : undefined;
|
|
2180
|
+
if (!target)
|
|
2181
|
+
throw new Error("usage: ay spawn <remote> [--cli X] [--cwd D] [--from S] -- <prompt>");
|
|
2182
|
+
const prompt = String(argv.prompt ?? argv._.slice(1).map(String).join(" "));
|
|
2183
|
+
|
|
2184
|
+
// v1 is remote-only: local spawning is just running the agent directly. A
|
|
2185
|
+
// target that doesn't resolve as a remote is almost certainly a mistake (e.g.
|
|
2186
|
+
// passing a cli name), so fail loudly with the local equivalent.
|
|
2187
|
+
const remote = await resolveRemoteSpec(target);
|
|
2188
|
+
if (!remote) {
|
|
2189
|
+
process.stderr.write(
|
|
2190
|
+
`ay spawn: '${target}' is not a known remote (token@host:port or a saved alias).\n` +
|
|
2191
|
+
` to spawn locally: ay ${argv.cli}${prompt ? ` -- "${prompt}"` : ""}\n` +
|
|
2192
|
+
` to add a remote: ay remote add <alias> http://<token>@<host>:<port>\n`,
|
|
2193
|
+
);
|
|
2194
|
+
return 1;
|
|
2195
|
+
}
|
|
2196
|
+
if (remote.keyword) {
|
|
2197
|
+
process.stderr.write(
|
|
2198
|
+
`ay spawn: target '${target}' carries a ':${remote.keyword}' keyword — spawn takes a remote, ` +
|
|
2199
|
+
`not an existing agent. Drop the ':${remote.keyword}'.\n`,
|
|
2200
|
+
);
|
|
2201
|
+
return 1;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
return runRemoteSpawn(remote, target, {
|
|
2205
|
+
cli: String(argv.cli || "claude"),
|
|
2206
|
+
cwd: argv.cwd ? String(argv.cwd) : undefined,
|
|
2207
|
+
from: argv.from ? String(argv.from) : undefined,
|
|
2208
|
+
prompt: prompt || undefined,
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2075
2212
|
// ---------------------------------------------------------------------------
|
|
2076
2213
|
// ay send
|
|
2077
2214
|
// ---------------------------------------------------------------------------
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import "./ts-DcZvAsIp.js";
|
|
2
|
-
import "./logger-CDIsZ-Pp.js";
|
|
3
|
-
import "./versionChecker-DOse329y.js";
|
|
4
|
-
import "./pidStore-fqXqTKkh.js";
|
|
5
|
-
import "./globalPidIndex-DlmmJlO8.js";
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-WcYvfnJQ.js";
|
|
7
|
-
|
|
8
|
-
export { SUPPORTED_CLIS };
|