agent-yes 1.122.3 → 1.124.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/default.config.yaml +19 -0
- package/dist/SUPPORTED_CLIS-Cvm7yo5d.js +8 -0
- package/dist/{SUPPORTED_CLIS-BleNYXA2.js → SUPPORTED_CLIS-D_-bIOlW.js} +2 -2
- package/dist/{agent-yes.config-z-IPzH5U.js → agent-yes.config-D6ycMApr.js} +2 -65
- package/dist/cli.js +6 -6
- package/dist/configShared-C5QaNPnz.js +71 -0
- package/dist/{globalPidIndex-gZuTvTBs.js → globalPidIndex-C7r2m6s7.js} +19 -20
- package/dist/index.js +4 -4
- package/dist/pidStore-C4c2O15q.js +5 -0
- package/dist/{pidStore-B5vBu8Px.js → pidStore-CGKIhaJO.js} +5 -4
- package/dist/reaper-BLVA780B.js +3 -0
- package/dist/{reaper-Dj8R7ltI.js → reaper-BkjPN7mw.js} +24 -2
- package/dist/{remotes-CpGcTr7A.js → remotes-BRCDVnR7.js} +1 -1
- package/dist/{remotes-D2fqaRU8.js → remotes-D8GvSbhf.js} +1 -1
- package/dist/{schedule-e4f7NlA2.js → schedule-D2cn8N7o.js} +7 -7
- package/dist/{serve-CzztmZ_N.js → serve-Bo3bDXQG.js} +202 -58
- package/dist/{setup-CPyRNiIA.js → setup-CvOr258q.js} +3 -3
- package/dist/{share-CS9XVrLF.js → share-YuM6-Q6A.js} +71 -13
- package/dist/{subcommands-CQowpr1t.js → subcommands-ClVHy-xI.js} +647 -32
- package/dist/subcommands-Llf9o8nh.js +7 -0
- package/dist/{tray-DjCIyakK.js → tray-BVnJLThD.js} +1 -1
- package/dist/{ts-9GThuc3w.js → ts-DGIglR4L.js} +10 -7
- package/dist/{versionChecker-Bv9XKddN.js → versionChecker-gaQkM2Hy.js} +2 -2
- package/dist/{workspaceConfig-XP2NEWmV.js → workspaceConfig-BJO4fzEn.js} +1 -1
- package/lab/ui/console-logic.js +222 -10
- package/lab/ui/icon.svg +5 -0
- package/lab/ui/index.html +1152 -28
- package/lab/ui/landing.html +276 -0
- package/lab/ui/manifest.webmanifest +14 -0
- package/lab/ui/sw.js +56 -0
- package/package.json +5 -1
- package/ts/agentTree.spec.ts +92 -0
- package/ts/agentTree.ts +149 -0
- package/ts/configShared.ts +4 -0
- package/ts/globalPidIndex.ts +28 -20
- package/ts/idleWaiter.spec.ts +7 -1
- package/ts/index.ts +9 -0
- package/ts/lsWatch.spec.ts +61 -0
- package/ts/lsWatch.ts +94 -0
- package/ts/needsInput.spec.ts +55 -0
- package/ts/needsInput.ts +68 -0
- package/ts/pidStore.ts +3 -0
- package/ts/reaper.spec.ts +26 -2
- package/ts/reaper.ts +25 -0
- package/ts/resultEnvelope.spec.ts +43 -0
- package/ts/resultEnvelope.ts +88 -0
- package/ts/serve.ts +276 -41
- package/ts/share.ts +144 -27
- package/ts/subcommands.ts +0 -0
- package/ts/todoParse.spec.ts +68 -0
- package/ts/todoParse.ts +88 -0
- package/ts/utils.spec.ts +4 -1
- package/dist/SUPPORTED_CLIS-ClaOErso.js +0 -8
- package/dist/pidStore-7y1cTcAE.js +0 -5
- package/dist/reaper-HqcUms2d.js +0 -3
- package/dist/subcommands-KAbIcd8_.js +0 -6
package/default.config.yaml
CHANGED
|
@@ -15,6 +15,14 @@ clis:
|
|
|
15
15
|
working:
|
|
16
16
|
- esc to interrupt
|
|
17
17
|
- to run in background
|
|
18
|
+
# needsInput: the agent is blocked on an interactive selection menu it did NOT
|
|
19
|
+
# auto-resolve — an AskUserQuestion / a permission prompt whose options aren't
|
|
20
|
+
# the auto-`enter`ed "Yes". The cursor `❯` sits on a numbered option. Surfaced
|
|
21
|
+
# by `ay ls` / `ay status` as the `needs_input` state (distinct from idle/done)
|
|
22
|
+
# so an orchestrator can tell "waiting for me to answer" from "finished".
|
|
23
|
+
needsInput:
|
|
24
|
+
- pattern: '❯ ?\d+\.'
|
|
25
|
+
flags: m
|
|
18
26
|
typingRespond:
|
|
19
27
|
"1\n":
|
|
20
28
|
- '│ Do you want to use this API key\?'
|
|
@@ -44,6 +52,12 @@ clis:
|
|
|
44
52
|
- pattern: "API Error.*Overloaded"
|
|
45
53
|
flags: i
|
|
46
54
|
- Overloaded
|
|
55
|
+
# Any 5xx API error (e.g. "API Error: 529 Overloaded", "API Error: 503 …",
|
|
56
|
+
# or a 529 rendered as a raw JSON error blob) is server-side + transient —
|
|
57
|
+
# retry with backoff regardless of the wording. Anchored to "API Error" so
|
|
58
|
+
# a stray "529"/"500" in normal output can't trigger a spurious retry.
|
|
59
|
+
- pattern: 'API Error.{0,4}5\d\d'
|
|
60
|
+
flags: i
|
|
47
61
|
- Claude usage limit reached
|
|
48
62
|
- hit your usage limit
|
|
49
63
|
- pattern: "rate.?limit"
|
|
@@ -94,6 +108,11 @@ clis:
|
|
|
94
108
|
# codex shows "• Working (… • esc to interrupt)" while streaming/running.
|
|
95
109
|
# (Approval dialogs say "esc to cancel", so this only marks real work.)
|
|
96
110
|
- esc to interrupt
|
|
111
|
+
# needsInput: a codex selection menu the agent is blocked on (cursor `›`/`>` on
|
|
112
|
+
# a numbered option). The bare `› ` idle prompt has no digit so it won't match.
|
|
113
|
+
needsInput:
|
|
114
|
+
- pattern: '[›>] ?\d+\.'
|
|
115
|
+
flags: m
|
|
97
116
|
enter:
|
|
98
117
|
# codex highlights the selected option with "›" (U+203A), NOT ASCII ">".
|
|
99
118
|
# Match the affirmative first option (Yes / Approve / Allow) when it is the
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "./ts-DGIglR4L.js";
|
|
2
|
+
import "./logger-B9h0djqx.js";
|
|
3
|
+
import "./versionChecker-gaQkM2Hy.js";
|
|
4
|
+
import "./pidStore-CGKIhaJO.js";
|
|
5
|
+
import "./globalPidIndex-C7r2m6s7.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D_-bIOlW.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-DGIglR4L.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-D_-bIOlW.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
2
|
+
import { n as normalizeAgentYesConfig, t as loadSharedCliDefaults } from "./configShared-C5QaNPnz.js";
|
|
2
3
|
import os from "node:os";
|
|
3
4
|
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
5
|
import path from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { parse } from "yaml";
|
|
7
7
|
|
|
8
8
|
//#region ts/defineConfig.ts
|
|
@@ -11,69 +11,6 @@ async function defineCliYesConfig(cfg) {
|
|
|
11
11
|
return cfg;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region ts/configShared.ts
|
|
16
|
-
function compileRegexSource(source) {
|
|
17
|
-
if (source instanceof RegExp) return source;
|
|
18
|
-
if (typeof source === "string") return new RegExp(source);
|
|
19
|
-
return new RegExp(source.pattern, source.flags ?? "");
|
|
20
|
-
}
|
|
21
|
-
function compileRegexList(sources) {
|
|
22
|
-
return sources?.map((source) => compileRegexSource(source));
|
|
23
|
-
}
|
|
24
|
-
function compileTypingRespond(typingRespond) {
|
|
25
|
-
if (!typingRespond) return void 0;
|
|
26
|
-
return Object.fromEntries(Object.entries(typingRespond).map(([message, patterns]) => [message, patterns.map(compileRegexSource)]));
|
|
27
|
-
}
|
|
28
|
-
function normalizeCliConfig(raw) {
|
|
29
|
-
const { ready, fatal, working, enter, enterExclude, typingRespond, restartWithoutContinueArg, updateAvailable, autoRetry, exitCommands, exitCommand, ...rest } = raw;
|
|
30
|
-
return {
|
|
31
|
-
...rest,
|
|
32
|
-
ready: compileRegexList(ready),
|
|
33
|
-
fatal: compileRegexList(fatal),
|
|
34
|
-
working: compileRegexList(working),
|
|
35
|
-
enter: compileRegexList(enter),
|
|
36
|
-
enterExclude: compileRegexList(enterExclude),
|
|
37
|
-
typingRespond: compileTypingRespond(typingRespond),
|
|
38
|
-
restartWithoutContinueArg: compileRegexList(restartWithoutContinueArg),
|
|
39
|
-
updateAvailable: compileRegexList(updateAvailable),
|
|
40
|
-
autoRetry: compileRegexList(autoRetry),
|
|
41
|
-
exitCommands: exitCommands ?? exitCommand
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function normalizeAgentYesConfig(raw) {
|
|
45
|
-
const normalized = {};
|
|
46
|
-
if (raw.configDir !== void 0) normalized.configDir = raw.configDir;
|
|
47
|
-
if (raw.logsDir !== void 0) normalized.logsDir = raw.logsDir;
|
|
48
|
-
if (raw.clis) normalized.clis = Object.fromEntries(Object.entries(raw.clis).map(([name, cliConfig]) => [name, normalizeCliConfig(cliConfig)]));
|
|
49
|
-
return normalized;
|
|
50
|
-
}
|
|
51
|
-
async function fileExists$1(filepath) {
|
|
52
|
-
try {
|
|
53
|
-
await access(filepath);
|
|
54
|
-
return true;
|
|
55
|
-
} catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async function findSharedCliDefaultsPath(fromUrl = import.meta.url) {
|
|
60
|
-
let currentDir = path.dirname(fileURLToPath(fromUrl));
|
|
61
|
-
while (true) {
|
|
62
|
-
const candidate = path.resolve(currentDir, "default.config.yaml");
|
|
63
|
-
if (await fileExists$1(candidate)) return candidate;
|
|
64
|
-
const parent = path.dirname(currentDir);
|
|
65
|
-
if (parent === currentDir) break;
|
|
66
|
-
currentDir = parent;
|
|
67
|
-
}
|
|
68
|
-
throw new Error("Unable to locate default.config.yaml from current package path");
|
|
69
|
-
}
|
|
70
|
-
async function loadSharedCliDefaults(fromUrl = import.meta.url) {
|
|
71
|
-
const filepath = await findSharedCliDefaultsPath(fromUrl);
|
|
72
|
-
const parsed = parse(await readFile(filepath, "utf8"));
|
|
73
|
-
if (!parsed || typeof parsed !== "object") throw new Error(`Invalid shared CLI defaults file: ${filepath}`);
|
|
74
|
-
return normalizeAgentYesConfig(parsed).clis ?? {};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
14
|
//#endregion
|
|
78
15
|
//#region ts/utils.ts
|
|
79
16
|
function deepMixin(target, source, ...more) {
|
|
@@ -289,4 +226,4 @@ async function getDefaultConfig() {
|
|
|
289
226
|
|
|
290
227
|
//#endregion
|
|
291
228
|
export { agent_yes_config_default as default };
|
|
292
|
-
//# sourceMappingURL=agent-yes.config-
|
|
229
|
+
//# sourceMappingURL=agent-yes.config-D6ycMApr.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-gaQkM2Hy.js";
|
|
4
4
|
import { argv } from "process";
|
|
5
5
|
import { execFileSync, spawn } from "child_process";
|
|
6
6
|
import ms from "ms";
|
|
@@ -482,7 +482,7 @@ function buildRustArgs(argv, cliFromScript, supportedClis) {
|
|
|
482
482
|
{
|
|
483
483
|
const rawArg = process.argv[2];
|
|
484
484
|
const isHelpFlag = rawArg === "-h" || rawArg === "--help";
|
|
485
|
-
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-
|
|
485
|
+
const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-Llf9o8nh.js");
|
|
486
486
|
if (isHelpFlag && process.argv.length === 3) {
|
|
487
487
|
cmdHelp();
|
|
488
488
|
process.exit(0);
|
|
@@ -496,12 +496,12 @@ await checkAndAutoUpdate();
|
|
|
496
496
|
logger.info(versionString());
|
|
497
497
|
const config = parseCliArgs(process.argv);
|
|
498
498
|
if (config.tray) {
|
|
499
|
-
const { startTray } = await import("./tray-
|
|
499
|
+
const { startTray } = await import("./tray-BVnJLThD.js");
|
|
500
500
|
await startTray();
|
|
501
501
|
await new Promise(() => {});
|
|
502
502
|
}
|
|
503
503
|
{
|
|
504
|
-
const { ensureTray } = await import("./tray-
|
|
504
|
+
const { ensureTray } = await import("./tray-BVnJLThD.js");
|
|
505
505
|
ensureTray();
|
|
506
506
|
}
|
|
507
507
|
if (config.useRust) {
|
|
@@ -515,7 +515,7 @@ if (config.useRust) {
|
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
517
|
if (rustBinary) {
|
|
518
|
-
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-
|
|
518
|
+
const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-Cvm7yo5d.js");
|
|
519
519
|
const rustArgs = buildRustArgs(process.argv, config.cli, SUPPORTED_CLIS);
|
|
520
520
|
if (config.verbose) {
|
|
521
521
|
console.log(`[rust] Using binary: ${rustBinary}`);
|
|
@@ -545,7 +545,7 @@ if (config.showVersion) {
|
|
|
545
545
|
process.exit(0);
|
|
546
546
|
}
|
|
547
547
|
if (config.appendPrompt) {
|
|
548
|
-
const { PidStore } = await import("./pidStore-
|
|
548
|
+
const { PidStore } = await import("./pidStore-C4c2O15q.js");
|
|
549
549
|
const ipcPath = await PidStore.findActiveFifo(process.cwd());
|
|
550
550
|
if (!ipcPath) {
|
|
551
551
|
console.error("No active agent with IPC found in current directory.");
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { access, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { parse } from "yaml";
|
|
5
|
+
|
|
6
|
+
//#region ts/configShared.ts
|
|
7
|
+
function compileRegexSource(source) {
|
|
8
|
+
if (source instanceof RegExp) return source;
|
|
9
|
+
if (typeof source === "string") return new RegExp(source);
|
|
10
|
+
return new RegExp(source.pattern, source.flags ?? "");
|
|
11
|
+
}
|
|
12
|
+
function compileRegexList(sources) {
|
|
13
|
+
return sources?.map((source) => compileRegexSource(source));
|
|
14
|
+
}
|
|
15
|
+
function compileTypingRespond(typingRespond) {
|
|
16
|
+
if (!typingRespond) return void 0;
|
|
17
|
+
return Object.fromEntries(Object.entries(typingRespond).map(([message, patterns]) => [message, patterns.map(compileRegexSource)]));
|
|
18
|
+
}
|
|
19
|
+
function normalizeCliConfig(raw) {
|
|
20
|
+
const { ready, fatal, working, enter, enterExclude, typingRespond, restartWithoutContinueArg, updateAvailable, autoRetry, needsInput, exitCommands, exitCommand, ...rest } = raw;
|
|
21
|
+
return {
|
|
22
|
+
...rest,
|
|
23
|
+
ready: compileRegexList(ready),
|
|
24
|
+
fatal: compileRegexList(fatal),
|
|
25
|
+
working: compileRegexList(working),
|
|
26
|
+
enter: compileRegexList(enter),
|
|
27
|
+
enterExclude: compileRegexList(enterExclude),
|
|
28
|
+
typingRespond: compileTypingRespond(typingRespond),
|
|
29
|
+
restartWithoutContinueArg: compileRegexList(restartWithoutContinueArg),
|
|
30
|
+
updateAvailable: compileRegexList(updateAvailable),
|
|
31
|
+
autoRetry: compileRegexList(autoRetry),
|
|
32
|
+
needsInput: compileRegexList(needsInput),
|
|
33
|
+
exitCommands: exitCommands ?? exitCommand
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function normalizeAgentYesConfig(raw) {
|
|
37
|
+
const normalized = {};
|
|
38
|
+
if (raw.configDir !== void 0) normalized.configDir = raw.configDir;
|
|
39
|
+
if (raw.logsDir !== void 0) normalized.logsDir = raw.logsDir;
|
|
40
|
+
if (raw.clis) normalized.clis = Object.fromEntries(Object.entries(raw.clis).map(([name, cliConfig]) => [name, normalizeCliConfig(cliConfig)]));
|
|
41
|
+
return normalized;
|
|
42
|
+
}
|
|
43
|
+
async function fileExists(filepath) {
|
|
44
|
+
try {
|
|
45
|
+
await access(filepath);
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function findSharedCliDefaultsPath(fromUrl = import.meta.url) {
|
|
52
|
+
let currentDir = path.dirname(fileURLToPath(fromUrl));
|
|
53
|
+
while (true) {
|
|
54
|
+
const candidate = path.resolve(currentDir, "default.config.yaml");
|
|
55
|
+
if (await fileExists(candidate)) return candidate;
|
|
56
|
+
const parent = path.dirname(currentDir);
|
|
57
|
+
if (parent === currentDir) break;
|
|
58
|
+
currentDir = parent;
|
|
59
|
+
}
|
|
60
|
+
throw new Error("Unable to locate default.config.yaml from current package path");
|
|
61
|
+
}
|
|
62
|
+
async function loadSharedCliDefaults(fromUrl = import.meta.url) {
|
|
63
|
+
const filepath = await findSharedCliDefaultsPath(fromUrl);
|
|
64
|
+
const parsed = parse(await readFile(filepath, "utf8"));
|
|
65
|
+
if (!parsed || typeof parsed !== "object") throw new Error(`Invalid shared CLI defaults file: ${filepath}`);
|
|
66
|
+
return normalizeAgentYesConfig(parsed).clis ?? {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
export { normalizeAgentYesConfig as n, loadSharedCliDefaults as t };
|
|
71
|
+
//# sourceMappingURL=configShared-C5QaNPnz.js.map
|
|
@@ -16,13 +16,9 @@ function resolveGlobalDir() {
|
|
|
16
16
|
function resolveGlobalFile() {
|
|
17
17
|
return path.join(resolveGlobalDir(), "pids.jsonl");
|
|
18
18
|
}
|
|
19
|
-
async function
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
async function withLock(fn) {
|
|
23
|
-
await ensureDir();
|
|
24
|
-
const file = resolveGlobalFile();
|
|
25
|
-
const dir = resolveGlobalDir();
|
|
19
|
+
async function withLock(file, fn) {
|
|
20
|
+
const dir = path.dirname(file);
|
|
21
|
+
await mkdir(dir, { recursive: true });
|
|
26
22
|
let release;
|
|
27
23
|
try {
|
|
28
24
|
release = await lock(dir, {
|
|
@@ -40,9 +36,10 @@ async function withLock(fn) {
|
|
|
40
36
|
}
|
|
41
37
|
/** Append one full record line. Caller must provide all required fields. */
|
|
42
38
|
async function appendGlobalPid(record) {
|
|
39
|
+
const file = resolveGlobalFile();
|
|
43
40
|
try {
|
|
44
|
-
await withLock(async () => {
|
|
45
|
-
await appendFile(
|
|
41
|
+
await withLock(file, async () => {
|
|
42
|
+
await appendFile(file, JSON.stringify(record) + "\n");
|
|
46
43
|
});
|
|
47
44
|
} catch (error) {
|
|
48
45
|
logger.debug("[globalPidIndex] append failed:", error);
|
|
@@ -50,15 +47,16 @@ async function appendGlobalPid(record) {
|
|
|
50
47
|
}
|
|
51
48
|
/** Append a partial update by pid (status, exit_code, exit_reason, log_file). */
|
|
52
49
|
async function updateGlobalPidStatus(pid, patch) {
|
|
50
|
+
const file = resolveGlobalFile();
|
|
53
51
|
try {
|
|
54
|
-
await withLock(async () => {
|
|
55
|
-
const existing = (await readGlobalPidsRaw()).find((r) => r.pid === pid);
|
|
52
|
+
await withLock(file, async () => {
|
|
53
|
+
const existing = (await readGlobalPidsRaw(file)).find((r) => r.pid === pid);
|
|
56
54
|
if (!existing) return;
|
|
57
55
|
const merged = {
|
|
58
56
|
...existing,
|
|
59
57
|
...patch
|
|
60
58
|
};
|
|
61
|
-
await appendFile(
|
|
59
|
+
await appendFile(file, JSON.stringify(merged) + "\n");
|
|
62
60
|
});
|
|
63
61
|
} catch (error) {
|
|
64
62
|
logger.debug("[globalPidIndex] updateStatus failed:", error);
|
|
@@ -67,10 +65,10 @@ async function updateGlobalPidStatus(pid, patch) {
|
|
|
67
65
|
/**
|
|
68
66
|
* Read the file once without merge logic — internal helper for status updates.
|
|
69
67
|
*/
|
|
70
|
-
async function readGlobalPidsRaw() {
|
|
68
|
+
async function readGlobalPidsRaw(file = resolveGlobalFile()) {
|
|
71
69
|
let raw;
|
|
72
70
|
try {
|
|
73
|
-
raw = await readFile(
|
|
71
|
+
raw = await readFile(file, "utf-8");
|
|
74
72
|
} catch (err) {
|
|
75
73
|
if (err.code === "ENOENT") return [];
|
|
76
74
|
throw err;
|
|
@@ -117,9 +115,10 @@ const COMPACT_THRESHOLD_LINES = 500;
|
|
|
117
115
|
* it no-ops when the file is already small enough.
|
|
118
116
|
*/
|
|
119
117
|
async function maybeCompactGlobalPids() {
|
|
118
|
+
const file = resolveGlobalFile();
|
|
120
119
|
let raw;
|
|
121
120
|
try {
|
|
122
|
-
raw = await readFile(
|
|
121
|
+
raw = await readFile(file, "utf-8");
|
|
123
122
|
} catch (err) {
|
|
124
123
|
if (err.code === "ENOENT") return;
|
|
125
124
|
return;
|
|
@@ -127,11 +126,11 @@ async function maybeCompactGlobalPids() {
|
|
|
127
126
|
const lineCount = raw.split("\n").filter((l) => l.trim()).length;
|
|
128
127
|
if (lineCount < COMPACT_THRESHOLD_LINES) return;
|
|
129
128
|
try {
|
|
130
|
-
await withLock(async () => {
|
|
131
|
-
const keep = (await readGlobalPidsRaw()).filter((r) => r.status !== "exited" || isProcessAlive(r.pid));
|
|
132
|
-
const tmpFile =
|
|
129
|
+
await withLock(file, async () => {
|
|
130
|
+
const keep = (await readGlobalPidsRaw(file)).filter((r) => r.status !== "exited" || isProcessAlive(r.pid));
|
|
131
|
+
const tmpFile = file + ".compact";
|
|
133
132
|
await writeFile(tmpFile, keep.map((r) => JSON.stringify(r)).join("\n") + (keep.length ? "\n" : ""));
|
|
134
|
-
await rename(tmpFile,
|
|
133
|
+
await rename(tmpFile, file);
|
|
135
134
|
logger.debug(`[globalPidIndex] compacted ${lineCount} → ${keep.length} lines`);
|
|
136
135
|
});
|
|
137
136
|
} catch (error) {
|
|
@@ -189,4 +188,4 @@ async function pruneOldLogs(maxAgeMs = retentionMs()) {
|
|
|
189
188
|
|
|
190
189
|
//#endregion
|
|
191
190
|
export { updateGlobalPidStatus as a, readGlobalPids as i, maybeCompactGlobalPids as n, pruneOldLogs as r, appendGlobalPid as t };
|
|
192
|
-
//# sourceMappingURL=globalPidIndex-
|
|
191
|
+
//# sourceMappingURL=globalPidIndex-C7r2m6s7.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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-DGIglR4L.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
4
|
-
import "./pidStore-
|
|
5
|
-
import "./globalPidIndex-
|
|
3
|
+
import "./versionChecker-gaQkM2Hy.js";
|
|
4
|
+
import "./pidStore-CGKIhaJO.js";
|
|
5
|
+
import "./globalPidIndex-C7r2m6s7.js";
|
|
6
6
|
|
|
7
7
|
export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as logger } from "./logger-B9h0djqx.js";
|
|
2
2
|
import { t as agentYesHome } from "./agentYesHome-BvaUOzCV.js";
|
|
3
|
-
import { a as updateGlobalPidStatus, n as maybeCompactGlobalPids, r as pruneOldLogs, t as appendGlobalPid } from "./globalPidIndex-
|
|
3
|
+
import { a as updateGlobalPidStatus, n as maybeCompactGlobalPids, r as pruneOldLogs, t as appendGlobalPid } from "./globalPidIndex-C7r2m6s7.js";
|
|
4
4
|
import { closeSync, existsSync, fsyncSync, openSync } from "fs";
|
|
5
5
|
import { appendFile, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
6
6
|
import path from "path";
|
|
@@ -203,7 +203,7 @@ var PidStore = class PidStore {
|
|
|
203
203
|
logger.warn("[pidStore] Failed to initialize:", error);
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
|
-
async registerProcess({ pid, cli, args, prompt, cwd, wrapperPid }) {
|
|
206
|
+
async registerProcess({ pid, cli, args, prompt, cwd, wrapperPid, parentPid }) {
|
|
207
207
|
const now = Date.now();
|
|
208
208
|
const argsJson = JSON.stringify(args);
|
|
209
209
|
const logFile = this.getRawLogPath(pid);
|
|
@@ -241,7 +241,8 @@ var PidStore = class PidStore {
|
|
|
241
241
|
exit_code: null,
|
|
242
242
|
exit_reason: null,
|
|
243
243
|
started_at: now,
|
|
244
|
-
wrapper_pid: wrapperPid ?? null
|
|
244
|
+
wrapper_pid: wrapperPid ?? null,
|
|
245
|
+
parent_pid: parentPid ?? null
|
|
245
246
|
}).then(() => maybeCompactGlobalPids()).catch(() => null);
|
|
246
247
|
return result;
|
|
247
248
|
}
|
|
@@ -362,4 +363,4 @@ pid-db/
|
|
|
362
363
|
|
|
363
364
|
//#endregion
|
|
364
365
|
export { PidStore as t };
|
|
365
|
-
//# sourceMappingURL=pidStore-
|
|
366
|
+
//# sourceMappingURL=pidStore-CGKIhaJO.js.map
|
|
@@ -13,6 +13,28 @@ function isAlive(pid) {
|
|
|
13
13
|
return e.code === "EPERM";
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
+
/** The recorded process-group id for a wrapper pid (newest entry wins), or null
|
|
17
|
+
* if unknown. Lets a force-kill target the agent's whole group, not just its
|
|
18
|
+
* wrapper pid — same registry the orphan sweep uses. */
|
|
19
|
+
async function pgidForWrapper(wpid) {
|
|
20
|
+
if (!wpid || wpid <= 1) return null;
|
|
21
|
+
let content;
|
|
22
|
+
try {
|
|
23
|
+
content = await readFile(registryPath(), "utf8");
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
let pgid = null;
|
|
28
|
+
for (const line of content.split("\n")) {
|
|
29
|
+
const t = line.trim();
|
|
30
|
+
if (!t) continue;
|
|
31
|
+
try {
|
|
32
|
+
const e = JSON.parse(t);
|
|
33
|
+
if (e.wpid === wpid && typeof e.pgid === "number" && e.pgid > 1) pgid = e.pgid;
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
return pgid;
|
|
37
|
+
}
|
|
16
38
|
/** Record this wrapper + its agent's process group for later sweeping. */
|
|
17
39
|
async function register(wrapperPid, pgid) {
|
|
18
40
|
if (pgid <= 1) return;
|
|
@@ -60,5 +82,5 @@ async function sweep() {
|
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
//#endregion
|
|
63
|
-
export {
|
|
64
|
-
//# sourceMappingURL=reaper-
|
|
85
|
+
export { register as n, sweep as r, pgidForWrapper as t };
|
|
86
|
+
//# sourceMappingURL=reaper-BkjPN7mw.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-D8GvSbhf.js";
|
|
2
2
|
|
|
3
3
|
export { cmdRemote };
|
|
@@ -147,4 +147,4 @@ async function cmdRemote(rest) {
|
|
|
147
147
|
|
|
148
148
|
//#endregion
|
|
149
149
|
export { resolveRemoteSpec as a, readRemotes as i, deleteRemoteAlias as n, writeRemoteAlias as o, parseDirectRemoteSpec as r, cmdRemote as t };
|
|
150
|
-
//# sourceMappingURL=remotes-
|
|
150
|
+
//# sourceMappingURL=remotes-D8GvSbhf.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./ts-
|
|
1
|
+
import "./ts-DGIglR4L.js";
|
|
2
2
|
import "./logger-B9h0djqx.js";
|
|
3
|
-
import "./versionChecker-
|
|
4
|
-
import "./pidStore-
|
|
5
|
-
import "./globalPidIndex-
|
|
6
|
-
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-
|
|
7
|
-
import { n as resolveSpawnCwd } from "./workspaceConfig-
|
|
3
|
+
import "./versionChecker-gaQkM2Hy.js";
|
|
4
|
+
import "./pidStore-CGKIhaJO.js";
|
|
5
|
+
import "./globalPidIndex-C7r2m6s7.js";
|
|
6
|
+
import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-D_-bIOlW.js";
|
|
7
|
+
import { n as resolveSpawnCwd } from "./workspaceConfig-BJO4fzEn.js";
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
|
|
10
10
|
//#region ts/oxmgrService.ts
|
|
@@ -141,4 +141,4 @@ async function cmdSchedule(rest) {
|
|
|
141
141
|
|
|
142
142
|
//#endregion
|
|
143
143
|
export { cmdSchedule };
|
|
144
|
-
//# sourceMappingURL=schedule-
|
|
144
|
+
//# sourceMappingURL=schedule-D2cn8N7o.js.map
|