agent-yes 1.122.3 → 1.123.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.
Files changed (56) hide show
  1. package/default.config.yaml +19 -0
  2. package/dist/{SUPPORTED_CLIS-BleNYXA2.js → SUPPORTED_CLIS-B4O2cFlt.js} +2 -2
  3. package/dist/SUPPORTED_CLIS-DHkqGoNv.js +8 -0
  4. package/dist/{agent-yes.config-z-IPzH5U.js → agent-yes.config-D6ycMApr.js} +2 -65
  5. package/dist/cli.js +6 -6
  6. package/dist/configShared-C5QaNPnz.js +71 -0
  7. package/dist/{globalPidIndex-gZuTvTBs.js → globalPidIndex-C7r2m6s7.js} +19 -20
  8. package/dist/index.js +4 -4
  9. package/dist/pidStore-C4c2O15q.js +5 -0
  10. package/dist/{pidStore-B5vBu8Px.js → pidStore-CGKIhaJO.js} +5 -4
  11. package/dist/reaper-BLVA780B.js +3 -0
  12. package/dist/{reaper-Dj8R7ltI.js → reaper-BkjPN7mw.js} +24 -2
  13. package/dist/{remotes-CpGcTr7A.js → remotes-BRCDVnR7.js} +1 -1
  14. package/dist/{remotes-D2fqaRU8.js → remotes-D8GvSbhf.js} +1 -1
  15. package/dist/{schedule-e4f7NlA2.js → schedule-DULdIkU9.js} +7 -7
  16. package/dist/{serve-CzztmZ_N.js → serve-r_2v9EKc.js} +202 -58
  17. package/dist/{setup-CPyRNiIA.js → setup-DHa6fX8M.js} +3 -3
  18. package/dist/{share-CS9XVrLF.js → share-YuM6-Q6A.js} +71 -13
  19. package/dist/{subcommands-CQowpr1t.js → subcommands-B13Kto-u.js} +647 -32
  20. package/dist/subcommands-Tv6AwUkD.js +7 -0
  21. package/dist/{tray-DjCIyakK.js → tray-BVnJLThD.js} +1 -1
  22. package/dist/{ts-9GThuc3w.js → ts-DgukRoEI.js} +10 -7
  23. package/dist/{versionChecker-Bv9XKddN.js → versionChecker-BqOr1YqC.js} +2 -2
  24. package/dist/{workspaceConfig-XP2NEWmV.js → workspaceConfig-BJO4fzEn.js} +1 -1
  25. package/lab/ui/console-logic.js +222 -10
  26. package/lab/ui/icon.svg +5 -0
  27. package/lab/ui/index.html +689 -14
  28. package/lab/ui/landing.html +276 -0
  29. package/lab/ui/manifest.webmanifest +14 -0
  30. package/lab/ui/sw.js +56 -0
  31. package/package.json +5 -1
  32. package/ts/agentTree.spec.ts +92 -0
  33. package/ts/agentTree.ts +149 -0
  34. package/ts/configShared.ts +4 -0
  35. package/ts/globalPidIndex.ts +28 -20
  36. package/ts/idleWaiter.spec.ts +7 -1
  37. package/ts/index.ts +9 -0
  38. package/ts/lsWatch.spec.ts +61 -0
  39. package/ts/lsWatch.ts +94 -0
  40. package/ts/needsInput.spec.ts +55 -0
  41. package/ts/needsInput.ts +68 -0
  42. package/ts/pidStore.ts +3 -0
  43. package/ts/reaper.spec.ts +26 -2
  44. package/ts/reaper.ts +25 -0
  45. package/ts/resultEnvelope.spec.ts +43 -0
  46. package/ts/resultEnvelope.ts +88 -0
  47. package/ts/serve.ts +276 -41
  48. package/ts/share.ts +144 -27
  49. package/ts/subcommands.ts +0 -0
  50. package/ts/todoParse.spec.ts +68 -0
  51. package/ts/todoParse.ts +88 -0
  52. package/ts/utils.spec.ts +4 -1
  53. package/dist/SUPPORTED_CLIS-ClaOErso.js +0 -8
  54. package/dist/pidStore-7y1cTcAE.js +0 -5
  55. package/dist/reaper-HqcUms2d.js +0 -3
  56. package/dist/subcommands-KAbIcd8_.js +0 -6
