agent-yes 1.75.1 → 1.75.2
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/README.md +19 -0
- package/dist/SUPPORTED_CLIS-C2w9JqbM.js +11 -0
- package/dist/cli.js +4 -4
- package/dist/{globalPidIndex-BHCkWll6.js → globalPidIndex-Cr-g75QF.js} +33 -3
- package/dist/index.js +3 -3
- package/dist/{package-DRIilF5m.js → package-8zpT1iww.js} +2 -2
- package/dist/pidStore-BCsY5BW3.js +5 -0
- package/dist/{pidStore-CYmzzaQQ.js → pidStore-C1JXxoPi.js} +3 -3
- package/dist/{subcommands-NWIZy8od.js → subcommands-DSm9WL-6.js} +2 -2
- package/dist/{ts-DfT_yx7e.js → ts-Cuys5-PF.js} +3 -3
- package/package.json +1 -1
- package/ts/globalPidIndex.spec.ts +63 -0
- package/ts/globalPidIndex.ts +38 -1
- package/ts/pidStore.ts +8 -2
- package/dist/SUPPORTED_CLIS-CqAT1Zud.js +0 -11
- package/dist/pidStore-CF54dFqr.js +0 -5
package/README.md
CHANGED
|
@@ -130,6 +130,25 @@ claude-yes --exit-on-idle=60s "run all tests and commit current changes"
|
|
|
130
130
|
claude-code-execute claude-yes "your task here"
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
### Inspect and message running agents (`cy ls / read / send`)
|
|
134
|
+
|
|
135
|
+
From any terminal you can list and interact with agents that are already
|
|
136
|
+
running on the machine — both TS- and Rust-spawned ones:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cy ls # list all running agents
|
|
140
|
+
cy ls codex # filter (matches pid, cwd, cli, or prompt)
|
|
141
|
+
cy tail <keyword> # render last 96 lines via @xterm/headless
|
|
142
|
+
cy read <keyword> # full rendered log
|
|
143
|
+
cy send <keyword> "next: run tests" # append a prompt to that agent's stdin
|
|
144
|
+
cy send <keyword> "" --code=ctrl-c # send a Ctrl+C
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`cy` (and `ay` / `agent-yes`) writes to a shared registry at
|
|
148
|
+
`~/.agent-yes/pids.jsonl` and a per-pid FIFO at `~/.agent-yes/fifo/<pid>.stdin`,
|
|
149
|
+
so subcommands work whether the target agent is the TS or Rust runtime.
|
|
150
|
+
Detailed reference (Japanese): [`docs/cy-subcommands.md`](./docs/cy-subcommands.md).
|
|
151
|
+
|
|
133
152
|
### Docker Usage
|
|
134
153
|
|
|
135
154
|
You can run `agent-yes` in a Docker container with all AI CLI tools pre-installed.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as CLIS_CONFIG } from "./ts-Cuys5-PF.js";
|
|
2
|
+
import "./logger-B9h0djqx.js";
|
|
3
|
+
import "./pidStore-C1JXxoPi.js";
|
|
4
|
+
import "./globalPidIndex-Cr-g75QF.js";
|
|
5
|
+
|
|
6
|
+
//#region ts/SUPPORTED_CLIS.ts
|
|
7
|
+
const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { SUPPORTED_CLIS };
|
|
11
|
+
//# sourceMappingURL=SUPPORTED_CLIS-C2w9JqbM.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 { n as version, t as name } from "./package-
|
|
3
|
+
import { n as version, t as name } from "./package-8zpT1iww.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
@@ -635,7 +635,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
635
635
|
}
|
|
636
636
|
}
|
|
637
637
|
{
|
|
638
|
-
const { isSubcommand, runSubcommand } = await import("./subcommands-
|
|
638
|
+
const { isSubcommand, runSubcommand } = await import("./subcommands-DSm9WL-6.js");
|
|
639
639
|
if (isSubcommand(process.argv[2])) {
|
|
640
640
|
const code = await runSubcommand(process.argv);
|
|
641
641
|
process.exit(code ?? 0);
|
|
@@ -664,7 +664,7 @@ if (config.useRust) {
|
|
|
664
664
|
}
|
|
665
665
|
}
|
|
666
666
|
if (rustBinary) {
|
|
667
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
667
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-C2w9JqbM.js");
|
|
668
668
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
669
669
|
if (config.verbose) {
|
|
670
670
|
console.log(`[rust] Using binary: ${rustBinary}`);
|
|
@@ -694,7 +694,7 @@ if (config.showVersion) {
|
|
|
694
694
|
process.exit(0);
|
|
695
695
|
}
|
|
696
696
|
if (config.appendPrompt) {
|
|
697
|
-
const { PidStore } = await import("./pidStore-
|
|
697
|
+
const { PidStore } = await import("./pidStore-BCsY5BW3.js");
|
|
698
698
|
const ipcPath = await PidStore.findActiveFifo(process.cwd());
|
|
699
699
|
if (!ipcPath) {
|
|
700
700
|
console.error("No active agent with IPC found in current directory.");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
2
|
-
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
2
|
+
import { appendFile, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { lock } from "proper-lockfile";
|
|
@@ -108,7 +108,37 @@ function isProcessAlive(pid) {
|
|
|
108
108
|
return false;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
const COMPACT_THRESHOLD_LINES = 500;
|
|
112
|
+
/**
|
|
113
|
+
* Best-effort compaction: rewrite the JSONL file with one line per known pid,
|
|
114
|
+
* dropping records whose pid is dead AND status is exited (those won't be
|
|
115
|
+
* referenced by `cy ls` anyway). Triggered opportunistically when the raw
|
|
116
|
+
* file grows past `COMPACT_THRESHOLD_LINES`. Safe to call unconditionally;
|
|
117
|
+
* it no-ops when the file is already small enough.
|
|
118
|
+
*/
|
|
119
|
+
async function maybeCompactGlobalPids() {
|
|
120
|
+
let raw;
|
|
121
|
+
try {
|
|
122
|
+
raw = await readFile(resolveGlobalFile(), "utf-8");
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (err.code === "ENOENT") return;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const lineCount = raw.split("\n").filter((l) => l.trim()).length;
|
|
128
|
+
if (lineCount < COMPACT_THRESHOLD_LINES) return;
|
|
129
|
+
try {
|
|
130
|
+
await withLock(async () => {
|
|
131
|
+
const keep = (await readGlobalPidsRaw()).filter((r) => r.status !== "exited" || isProcessAlive(r.pid));
|
|
132
|
+
const tmpFile = resolveGlobalFile() + ".compact";
|
|
133
|
+
await writeFile(tmpFile, keep.map((r) => JSON.stringify(r)).join("\n") + (keep.length ? "\n" : ""));
|
|
134
|
+
await rename(tmpFile, resolveGlobalFile());
|
|
135
|
+
logger.debug(`[globalPidIndex] compacted ${lineCount} → ${keep.length} lines`);
|
|
136
|
+
});
|
|
137
|
+
} catch (error) {
|
|
138
|
+
logger.debug("[globalPidIndex] compact failed:", error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
111
141
|
|
|
112
142
|
//#endregion
|
|
113
|
-
export {
|
|
114
|
-
//# sourceMappingURL=globalPidIndex-
|
|
143
|
+
export { updateGlobalPidStatus as i, maybeCompactGlobalPids as n, readGlobalPids as r, appendGlobalPid as t };
|
|
144
|
+
//# sourceMappingURL=globalPidIndex-Cr-g75QF.js.map
|
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-Cuys5-PF.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./pidStore-
|
|
4
|
-
import "./globalPidIndex-
|
|
3
|
+
import "./pidStore-C1JXxoPi.js";
|
|
4
|
+
import "./globalPidIndex-Cr-g75QF.js";
|
|
5
5
|
|
|
6
6
|
export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
2
|
-
import {
|
|
2
|
+
import { i as updateGlobalPidStatus, n as maybeCompactGlobalPids, t as appendGlobalPid } from "./globalPidIndex-Cr-g75QF.js";
|
|
3
3
|
import { closeSync, existsSync, fsyncSync, openSync } from "fs";
|
|
4
4
|
import { appendFile, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
5
5
|
import path from "path";
|
|
@@ -239,7 +239,7 @@ var PidStore = class PidStore {
|
|
|
239
239
|
exit_code: null,
|
|
240
240
|
exit_reason: null,
|
|
241
241
|
started_at: now
|
|
242
|
-
}).catch(() => null);
|
|
242
|
+
}).then(() => maybeCompactGlobalPids()).catch(() => null);
|
|
243
243
|
return result;
|
|
244
244
|
}
|
|
245
245
|
async updateStatus(pid, status, extra) {
|
|
@@ -337,4 +337,4 @@ pid-db/
|
|
|
337
337
|
|
|
338
338
|
//#endregion
|
|
339
339
|
export { PidStore as t };
|
|
340
|
-
//# sourceMappingURL=pidStore-
|
|
340
|
+
//# sourceMappingURL=pidStore-C1JXxoPi.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./logger-B9h0djqx.js";
|
|
2
|
-
import {
|
|
2
|
+
import { r as readGlobalPids } from "./globalPidIndex-Cr-g75QF.js";
|
|
3
3
|
import { readFile, stat } from "fs/promises";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
import path from "path";
|
|
@@ -388,4 +388,4 @@ async function writeToIpc(ipcPath, payload) {
|
|
|
388
388
|
|
|
389
389
|
//#endregion
|
|
390
390
|
export { isSubcommand, runSubcommand };
|
|
391
|
-
//# sourceMappingURL=subcommands-
|
|
391
|
+
//# sourceMappingURL=subcommands-DSm9WL-6.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as logger, t as addTransport } from "./logger-B9h0djqx.js";
|
|
2
|
-
import { n as version } from "./package-
|
|
2
|
+
import { n as version } from "./package-8zpT1iww.js";
|
|
3
3
|
import { i as shouldUseLock, r as releaseLock, t as acquireLock } from "./runningLock-DQWJSptq.js";
|
|
4
|
-
import { t as PidStore } from "./pidStore-
|
|
4
|
+
import { t as PidStore } from "./pidStore-C1JXxoPi.js";
|
|
5
5
|
import { arch, platform } from "process";
|
|
6
6
|
import { execSync } from "child_process";
|
|
7
7
|
import { closeSync, constants, createReadStream, existsSync, mkdirSync, openSync } from "fs";
|
|
@@ -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-Cuys5-PF.js.map
|
package/package.json
CHANGED
|
@@ -142,6 +142,69 @@ describe("globalPidIndex", () => {
|
|
|
142
142
|
expect(records).toEqual([]);
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
+
it("maybeCompactGlobalPids no-ops when below threshold", async () => {
|
|
146
|
+
const mod = await loadModule();
|
|
147
|
+
await mod.appendGlobalPid({
|
|
148
|
+
pid: 1234,
|
|
149
|
+
cli: "claude",
|
|
150
|
+
prompt: null,
|
|
151
|
+
cwd: "/a",
|
|
152
|
+
log_file: null,
|
|
153
|
+
status: "active",
|
|
154
|
+
exit_code: null,
|
|
155
|
+
exit_reason: null,
|
|
156
|
+
started_at: 1,
|
|
157
|
+
});
|
|
158
|
+
const before = (await import("fs/promises")).readFile;
|
|
159
|
+
const beforeContent = await before(mod.getGlobalPidIndexPath(), "utf-8");
|
|
160
|
+
await mod.maybeCompactGlobalPids();
|
|
161
|
+
const afterContent = await before(mod.getGlobalPidIndexPath(), "utf-8");
|
|
162
|
+
expect(afterContent).toBe(beforeContent);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("maybeCompactGlobalPids collapses event spam to one line per pid", async () => {
|
|
166
|
+
const mod = await loadModule();
|
|
167
|
+
// Emit > 500 status events across two pids (one alive, one will be exited+dead)
|
|
168
|
+
for (let i = 0; i < 260; i++) {
|
|
169
|
+
await mod.appendGlobalPid({
|
|
170
|
+
pid: process.pid,
|
|
171
|
+
cli: "claude",
|
|
172
|
+
prompt: null,
|
|
173
|
+
cwd: "/a",
|
|
174
|
+
log_file: null,
|
|
175
|
+
status: "active",
|
|
176
|
+
exit_code: null,
|
|
177
|
+
exit_reason: null,
|
|
178
|
+
started_at: 1,
|
|
179
|
+
});
|
|
180
|
+
await mod.appendGlobalPid({
|
|
181
|
+
pid: 999999, // dead
|
|
182
|
+
cli: "codex",
|
|
183
|
+
prompt: null,
|
|
184
|
+
cwd: "/b",
|
|
185
|
+
log_file: null,
|
|
186
|
+
status: "exited",
|
|
187
|
+
exit_code: 0,
|
|
188
|
+
exit_reason: "done",
|
|
189
|
+
started_at: 1,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
const fs = await import("fs/promises");
|
|
193
|
+
const before = (await fs.readFile(mod.getGlobalPidIndexPath(), "utf-8")).split("\n").length;
|
|
194
|
+
await mod.maybeCompactGlobalPids();
|
|
195
|
+
const after = (await fs.readFile(mod.getGlobalPidIndexPath(), "utf-8")).split("\n").length;
|
|
196
|
+
// Compaction must have shrunk the file dramatically and dropped the
|
|
197
|
+
// dead-and-exited pid 999999 entirely.
|
|
198
|
+
expect(after).toBeLessThan(before / 10);
|
|
199
|
+
const records = await mod.readGlobalPids();
|
|
200
|
+
expect(records.map((r) => r.pid)).toEqual([process.pid]);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("maybeCompactGlobalPids on missing file is a noop", async () => {
|
|
204
|
+
const mod = await loadModule();
|
|
205
|
+
await mod.maybeCompactGlobalPids(); // no throw, no error
|
|
206
|
+
});
|
|
207
|
+
|
|
145
208
|
it("skips corrupt lines without throwing", async () => {
|
|
146
209
|
const mod = await loadModule();
|
|
147
210
|
await mod.appendGlobalPid({
|
package/ts/globalPidIndex.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { appendFile, mkdir, readFile } from "fs/promises";
|
|
1
|
+
import { appendFile, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
2
2
|
import { homedir } from "os";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import { lock } from "proper-lockfile";
|
|
@@ -153,3 +153,40 @@ function isProcessAlive(pid: number): boolean {
|
|
|
153
153
|
return false;
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
+
|
|
157
|
+
const COMPACT_THRESHOLD_LINES = 500; // raw events; one merged record per pid
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Best-effort compaction: rewrite the JSONL file with one line per known pid,
|
|
161
|
+
* dropping records whose pid is dead AND status is exited (those won't be
|
|
162
|
+
* referenced by `cy ls` anyway). Triggered opportunistically when the raw
|
|
163
|
+
* file grows past `COMPACT_THRESHOLD_LINES`. Safe to call unconditionally;
|
|
164
|
+
* it no-ops when the file is already small enough.
|
|
165
|
+
*/
|
|
166
|
+
export async function maybeCompactGlobalPids(): Promise<void> {
|
|
167
|
+
let raw: string;
|
|
168
|
+
try {
|
|
169
|
+
raw = await readFile(resolveGlobalFile(), "utf-8");
|
|
170
|
+
} catch (err: any) {
|
|
171
|
+
if (err.code === "ENOENT") return;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const lineCount = raw.split("\n").filter((l) => l.trim()).length;
|
|
175
|
+
if (lineCount < COMPACT_THRESHOLD_LINES) return;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
await withLock(async () => {
|
|
179
|
+
const merged = await readGlobalPidsRaw();
|
|
180
|
+
// Drop dead-and-exited entries; keep dead-but-not-yet-exited so a later
|
|
181
|
+
// status-update from elsewhere can still be matched against them.
|
|
182
|
+
const keep = merged.filter((r) => r.status !== "exited" || isProcessAlive(r.pid));
|
|
183
|
+
const tmpFile = resolveGlobalFile() + ".compact";
|
|
184
|
+
const content = keep.map((r) => JSON.stringify(r)).join("\n") + (keep.length ? "\n" : "");
|
|
185
|
+
await writeFile(tmpFile, content);
|
|
186
|
+
await rename(tmpFile, resolveGlobalFile());
|
|
187
|
+
logger.debug(`[globalPidIndex] compacted ${lineCount} → ${keep.length} lines`);
|
|
188
|
+
});
|
|
189
|
+
} catch (error) {
|
|
190
|
+
logger.debug("[globalPidIndex] compact failed:", error);
|
|
191
|
+
}
|
|
192
|
+
}
|
package/ts/pidStore.ts
CHANGED
|
@@ -2,7 +2,11 @@ import { mkdir, writeFile } from "fs/promises";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { logger } from "./logger.ts";
|
|
4
4
|
import { JsonlStore } from "./JsonlStore.ts";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
appendGlobalPid,
|
|
7
|
+
maybeCompactGlobalPids,
|
|
8
|
+
updateGlobalPidStatus,
|
|
9
|
+
} from "./globalPidIndex.ts";
|
|
6
10
|
|
|
7
11
|
export interface PidRecord {
|
|
8
12
|
_id?: string;
|
|
@@ -100,7 +104,9 @@ export class PidStore {
|
|
|
100
104
|
exit_code: null,
|
|
101
105
|
exit_reason: null,
|
|
102
106
|
started_at: now,
|
|
103
|
-
})
|
|
107
|
+
})
|
|
108
|
+
.then(() => maybeCompactGlobalPids())
|
|
109
|
+
.catch(() => null);
|
|
104
110
|
|
|
105
111
|
return result;
|
|
106
112
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { t as CLIS_CONFIG } from "./ts-DfT_yx7e.js";
|
|
2
|
-
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./pidStore-CYmzzaQQ.js";
|
|
4
|
-
import "./globalPidIndex-BHCkWll6.js";
|
|
5
|
-
|
|
6
|
-
//#region ts/SUPPORTED_CLIS.ts
|
|
7
|
-
const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
|
|
8
|
-
|
|
9
|
-
//#endregion
|
|
10
|
-
export { SUPPORTED_CLIS };
|
|
11
|
-
//# sourceMappingURL=SUPPORTED_CLIS-CqAT1Zud.js.map
|