claude-yes 1.78.0 → 1.79.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-eyTIFAJl.js → SUPPORTED_CLIS-BcN2aqoM.js} +3 -3
- package/dist/cli.js +3 -3
- package/dist/index.js +2 -2
- package/dist/{subcommands-Ctgm4cEn.js → subcommands-DQY6uKK-.js} +62 -14
- package/dist/{ts-B2M_r506.js → ts-DCMrcZpL.js} +2 -2
- package/dist/{versionChecker-CoV20GQ7.js → versionChecker-CEkbd2dm.js} +2 -2
- package/package.json +1 -1
- package/ts/subcommands.spec.ts +1 -1
- package/ts/subcommands.ts +79 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-DCMrcZpL.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CEkbd2dm.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-BcN2aqoM.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-CEkbd2dm.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
@@ -475,7 +475,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
{
|
|
478
|
-
const { isSubcommand, runSubcommand } = await import("./subcommands-
|
|
478
|
+
const { isSubcommand, runSubcommand } = await import("./subcommands-DQY6uKK-.js");
|
|
479
479
|
if (isSubcommand(process.argv[2])) {
|
|
480
480
|
const code = await runSubcommand(process.argv);
|
|
481
481
|
process.exit(code ?? 0);
|
|
@@ -504,7 +504,7 @@ if (config.useRust) {
|
|
|
504
504
|
}
|
|
505
505
|
}
|
|
506
506
|
if (rustBinary) {
|
|
507
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
507
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-BcN2aqoM.js");
|
|
508
508
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
509
509
|
if (config.verbose) {
|
|
510
510
|
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-DCMrcZpL.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
3
|
+
import "./versionChecker-CEkbd2dm.js";
|
|
4
4
|
import "./pidStore-C1JXxoPi.js";
|
|
5
5
|
import "./globalPidIndex-Cr-g75QF.js";
|
|
6
6
|
|
|
@@ -81,7 +81,8 @@ const SUBCOMMANDS = new Set([
|
|
|
81
81
|
"cat",
|
|
82
82
|
"tail",
|
|
83
83
|
"head",
|
|
84
|
-
"send"
|
|
84
|
+
"send",
|
|
85
|
+
"restart"
|
|
85
86
|
]);
|
|
86
87
|
function isSubcommand(name) {
|
|
87
88
|
return !!name && SUBCOMMANDS.has(name);
|
|
@@ -104,6 +105,7 @@ async function runSubcommand(argv) {
|
|
|
104
105
|
case "tail": return await cmdRead(rest, { mode: "tail" });
|
|
105
106
|
case "head": return await cmdRead(rest, { mode: "head" });
|
|
106
107
|
case "send": return await cmdSend(rest);
|
|
108
|
+
case "restart": return await cmdRestart(rest);
|
|
107
109
|
default: return null;
|
|
108
110
|
}
|
|
109
111
|
} catch (err) {
|
|
@@ -125,6 +127,7 @@ function parseArgs(rest) {
|
|
|
125
127
|
const next = rest[i + 1];
|
|
126
128
|
if ([
|
|
127
129
|
"all",
|
|
130
|
+
"active",
|
|
128
131
|
"json",
|
|
129
132
|
"latest"
|
|
130
133
|
].includes(key) || !next || next.startsWith("-")) flags[key] = true;
|
|
@@ -147,6 +150,7 @@ function parseArgs(rest) {
|
|
|
147
150
|
function commonOpts(flags) {
|
|
148
151
|
return {
|
|
149
152
|
all: !!flags.all,
|
|
153
|
+
active: !!flags.active,
|
|
150
154
|
cwdScope: typeof flags.cwd === "string" ? path.resolve(flags.cwd) : flags.cwd === true ? process.cwd() : null,
|
|
151
155
|
latest: !!flags.latest,
|
|
152
156
|
json: !!flags.json
|
|
@@ -163,7 +167,8 @@ function matchKeyword(record, keyword) {
|
|
|
163
167
|
}
|
|
164
168
|
async function listRecords(keyword, opts) {
|
|
165
169
|
let records = mergeRecords(await readLocalTsPids(process.cwd()), opts.cwdScope ? await readLocalTsPids(opts.cwdScope) : [], await readGlobalPids());
|
|
166
|
-
if (!opts.all) records = records.filter((r) => r.status !== "exited"
|
|
170
|
+
if (!opts.all) records = records.filter((r) => r.status !== "exited");
|
|
171
|
+
if (opts.active) records = records.filter((r) => isPidAlive(r.pid));
|
|
167
172
|
if (opts.cwdScope) {
|
|
168
173
|
const scope = opts.cwdScope;
|
|
169
174
|
records = records.filter((r) => r.cwd === scope || r.cwd.startsWith(scope + path.sep));
|
|
@@ -183,7 +188,7 @@ function isPidAlive(pid) {
|
|
|
183
188
|
async function resolveOne(keyword, opts) {
|
|
184
189
|
if (!keyword) throw new Error("keyword required (pid, cwd substring, cli name, or prompt substring)");
|
|
185
190
|
const matches = await listRecords(keyword, opts);
|
|
186
|
-
if (matches.length === 0) throw new Error(`no
|
|
191
|
+
if (matches.length === 0) throw new Error(`no agent matched "${keyword}"`);
|
|
187
192
|
if (matches.length === 1) return matches[0];
|
|
188
193
|
if (opts.latest) return matches[0];
|
|
189
194
|
const lines = matches.slice(0, 10).map((r) => ` ${r.pid} ${r.cli} ${r.cwd}`).join("\n");
|
|
@@ -215,18 +220,20 @@ async function cmdLs(rest) {
|
|
|
215
220
|
const promptBudget = Math.max(20, termWidth - fixedWidth - 1);
|
|
216
221
|
const IDLE_THRESHOLD_MS = 60 * 1e3;
|
|
217
222
|
const rows = await Promise.all(records.map(async (r) => {
|
|
218
|
-
let displayStatus
|
|
219
|
-
if (r.
|
|
223
|
+
let displayStatus;
|
|
224
|
+
if (!isPidAlive(r.pid)) displayStatus = "stopped";
|
|
225
|
+
else if (r.log_file) {
|
|
220
226
|
const mtime = await stat(r.log_file).then((s) => s.mtimeMs).catch(() => null);
|
|
221
|
-
|
|
222
|
-
}
|
|
227
|
+
displayStatus = mtime !== null && Date.now() - mtime > IDLE_THRESHOLD_MS ? "idle" : "active";
|
|
228
|
+
} else displayStatus = "active";
|
|
223
229
|
return {
|
|
224
230
|
pid: String(r.pid),
|
|
225
231
|
cli: r.cli,
|
|
226
232
|
status: displayStatus,
|
|
227
233
|
age: humanizeAge(Date.now() - r.started_at),
|
|
228
234
|
cwd: shortenPath(r.cwd),
|
|
229
|
-
prompt: truncate(r.prompt ?? "", promptBudget)
|
|
235
|
+
prompt: truncate(r.prompt ?? "", promptBudget),
|
|
236
|
+
_alive: displayStatus !== "stopped"
|
|
230
237
|
};
|
|
231
238
|
}));
|
|
232
239
|
const header = [
|
|
@@ -246,9 +253,18 @@ async function cmdLs(rest) {
|
|
|
246
253
|
r.cwd.padEnd(widths.cwd),
|
|
247
254
|
r.prompt
|
|
248
255
|
].join(" ") + "\n");
|
|
249
|
-
if (!opts.json &&
|
|
250
|
-
const
|
|
251
|
-
|
|
256
|
+
if (!opts.json && rows.length > 0) {
|
|
257
|
+
const alive = rows.find((r) => r._alive);
|
|
258
|
+
const stopped = rows.find((r) => !r._alive);
|
|
259
|
+
const hints = ["\n"];
|
|
260
|
+
if (alive) {
|
|
261
|
+
hints.push(` cy tail ${alive.pid} # view latest output\n`);
|
|
262
|
+
hints.push(` cy send ${alive.pid} "next: ..." # send a prompt\n`);
|
|
263
|
+
hints.push(` cy send ${alive.pid} "" --code=ctrl-c # interrupt\n`);
|
|
264
|
+
}
|
|
265
|
+
if (stopped) hints.push(` cy restart ${stopped.pid} # restart stopped agent\n`);
|
|
266
|
+
if (!alive && !stopped) hints.push(` cy ls --all # show exited agents\n`);
|
|
267
|
+
process.stderr.write(hints.join(""));
|
|
252
268
|
}
|
|
253
269
|
return 0;
|
|
254
270
|
}
|
|
@@ -344,8 +360,13 @@ async function cmdSend(rest) {
|
|
|
344
360
|
const record = await resolveOne(keyword, opts);
|
|
345
361
|
const fifoPath = record.fifo_file;
|
|
346
362
|
if (!fifoPath) throw new Error(`pid ${record.pid}: no fifo_file recorded — agent was not started with --stdpush (or was spawned by Rust which doesn't yet support FIFO IPC; see ROADMAP item 10)`);
|
|
347
|
-
const
|
|
348
|
-
|
|
363
|
+
const body = message ?? "";
|
|
364
|
+
if (body && trailing) {
|
|
365
|
+
await writeToIpc(fifoPath, body);
|
|
366
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
367
|
+
await writeToIpc(fifoPath, trailing);
|
|
368
|
+
} else await writeToIpc(fifoPath, body + trailing);
|
|
369
|
+
const payload = body + trailing;
|
|
349
370
|
process.stdout.write(`sent to pid ${record.pid} (${record.cli}): ${truncate(payload, 80)}\n`);
|
|
350
371
|
process.stderr.write(`\n cy tail ${record.pid} # watch output\n cy ls # list all agents\n`);
|
|
351
372
|
return 0;
|
|
@@ -402,7 +423,34 @@ async function writeToIpc(ipcPath, payload) {
|
|
|
402
423
|
}
|
|
403
424
|
}
|
|
404
425
|
}
|
|
426
|
+
async function cmdRestart(rest) {
|
|
427
|
+
const { flags, positional } = parseArgs(rest);
|
|
428
|
+
const opts = {
|
|
429
|
+
...commonOpts(flags),
|
|
430
|
+
all: true
|
|
431
|
+
};
|
|
432
|
+
const keyword = positional[0];
|
|
433
|
+
const record = await resolveOne(keyword, opts);
|
|
434
|
+
if (isPidAlive(record.pid)) {
|
|
435
|
+
process.stderr.write(`pid ${record.pid} is still running — stop it first or use cy send\n`);
|
|
436
|
+
return 1;
|
|
437
|
+
}
|
|
438
|
+
const args = ["--cli=" + record.cli];
|
|
439
|
+
if (record.prompt) args.push(record.prompt);
|
|
440
|
+
const proc = Bun.spawn(["agent-yes", ...args], {
|
|
441
|
+
cwd: record.cwd,
|
|
442
|
+
detached: true,
|
|
443
|
+
stdio: [
|
|
444
|
+
"ignore",
|
|
445
|
+
"ignore",
|
|
446
|
+
"ignore"
|
|
447
|
+
]
|
|
448
|
+
});
|
|
449
|
+
process.stdout.write(`restarted ${record.cli} in ${shortenPath(record.cwd)} (new pid: ${proc.pid})\n`);
|
|
450
|
+
process.stderr.write(`\n cy tail ${proc.pid} # watch output\n cy ls # list all agents\n`);
|
|
451
|
+
return 0;
|
|
452
|
+
}
|
|
405
453
|
|
|
406
454
|
//#endregion
|
|
407
455
|
export { isSubcommand, runSubcommand };
|
|
408
|
-
//# sourceMappingURL=subcommands-
|
|
456
|
+
//# sourceMappingURL=subcommands-DQY6uKK-.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-CEkbd2dm.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 { arch, platform } from "process";
|
|
@@ -1679,4 +1679,4 @@ function sleep(ms) {
|
|
|
1679
1679
|
|
|
1680
1680
|
//#endregion
|
|
1681
1681
|
export { removeControlCharacters as a, AgentContext as i, agentYes as n, config as r, CLIS_CONFIG as t };
|
|
1682
|
-
//# sourceMappingURL=ts-
|
|
1682
|
+
//# sourceMappingURL=ts-DCMrcZpL.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.79.0";
|
|
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-CEkbd2dm.js.map
|
package/package.json
CHANGED
package/ts/subcommands.spec.ts
CHANGED
|
@@ -206,7 +206,7 @@ describe("subcommands.runSubcommand routing", () => {
|
|
|
206
206
|
try {
|
|
207
207
|
const code = await runSubcommand(["bun", "cli.js", "read", "no-such-agent-keyword"]);
|
|
208
208
|
expect(code).toBe(1);
|
|
209
|
-
expect(stderr.join("")).toMatch(/no
|
|
209
|
+
expect(stderr.join("")).toMatch(/no agent matched/);
|
|
210
210
|
} finally {
|
|
211
211
|
process.stderr.write = orig;
|
|
212
212
|
}
|
package/ts/subcommands.ts
CHANGED
|
@@ -76,7 +76,7 @@ function mergeRecords(...buckets: GlobalPidRecord[][]): GlobalPidRecord[] {
|
|
|
76
76
|
return Array.from(out.values());
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const SUBCOMMANDS = new Set(["ls", "list", "ps", "read", "cat", "tail", "head", "send"]);
|
|
79
|
+
const SUBCOMMANDS = new Set(["ls", "list", "ps", "read", "cat", "tail", "head", "send", "restart"]);
|
|
80
80
|
|
|
81
81
|
export function isSubcommand(name: string | undefined): boolean {
|
|
82
82
|
return !!name && SUBCOMMANDS.has(name);
|
|
@@ -107,6 +107,8 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
107
107
|
return await cmdRead(rest, { mode: "head" });
|
|
108
108
|
case "send":
|
|
109
109
|
return await cmdSend(rest);
|
|
110
|
+
case "restart":
|
|
111
|
+
return await cmdRestart(rest);
|
|
110
112
|
default:
|
|
111
113
|
return null;
|
|
112
114
|
}
|
|
@@ -123,6 +125,7 @@ export async function runSubcommand(argv: string[]): Promise<number | null> {
|
|
|
123
125
|
|
|
124
126
|
interface CommonOpts {
|
|
125
127
|
all: boolean;
|
|
128
|
+
active: boolean;
|
|
126
129
|
cwdScope: string | null;
|
|
127
130
|
latest: boolean;
|
|
128
131
|
json: boolean;
|
|
@@ -146,7 +149,7 @@ export function parseArgs(rest: string[]): ParsedArgs {
|
|
|
146
149
|
const key = arg.slice(2);
|
|
147
150
|
const next = rest[i + 1];
|
|
148
151
|
// Boolean flags: --all, --json, --latest
|
|
149
|
-
if (["all", "json", "latest"].includes(key) || !next || next.startsWith("-")) {
|
|
152
|
+
if (["all", "active", "json", "latest"].includes(key) || !next || next.startsWith("-")) {
|
|
150
153
|
flags[key] = true;
|
|
151
154
|
} else {
|
|
152
155
|
flags[key] = next;
|
|
@@ -171,6 +174,7 @@ export function parseArgs(rest: string[]): ParsedArgs {
|
|
|
171
174
|
function commonOpts(flags: Record<string, string | boolean>): CommonOpts {
|
|
172
175
|
return {
|
|
173
176
|
all: !!flags.all,
|
|
177
|
+
active: !!flags.active,
|
|
174
178
|
cwdScope:
|
|
175
179
|
typeof flags.cwd === "string"
|
|
176
180
|
? path.resolve(flags.cwd)
|
|
@@ -210,7 +214,10 @@ async function listRecords(
|
|
|
210
214
|
let records = mergeRecords(local, scopeLocal, global);
|
|
211
215
|
|
|
212
216
|
if (!opts.all) {
|
|
213
|
-
records = records.filter((r) => r.status !== "exited"
|
|
217
|
+
records = records.filter((r) => r.status !== "exited");
|
|
218
|
+
}
|
|
219
|
+
if (opts.active) {
|
|
220
|
+
records = records.filter((r) => isPidAlive(r.pid));
|
|
214
221
|
}
|
|
215
222
|
if (opts.cwdScope) {
|
|
216
223
|
const scope = opts.cwdScope;
|
|
@@ -237,7 +244,7 @@ async function resolveOne(keyword: string | undefined, opts: CommonOpts): Promis
|
|
|
237
244
|
}
|
|
238
245
|
const matches = await listRecords(keyword, opts);
|
|
239
246
|
if (matches.length === 0) {
|
|
240
|
-
throw new Error(`no
|
|
247
|
+
throw new Error(`no agent matched "${keyword}"`);
|
|
241
248
|
}
|
|
242
249
|
if (matches.length === 1) return matches[0]!;
|
|
243
250
|
if (opts.latest) return matches[0]!; // already sorted newest-first
|
|
@@ -291,12 +298,17 @@ async function cmdLs(rest: string[]): Promise<number> {
|
|
|
291
298
|
const IDLE_THRESHOLD_MS = 60 * 1000;
|
|
292
299
|
const rows = await Promise.all(
|
|
293
300
|
records.map(async (r) => {
|
|
294
|
-
let displayStatus
|
|
295
|
-
if (r.
|
|
301
|
+
let displayStatus: string;
|
|
302
|
+
if (!isPidAlive(r.pid)) {
|
|
303
|
+
displayStatus = "stopped";
|
|
304
|
+
} else if (r.log_file) {
|
|
296
305
|
const mtime = await stat(r.log_file)
|
|
297
306
|
.then((s) => s.mtimeMs)
|
|
298
307
|
.catch(() => null);
|
|
299
|
-
|
|
308
|
+
displayStatus =
|
|
309
|
+
mtime !== null && Date.now() - mtime > IDLE_THRESHOLD_MS ? "idle" : "active";
|
|
310
|
+
} else {
|
|
311
|
+
displayStatus = "active";
|
|
300
312
|
}
|
|
301
313
|
return {
|
|
302
314
|
pid: String(r.pid),
|
|
@@ -305,6 +317,7 @@ async function cmdLs(rest: string[]): Promise<number> {
|
|
|
305
317
|
age: humanizeAge(Date.now() - r.started_at),
|
|
306
318
|
cwd: shortenPath(r.cwd),
|
|
307
319
|
prompt: truncate(r.prompt ?? "", promptBudget),
|
|
320
|
+
_alive: displayStatus !== "stopped",
|
|
308
321
|
};
|
|
309
322
|
}),
|
|
310
323
|
);
|
|
@@ -333,15 +346,21 @@ async function cmdLs(rest: string[]): Promise<number> {
|
|
|
333
346
|
);
|
|
334
347
|
}
|
|
335
348
|
|
|
336
|
-
if (!opts.json &&
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
349
|
+
if (!opts.json && rows.length > 0) {
|
|
350
|
+
const alive = rows.find((r) => r._alive);
|
|
351
|
+
const stopped = rows.find((r) => !r._alive);
|
|
352
|
+
const hints: string[] = ["\n"];
|
|
353
|
+
if (alive) {
|
|
354
|
+
hints.push(` cy tail ${alive.pid} # view latest output\n`);
|
|
355
|
+
hints.push(` cy send ${alive.pid} "next: ..." # send a prompt\n`);
|
|
356
|
+
hints.push(` cy send ${alive.pid} "" --code=ctrl-c # interrupt\n`);
|
|
357
|
+
}
|
|
358
|
+
if (stopped) {
|
|
359
|
+
hints.push(` cy restart ${stopped.pid} # restart stopped agent\n`);
|
|
360
|
+
}
|
|
361
|
+
if (!alive && !stopped)
|
|
362
|
+
hints.push(` cy ls --all # show exited agents\n`);
|
|
363
|
+
process.stderr.write(hints.join(""));
|
|
345
364
|
}
|
|
346
365
|
|
|
347
366
|
return 0;
|
|
@@ -491,8 +510,15 @@ async function cmdSend(rest: string[]): Promise<number> {
|
|
|
491
510
|
);
|
|
492
511
|
}
|
|
493
512
|
|
|
494
|
-
const
|
|
495
|
-
|
|
513
|
+
const body = message ?? "";
|
|
514
|
+
if (body && trailing) {
|
|
515
|
+
await writeToIpc(fifoPath, body);
|
|
516
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
517
|
+
await writeToIpc(fifoPath, trailing);
|
|
518
|
+
} else {
|
|
519
|
+
await writeToIpc(fifoPath, body + trailing);
|
|
520
|
+
}
|
|
521
|
+
const payload = body + trailing;
|
|
496
522
|
process.stdout.write(`sent to pid ${record.pid} (${record.cli}): ${truncate(payload, 80)}\n`);
|
|
497
523
|
|
|
498
524
|
process.stderr.write(
|
|
@@ -564,3 +590,38 @@ async function writeToIpc(ipcPath: string, payload: string): Promise<void> {
|
|
|
564
590
|
}
|
|
565
591
|
}
|
|
566
592
|
}
|
|
593
|
+
|
|
594
|
+
// ---------------------------------------------------------------------------
|
|
595
|
+
// cy restart
|
|
596
|
+
// ---------------------------------------------------------------------------
|
|
597
|
+
|
|
598
|
+
async function cmdRestart(rest: string[]): Promise<number> {
|
|
599
|
+
const { flags, positional } = parseArgs(rest);
|
|
600
|
+
const opts = { ...commonOpts(flags), all: true }; // search stopped agents too
|
|
601
|
+
const keyword = positional[0];
|
|
602
|
+
const record = await resolveOne(keyword, opts);
|
|
603
|
+
|
|
604
|
+
if (isPidAlive(record.pid)) {
|
|
605
|
+
process.stderr.write(`pid ${record.pid} is still running — stop it first or use cy send\n`);
|
|
606
|
+
return 1;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
const args = ["--cli=" + record.cli];
|
|
610
|
+
if (record.prompt) args.push(record.prompt);
|
|
611
|
+
|
|
612
|
+
const proc = Bun.spawn(["agent-yes", ...args], {
|
|
613
|
+
cwd: record.cwd,
|
|
614
|
+
detached: true,
|
|
615
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
process.stdout.write(
|
|
619
|
+
`restarted ${record.cli} in ${shortenPath(record.cwd)} (new pid: ${proc.pid})\n`,
|
|
620
|
+
);
|
|
621
|
+
process.stderr.write(
|
|
622
|
+
`\n` +
|
|
623
|
+
` cy tail ${proc.pid} # watch output\n` +
|
|
624
|
+
` cy ls # list all agents\n`,
|
|
625
|
+
);
|
|
626
|
+
return 0;
|
|
627
|
+
}
|