@@ -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
@@ -1,8 +1,8 @@
1
- import { t as CLIS_CONFIG } from "./ts-9GThuc3w.js";
1
+ import { t as CLIS_CONFIG } from "./ts-DgukRoEI.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-BleNYXA2.js.map
8
+ //# sourceMappingURL=SUPPORTED_CLIS-B4O2cFlt.js.map
@@ -0,0 +1,8 @@
1
+ import "./ts-DgukRoEI.js";
2
+ import "./logger-B9h0djqx.js";
3
+ import "./versionChecker-BqOr1YqC.js";
4
+ import "./pidStore-CGKIhaJO.js";
5
+ import "./globalPidIndex-C7r2m6s7.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-B4O2cFlt.js";
7
+
8
+ export { SUPPORTED_CLIS };
@@ -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-z-IPzH5U.js.map
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-Bv9XKddN.js";
3
+ import { i as versionString, n as displayVersion, r as getInstalledPackage, t as checkAndAutoUpdate } from "./versionChecker-BqOr1YqC.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-KAbIcd8_.js");
485
+ const { isSubcommand, runSubcommand, cmdHelp } = await import("./subcommands-Tv6AwUkD.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-DjCIyakK.js");
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-DjCIyakK.js");
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-ClaOErso.js");
518
+ const { SUPPORTED_CLIS } = await import("./SUPPORTED_CLIS-DHkqGoNv.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-7y1cTcAE.js");
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 ensureDir() {
20
- await mkdir(resolveGlobalDir(), { recursive: true });
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(resolveGlobalFile(), JSON.stringify(record) + "\n");
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(resolveGlobalFile(), JSON.stringify(merged) + "\n");
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(resolveGlobalFile(), "utf-8");
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(resolveGlobalFile(), "utf-8");
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 = resolveGlobalFile() + ".compact";
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, resolveGlobalFile());
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-gZuTvTBs.js.map
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-9GThuc3w.js";
1
+ import { a as removeControlCharacters, i as AgentContext, n as agentYes, r as config, t as CLIS_CONFIG } from "./ts-DgukRoEI.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-Bv9XKddN.js";
4
- import "./pidStore-B5vBu8Px.js";
5
- import "./globalPidIndex-gZuTvTBs.js";
3
+ import "./versionChecker-BqOr1YqC.js";
4
+ import "./pidStore-CGKIhaJO.js";
5
+ import "./globalPidIndex-C7r2m6s7.js";
6
6
 
7
7
  export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
@@ -0,0 +1,5 @@
1
+ import "./logger-B9h0djqx.js";
2
+ import { t as PidStore } from "./pidStore-CGKIhaJO.js";
3
+ import "./globalPidIndex-C7r2m6s7.js";
4
+
5
+ export { PidStore };
@@ -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-gZuTvTBs.js";
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-B5vBu8Px.js.map
366
+ //# sourceMappingURL=pidStore-CGKIhaJO.js.map
@@ -0,0 +1,3 @@
1
+ import { n as register, r as sweep, t as pgidForWrapper } from "./reaper-BkjPN7mw.js";
2
+
3
+ export { sweep };
@@ -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 { sweep as n, register as t };
64
- //# sourceMappingURL=reaper-Dj8R7ltI.js.map
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-D2fqaRU8.js";
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-D2fqaRU8.js.map
150
+ //# sourceMappingURL=remotes-D8GvSbhf.js.map
@@ -1,10 +1,10 @@
1
- import "./ts-9GThuc3w.js";
1
+ import "./ts-DgukRoEI.js";
2
2
  import "./logger-B9h0djqx.js";
3
- import "./versionChecker-Bv9XKddN.js";
4
- import "./pidStore-B5vBu8Px.js";
5
- import "./globalPidIndex-gZuTvTBs.js";
6
- import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BleNYXA2.js";
7
- import { n as resolveSpawnCwd } from "./workspaceConfig-XP2NEWmV.js";
3
+ import "./versionChecker-BqOr1YqC.js";
4
+ import "./pidStore-CGKIhaJO.js";
5
+ import "./globalPidIndex-C7r2m6s7.js";
6
+ import { t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-B4O2cFlt.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-e4f7NlA2.js.map
144
+ //# sourceMappingURL=schedule-DULdIkU9.js.map