claude-yes 1.87.0 → 1.88.1
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-DFGyxVkl.js → SUPPORTED_CLIS-CXRwTMf2.js} +3 -3
- package/dist/cli.js +10 -4
- package/dist/index.js +2 -2
- package/dist/{remotes-CFrho898.js → remotes-Bjp2GYPz.js} +26 -7
- package/dist/{remotes-kfUzk-JT.js → remotes-oNI1fR7_.js} +1 -1
- package/dist/{serve-8dWQHSBu.js → serve-Bk36c6qq.js} +16 -4
- package/dist/subcommands-8Pp3UUwj.js +6 -0
- package/dist/{subcommands-BltyYaEs.js → subcommands-DxafpA6_.js} +84 -6
- package/dist/{ts-Oxr2rEMA.js → ts-DGhJYVFb.js} +2 -2
- package/dist/{versionChecker--29PmTlR.js → versionChecker-DK6U9T31.js} +2 -2
- package/package.json +1 -1
- package/ts/cli.ts +9 -2
- package/ts/remotes.ts +42 -9
- package/ts/serve.ts +25 -1
- package/ts/subcommands.ts +126 -0
- package/dist/subcommands-B2lxwpQn.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-DGhJYVFb.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker
|
|
3
|
+
import "./versionChecker-DK6U9T31.js";
|
|
4
4
|
import "./pidStore-C1JXxoPi.js";
|
|
5
5
|
import "./globalPidIndex-Cr-g75QF.js";
|
|
6
6
|
|
|
@@ -9,4 +9,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
|
9
9
|
|
|
10
10
|
//#endregion
|
|
11
11
|
export { SUPPORTED_CLIS };
|
|
12
|
-
//# sourceMappingURL=SUPPORTED_CLIS-
|
|
12
|
+
//# sourceMappingURL=SUPPORTED_CLIS-CXRwTMf2.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
3
|
-
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker
|
|
3
|
+
import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-DK6U9T31.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
@@ -480,8 +480,14 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
480
480
|
}
|
|
481
481
|
}
|
|
482
482
|
{
|
|
483
|
-
const
|
|
484
|
-
|
|
483
|
+
const rawArg = process.argv[2];
|
|
484
|
+
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
485
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-8Pp3UUwj.js");
|
|
486
|
+
if (isHelpFlag && process.argv.length === 3) {
|
|
487
|
+
cmdHelp();
|
|
488
|
+
process.exit(0);
|
|
489
|
+
}
|
|
490
|
+
if (isSubcommand(rawArg)) {
|
|
485
491
|
const code = await runSubcommand(process.argv);
|
|
486
492
|
process.exit(code ?? 0);
|
|
487
493
|
}
|
|
@@ -509,7 +515,7 @@ if (config.useRust) {
|
|
|
509
515
|
}
|
|
510
516
|
}
|
|
511
517
|
if (rustBinary) {
|
|
512
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
518
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-CXRwTMf2.js");
|
|
513
519
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
514
520
|
if (config.verbose) {
|
|
515
521
|
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-DGhJYVFb.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker
|
|
3
|
+
import "./versionChecker-DK6U9T31.js";
|
|
4
4
|
import "./pidStore-C1JXxoPi.js";
|
|
5
5
|
import "./globalPidIndex-Cr-g75QF.js";
|
|
6
6
|
|
|
@@ -79,11 +79,15 @@ async function resolveRemoteSpec(spec) {
|
|
|
79
79
|
}
|
|
80
80
|
async function cmdRemote(rest) {
|
|
81
81
|
const sub = rest[0];
|
|
82
|
+
if (sub === "-h" || sub === "--help") {
|
|
83
|
+
process.stdout.write("Usage: ay remote <subcommand>\n\nManage saved remote server aliases.\n\nSubcommands:\n ay remote ls list configured remotes\n ay remote add <alias> http://<token>@<host>:<port> add a remote\n ay remote rm <alias> remove a remote\n\nOnce added, use the alias anywhere a keyword is accepted:\n ay ls <alias>\n ay tail <alias>:<keyword>\n ay send <alias>:<keyword> \"message\"\n");
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
82
86
|
if (!sub || sub === "ls" || sub === "list") {
|
|
83
87
|
const remotes = await readRemotes();
|
|
84
88
|
if (remotes.size === 0) {
|
|
85
89
|
process.stdout.write("no remotes configured\n");
|
|
86
|
-
process.stderr.write("\n ay remote add <alias>
|
|
90
|
+
process.stderr.write("\n ay remote add <alias> http://<token>@<host>:<port> # add a remote\n ay serve # start server (prints token)\n");
|
|
87
91
|
return 0;
|
|
88
92
|
}
|
|
89
93
|
for (const [alias, cfg] of remotes) {
|
|
@@ -93,10 +97,25 @@ async function cmdRemote(rest) {
|
|
|
93
97
|
return 0;
|
|
94
98
|
}
|
|
95
99
|
if (sub === "add") {
|
|
96
|
-
const [, alias,
|
|
97
|
-
if (!alias || !
|
|
98
|
-
process.stderr.write("usage: ay remote add <alias>
|
|
99
|
-
process.stderr.write(" example: ay remote add work-mac http://192.168.1.5:7432
|
|
100
|
+
const [, alias, rawUrl] = rest;
|
|
101
|
+
if (!alias || !rawUrl) {
|
|
102
|
+
process.stderr.write("usage: ay remote add <alias> http://<token>@<host>:<port>\n");
|
|
103
|
+
process.stderr.write(" example: ay remote add work-mac http://mytoken123@192.168.1.5:7432\n");
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
let url, token;
|
|
107
|
+
try {
|
|
108
|
+
const parsed = new URL(rawUrl);
|
|
109
|
+
token = parsed.username;
|
|
110
|
+
parsed.username = "";
|
|
111
|
+
parsed.password = "";
|
|
112
|
+
url = parsed.toString().replace(/\/$/, "");
|
|
113
|
+
} catch {
|
|
114
|
+
process.stderr.write(`ay remote add: invalid URL '${rawUrl}'\n`);
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
if (!token) {
|
|
118
|
+
process.stderr.write(`ay remote add: no token in URL — expected http://<token>@<host>:<port>\n`);
|
|
100
119
|
return 1;
|
|
101
120
|
}
|
|
102
121
|
await writeRemoteAlias(alias, {
|
|
@@ -122,10 +141,10 @@ async function cmdRemote(rest) {
|
|
|
122
141
|
return 0;
|
|
123
142
|
}
|
|
124
143
|
process.stderr.write(`ay remote: unknown subcommand '${sub}'\n`);
|
|
125
|
-
process.stderr.write(" ay remote ls
|
|
144
|
+
process.stderr.write(" ay remote ls # list configured remotes\n ay remote add <alias> http://<token>@<host>:<port> # add a remote\n ay remote rm <alias> # remove a remote\n");
|
|
126
145
|
return 1;
|
|
127
146
|
}
|
|
128
147
|
|
|
129
148
|
//#endregion
|
|
130
149
|
export { resolveRemoteSpec as a, readRemotes as i, deleteRemoteAlias as n, writeRemoteAlias as o, parseDirectRemoteSpec as r, cmdRemote as t };
|
|
131
|
-
//# sourceMappingURL=remotes-
|
|
150
|
+
//# sourceMappingURL=remotes-Bjp2GYPz.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-
|
|
1
|
+
import { a as resolveRemoteSpec, i as readRemotes, n as deleteRemoteAlias, o as writeRemoteAlias, r as parseDirectRemoteSpec, t as cmdRemote } from "./remotes-Bjp2GYPz.js";
|
|
2
2
|
|
|
3
3
|
export { cmdRemote };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./logger-B9h0djqx.js";
|
|
2
2
|
import "./globalPidIndex-Cr-g75QF.js";
|
|
3
|
-
import "./remotes-
|
|
4
|
-
import {
|
|
3
|
+
import "./remotes-Bjp2GYPz.js";
|
|
4
|
+
import { a as listRecords, c as renderRawLog, d as snapshotStatus, f as writeToIpc, l as resolveOne, n as controlCodeFromName, s as readNotes } from "./subcommands-DxafpA6_.js";
|
|
5
5
|
import yargs from "yargs";
|
|
6
6
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
7
7
|
import { homedir } from "os";
|
|
@@ -72,7 +72,8 @@ async function cmdServeDaemon(sub, args) {
|
|
|
72
72
|
if (code === 0) {
|
|
73
73
|
process.stdout.write(`\ninstalled '${DAEMON_NAME}' as a daemon via oxmgr\n`);
|
|
74
74
|
process.stdout.write(`token: ${token}\n\n`);
|
|
75
|
-
process.stdout.write(` ay ls
|
|
75
|
+
process.stdout.write(` ay ls ${token}@<host>:${DEFAULT_PORT}\n`);
|
|
76
|
+
process.stdout.write(` ay remote add <alias> http://${token}@<host>:${DEFAULT_PORT}\n`);
|
|
76
77
|
process.stdout.write(` ay serve logs # view server logs\n`);
|
|
77
78
|
process.stdout.write(` ay serve uninstall # remove daemon\n`);
|
|
78
79
|
}
|
|
@@ -100,6 +101,15 @@ async function cmdServeDaemon(sub, args) {
|
|
|
100
101
|
return 1;
|
|
101
102
|
}
|
|
102
103
|
async function cmdServe(rest) {
|
|
104
|
+
if (rest.includes("-h") || rest.includes("--help")) {
|
|
105
|
+
process.stdout.write(`Usage: ay serve [options]
|
|
106
|
+
|
|
107
|
+
Start an HTTP API server so remote machines can list/tail/send agents.
|
|
108
|
+
|
|
109
|
+
Options:
|
|
110
|
+
--port N Port to listen on (default: ${DEFAULT_PORT})\n --host HOST Interface to bind (default: 127.0.0.1; use 0.0.0.0 to expose)\n --token TOKEN Auth token (auto-generated and saved if omitted)\n --tls-cert FILE TLS certificate PEM\n --tls-key FILE TLS private key PEM\n\nSubcommands:\n ay serve install install as background daemon via oxmgr\n ay serve uninstall remove daemon\n ay serve logs view daemon logs\n\nOnce running, connect from another machine:\n ay ls <token>@<host>:${DEFAULT_PORT}\n ay remote add <alias> http://<token>@<host>:${DEFAULT_PORT}\n`);
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
103
113
|
const sub = rest[0];
|
|
104
114
|
if (sub === "install" || sub === "uninstall" || sub === "logs") return cmdServeDaemon(sub, rest.slice(1));
|
|
105
115
|
const argv = await yargs(rest).usage("Usage: ay serve [options]").option("port", {
|
|
@@ -283,6 +293,8 @@ async function cmdServe(rest) {
|
|
|
283
293
|
process.stdout.write(` ay ls ${token}@<host>:${port}\n`);
|
|
284
294
|
process.stdout.write(` ay tail ${token}@<host>:${port}:<keyword>\n`);
|
|
285
295
|
process.stdout.write(` ay send ${token}@<host>:${port}:<keyword> "message"\n\n`);
|
|
296
|
+
process.stdout.write(`save as alias:\n`);
|
|
297
|
+
process.stdout.write(` ay remote add <alias> ${scheme}://${token}@<host>:${port}\n\n`);
|
|
286
298
|
if (!useHttps) process.stdout.write("for HTTPS: ay serve --tls-cert cert.pem --tls-key key.pem\n openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'\n\n");
|
|
287
299
|
process.stdout.write(`(Ctrl-C to stop)\n`);
|
|
288
300
|
await new Promise((resolve) => {
|
|
@@ -300,4 +312,4 @@ async function cmdServe(rest) {
|
|
|
300
312
|
|
|
301
313
|
//#endregion
|
|
302
314
|
export { cmdServe };
|
|
303
|
-
//# sourceMappingURL=serve-
|
|
315
|
+
//# sourceMappingURL=serve-Bk36c6qq.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import "./logger-B9h0djqx.js";
|
|
2
|
+
import "./globalPidIndex-Cr-g75QF.js";
|
|
3
|
+
import "./remotes-Bjp2GYPz.js";
|
|
4
|
+
import { a as listRecords, c as renderRawLog, d as snapshotStatus, f as writeToIpc, i as isSubcommand, l as resolveOne, n as controlCodeFromName, o as matchKeyword, r as isPidAlive, s as readNotes, t as cmdHelp, u as runSubcommand } from "./subcommands-DxafpA6_.js";
|
|
5
|
+
|
|
6
|
+
export { cmdHelp, isSubcommand, runSubcommand };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
|
|
2
|
-
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-
|
|
2
|
+
import { a as resolveRemoteSpec, i as readRemotes } from "./remotes-Bjp2GYPz.js";
|
|
3
3
|
import ms from "ms";
|
|
4
4
|
import yargs from "yargs";
|
|
5
5
|
import { appendFile, mkdir, open, readFile, stat, writeFile } from "fs/promises";
|
|
@@ -129,7 +129,8 @@ const SUBCOMMANDS = new Set([
|
|
|
129
129
|
"restart",
|
|
130
130
|
"note",
|
|
131
131
|
"serve",
|
|
132
|
-
"remote"
|
|
132
|
+
"remote",
|
|
133
|
+
"help"
|
|
133
134
|
]);
|
|
134
135
|
const IDLE_THRESHOLD_MS = 60 * 1e3;
|
|
135
136
|
function isSubcommand(name) {
|
|
@@ -157,13 +158,14 @@ async function runSubcommand(argv) {
|
|
|
157
158
|
case "restart": return await cmdRestart(rest);
|
|
158
159
|
case "note": return await cmdNote(rest);
|
|
159
160
|
case "serve": {
|
|
160
|
-
const { cmdServe } = await import("./serve-
|
|
161
|
+
const { cmdServe } = await import("./serve-Bk36c6qq.js");
|
|
161
162
|
return cmdServe(rest);
|
|
162
163
|
}
|
|
163
164
|
case "remote": {
|
|
164
|
-
const { cmdRemote } = await import("./remotes-
|
|
165
|
+
const { cmdRemote } = await import("./remotes-oNI1fR7_.js");
|
|
165
166
|
return cmdRemote(rest);
|
|
166
167
|
}
|
|
168
|
+
case "help": return cmdHelp();
|
|
167
169
|
default: return null;
|
|
168
170
|
}
|
|
169
171
|
} catch (err) {
|
|
@@ -172,6 +174,10 @@ async function runSubcommand(argv) {
|
|
|
172
174
|
return 1;
|
|
173
175
|
}
|
|
174
176
|
}
|
|
177
|
+
function cmdHelp() {
|
|
178
|
+
process.stdout.write("ay - agent-yes CLI\n\nManagement:\n ay ls [keyword] list running agents\n ay tail [-f] <keyword> stream output (Ctrl-C to stop)\n ay cat <keyword> full log\n ay head <keyword> first N lines\n ay send <keyword> <msg> send a message\n ay status <keyword> agent status snapshot\n\nRemote:\n ay serve [--port N] start HTTP API server (prints token)\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 in ./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");
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
175
181
|
function matchKeyword(record, keyword) {
|
|
176
182
|
if (!keyword) return true;
|
|
177
183
|
const kw = keyword.toLowerCase();
|
|
@@ -201,12 +207,84 @@ function isPidAlive(pid) {
|
|
|
201
207
|
return false;
|
|
202
208
|
}
|
|
203
209
|
}
|
|
210
|
+
async function pickInteractive(matches) {
|
|
211
|
+
const list = matches.slice(0, 10);
|
|
212
|
+
let sel = 0;
|
|
213
|
+
const render = () => {
|
|
214
|
+
for (let i = 0; i < list.length; i++) {
|
|
215
|
+
const r = list[i];
|
|
216
|
+
const marker = i === sel ? "\x1B[36m>\x1B[0m" : " ";
|
|
217
|
+
process.stderr.write(`${marker} ${r.pid} ${r.cli} ${r.cwd}\n`);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
process.stderr.write(`Multiple matches — select with ↑↓ Enter (or type 1-${list.length}):\n`);
|
|
221
|
+
render();
|
|
222
|
+
return new Promise((resolve) => {
|
|
223
|
+
process.stdin.setRawMode(true);
|
|
224
|
+
process.stdin.resume();
|
|
225
|
+
process.stdin.setEncoding("utf8");
|
|
226
|
+
const redraw = () => {
|
|
227
|
+
process.stderr.write(`\x1b[${list.length}A\x1b[0J`);
|
|
228
|
+
render();
|
|
229
|
+
};
|
|
230
|
+
const cleanup = () => {
|
|
231
|
+
process.stdin.off("data", onData);
|
|
232
|
+
try {
|
|
233
|
+
process.stdin.setRawMode(false);
|
|
234
|
+
} catch {}
|
|
235
|
+
process.stdin.pause();
|
|
236
|
+
};
|
|
237
|
+
let buf = "";
|
|
238
|
+
const onData = (chunk) => {
|
|
239
|
+
buf += chunk;
|
|
240
|
+
while (buf.length > 0) if (buf[0] === "\x1B") {
|
|
241
|
+
if (buf.length < 3) break;
|
|
242
|
+
const seq = buf.slice(0, 3);
|
|
243
|
+
buf = buf.slice(3);
|
|
244
|
+
if (seq === "\x1B[A") {
|
|
245
|
+
sel = Math.max(0, sel - 1);
|
|
246
|
+
redraw();
|
|
247
|
+
} else if (seq === "\x1B[B") {
|
|
248
|
+
sel = Math.min(list.length - 1, sel + 1);
|
|
249
|
+
redraw();
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
const key = buf[0];
|
|
253
|
+
buf = buf.slice(1);
|
|
254
|
+
if (key === "") {
|
|
255
|
+
cleanup();
|
|
256
|
+
process.stderr.write("\n");
|
|
257
|
+
resolve(null);
|
|
258
|
+
return;
|
|
259
|
+
} else if (key === "\r" || key === "\n") {
|
|
260
|
+
cleanup();
|
|
261
|
+
process.stderr.write("\n");
|
|
262
|
+
resolve(list[sel]);
|
|
263
|
+
return;
|
|
264
|
+
} else if (key >= "1" && key <= String(list.length)) {
|
|
265
|
+
sel = parseInt(key, 10) - 1;
|
|
266
|
+
redraw();
|
|
267
|
+
cleanup();
|
|
268
|
+
process.stderr.write("\n");
|
|
269
|
+
resolve(list[sel]);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
process.stdin.on("data", onData);
|
|
275
|
+
});
|
|
276
|
+
}
|
|
204
277
|
async function resolveOne(keyword, opts) {
|
|
205
278
|
if (!keyword) throw new Error("keyword required (pid, cwd substring, cli name, or prompt substring)");
|
|
206
279
|
const matches = await listRecords(keyword, opts);
|
|
207
280
|
if (matches.length === 0) throw new Error(`no agent matched "${keyword}"`);
|
|
208
281
|
if (matches.length === 1) return matches[0];
|
|
209
282
|
if (opts.latest) return matches[0];
|
|
283
|
+
if (process.stderr.isTTY && process.stdin.isTTY) {
|
|
284
|
+
const chosen = await pickInteractive(matches);
|
|
285
|
+
if (chosen) return chosen;
|
|
286
|
+
throw new Error("no agent selected");
|
|
287
|
+
}
|
|
210
288
|
const lines = matches.slice(0, 10).map((r) => ` ${r.pid} ${r.cli} ${r.cwd}`).join("\n");
|
|
211
289
|
throw new Error(`keyword "${keyword}" matched ${matches.length} agents — disambiguate by pid or pass --latest:\n${lines}`);
|
|
212
290
|
}
|
|
@@ -1108,5 +1186,5 @@ async function cmdStatus(rest) {
|
|
|
1108
1186
|
}
|
|
1109
1187
|
|
|
1110
1188
|
//#endregion
|
|
1111
|
-
export {
|
|
1112
|
-
//# sourceMappingURL=subcommands-
|
|
1189
|
+
export { listRecords as a, renderRawLog as c, snapshotStatus as d, writeToIpc as f, isSubcommand as i, resolveOne as l, controlCodeFromName as n, matchKeyword as o, isPidAlive as r, readNotes as s, cmdHelp as t, runSubcommand as u };
|
|
1190
|
+
//# sourceMappingURL=subcommands-DxafpA6_.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as logger, t as addTransport } from "./logger-B9h0djqx.js";
|
|
2
|
-
import { r as getInstalledPackage } from "./versionChecker
|
|
2
|
+
import { r as getInstalledPackage } from "./versionChecker-DK6U9T31.js";
|
|
3
3
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-C22d9SRJ.js";
|
|
4
4
|
import { t as PidStore } from "./pidStore-C1JXxoPi.js";
|
|
5
5
|
import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
|
|
@@ -1693,4 +1693,4 @@ function sleep(ms) {
|
|
|
1693
1693
|
|
|
1694
1694
|
//#endregion
|
|
1695
1695
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1696
|
-
//# sourceMappingURL=ts-
|
|
1696
|
+
//# sourceMappingURL=ts-DGhJYVFb.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.88.1";
|
|
11
11
|
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ts/versionChecker.ts
|
|
@@ -221,4 +221,4 @@ async function displayVersion() {
|
|
|
221
221
|
|
|
222
222
|
//#endregion
|
|
223
223
|
export { versionString as i, displayVersion as n, getInstalledPackage as r, checkAndAutoUpdate as t };
|
|
224
|
-
//# sourceMappingURL=versionChecker
|
|
224
|
+
//# sourceMappingURL=versionChecker-DK6U9T31.js.map
|
package/package.json
CHANGED
package/ts/cli.ts
CHANGED
|
@@ -20,8 +20,15 @@ import { buildRustArgs } from "./buildRustArgs.ts";
|
|
|
20
20
|
// agent-spawn machinery (and the --rust dispatch) and operate on the global
|
|
21
21
|
// pid index instead. Must run before checkAndAutoUpdate / yargs / Rust spawn.
|
|
22
22
|
{
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const rawArg = process.argv[2];
|
|
24
|
+
// Intercept bare -h/--help so we show TS subcommands, not just Rust agent-runner options.
|
|
25
|
+
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
26
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands.ts");
|
|
27
|
+
if (isHelpFlag && process.argv.length === 3) {
|
|
28
|
+
cmdHelp();
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if (isSubcommand(rawArg)) {
|
|
25
32
|
const code = await runSubcommand(process.argv);
|
|
26
33
|
process.exit(code ?? 0);
|
|
27
34
|
}
|
package/ts/remotes.ts
CHANGED
|
@@ -102,14 +102,30 @@ export async function resolveRemoteSpec(spec: string): Promise<ResolvedRemote |
|
|
|
102
102
|
export async function cmdRemote(rest: string[]): Promise<number> {
|
|
103
103
|
const sub = rest[0];
|
|
104
104
|
|
|
105
|
+
if (sub === "-h" || sub === "--help") {
|
|
106
|
+
process.stdout.write(
|
|
107
|
+
`Usage: ay remote <subcommand>\n\n` +
|
|
108
|
+
`Manage saved remote server aliases.\n\n` +
|
|
109
|
+
`Subcommands:\n` +
|
|
110
|
+
` ay remote ls list configured remotes\n` +
|
|
111
|
+
` ay remote add <alias> http://<token>@<host>:<port> add a remote\n` +
|
|
112
|
+
` ay remote rm <alias> remove a remote\n\n` +
|
|
113
|
+
`Once added, use the alias anywhere a keyword is accepted:\n` +
|
|
114
|
+
` ay ls <alias>\n` +
|
|
115
|
+
` ay tail <alias>:<keyword>\n` +
|
|
116
|
+
` ay send <alias>:<keyword> "message"\n`,
|
|
117
|
+
);
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
105
121
|
if (!sub || sub === "ls" || sub === "list") {
|
|
106
122
|
const remotes = await readRemotes();
|
|
107
123
|
if (remotes.size === 0) {
|
|
108
124
|
process.stdout.write("no remotes configured\n");
|
|
109
125
|
process.stderr.write(
|
|
110
126
|
"\n" +
|
|
111
|
-
" ay remote add <alias>
|
|
112
|
-
" ay serve
|
|
127
|
+
" ay remote add <alias> http://<token>@<host>:<port> # add a remote\n" +
|
|
128
|
+
" ay serve # start server (prints token)\n",
|
|
113
129
|
);
|
|
114
130
|
return 0;
|
|
115
131
|
}
|
|
@@ -121,11 +137,28 @@ export async function cmdRemote(rest: string[]): Promise<number> {
|
|
|
121
137
|
}
|
|
122
138
|
|
|
123
139
|
if (sub === "add") {
|
|
124
|
-
const [, alias,
|
|
125
|
-
if (!alias || !
|
|
126
|
-
process.stderr.write("usage: ay remote add <alias>
|
|
140
|
+
const [, alias, rawUrl] = rest;
|
|
141
|
+
if (!alias || !rawUrl) {
|
|
142
|
+
process.stderr.write("usage: ay remote add <alias> http://<token>@<host>:<port>\n");
|
|
143
|
+
process.stderr.write(
|
|
144
|
+
" example: ay remote add work-mac http://mytoken123@192.168.1.5:7432\n",
|
|
145
|
+
);
|
|
146
|
+
return 1;
|
|
147
|
+
}
|
|
148
|
+
let url: string, token: string;
|
|
149
|
+
try {
|
|
150
|
+
const parsed = new URL(rawUrl);
|
|
151
|
+
token = parsed.username;
|
|
152
|
+
parsed.username = "";
|
|
153
|
+
parsed.password = "";
|
|
154
|
+
url = parsed.toString().replace(/\/$/, "");
|
|
155
|
+
} catch {
|
|
156
|
+
process.stderr.write(`ay remote add: invalid URL '${rawUrl}'\n`);
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
if (!token) {
|
|
127
160
|
process.stderr.write(
|
|
128
|
-
|
|
161
|
+
`ay remote add: no token in URL — expected http://<token>@<host>:<port>\n`,
|
|
129
162
|
);
|
|
130
163
|
return 1;
|
|
131
164
|
}
|
|
@@ -153,9 +186,9 @@ export async function cmdRemote(rest: string[]): Promise<number> {
|
|
|
153
186
|
|
|
154
187
|
process.stderr.write(`ay remote: unknown subcommand '${sub}'\n`);
|
|
155
188
|
process.stderr.write(
|
|
156
|
-
" ay remote ls
|
|
157
|
-
" ay remote add <alias>
|
|
158
|
-
" ay remote rm <alias>
|
|
189
|
+
" ay remote ls # list configured remotes\n" +
|
|
190
|
+
" ay remote add <alias> http://<token>@<host>:<port> # add a remote\n" +
|
|
191
|
+
" ay remote rm <alias> # remove a remote\n",
|
|
159
192
|
);
|
|
160
193
|
return 1;
|
|
161
194
|
}
|
package/ts/serve.ts
CHANGED
|
@@ -85,7 +85,8 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
85
85
|
if (code === 0) {
|
|
86
86
|
process.stdout.write(`\ninstalled '${DAEMON_NAME}' as a daemon via oxmgr\n`);
|
|
87
87
|
process.stdout.write(`token: ${token}\n\n`);
|
|
88
|
-
process.stdout.write(` ay ls
|
|
88
|
+
process.stdout.write(` ay ls ${token}@<host>:${DEFAULT_PORT}\n`);
|
|
89
|
+
process.stdout.write(` ay remote add <alias> http://${token}@<host>:${DEFAULT_PORT}\n`);
|
|
89
90
|
process.stdout.write(` ay serve logs # view server logs\n`);
|
|
90
91
|
process.stdout.write(` ay serve uninstall # remove daemon\n`);
|
|
91
92
|
}
|
|
@@ -114,6 +115,27 @@ async function cmdServeDaemon(sub: string, args: string[]): Promise<number> {
|
|
|
114
115
|
// ---------------------------------------------------------------------------
|
|
115
116
|
|
|
116
117
|
export async function cmdServe(rest: string[]): Promise<number> {
|
|
118
|
+
if (rest.includes("-h") || rest.includes("--help")) {
|
|
119
|
+
process.stdout.write(
|
|
120
|
+
`Usage: ay serve [options]\n\n` +
|
|
121
|
+
`Start an HTTP API server so remote machines can list/tail/send agents.\n\n` +
|
|
122
|
+
`Options:\n` +
|
|
123
|
+
` --port N Port to listen on (default: ${DEFAULT_PORT})\n` +
|
|
124
|
+
` --host HOST Interface to bind (default: 127.0.0.1; use 0.0.0.0 to expose)\n` +
|
|
125
|
+
` --token TOKEN Auth token (auto-generated and saved if omitted)\n` +
|
|
126
|
+
` --tls-cert FILE TLS certificate PEM\n` +
|
|
127
|
+
` --tls-key FILE TLS private key PEM\n\n` +
|
|
128
|
+
`Subcommands:\n` +
|
|
129
|
+
` ay serve install install as background daemon via oxmgr\n` +
|
|
130
|
+
` ay serve uninstall remove daemon\n` +
|
|
131
|
+
` ay serve logs view daemon logs\n\n` +
|
|
132
|
+
`Once running, connect from another machine:\n` +
|
|
133
|
+
` ay ls <token>@<host>:${DEFAULT_PORT}\n` +
|
|
134
|
+
` ay remote add <alias> http://<token>@<host>:${DEFAULT_PORT}\n`,
|
|
135
|
+
);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
117
139
|
// Daemon subcommands
|
|
118
140
|
const sub = rest[0];
|
|
119
141
|
if (sub === "install" || sub === "uninstall" || sub === "logs") {
|
|
@@ -350,6 +372,8 @@ export async function cmdServe(rest: string[]): Promise<number> {
|
|
|
350
372
|
process.stdout.write(` ay ls ${token}@<host>:${port}\n`);
|
|
351
373
|
process.stdout.write(` ay tail ${token}@<host>:${port}:<keyword>\n`);
|
|
352
374
|
process.stdout.write(` ay send ${token}@<host>:${port}:<keyword> "message"\n\n`);
|
|
375
|
+
process.stdout.write(`save as alias:\n`);
|
|
376
|
+
process.stdout.write(` ay remote add <alias> ${scheme}://${token}@<host>:${port}\n\n`);
|
|
353
377
|
if (!useHttps) {
|
|
354
378
|
process.stdout.write(
|
|
355
379
|
`for HTTPS: ay serve --tls-cert cert.pem --tls-key key.pem\n` +
|
package/ts/subcommands.ts
CHANGED
|
@@ -140,6 +140,7 @@ const SUBCOMMANDS = new Set([
|
|
|
140
140
|
"note",
|
|
141
141
|
"serve",
|
|
142
142
|
"remote",
|
|
143
|
+
"help",
|
|
143
144
|
]);
|
|
144
145
|
|
|
145
146
|
const IDLE_THRESHOLD_MS = 60 * 1000;
|
|
@@ -187,6 +188,8 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
187
188
|
const { cmdRemote } = await import("./remotes.ts");
|
|
188
189
|
return cmdRemote(rest);
|
|
189
190
|
}
|
|
191
|
+
case "help":
|
|
192
|
+
return cmdHelp();
|
|
190
193
|
default:
|
|
191
194
|
return null;
|
|
192
195
|
}
|
|
@@ -197,6 +200,42 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
197
200
|
}
|
|
198
201
|
}
|
|
199
202
|
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
// ay help
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
export function cmdHelp(): number {
|
|
208
|
+
process.stdout.write(
|
|
209
|
+
`ay - agent-yes CLI\n` +
|
|
210
|
+
`\n` +
|
|
211
|
+
`Management:\n` +
|
|
212
|
+
` ay ls [keyword] list running agents\n` +
|
|
213
|
+
` ay tail [-f] <keyword> stream output (Ctrl-C to stop)\n` +
|
|
214
|
+
` ay cat <keyword> full log\n` +
|
|
215
|
+
` ay head <keyword> first N lines\n` +
|
|
216
|
+
` ay send <keyword> <msg> send a message\n` +
|
|
217
|
+
` ay status <keyword> agent status snapshot\n` +
|
|
218
|
+
`\n` +
|
|
219
|
+
`Remote:\n` +
|
|
220
|
+
` ay serve [--port N] start HTTP API server (prints token)\n` +
|
|
221
|
+
` ay remote add <alias> http://<token>@<host>:<port>\n` +
|
|
222
|
+
` ay remote ls / rm <alias> manage saved remotes\n` +
|
|
223
|
+
` ay ls <token>@<host>:<port> connect inline (no alias needed)\n` +
|
|
224
|
+
` ay send <token>@<host>:<port>:<kw> <msg>\n` +
|
|
225
|
+
`\n` +
|
|
226
|
+
`Run an agent:\n` +
|
|
227
|
+
` ay [claude|codex|gemini|...] [options] -- [prompt]\n` +
|
|
228
|
+
` ay claude -- "fix the bug in auth.ts"\n` +
|
|
229
|
+
` ay claude --help full agent-runner options\n` +
|
|
230
|
+
`\n` +
|
|
231
|
+
`Labs (examples in ./lab/):\n` +
|
|
232
|
+
` local-role-play/ designer + builder on one machine\n` +
|
|
233
|
+
` http-remote/ ay serve remote access demo\n` +
|
|
234
|
+
` p2p-pairing/ libp2p P2P (needs: cargo build --features swarm)\n`,
|
|
235
|
+
);
|
|
236
|
+
return 0;
|
|
237
|
+
}
|
|
238
|
+
|
|
200
239
|
// ---------------------------------------------------------------------------
|
|
201
240
|
// shared helpers
|
|
202
241
|
// ---------------------------------------------------------------------------
|
|
@@ -261,6 +300,88 @@ export function isPidAlive(pid: number): boolean {
|
|
|
261
300
|
}
|
|
262
301
|
}
|
|
263
302
|
|
|
303
|
+
async function pickInteractive(matches: GlobalPidRecord[]): Promise<GlobalPidRecord | null> {
|
|
304
|
+
const list = matches.slice(0, 10);
|
|
305
|
+
let sel = 0;
|
|
306
|
+
|
|
307
|
+
const render = () => {
|
|
308
|
+
for (let i = 0; i < list.length; i++) {
|
|
309
|
+
const r = list[i]!;
|
|
310
|
+
const marker = i === sel ? "\x1b[36m>\x1b[0m" : " ";
|
|
311
|
+
process.stderr.write(`${marker} ${r.pid} ${r.cli} ${r.cwd}\n`);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
process.stderr.write(`Multiple matches — select with ↑↓ Enter (or type 1-${list.length}):\n`);
|
|
316
|
+
render();
|
|
317
|
+
|
|
318
|
+
return new Promise((resolve) => {
|
|
319
|
+
process.stdin.setRawMode(true);
|
|
320
|
+
process.stdin.resume();
|
|
321
|
+
process.stdin.setEncoding("utf8");
|
|
322
|
+
|
|
323
|
+
const redraw = () => {
|
|
324
|
+
process.stderr.write(`\x1b[${list.length}A\x1b[0J`);
|
|
325
|
+
render();
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const cleanup = () => {
|
|
329
|
+
process.stdin.off("data", onData);
|
|
330
|
+
try {
|
|
331
|
+
process.stdin.setRawMode(false);
|
|
332
|
+
} catch {
|
|
333
|
+
/* not a tty */
|
|
334
|
+
}
|
|
335
|
+
process.stdin.pause();
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// Buffer partial escape sequences — arrow keys (\x1b[A/B) can arrive split
|
|
339
|
+
// across multiple data events on some terminals and PTY wrappers.
|
|
340
|
+
let buf = "";
|
|
341
|
+
const onData = (chunk: string) => {
|
|
342
|
+
buf += chunk;
|
|
343
|
+
while (buf.length > 0) {
|
|
344
|
+
if (buf[0] === "\x1b") {
|
|
345
|
+
if (buf.length < 3) break; // wait for rest of sequence
|
|
346
|
+
const seq = buf.slice(0, 3);
|
|
347
|
+
buf = buf.slice(3);
|
|
348
|
+
if (seq === "\x1b[A") {
|
|
349
|
+
sel = Math.max(0, sel - 1);
|
|
350
|
+
redraw();
|
|
351
|
+
} else if (seq === "\x1b[B") {
|
|
352
|
+
sel = Math.min(list.length - 1, sel + 1);
|
|
353
|
+
redraw();
|
|
354
|
+
}
|
|
355
|
+
// ignore other escape sequences
|
|
356
|
+
} else {
|
|
357
|
+
const key = buf[0]!;
|
|
358
|
+
buf = buf.slice(1);
|
|
359
|
+
if (key === "\x03") {
|
|
360
|
+
cleanup();
|
|
361
|
+
process.stderr.write("\n");
|
|
362
|
+
resolve(null);
|
|
363
|
+
return;
|
|
364
|
+
} else if (key === "\r" || key === "\n") {
|
|
365
|
+
cleanup();
|
|
366
|
+
process.stderr.write("\n");
|
|
367
|
+
resolve(list[sel]!);
|
|
368
|
+
return;
|
|
369
|
+
} else if (key >= "1" && key <= String(list.length)) {
|
|
370
|
+
sel = parseInt(key, 10) - 1;
|
|
371
|
+
redraw();
|
|
372
|
+
cleanup();
|
|
373
|
+
process.stderr.write("\n");
|
|
374
|
+
resolve(list[sel]!);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
process.stdin.on("data", onData);
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
264
385
|
export async function resolveOne(
|
|
265
386
|
keyword: string | undefined,
|
|
266
387
|
opts: CommonOpts,
|
|
@@ -274,6 +395,11 @@ export async function resolveOne(
|
|
|
274
395
|
}
|
|
275
396
|
if (matches.length === 1) return matches[0]!;
|
|
276
397
|
if (opts.latest) return matches[0]!; // already sorted newest-first
|
|
398
|
+
if (process.stderr.isTTY && process.stdin.isTTY) {
|
|
399
|
+
const chosen = await pickInteractive(matches);
|
|
400
|
+
if (chosen) return chosen;
|
|
401
|
+
throw new Error("no agent selected");
|
|
402
|
+
}
|
|
277
403
|
const lines = matches
|
|
278
404
|
.slice(0, 10)
|
|
279
405
|
.map((r) => ` ${r.pid} ${r.cli} ${r.cwd}`)
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import "./logger-B9h0djqx.js";
|
|
2
|
-
import "./globalPidIndex-Cr-g75QF.js";
|
|
3
|
-
import "./remotes-CFrho898.js";
|
|
4
|
-
import { a as matchKeyword, c as resolveOne, d as writeToIpc, i as listRecords, l as runSubcommand, n as isPidAlive, o as readNotes, r as isSubcommand, s as renderRawLog, t as controlCodeFromName, u as snapshotStatus } from "./subcommands-BltyYaEs.js";
|
|
5
|
-
|
|
6
|
-
export { isSubcommand, runSubcommand };
|