@livx.cc/agentx 0.99.73 → 0.99.75

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/cli.js CHANGED
@@ -20,134 +20,14 @@ var init_logging = __esm({
20
20
  });
21
21
 
22
22
  // src/imageWire.ts
23
- import { readFileSync, writeFileSync as writeFileSync2, statSync as statSync2, mkdtempSync, rmSync } from "fs";
24
- import { spawnSync } from "child_process";
25
- import { createHash } from "crypto";
26
- import { tmpdir } from "os";
27
- import { join as join2 } from "path";
28
- import { PNG } from "pngjs";
29
- import jpeg from "jpeg-js";
30
- function imageSize(b) {
31
- const u16 = (i) => b[i] << 8 | b[i + 1];
32
- const le16 = (i) => b[i] | b[i + 1] << 8;
33
- const u32 = (i) => (b[i] << 24 >>> 0) + (b[i + 1] << 16) + (b[i + 2] << 8) + b[i + 3];
34
- if (b[0] === 137 && b[1] === 80 && b.length >= 24) return { w: u32(16), h: u32(20) };
35
- if (b[0] === 71 && b[1] === 73 && b.length >= 10) return { w: le16(6), h: le16(8) };
36
- if (b[0] === 255 && b[1] === 216) {
37
- for (let i = 2; i + 9 < b.length; ) {
38
- if (b[i] !== 255) return null;
39
- const m = b[i + 1];
40
- if (m >= 192 && m <= 207 && m !== 196 && m !== 200 && m !== 204) return { w: u16(i + 7), h: u16(i + 5) };
41
- i += 2 + u16(i + 2);
42
- }
43
- return null;
44
- }
45
- if (b.length >= 30 && String.fromCharCode(...b.subarray(8, 12)) === "WEBP") {
46
- const kind = String.fromCharCode(...b.subarray(12, 16));
47
- if (kind === "VP8X") return { w: 1 + (b[24] | b[25] << 8 | b[26] << 16), h: 1 + (b[27] | b[28] << 8 | b[29] << 16) };
48
- if (kind === "VP8 ") return { w: le16(26) & 16383, h: le16(28) & 16383 };
49
- if (kind === "VP8L") {
50
- const v = b[21] | b[22] << 8 | b[23] << 16 | b[24] << 24;
51
- return { w: (v & 16383) + 1, h: (v >> 14 & 16383) + 1 };
52
- }
53
- }
54
- return null;
55
- }
56
- function imageNote(what, bytes, dims, why) {
57
- return `[image ${what}${dims ? `, ${dims.w}x${dims.h}` : ""}, ${fmtBytes(bytes)} \u2014 not sent: ${why}]`;
58
- }
59
- function downscaleJs(buf, maxSide) {
60
- let src;
61
- try {
62
- if (buf[0] === 137 && buf[1] === 80) src = PNG.sync.read(buf);
63
- else if (buf[0] === 255 && buf[1] === 216) src = jpeg.decode(buf, { useTArray: true, maxMemoryUsageInMB: 1024 });
64
- else return null;
65
- } catch (e) {
66
- log2.warn("pure-JS image decode failed", e);
67
- return null;
68
- }
69
- const { width: sw, height: sh, data: s } = src;
70
- const k = Math.min(1, maxSide / Math.max(sw, sh));
71
- const w = Math.max(1, Math.round(sw * k)), h = Math.max(1, Math.round(sh * k));
72
- const d = new Uint8Array(w * h * 4);
73
- for (let y = 0; y < h; y++) {
74
- const y0 = Math.floor(y * sh / h), y1 = Math.max(y0 + 1, Math.floor((y + 1) * sh / h));
75
- for (let x = 0; x < w; x++) {
76
- const x0 = Math.floor(x * sw / w), x1 = Math.max(x0 + 1, Math.floor((x + 1) * sw / w));
77
- let r = 0, g = 0, b = 0, a = 0;
78
- for (let yy = y0; yy < y1; yy++) for (let xx = x0; xx < x1; xx++) {
79
- const i = (yy * sw + xx) * 4, al = s[i + 3];
80
- r += s[i] * al;
81
- g += s[i + 1] * al;
82
- b += s[i + 2] * al;
83
- a += al;
84
- }
85
- const o = (y * w + x) * 4, n = (y1 - y0) * (x1 - x0), bg = 255 * (n - a / 255);
86
- d[o] = (r / 255 + bg) / n;
87
- d[o + 1] = (g / 255 + bg) / n;
88
- d[o + 2] = (b / 255 + bg) / n;
89
- d[o + 3] = 255;
90
- }
91
- }
92
- let out = Buffer.alloc(0);
93
- for (const q2 of [80, 60, 40]) {
94
- out = Buffer.from(jpeg.encode({ width: w, height: h, data: d }, q2).data);
95
- if (out.length <= IMAGE_MAX_BYTES) break;
96
- }
97
- return out;
98
- }
99
- function downscale(path, maxSide) {
100
- const dir = mkdtempSync(join2(tmpdir(), "agentx-img-"));
101
- const out = join2(dir, "x.jpg");
102
- try {
103
- const tries = [
104
- ["sips", ["-Z", String(maxSide), "-s", "format", "jpeg", "-s", "formatOptions", "80", path, "--out", out]],
105
- ["magick", [path, "-resize", `${maxSide}x${maxSide}>`, "-quality", "80", out]],
106
- ["convert", [path, "-resize", `${maxSide}x${maxSide}>`, "-quality", "80", out]]
107
- ];
108
- for (const [cmd, args] of tries) {
109
- const r = spawnSync(cmd, args, { stdio: "ignore", timeout: 15e3 });
110
- if (r.status !== 0) continue;
111
- try {
112
- const o = readFileSync(out);
113
- if (o.length <= IMAGE_MAX_BYTES) return o;
114
- break;
115
- } catch {
116
- }
117
- }
118
- const js = downscaleJs(readFileSync(path), maxSide);
119
- if (!js) log2.warn(`could not downscale ${path} (tried sips/magick/convert/pure JS)`);
120
- return js;
121
- } finally {
122
- rmSync(dir, { recursive: true, force: true });
123
- }
124
- }
23
+ import { readFileSync, statSync as statSync2 } from "fs";
24
+ import { imageWireOf, inlineImageForWire, scrubBase64Text, imageSize, imageNote, IMAGE_MAX_SIDE, IMAGE_MAX_BYTES } from "ai.libx.js";
125
25
  function remember(id, w) {
126
26
  cache.delete(id);
127
27
  cache.set(id, w);
128
28
  if (cache.size > CACHE_MAX) cache.delete(cache.keys().next().value);
129
29
  return w;
130
30
  }
131
- function wireOf(key, buf, mime, label, file) {
132
- const dims = imageSize(buf);
133
- const fits = buf.length <= IMAGE_MAX_BYTES && (!dims || Math.max(dims.w, dims.h) <= IMAGE_MAX_SIDE);
134
- let small = null;
135
- if (!fits) {
136
- if (file) small = downscale(file, IMAGE_MAX_SIDE);
137
- else {
138
- const dir = mkdtempSync(join2(tmpdir(), "agentx-img-in-"));
139
- try {
140
- const f = join2(dir, `in.${mime.split("/")[1] || "img"}`);
141
- writeFileSync2(f, buf);
142
- small = downscale(f, IMAGE_MAX_SIDE);
143
- } finally {
144
- rmSync(dir, { recursive: true, force: true });
145
- }
146
- }
147
- }
148
- const url = fits ? `data:${mime};base64,${buf.toString("base64")}` : small && small.length <= IMAGE_MAX_BYTES ? `data:image/jpeg;base64,${small.toString("base64")}` : null;
149
- return { key, url, note: imageNote(label, buf.length, dims, url ? "this model can't see images" : "too large and it couldn't be downscaled") };
150
- }
151
31
  function imageForWire(path, mime, vision) {
152
32
  let st;
153
33
  try {
@@ -158,48 +38,30 @@ function imageForWire(path, mime, vision) {
158
38
  }
159
39
  const key = `${st.mtimeMs}:${st.size}`;
160
40
  let hit = cache.get(path);
161
- if (!hit || hit.key !== key) hit = remember(path, wireOf(key, readFileSync(path), mime, path, path));
41
+ if (!hit || hit.key !== key) hit = remember(path, { key, ...imageWireOf(readFileSync(path), mime, path, path) });
162
42
  return vision && hit.url ? { url: hit.url } : { note: hit.note };
163
43
  }
164
- function inlineImageForWire(url, vision) {
165
- const comma = url.indexOf(",");
166
- const mime = url.slice(5, url.indexOf(";"));
167
- if (vision && url.length < 3e5) {
168
- const b64 = url.slice(comma + 1);
169
- const dims = imageSize(Buffer.from(b64.slice(0, 4096), "base64")) ?? imageSize(Buffer.from(b64, "base64"));
170
- if (!dims || Math.max(dims.w, dims.h) <= IMAGE_MAX_SIDE) return { url };
171
- }
172
- const id = `inline:${createHash("sha1").update(url).digest("base64")}`;
173
- let hit = cache.get(id);
174
- if (!hit) {
175
- const buf = Buffer.from(url.slice(comma + 1), "base64");
176
- hit = remember(id, wireOf(id, buf, mime, `(${mime})`));
177
- }
178
- return vision && hit.url ? { url: hit.url } : { note: hit.note };
44
+ function imageTokens(dims) {
45
+ return dims ? Math.min(IMAGE_TOKENS_MAX, Math.max(1, Math.ceil(dims.w * dims.h / 750))) : IMAGE_TOKENS_MAX;
179
46
  }
180
- function imageWireBytes(path, mime, vision) {
181
- const r = imageForWire(path, mime, vision);
182
- return !r ? 0 : "url" in r ? r.url.length : r.note.length;
47
+ function wiredImageWeight(r) {
48
+ if ("note" in r) return r.note.length;
49
+ const b64 = r.url.slice(r.url.indexOf(",") + 1);
50
+ return 4 * imageTokens(imageSize(Buffer.from(b64.slice(0, 4096), "base64")));
183
51
  }
184
- function scrubBase64Text(s) {
185
- if (s.length < 2e3) return s;
186
- const out = s.replace(DATA_URI, (m) => imageNote(m.slice(5, m.indexOf(";")), Math.floor((m.length - m.indexOf(",") - 1) * 3 / 4), null, "base64 is never sent as text")).replace(B64_RUN, (m) => !/[+/]/.test(m) || !/\d/.test(m) ? m : `[base64 data, ${fmtBytes(Math.floor(m.length * 3 / 4))} \u2014 not sent: base64 is never sent as text]`);
187
- if (out !== s) log2.warn(`scrubbed base64 from request text (${s.length} \u2192 ${out.length} chars)`);
188
- return out;
52
+ function imageWireWeight(path, mime, vision) {
53
+ const r = imageForWire(path, mime, vision);
54
+ return r ? wiredImageWeight(r) : 0;
189
55
  }
190
- var log2, IMAGE_MAX_SIDE, IMAGE_MAX_BYTES, fmtBytes, cache, CACHE_MAX, DATA_URI, B64_RUN;
56
+ var log2, cache, CACHE_MAX, IMAGE_TOKENS_MAX;
191
57
  var init_imageWire = __esm({
192
58
  "src/imageWire.ts"() {
193
59
  "use strict";
194
60
  init_logging();
195
61
  log2 = forComponent("imageWire");
196
- IMAGE_MAX_SIDE = 1568;
197
- IMAGE_MAX_BYTES = 1e6;
198
- fmtBytes = (n) => n >= 1e6 ? `${(n / 1e6).toFixed(1)} MB` : n >= 1e3 ? `${Math.round(n / 1e3)} KB` : `${n} B`;
199
62
  cache = /* @__PURE__ */ new Map();
200
63
  CACHE_MAX = 8;
201
- DATA_URI = /data:image\/[\w.+-]+;base64,[A-Za-z0-9+/=]+/g;
202
- B64_RUN = /[A-Za-z0-9+/=]{2000,}/g;
64
+ IMAGE_TOKENS_MAX = 1600;
203
65
  }
204
66
  });
205
67
 
@@ -394,7 +256,7 @@ function sendBytesPer(messages, keepRecent = 1, vision = true, stub = IMAGE_ELID
394
256
  }
395
257
  function wireBytes(content, kept, vision, stub) {
396
258
  const tool = toolImageRef(content);
397
- if (tool) return kept ? imageWireBytes(tool.path, tool.mime, vision) || stub.length : stub.length;
259
+ if (tool) return kept ? imageWireWeight(tool.path, tool.mime, vision) || stub.length : stub.length;
398
260
  if (content == null || typeof content === "string") return contentBytes(content);
399
261
  if (kept) {
400
262
  let n2 = 0;
@@ -402,7 +264,7 @@ function wireBytes(content, kept, vision, stub) {
402
264
  const url = p.type === "image_url" ? p.image_url?.url ?? "" : "";
403
265
  const ref = url ? parseImageRef(url) : null;
404
266
  const inline = url.startsWith("data:") ? inlineImageForWire(url, vision) : null;
405
- n2 += ref ? imageWireBytes(ref.path, ref.mime, vision) : inline ? ("url" in inline ? inline.url : inline.note).length : contentBytes([p]);
267
+ n2 += ref ? imageWireWeight(ref.path, ref.mime, vision) : inline ? wiredImageWeight(inline) : contentBytes([p]);
406
268
  }
407
269
  return n2;
408
270
  }
@@ -2149,9 +2011,9 @@ __export(worktree_exports, {
2149
2011
  validateWorktreeSlug: () => validateWorktreeSlug,
2150
2012
  worktreeBranchName: () => worktreeBranchName
2151
2013
  });
2152
- import { spawnSync as spawnSync2 } from "child_process";
2153
- import { symlinkSync, mkdirSync, statSync as statSync4, readFileSync as readFileSync3, rmSync as rmSync2 } from "fs";
2154
- import { join as join3 } from "path";
2014
+ import { spawnSync } from "child_process";
2015
+ import { symlinkSync, mkdirSync, statSync as statSync4, readFileSync as readFileSync3, rmSync } from "fs";
2016
+ import { join as join2 } from "path";
2155
2017
  function validateWorktreeSlug(slug2) {
2156
2018
  if (!slug2) throw new Error("worktree slug must not be empty");
2157
2019
  if (slug2.length > MAX_SLUG_LENGTH) throw new Error(`worktree slug must be \u2264${MAX_SLUG_LENGTH} chars (got ${slug2.length})`);
@@ -2167,13 +2029,13 @@ function worktreeBranchName(slug2) {
2167
2029
  return `worktree-${flattenSlug(slug2)}`;
2168
2030
  }
2169
2031
  function worktreesDir(repoRoot) {
2170
- return join3(repoRoot, ".claude", "worktrees");
2032
+ return join2(repoRoot, ".claude", "worktrees");
2171
2033
  }
2172
2034
  function worktreePathFor(repoRoot, slug2) {
2173
- return join3(worktreesDir(repoRoot), flattenSlug(slug2));
2035
+ return join2(worktreesDir(repoRoot), flattenSlug(slug2));
2174
2036
  }
2175
2037
  function git(args, cwd) {
2176
- const r = spawnSync2("git", args, {
2038
+ const r = spawnSync("git", args, {
2177
2039
  cwd,
2178
2040
  stdio: ["ignore", "pipe", "pipe"],
2179
2041
  env: { ...process.env, ...GIT_NO_PROMPT_ENV }
@@ -2186,14 +2048,14 @@ function findGitRoot(from) {
2186
2048
  }
2187
2049
  function readWorktreeHead(worktreePath) {
2188
2050
  try {
2189
- const gitFile = readFileSync3(join3(worktreePath, ".git"), "utf-8").trim();
2051
+ const gitFile = readFileSync3(join2(worktreePath, ".git"), "utf-8").trim();
2190
2052
  const m = gitFile.match(/^gitdir:\s*(.+)$/);
2191
2053
  if (!m) return null;
2192
- const headPath = join3(m[1], "HEAD");
2054
+ const headPath = join2(m[1], "HEAD");
2193
2055
  const head = readFileSync3(headPath, "utf-8").trim();
2194
2056
  const refMatch = head.match(/^ref:\s*(.+)$/);
2195
2057
  if (!refMatch) return head.length === 40 ? head : null;
2196
- const refPath = join3(m[1], "..", refMatch[1]);
2058
+ const refPath = join2(m[1], "..", refMatch[1]);
2197
2059
  try {
2198
2060
  return readFileSync3(refPath, "utf-8").trim();
2199
2061
  } catch {
@@ -2228,8 +2090,8 @@ function getOrCreateWorktree(repoRoot, slug2) {
2228
2090
  }
2229
2091
  function symlinkDirs(repoRoot, worktreePath, dirs) {
2230
2092
  for (const dir of dirs) {
2231
- const src = join3(repoRoot, dir);
2232
- const dst = join3(worktreePath, dir);
2093
+ const src = join2(repoRoot, dir);
2094
+ const dst = join2(worktreePath, dir);
2233
2095
  try {
2234
2096
  statSync4(src);
2235
2097
  } catch {
@@ -2257,7 +2119,7 @@ function cleanupWorktree(repoRoot, slug2, opts) {
2257
2119
  }
2258
2120
  for (const dir of ["node_modules", ".bun"]) {
2259
2121
  try {
2260
- rmSync2(join3(worktreePath, dir));
2122
+ rmSync(join2(worktreePath, dir));
2261
2123
  } catch {
2262
2124
  }
2263
2125
  }
@@ -3172,9 +3034,9 @@ var init_tools_shell = __esm({
3172
3034
 
3173
3035
  // cli/cli.ts
3174
3036
  import { createInterface } from "readline/promises";
3175
- import { existsSync as existsSync9, readFileSync as readFileSync10, appendFileSync, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10, readdirSync as readdirSync4, statSync as statSync7, unlinkSync as unlinkSync5 } from "fs";
3037
+ import { existsSync as existsSync9, readFileSync as readFileSync10, appendFileSync, mkdirSync as mkdirSync12, writeFileSync as writeFileSync9, readdirSync as readdirSync4, statSync as statSync7, unlinkSync as unlinkSync5 } from "fs";
3176
3038
  import { homedir as homedir10 } from "os";
3177
- import { spawnSync as spawnSync7 } from "child_process";
3039
+ import { spawnSync as spawnSync6 } from "child_process";
3178
3040
 
3179
3041
  // cli/clipboard.ts
3180
3042
  import { execFileSync } from "child_process";
@@ -3241,7 +3103,7 @@ function copyTextToClipboard(text, platform2 = process.platform) {
3241
3103
  }
3242
3104
 
3243
3105
  // cli/cli.ts
3244
- import { join as join15, resolve as resolve4, basename as basename2, extname, dirname as dirname5 } from "path";
3106
+ import { join as join14, resolve as resolve4, basename as basename2, extname, dirname as dirname5 } from "path";
3245
3107
  import { AIClient, DecideClient, listModels, listProviders, getProviderFromModel, getModelInfo, resolveModel, isModelSupported, disposeCursorSessions, disposeClaudeCodeSessions } from "ai.libx.js";
3246
3108
 
3247
3109
  // src/ccBridge.ts
@@ -3822,8 +3684,8 @@ ${sections.join("\n\n---\n\n")}`;
3822
3684
 
3823
3685
  // src/subagent.ts
3824
3686
  init_tools();
3825
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
3826
- import { join as join5 } from "path";
3687
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
3688
+ import { join as join4 } from "path";
3827
3689
 
3828
3690
  // src/models.ts
3829
3691
  var MODEL_ALIASES = {
@@ -4072,7 +3934,7 @@ function traceFileFor(dir, label, depth) {
4072
3934
  try {
4073
3935
  mkdirSync2(dir, { recursive: true });
4074
3936
  const id = `${Date.now().toString(36)}-${(traceSeq++).toString(36)}`;
4075
- return join5(dir, `${id}-d${depth}-${sanitizeSlug(label) || "sub"}.json`);
3937
+ return join4(dir, `${id}-d${depth}-${sanitizeSlug(label) || "sub"}.json`);
4076
3938
  } catch (e) {
4077
3939
  log7.warn(`subagent trace dir unavailable (${dir}) \u2014 running without a trace: ${e instanceof Error ? e.message : String(e)}`);
4078
3940
  return void 0;
@@ -4080,7 +3942,7 @@ function traceFileFor(dir, label, depth) {
4080
3942
  }
4081
3943
  function flushTrace(file, meta, messages, status) {
4082
3944
  try {
4083
- writeFileSync3(file, JSON.stringify({ ...meta, status, updated: Date.now(), messages }, null, 2));
3945
+ writeFileSync2(file, JSON.stringify({ ...meta, status, updated: Date.now(), messages }, null, 2));
4084
3946
  } catch (e) {
4085
3947
  log7.warn(`subagent trace flush failed (${file}): ${e instanceof Error ? e.message : String(e)}`);
4086
3948
  }
@@ -5014,6 +4876,7 @@ var Agent = class _Agent {
5014
4876
  let steps = 0;
5015
4877
  const usage = { promptTokens: 0, completionTokens: 0, totalTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
5016
4878
  let usageEstimated = false;
4879
+ let spent = 0, prevPrompt = -1, stepPrompt = 0;
5017
4880
  const start = Date.now();
5018
4881
  this.parkedMs = 0;
5019
4882
  this.ctx.needsInput = void 0;
@@ -5024,12 +4887,12 @@ var Agent = class _Agent {
5024
4887
  let closureNudged = false;
5025
4888
  let lastProgressAt = start;
5026
4889
  const kill = (finishReason) => {
5027
- log8.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, budgetTokens=${Math.round(usage.totalTokens - 0.9 * usage.cacheReadTokens)}, ms=${Date.now() - start - this.parkedMs}${finishReason === "timeout" ? `, idle=${Date.now() - lastProgressAt - this.parkedMs}ms` : ""}${this.parkedMs ? ` +${this.parkedMs} parked` : ""})`);
4890
+ log8.warn(`kill-switch: ${finishReason} (steps=${steps}, tokens=${usage.totalTokens}, budgetTokens=${Math.round(spent)}, ms=${Date.now() - start - this.parkedMs}${finishReason === "timeout" ? `, idle=${Date.now() - lastProgressAt - this.parkedMs}ms` : ""}${this.parkedMs ? ` +${this.parkedMs} parked` : ""})`);
5028
4891
  this.jobs.killAll(`run ended: ${finishReason}`, true);
5029
4892
  const claims = this.survivingClaims();
5030
- return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated, ...claims.length ? { fabricatedToolClaims: claims } : {} };
4893
+ return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated, ...finishReason === "budget" ? { budget: { spent: Math.round(spent), limit: o.maxTokens, stepPrompt } } : {}, ...claims.length ? { fabricatedToolClaims: claims } : {} };
5031
4894
  };
5032
- const overBudget = () => !!o.maxTokens && usage.totalTokens - 0.9 * usage.cacheReadTokens >= o.maxTokens;
4895
+ const overBudget = () => !!o.maxTokens && spent >= o.maxTokens;
5033
4896
  const canNudge = () => steps < o.maxSteps && !overBudget();
5034
4897
  while (true) {
5035
4898
  if (o.signal?.aborted) return kill("aborted");
@@ -5183,6 +5046,14 @@ var Agent = class _Agent {
5183
5046
  usage.totalTokens += res.usage.totalTokens ?? 0;
5184
5047
  usage.cacheCreationTokens += res.usage.cacheCreationTokens ?? 0;
5185
5048
  usage.cacheReadTokens += res.usage.cacheReadTokens ?? 0;
5049
+ const prompt = res.usage.promptTokens ?? 0, cacheRead = res.usage.cacheReadTokens ?? 0;
5050
+ if (prevPrompt < 0) {
5051
+ const u = sent.map((m) => m.role).lastIndexOf("user");
5052
+ prevPrompt = u > 0 ? estimateTokens(sent.slice(0, u)) : 0;
5053
+ }
5054
+ const reused = Math.min(prompt, Math.max(cacheRead, prevPrompt));
5055
+ spent += (res.usage.totalTokens ?? 0) - 0.9 * reused;
5056
+ prevPrompt = stepPrompt = prompt;
5186
5057
  }
5187
5058
  const delegatedTools = res.delegatedTools ?? [];
5188
5059
  if (delegatedTools.length) {
@@ -11459,7 +11330,7 @@ import { MemFilesystem as MemFilesystem3, IndexedDbFilesystem, CommandExecutor a
11459
11330
  // src/mcp.client.ts
11460
11331
  init_logging();
11461
11332
  import { spawn } from "child_process";
11462
- import { createHash as createHash2 } from "crypto";
11333
+ import { createHash } from "crypto";
11463
11334
  var log23 = forComponent("mcp");
11464
11335
  var PROTOCOL_VERSION = "2025-06-18";
11465
11336
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -11865,8 +11736,8 @@ var defaultPool = new McpPool();
11865
11736
 
11866
11737
  // cli/mcpOAuth.ts
11867
11738
  import { createServer } from "http";
11868
- import { randomBytes as randomBytes2, createHash as createHash3 } from "crypto";
11869
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, existsSync } from "fs";
11739
+ import { randomBytes as randomBytes2, createHash as createHash2 } from "crypto";
11740
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync } from "fs";
11870
11741
  import { dirname as dirname2 } from "path";
11871
11742
  var McpOAuthOptions = class {
11872
11743
  /** Where to persist tokens. Mode 0600. */
@@ -11901,7 +11772,7 @@ var McpOAuth = class {
11901
11772
  }
11902
11773
  save(store) {
11903
11774
  mkdirSync3(dirname2(this.options.storePath), { recursive: true });
11904
- writeFileSync4(this.options.storePath, JSON.stringify(store, null, 2), { mode: 384 });
11775
+ writeFileSync3(this.options.storePath, JSON.stringify(store, null, 2), { mode: 384 });
11905
11776
  }
11906
11777
  // -- ATTENDED: one-time authorization ----------------------------------------
11907
11778
  /** Run the authorization-code + PKCE flow and persist the resulting tokens for `serverUrl`. */
@@ -11909,7 +11780,7 @@ var McpOAuth = class {
11909
11780
  const meta = await this.discover(serverUrl);
11910
11781
  const clientId = this.options.clientId ?? await this.registerClient(meta, serverUrl);
11911
11782
  const verifier = b64url(randomBytes2(32));
11912
- const challenge = b64url(createHash3("sha256").update(verifier).digest());
11783
+ const challenge = b64url(createHash2("sha256").update(verifier).digest());
11913
11784
  const state = b64url(randomBytes2(16));
11914
11785
  const { code, redirectUri } = await this.captureCode(meta.authorization_endpoint, clientId, challenge, state);
11915
11786
  const tok = await this.exchange(meta.token_endpoint, {
@@ -12059,9 +11930,9 @@ function defaultOpenBrowser(url) {
12059
11930
  // cli/core.ts
12060
11931
  import { randomUUID } from "crypto";
12061
11932
  import { execFile as execFile2 } from "child_process";
12062
- import { resolve as resolve2, basename, join as join6 } from "path";
11933
+ import { resolve as resolve2, basename, join as join5 } from "path";
12063
11934
  import { existsSync as existsSync3, mkdirSync as mkdirSync4 } from "fs";
12064
- import { platform, arch, release, userInfo, homedir as homedir2, tmpdir as tmpdir2 } from "os";
11935
+ import { platform, arch, release, userInfo, homedir as homedir2, tmpdir } from "os";
12065
11936
  init_tools_shell();
12066
11937
 
12067
11938
  // src/tools.notify.ts
@@ -12249,7 +12120,7 @@ async function buildAgent(o) {
12249
12120
  } else if (o.boddb) {
12250
12121
  const root = resolve2(o.boddb);
12251
12122
  mkdirSync4(root, { recursive: true });
12252
- const db = new BodDB2({ path: join6(root, "meta.db"), sweepInterval: 0, vfs: { storageRoot: join6(root, "files") } });
12123
+ const db = new BodDB2({ path: join5(root, "meta.db"), sweepInterval: 0, vfs: { storageRoot: join5(root, "files") } });
12253
12124
  const bod = new BodDbFilesystem(db);
12254
12125
  const firstRun = (await bod.readDir("/").catch(() => [])).length === 0;
12255
12126
  await mkdirp(bod, cwd);
@@ -12316,7 +12187,7 @@ Reference files in them by their mount path (the left side).`;
12316
12187
  });
12317
12188
  realShell = [makeRealShellTool({ cwd, registry: jobs, osSandbox: o.osSandbox, jobsSurviveRun: o.singleRun !== true }), ...makeShellJobTools(jobs)];
12318
12189
  }
12319
- const scratchDir = o.scratch ? o.scratchDir ?? (virtual ? `${cwd}/.agent/scratch` : `${tmpdir2()}/agentx-scratch-${process.pid}`) : void 0;
12190
+ const scratchDir = o.scratch ? o.scratchDir ?? (virtual ? `${cwd}/.agent/scratch` : `${tmpdir()}/agentx-scratch-${process.pid}`) : void 0;
12320
12191
  const scratch = scratchDir ? new Scratch(fs, { dir: scratchDir }) : void 0;
12321
12192
  return agentRef.agent = new Agent({
12322
12193
  ai: o.ai,
@@ -12429,10 +12300,10 @@ var trunc = (s, n) => (s == null ? "" : String(s).length > n ? String(s).slice(0
12429
12300
 
12430
12301
  // cli/voice.ts
12431
12302
  init_logging();
12432
- import { spawn as spawn2, spawnSync as spawnSync3 } from "child_process";
12303
+ import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
12433
12304
  import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, statSync as statSync5 } from "fs";
12434
12305
  import { homedir as homedir3 } from "os";
12435
- import { dirname as dirname3, join as join7 } from "path";
12306
+ import { dirname as dirname3, join as join6 } from "path";
12436
12307
  import { fileURLToPath } from "url";
12437
12308
  var log27 = forComponent("VoiceIO");
12438
12309
  var now3 = () => performance.now();
@@ -12475,10 +12346,10 @@ var Player = class {
12475
12346
  this.proc = null;
12476
12347
  }
12477
12348
  };
12478
- var nativeDir = () => join7(dirname3(fileURLToPath(import.meta.url)), "native");
12349
+ var nativeDir = () => join6(dirname3(fileURLToPath(import.meta.url)), "native");
12479
12350
  function detectFfmpegMic() {
12480
12351
  if (process.env.MIC_DEVICE) return process.env.MIC_DEVICE;
12481
- const r = spawnSync3("ffmpeg", ["-f", "avfoundation", "-list_devices", "true", "-i", ""], { encoding: "utf8" });
12352
+ const r = spawnSync2("ffmpeg", ["-f", "avfoundation", "-list_devices", "true", "-i", ""], { encoding: "utf8" });
12482
12353
  if (r.error?.code === "ENOENT") throw new Error("ffmpeg not installed \u2014 run `brew install ffmpeg` to enable voice");
12483
12354
  if (r.error) throw new Error(`ffmpeg failed to run (${r.error.message}) \u2014 likely a wrong-arch binary; run \`brew reinstall ffmpeg\``);
12484
12355
  const out = r.stderr ?? "";
@@ -12492,10 +12363,10 @@ function detectFfmpegMic() {
12492
12363
  function detectedInputDevice() {
12493
12364
  if (process.platform !== "darwin") return null;
12494
12365
  let name = "";
12495
- if (spawnSync3("which", ["SwitchAudioSource"]).status === 0) {
12496
- name = (spawnSync3("SwitchAudioSource", ["-c", "-t", "input"], { encoding: "utf8" }).stdout || "").trim();
12366
+ if (spawnSync2("which", ["SwitchAudioSource"]).status === 0) {
12367
+ name = (spawnSync2("SwitchAudioSource", ["-c", "-t", "input"], { encoding: "utf8" }).stdout || "").trim();
12497
12368
  } else {
12498
- const out = spawnSync3("system_profiler", ["SPAudioDataType"], { encoding: "utf8" }).stdout || "";
12369
+ const out = spawnSync2("system_profiler", ["SPAudioDataType"], { encoding: "utf8" }).stdout || "";
12499
12370
  let last = "";
12500
12371
  for (const ln of out.split("\n")) {
12501
12372
  const hdr = ln.match(/^\s{6,}(\S.*?):\s*$/);
@@ -12514,21 +12385,21 @@ function detectedInputDevice() {
12514
12385
  }
12515
12386
  function resolveAecBinary() {
12516
12387
  if (process.env.MIC_AEC === "0" || process.platform !== "darwin") return null;
12517
- const src = join7(nativeDir(), "mic-aec.swift");
12518
- const plist = join7(nativeDir(), "Info.plist");
12388
+ const src = join6(nativeDir(), "mic-aec.swift");
12389
+ const plist = join6(nativeDir(), "Info.plist");
12519
12390
  if (!existsSync4(src)) return null;
12520
- const cacheDir = join7(homedir3(), ".agent", "cache");
12521
- const bin = join7(cacheDir, "mic-aec");
12391
+ const cacheDir = join6(homedir3(), ".agent", "cache");
12392
+ const bin = join6(cacheDir, "mic-aec");
12522
12393
  if (existsSync4(bin) && statSync5(bin).mtimeMs >= statSync5(src).mtimeMs) return bin;
12523
- if (spawnSync3("which", ["swiftc"]).status !== 0) return null;
12394
+ if (spawnSync2("which", ["swiftc"]).status !== 0) return null;
12524
12395
  mkdirSync5(cacheDir, { recursive: true });
12525
12396
  log27.info("compiling AEC mic helper (first run)\u2026");
12526
- const build = spawnSync3("swiftc", ["-O", "-o", bin, src, "-Xlinker", "-sectcreate", "-Xlinker", "__TEXT", "-Xlinker", "__info_plist", "-Xlinker", plist], { encoding: "utf8" });
12397
+ const build = spawnSync2("swiftc", ["-O", "-o", bin, src, "-Xlinker", "-sectcreate", "-Xlinker", "__TEXT", "-Xlinker", "__info_plist", "-Xlinker", plist], { encoding: "utf8" });
12527
12398
  if (build.status !== 0) {
12528
12399
  log27.warn(`AEC build failed: ${build.stderr?.slice(0, 400)}`);
12529
12400
  return null;
12530
12401
  }
12531
- const sign = spawnSync3("codesign", ["-fs", "-", bin], { encoding: "utf8" });
12402
+ const sign = spawnSync2("codesign", ["-fs", "-", bin], { encoding: "utf8" });
12532
12403
  if (sign.status !== 0) {
12533
12404
  log27.warn(`codesign failed: ${sign.stderr?.slice(0, 200)}`);
12534
12405
  return null;
@@ -12538,14 +12409,14 @@ function resolveAecBinary() {
12538
12409
  function openMicSettings() {
12539
12410
  if (process.platform !== "darwin") return;
12540
12411
  try {
12541
- spawnSync3("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]);
12412
+ spawnSync2("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]);
12542
12413
  } catch {
12543
12414
  }
12544
12415
  }
12545
12416
  function micPermissionStatus() {
12546
12417
  const bin = resolveAecBinary();
12547
12418
  if (!bin) return null;
12548
- const r = spawnSync3(bin, ["--check-mic"], { encoding: "utf8" });
12419
+ const r = spawnSync2(bin, ["--check-mic"], { encoding: "utf8" });
12549
12420
  const out = (r.stdout ?? "").trim();
12550
12421
  if (out === "authorized") return "authorized";
12551
12422
  if (out === "denied" || out === "restricted") return "denied";
@@ -12555,7 +12426,7 @@ function micPermissionStatus() {
12555
12426
  function aecUnavailableHint() {
12556
12427
  if (process.env.MIC_AEC === "0" || process.platform !== "darwin") return null;
12557
12428
  if (resolveAecBinary()) return null;
12558
- if (spawnSync3("which", ["swiftc"]).status !== 0) return "install Xcode CLI tools (`xcode-select --install`) for echo cancellation";
12429
+ if (spawnSync2("which", ["swiftc"]).status !== 0) return "install Xcode CLI tools (`xcode-select --install`) for echo cancellation";
12559
12430
  return null;
12560
12431
  }
12561
12432
  var NodeMicSource = class {
@@ -12571,7 +12442,7 @@ var NodeMicSource = class {
12571
12442
  if (this.bin) {
12572
12443
  this.proc = spawn2(this.bin, [], { stdio: ["ignore", "pipe", "ignore"] });
12573
12444
  } else {
12574
- if (spawnSync3("which", ["ffmpeg"]).status !== 0) throw new Error("voice I/O unavailable: no AEC helper and no ffmpeg on PATH");
12445
+ if (spawnSync2("which", ["ffmpeg"]).status !== 0) throw new Error("voice I/O unavailable: no AEC helper and no ffmpeg on PATH");
12575
12446
  log27.info("mic: raw capture (no AEC) \u2014 echo handled heuristically; headphones recommended");
12576
12447
  this.proc = spawn2(
12577
12448
  "ffmpeg",
@@ -13020,12 +12891,12 @@ var JsonlDiagSink = class {
13020
12891
  // cli/config.ts
13021
12892
  import { homedir as homedir4 } from "os";
13022
12893
  import { existsSync as existsSync5, readFileSync as readFileSync7 } from "fs";
13023
- import { join as join8 } from "path";
12894
+ import { join as join7 } from "path";
13024
12895
  import { pathToFileURL } from "url";
13025
12896
  var FILES = ["config.ts", "config.js", "config.mjs", "config.json"];
13026
12897
  async function loadFrom(dir) {
13027
12898
  for (const f of FILES) {
13028
- const p = join8(dir, ".agent", f);
12899
+ const p = join7(dir, ".agent", f);
13029
12900
  if (!existsSync5(p)) continue;
13030
12901
  try {
13031
12902
  const mod = await import(pathToFileURL(p).href, f.endsWith(".json") ? { with: { type: "json" } } : void 0);
@@ -13038,7 +12909,7 @@ async function loadFrom(dir) {
13038
12909
  return {};
13039
12910
  }
13040
12911
  function loadSettings(dir) {
13041
- const p = join8(dir, ".agent", "settings.json");
12912
+ const p = join7(dir, ".agent", "settings.json");
13042
12913
  if (!existsSync5(p)) return {};
13043
12914
  try {
13044
12915
  const raw = JSON.parse(readFileSync7(p, "utf8"));
@@ -13074,7 +12945,7 @@ async function loadConfig(cwd) {
13074
12945
  }
13075
12946
 
13076
12947
  // cli/hooks-config.ts
13077
- import { spawnSync as spawnSync4 } from "child_process";
12948
+ import { spawnSync as spawnSync3 } from "child_process";
13078
12949
  var log29 = forComponent("hooks");
13079
12950
  var escapeRegex = (s) => s.replace(/[.+^${}()|[\]\\]/g, "\\$&");
13080
12951
  function ruleMatches(rule, toolName) {
@@ -13084,7 +12955,7 @@ function ruleMatches(rule, toolName) {
13084
12955
  }
13085
12956
  function runCmd(rule, env) {
13086
12957
  try {
13087
- const r = spawnSync4(rule.command, {
12958
+ const r = spawnSync3(rule.command, {
13088
12959
  shell: true,
13089
12960
  encoding: "utf8",
13090
12961
  timeout: rule.timeoutMs ?? 1e4,
@@ -13196,15 +13067,15 @@ function formatDiff(ops, opts = {}) {
13196
13067
  }
13197
13068
 
13198
13069
  // cli/session.ts
13199
- import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync5, readdirSync, renameSync, symlinkSync as symlinkSync2, unlinkSync, readlinkSync, statSync as statSync6 } from "fs";
13070
+ import { existsSync as existsSync6, mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync4, readdirSync, renameSync, symlinkSync as symlinkSync2, unlinkSync, readlinkSync, statSync as statSync6 } from "fs";
13200
13071
  import { homedir as homedir5 } from "os";
13201
- import { join as join9 } from "path";
13072
+ import { join as join8 } from "path";
13202
13073
  var log30 = forComponent("session");
13203
- var globalDir = () => join9(homedir5(), ".agent", "sessions");
13074
+ var globalDir = () => join8(homedir5(), ".agent", "sessions");
13204
13075
  var SessionStore = class {
13205
13076
  dir;
13206
13077
  constructor(cwd) {
13207
- this.dir = join9(cwd, ".agent", "sessions");
13078
+ this.dir = join8(cwd, ".agent", "sessions");
13208
13079
  }
13209
13080
  /** Sortable, human-readable id: `YYYYMMDD-HHMMSS-<folder>`. */
13210
13081
  newId(now4 = Date.now(), cwd) {
@@ -13212,10 +13083,10 @@ var SessionStore = class {
13212
13083
  const p = (n, w = 2) => String(n).padStart(w, "0");
13213
13084
  const slug2 = (cwd ?? process.cwd()).split("/").pop()?.replace(/[^A-Za-z0-9_-]/g, "") || "session";
13214
13085
  let id = `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}-${slug2}`;
13215
- if (existsSync6(this.dir) && existsSync6(join9(this.dir, `${id}.json`))) {
13086
+ if (existsSync6(this.dir) && existsSync6(join8(this.dir, `${id}.json`))) {
13216
13087
  for (let i = 2; i <= 99; i++) {
13217
13088
  const c = `${id}-${i}`;
13218
- if (!existsSync6(join9(this.dir, `${c}.json`))) {
13089
+ if (!existsSync6(join8(this.dir, `${c}.json`))) {
13219
13090
  id = c;
13220
13091
  break;
13221
13092
  }
@@ -13230,14 +13101,14 @@ var SessionStore = class {
13230
13101
  save(data) {
13231
13102
  if (!this.safeId(data.meta.id)) throw new Error(`unsafe session id: ${data.meta.id}`);
13232
13103
  if (!existsSync6(this.dir)) mkdirSync7(this.dir, { recursive: true });
13233
- const path = join9(this.dir, `${data.meta.id}.json`);
13104
+ const path = join8(this.dir, `${data.meta.id}.json`);
13234
13105
  const tmp = `${path}.${process.pid}.tmp`;
13235
- writeFileSync5(tmp, JSON.stringify(data));
13106
+ writeFileSync4(tmp, JSON.stringify(data));
13236
13107
  renameSync(tmp, path);
13237
13108
  try {
13238
13109
  const gd = globalDir();
13239
13110
  if (!existsSync6(gd)) mkdirSync7(gd, { recursive: true });
13240
- const link2 = join9(gd, `${data.meta.id}.json`);
13111
+ const link2 = join8(gd, `${data.meta.id}.json`);
13241
13112
  if (!existsSync6(link2)) symlinkSync2(path, link2);
13242
13113
  } catch {
13243
13114
  }
@@ -13247,7 +13118,7 @@ var SessionStore = class {
13247
13118
  log30.debug(`rejecting unsafe session id: ${id}`);
13248
13119
  return void 0;
13249
13120
  }
13250
- const path = join9(this.dir, `${id}.json`);
13121
+ const path = join8(this.dir, `${id}.json`);
13251
13122
  if (!existsSync6(path)) return void 0;
13252
13123
  try {
13253
13124
  return JSON.parse(readFileSync8(path, "utf8"));
@@ -13263,7 +13134,7 @@ var SessionStore = class {
13263
13134
  for (const f of readdirSync(this.dir)) {
13264
13135
  if (!f.endsWith(".json")) continue;
13265
13136
  try {
13266
- metas.push(JSON.parse(readFileSync8(join9(this.dir, f), "utf8")).meta);
13137
+ metas.push(JSON.parse(readFileSync8(join8(this.dir, f), "utf8")).meta);
13267
13138
  } catch (e) {
13268
13139
  log30.debug(`skipping unreadable session file ${f}`, e);
13269
13140
  }
@@ -13278,7 +13149,7 @@ var SessionStore = class {
13278
13149
  for (const f of readdirSync(this.dir)) {
13279
13150
  if (!f.endsWith(".json")) continue;
13280
13151
  try {
13281
- const st = statSync6(join9(this.dir, f));
13152
+ const st = statSync6(join8(this.dir, f));
13282
13153
  out.push({ id: f.slice(0, -5), mtime: st.mtimeMs, size: st.size });
13283
13154
  } catch {
13284
13155
  }
@@ -13297,7 +13168,7 @@ var SessionStore = class {
13297
13168
  function globalSessionLoad(idOrPrefix) {
13298
13169
  const gd = globalDir();
13299
13170
  if (!existsSync6(gd)) return void 0;
13300
- const exact = join9(gd, `${idOrPrefix}.json`);
13171
+ const exact = join8(gd, `${idOrPrefix}.json`);
13301
13172
  if (existsSync6(exact)) {
13302
13173
  try {
13303
13174
  const target = readlinkSync(exact);
@@ -13311,7 +13182,7 @@ function globalSessionLoad(idOrPrefix) {
13311
13182
  if (!f.endsWith(".json")) continue;
13312
13183
  const base = f.slice(0, -5);
13313
13184
  if (base.includes(idOrPrefix) || base.endsWith(idOrPrefix)) {
13314
- const target = readlinkSync(join9(gd, f));
13185
+ const target = readlinkSync(join8(gd, f));
13315
13186
  return JSON.parse(readFileSync8(target, "utf8"));
13316
13187
  }
13317
13188
  }
@@ -13326,10 +13197,10 @@ function globalSessionList() {
13326
13197
  for (const f of readdirSync(gd)) {
13327
13198
  if (!f.endsWith(".json")) continue;
13328
13199
  try {
13329
- const target = readlinkSync(join9(gd, f));
13200
+ const target = readlinkSync(join8(gd, f));
13330
13201
  if (!existsSync6(target)) {
13331
13202
  try {
13332
- unlinkSync(join9(gd, f));
13203
+ unlinkSync(join8(gd, f));
13333
13204
  } catch {
13334
13205
  }
13335
13206
  continue;
@@ -13501,9 +13372,9 @@ ${formatDiff(ops)}`);
13501
13372
  // cli/gitCheckpoints.ts
13502
13373
  import { execFile as execFile3 } from "child_process";
13503
13374
  import { promisify } from "util";
13504
- import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
13375
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync8 } from "fs";
13505
13376
  import { homedir as homedir6 } from "os";
13506
- import { join as join10, resolve as resolve3, sep as sep3, parse as parsePath } from "path";
13377
+ import { join as join9, resolve as resolve3, sep as sep3, parse as parsePath } from "path";
13507
13378
  var log31 = forComponent("checkpoints");
13508
13379
  var exec = promisify(execFile3);
13509
13380
  var DEFAULT_EXCLUDE = [".agent/", ".git/", "node_modules/", "dist/", "build/", ".next/", "target/", ".venv/", "__pycache__/", "*.log"];
@@ -13546,8 +13417,8 @@ var ShadowRepo = class {
13546
13417
  mkdirSync8(this.gitDir, { recursive: true });
13547
13418
  const valid = await this.run("rev-parse", "--git-dir").then(() => true, () => false);
13548
13419
  if (!valid) await this.run("init", "-q");
13549
- mkdirSync8(join10(this.gitDir, "info"), { recursive: true });
13550
- writeFileSync6(join10(this.gitDir, "info", "exclude"), this.exclude.join("\n") + "\n");
13420
+ mkdirSync8(join9(this.gitDir, "info"), { recursive: true });
13421
+ writeFileSync5(join9(this.gitDir, "info", "exclude"), this.exclude.join("\n") + "\n");
13551
13422
  this.ready = true;
13552
13423
  } catch (e) {
13553
13424
  log31.debug(`git checkpoints unavailable for ${this.workTree}`, e);
@@ -13662,7 +13533,7 @@ var GitCheckpoints = class {
13662
13533
  const abs = resolve3(d);
13663
13534
  if (abs === cwd || abs.startsWith(cwd + sep3)) continue;
13664
13535
  if (cwd.startsWith(abs + sep3)) continue;
13665
- out.push({ workTree: abs, gitDir: join10(abs, ".agent", "checkpoints.git") });
13536
+ out.push({ workTree: abs, gitDir: join9(abs, ".agent", "checkpoints.git") });
13666
13537
  }
13667
13538
  return out;
13668
13539
  }
@@ -13805,7 +13676,7 @@ var GitCheckpointsOptions = class {
13805
13676
  /** Real working tree to snapshot (the launch cwd). */
13806
13677
  workTree = process.cwd();
13807
13678
  /** Isolated git dir for the cwd shadow repo (kept out of the user's real .git). */
13808
- gitDir = join10(process.cwd(), ".agent", "checkpoints.git");
13679
+ gitDir = join9(process.cwd(), ".agent", "checkpoints.git");
13809
13680
  /** Extra mounted dirs (`--add-dir`); those outside cwd each get their own shadow repo. */
13810
13681
  addDirs = [];
13811
13682
  /** Conversation id → per-session restore-point ref. */
@@ -13821,9 +13692,9 @@ var GitCheckpointsOptions = class {
13821
13692
  };
13822
13693
 
13823
13694
  // cli/permissions.ts
13824
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
13695
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync9 } from "fs";
13825
13696
  import { homedir as homedir7 } from "os";
13826
- import { join as join11 } from "path";
13697
+ import { join as join10 } from "path";
13827
13698
  var RULE_RE = /^(\w[\w*-]*)(?:\((.+)\))?$/;
13828
13699
  function parseOne(raw, decision) {
13829
13700
  const m = RULE_RE.exec(raw.trim());
@@ -13845,13 +13716,13 @@ function parsePermRules(perms, explicit = false) {
13845
13716
  function describeRule(r) {
13846
13717
  return `${r.decision.padEnd(5)} ${r.tool ?? "*"}${r.pathGlob ? `(${r.pathGlob})` : ""}`;
13847
13718
  }
13848
- var PERM_FILE = (cwd) => join11(cwd, ".agent", "permissions.json");
13719
+ var PERM_FILE = (cwd) => join10(cwd, ".agent", "permissions.json");
13849
13720
  function loadPersistedRules(cwd) {
13850
13721
  const j = readJsonFile(PERM_FILE(cwd), null);
13851
13722
  return j ? { allow: j.allow ?? [], ask: j.ask ?? [], deny: j.deny ?? [] } : {};
13852
13723
  }
13853
13724
  function loadClaudeSettings(cwd, home = homedir7()) {
13854
- const files = [join11(home, ".claude", "settings.json"), join11(cwd, ".claude", "settings.json"), join11(cwd, ".claude", "settings.local.json")];
13725
+ const files = [join10(home, ".claude", "settings.json"), join10(cwd, ".claude", "settings.json"), join10(cwd, ".claude", "settings.local.json")];
13855
13726
  let out = {};
13856
13727
  for (const p of files) {
13857
13728
  const perms = readJsonFile(p, null)?.permissions;
@@ -13864,8 +13735,8 @@ function persistRule(cwd, decision, ruleStr) {
13864
13735
  const list = cur[decision] ??= [];
13865
13736
  if (!list.includes(ruleStr)) list.push(ruleStr);
13866
13737
  try {
13867
- mkdirSync9(join11(cwd, ".agent"), { recursive: true });
13868
- writeFileSync7(PERM_FILE(cwd), JSON.stringify(cur, null, 2) + "\n");
13738
+ mkdirSync9(join10(cwd, ".agent"), { recursive: true });
13739
+ writeFileSync6(PERM_FILE(cwd), JSON.stringify(cur, null, 2) + "\n");
13869
13740
  } catch {
13870
13741
  }
13871
13742
  }
@@ -13878,7 +13749,7 @@ function mergePerms(a, b) {
13878
13749
  }
13879
13750
  return Object.keys(out).length ? out : void 0;
13880
13751
  }
13881
- var TRUST_FILE = join11(homedir7(), ".agent", "trusted.json");
13752
+ var TRUST_FILE = join10(homedir7(), ".agent", "trusted.json");
13882
13753
  function isTrusted(cwd, file = TRUST_FILE) {
13883
13754
  const list = readJsonFile(file, []);
13884
13755
  return Array.isArray(list) && list.includes(cwd);
@@ -13888,8 +13759,8 @@ function trustDir(cwd, file = TRUST_FILE) {
13888
13759
  if (!Array.isArray(list)) list = [];
13889
13760
  if (!list.includes(cwd)) list.push(cwd);
13890
13761
  try {
13891
- mkdirSync9(join11(file, ".."), { recursive: true });
13892
- writeFileSync7(file, JSON.stringify(list, null, 2) + "\n");
13762
+ mkdirSync9(join10(file, ".."), { recursive: true });
13763
+ writeFileSync6(file, JSON.stringify(list, null, 2) + "\n");
13893
13764
  } catch {
13894
13765
  }
13895
13766
  }
@@ -13952,10 +13823,10 @@ function completePath(listDir, ref) {
13952
13823
 
13953
13824
  // cli/lineEditor.ts
13954
13825
  import { emitKeypressEvents } from "readline";
13955
- import { spawnSync as spawnSync5 } from "child_process";
13956
- import { writeFileSync as writeFileSync8, readFileSync as readFileSync9, unlinkSync as unlinkSync2 } from "fs";
13957
- import { tmpdir as tmpdir3 } from "os";
13958
- import { join as join12 } from "path";
13826
+ import { spawnSync as spawnSync4 } from "child_process";
13827
+ import { writeFileSync as writeFileSync7, readFileSync as readFileSync9, unlinkSync as unlinkSync2 } from "fs";
13828
+ import { tmpdir as tmpdir2 } from "os";
13829
+ import { join as join11 } from "path";
13959
13830
 
13960
13831
  // cli/bidi.ts
13961
13832
  var RTL_RE = /[\u0590-\u05ff\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb1d-\ufdff\ufe70-\ufeff]/;
@@ -15142,12 +15013,12 @@ function createLineEditor(out, input = keyInput) {
15142
15013
  function externalEdit(s) {
15143
15014
  const spec = process.env.VISUAL || process.env.EDITOR || "vi";
15144
15015
  const [cmd, ...cargs] = spec.split(" ").filter(Boolean);
15145
- const file = join12(tmpdir3(), `agentx-edit-${process.pid}-${Date.now()}.md`);
15016
+ const file = join11(tmpdir2(), `agentx-edit-${process.pid}-${Date.now()}.md`);
15146
15017
  try {
15147
- writeFileSync8(file, s.buf);
15018
+ writeFileSync7(file, s.buf);
15148
15019
  process.stdin.setRawMode(false);
15149
15020
  out.write("\x1B[?2004l");
15150
- const r = spawnSync5(cmd, [...cargs, file], { stdio: "inherit" });
15021
+ const r = spawnSync4(cmd, [...cargs, file], { stdio: "inherit" });
15151
15022
  if (r.status === 0) {
15152
15023
  const text = readFileSync9(file, "utf8").replace(/\n$/, "");
15153
15024
  s.reset();
@@ -15602,10 +15473,10 @@ function readPlainLine() {
15602
15473
  }
15603
15474
 
15604
15475
  // cli/osScheduler.ts
15605
- import { spawnSync as spawnSync6 } from "child_process";
15606
- import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3, chmodSync, existsSync as existsSync7 } from "fs";
15476
+ import { spawnSync as spawnSync5 } from "child_process";
15477
+ import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync10, readdirSync as readdirSync2, unlinkSync as unlinkSync3, chmodSync, existsSync as existsSync7 } from "fs";
15607
15478
  import { homedir as homedir8 } from "os";
15608
- import { join as join13 } from "path";
15479
+ import { join as join12 } from "path";
15609
15480
  var log32 = forComponent("os-sched");
15610
15481
  var OsScheduler = class {
15611
15482
  options;
@@ -15613,13 +15484,13 @@ var OsScheduler = class {
15613
15484
  this.options = { ...new OsSchedulerOptions(), ...options };
15614
15485
  }
15615
15486
  get dir() {
15616
- return join13(this.options.home, ".agent", "sched");
15487
+ return join12(this.options.home, ".agent", "sched");
15617
15488
  }
15618
15489
  label(id) {
15619
15490
  return `cc.livx.agentx.sched-${id}`;
15620
15491
  }
15621
15492
  plistPath(id) {
15622
- return join13(this.options.home, "Library", "LaunchAgents", `${this.label(id)}.plist`);
15493
+ return join12(this.options.home, "Library", "LaunchAgents", `${this.label(id)}.plist`);
15623
15494
  }
15624
15495
  run(cmd, args, input) {
15625
15496
  return this.options.exec(cmd, args, input);
@@ -15635,11 +15506,11 @@ var OsScheduler = class {
15635
15506
  const script = this.writeScript(spec, oneOff);
15636
15507
  const mechanism = this.options.platform === "darwin" ? this.scheduleDarwin(spec, script) : this.scheduleLinux(spec, script, oneOff);
15637
15508
  const meta = { ...spec, created: Date.now(), mechanism };
15638
- writeFileSync9(join13(this.dir, `${spec.id}.json`), JSON.stringify(meta, null, 2));
15509
+ writeFileSync8(join12(this.dir, `${spec.id}.json`), JSON.stringify(meta, null, 2));
15639
15510
  return mechanism;
15640
15511
  }
15641
15512
  cancel(id) {
15642
- const meta = readJsonFile(join13(this.dir, `${id}.json`), null);
15513
+ const meta = readJsonFile(join12(this.dir, `${id}.json`), null);
15643
15514
  if (!meta) return false;
15644
15515
  try {
15645
15516
  if (this.options.platform === "darwin") {
@@ -15672,7 +15543,7 @@ var OsScheduler = class {
15672
15543
  }
15673
15544
  for (const f of [`${id}.json`, `${id}.sh`]) {
15674
15545
  try {
15675
- unlinkSync3(join13(this.dir, f));
15546
+ unlinkSync3(join12(this.dir, f));
15676
15547
  } catch {
15677
15548
  }
15678
15549
  }
@@ -15680,19 +15551,19 @@ var OsScheduler = class {
15680
15551
  }
15681
15552
  list() {
15682
15553
  if (!existsSync7(this.dir)) return [];
15683
- return readdirSync2(this.dir).filter((f) => f.endsWith(".json")).map((f) => readJsonFile(join13(this.dir, f), null)).filter(Boolean);
15554
+ return readdirSync2(this.dir).filter((f) => f.endsWith(".json")).map((f) => readJsonFile(join12(this.dir, f), null)).filter(Boolean);
15684
15555
  }
15685
15556
  /** The per-job runner script: cd to the project, headless-resume the session, log, notify. */
15686
15557
  writeScript(spec, oneOff) {
15687
- const p = join13(this.dir, `${spec.id}.sh`);
15558
+ const p = join12(this.dir, `${spec.id}.sh`);
15688
15559
  const q2 = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
15689
- const cleanup = oneOff ? this.options.platform === "darwin" ? `launchctl remove ${this.label(spec.id)} 2>/dev/null; rm -f ${q2(this.plistPath(spec.id))} ${q2(join13(this.dir, `${spec.id}.json`))} ${q2(p)}
15690
- ` : `rm -f ${q2(join13(this.dir, `${spec.id}.json`))} ${q2(p)}
15560
+ const cleanup = oneOff ? this.options.platform === "darwin" ? `launchctl remove ${this.label(spec.id)} 2>/dev/null; rm -f ${q2(this.plistPath(spec.id))} ${q2(join12(this.dir, `${spec.id}.json`))} ${q2(p)}
15561
+ ` : `rm -f ${q2(join12(this.dir, `${spec.id}.json`))} ${q2(p)}
15691
15562
  ` : "";
15692
- writeFileSync9(p, `#!/bin/sh
15563
+ writeFileSync8(p, `#!/bin/sh
15693
15564
  # agentx scheduled job ${spec.id}${spec.label ? ` \u2014 ${spec.label}` : ""}
15694
15565
  cd ${q2(spec.cwd)} || exit 1
15695
- ${this.options.agentx} -p ${q2(spec.prompt)} --resume ${q2(spec.sessionId)} --yes >> ${q2(join13(this.dir, `${spec.id}.log`))} 2>&1
15566
+ ${this.options.agentx} -p ${q2(spec.prompt)} --resume ${q2(spec.sessionId)} --yes >> ${q2(join12(this.dir, `${spec.id}.log`))} 2>&1
15696
15567
  ${cleanup}`);
15697
15568
  chmodSync(p, 493);
15698
15569
  return p;
@@ -15729,8 +15600,8 @@ ${trigger}
15729
15600
  <key>RunAtLoad</key><false/>
15730
15601
  </dict></plist>
15731
15602
  `;
15732
- mkdirSync10(join13(this.options.home, "Library", "LaunchAgents"), { recursive: true });
15733
- writeFileSync9(this.plistPath(spec.id), plist);
15603
+ mkdirSync10(join12(this.options.home, "Library", "LaunchAgents"), { recursive: true });
15604
+ writeFileSync8(this.plistPath(spec.id), plist);
15734
15605
  this.run("launchctl", ["load", this.plistPath(spec.id)]);
15735
15606
  return `launchd:${this.label(spec.id)}`;
15736
15607
  }
@@ -15767,7 +15638,7 @@ var OsSchedulerOptions = class {
15767
15638
  /** Injectable executor for tests. Returns stdout+stderr merged — `at` reports "job N" on STDERR,
15768
15639
  * and the job id is what atrm needs for cancel. Throws on non-zero exit. */
15769
15640
  exec = (cmd, args, input) => {
15770
- const r = spawnSync6(cmd, args, { input, encoding: "utf8" });
15641
+ const r = spawnSync5(cmd, args, { input, encoding: "utf8" });
15771
15642
  if (r.error) throw r.error;
15772
15643
  if (r.status !== 0) throw new Error(`${cmd} exited ${r.status}: ${r.stderr || r.stdout}`);
15773
15644
  return `${r.stdout ?? ""}${r.stderr ?? ""}`;
@@ -15784,10 +15655,10 @@ import { createServer as createServer2, createConnection } from "net";
15784
15655
  import { spawn as spawn3 } from "child_process";
15785
15656
  import { existsSync as existsSync8, mkdirSync as mkdirSync11, unlinkSync as unlinkSync4, readdirSync as readdirSync3 } from "fs";
15786
15657
  import { homedir as homedir9 } from "os";
15787
- import { join as join14 } from "path";
15658
+ import { join as join13 } from "path";
15788
15659
  var log33 = forComponent("remote-trigger");
15789
- var TRIGGER_DIR = () => join14(homedir9(), ".agent", "triggers");
15790
- var sockPath = (sessionId, dir = TRIGGER_DIR()) => join14(dir, `${sessionId}.sock`);
15660
+ var TRIGGER_DIR = () => join13(homedir9(), ".agent", "triggers");
15661
+ var sockPath = (sessionId, dir = TRIGGER_DIR()) => join13(dir, `${sessionId}.sock`);
15791
15662
  var TriggerServer = class {
15792
15663
  constructor(onTrigger) {
15793
15664
  this.onTrigger = onTrigger;
@@ -15973,7 +15844,7 @@ async function checkForUpdate(current) {
15973
15844
  return `Update available: ${current} \u2192 ${latest}. Run \`bun add -g @livx.cc/agentx\` to update.`;
15974
15845
  }
15975
15846
  function installUpdate() {
15976
- const r = spawnSync7("bun", ["add", "-g", "@livx.cc/agentx"], { stdio: "inherit" });
15847
+ const r = spawnSync6("bun", ["add", "-g", "@livx.cc/agentx"], { stdio: "inherit" });
15977
15848
  return (r.status ?? 1) === 0;
15978
15849
  }
15979
15850
  var typeaheadOnLine = false;
@@ -16272,10 +16143,10 @@ function loadEnvFile(file) {
16272
16143
  }
16273
16144
  function loadInstallEnv() {
16274
16145
  let dir = dirname5(import.meta.path);
16275
- for (let i = 0; i < 5 && !existsSync9(join15(dir, "package.json")); i++) dir = dirname5(dir);
16146
+ for (let i = 0; i < 5 && !existsSync9(join14(dir, "package.json")); i++) dir = dirname5(dir);
16276
16147
  for (const name of [".env", ".env.local"]) {
16277
- loadEnvFile(join15(dir, name));
16278
- loadEnvFile(join15(homedir10(), ".agent", name));
16148
+ loadEnvFile(join14(dir, name));
16149
+ loadEnvFile(join14(homedir10(), ".agent", name));
16279
16150
  }
16280
16151
  }
16281
16152
  async function loadBodifySecrets() {
@@ -16999,7 +16870,7 @@ var IMG_EXT = { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg"
16999
16870
  function mentionRefs(line) {
17000
16871
  return [...line.matchAll(/(?:^|\s)@(?:"([^"]+)"|(\S+))/g)].map((m) => m[1] ?? m[2].replace(/[?!.,;:)\]}'">]+$/, "")).filter(Boolean);
17001
16872
  }
17002
- var untilde = (p) => p.startsWith("~/") ? join15(homedir10(), p.slice(2)) : p;
16873
+ var untilde = (p) => p.startsWith("~/") ? join14(homedir10(), p.slice(2)) : p;
17003
16874
  function readImageParts(cwd, line) {
17004
16875
  const refs = mentionRefs(line);
17005
16876
  const parts = [];
@@ -17080,6 +16951,7 @@ function jsonResult(res, session) {
17080
16951
  steps: res.steps,
17081
16952
  tools: res.messages.slice(lastUser).filter((m) => m.role === "tool").length,
17082
16953
  usage: res.usage,
16954
+ ...res.budget ? { budget: res.budget } : {},
17083
16955
  ...res.routing ? { costUsd: res.costUsd, routing: res.routing } : {},
17084
16956
  // cast: tsup dts hoists a modelRouter import above the shebang
17085
16957
  sessionId: session.meta.id,
@@ -17203,7 +17075,7 @@ async function runTurn(agent, store, session, task, cp, cwd = process.cwd(), sen
17203
17075
  }
17204
17076
  return { ok, res };
17205
17077
  }
17206
- var remintSessionImages = (data, store, cwd) => remintImageRefs(data.messages, [join15(store.dir, `${data.meta.id}.images`), cwd]);
17078
+ var remintSessionImages = (data, store, cwd) => remintImageRefs(data.messages, [join14(store.dir, `${data.meta.id}.images`), cwd]);
17207
17079
  function startSession(args, store, agent, cwd) {
17208
17080
  if (args.resume || args.cont) {
17209
17081
  const data = args.resume ? store.load(args.resume) ?? globalSessionLoad(args.resume) : store.latestData();
@@ -17250,25 +17122,25 @@ var AGENTS_MD_TEMPLATE = `# ${"${name}"}
17250
17122
  `;
17251
17123
  function initInstructions(cwd) {
17252
17124
  for (const f of ["AGENTS.md", "CLAUDE.md"]) {
17253
- if (existsSync9(join15(cwd, f))) {
17125
+ if (existsSync9(join14(cwd, f))) {
17254
17126
  err(yellow(` ${f} already exists \u2014 leaving it as-is
17255
17127
  `));
17256
17128
  return;
17257
17129
  }
17258
17130
  }
17259
- const path = join15(cwd, "AGENTS.md");
17260
- writeFileSync10(path, AGENTS_MD_TEMPLATE.replace("${name}", basename2(cwd)));
17131
+ const path = join14(cwd, "AGENTS.md");
17132
+ writeFileSync9(path, AGENTS_MD_TEMPLATE.replace("${name}", basename2(cwd)));
17261
17133
  err(green(` created ${path}
17262
17134
  `) + dim(" edit it, then it auto-loads into every run.\n"));
17263
17135
  }
17264
17136
  function persistSetting(cwd, key, value) {
17265
- const path = join15(cwd, ".agent", "settings.json");
17137
+ const path = join14(cwd, ".agent", "settings.json");
17266
17138
  try {
17267
17139
  const obj = existsSync9(path) ? JSON.parse(readFileSync10(path, "utf8")) : {};
17268
17140
  if (obj[key] === value) return;
17269
17141
  obj[key] = value;
17270
17142
  mkdirSync12(dirname5(path), { recursive: true });
17271
- writeFileSync10(path, JSON.stringify(obj, null, 2) + "\n");
17143
+ writeFileSync9(path, JSON.stringify(obj, null, 2) + "\n");
17272
17144
  } catch (e) {
17273
17145
  err(yellow(` \u26A0 couldn't persist ${key} to ${path} \u2014 ${e?.message ?? e}
17274
17146
  `));
@@ -17300,7 +17172,7 @@ function installCancelGuards(mounted) {
17300
17172
  });
17301
17173
  }
17302
17174
  async function repl(args, ai, cfg, cwd) {
17303
- const oauth = new McpOAuth({ storePath: join15(cwd, ".agent", "mcp-auth.json") });
17175
+ const oauth = new McpOAuth({ storePath: join14(cwd, ".agent", "mcp-auth.json") });
17304
17176
  const mounted = await mountMcp(cfg, oauth);
17305
17177
  let mcpToolNames = [];
17306
17178
  const initialMcpTools = mcpAgentTools(mounted);
@@ -17576,7 +17448,7 @@ async function repl(args, ai, cfg, cwd) {
17576
17448
  quickLook: {
17577
17449
  branch: () => {
17578
17450
  try {
17579
- const head = readFileSync10(join15(cwd, ".git", "HEAD"), "utf8").trim();
17451
+ const head = readFileSync10(join14(cwd, ".git", "HEAD"), "utf8").trim();
17580
17452
  return head.startsWith("ref: refs/heads/") ? `branch: ${head.slice("ref: refs/heads/".length)}` : `detached HEAD at ${head.slice(0, 12)}`;
17581
17453
  } catch {
17582
17454
  return "not a git repository";
@@ -17710,7 +17582,7 @@ async function repl(args, ai, cfg, cwd) {
17710
17582
  const pendingImages = [];
17711
17583
  const bangContext = [];
17712
17584
  const grabClipboardAttachment = () => {
17713
- const dir = join15(store.dir, `${session.meta.id}.images`);
17585
+ const dir = join14(store.dir, `${session.meta.id}.images`);
17714
17586
  try {
17715
17587
  mkdirSync12(dir, { recursive: true });
17716
17588
  } catch (e) {
@@ -17768,7 +17640,7 @@ async function repl(args, ai, cfg, cwd) {
17768
17640
  err(dim(` \u23F0 ${scheduler.size} scheduled job(s) re-armed
17769
17641
  `));
17770
17642
  }
17771
- const checkpoints = args.vfs || args.boddb ? new CheckpointStack(agent.options.fs) : new GitCheckpoints({ workTree: cwd, gitDir: join15(cwd, ".agent", "checkpoints.git"), addDirs: args.addDirs, sessionId: session.meta.id });
17643
+ const checkpoints = args.vfs || args.boddb ? new CheckpointStack(agent.options.fs) : new GitCheckpoints({ workTree: cwd, gitDir: join14(cwd, ".agent", "checkpoints.git"), addDirs: args.addDirs, sessionId: session.meta.id });
17772
17644
  const cpHooks = checkpoints.hooks?.();
17773
17645
  if (cpHooks) {
17774
17646
  agent.options.hooks = composeHooks(agent.options.hooks, cpHooks);
@@ -17820,11 +17692,11 @@ ${lines.join("\n")}
17820
17692
  Added entries are loadable now via the Skill/SlashCommand tools; removed ones are gone even if still listed in the system prompt.
17821
17693
  </system-reminder>`;
17822
17694
  };
17823
- const histPath = join15(cwd, ".agent", "history");
17695
+ const histPath = join14(cwd, ".agent", "history");
17824
17696
  const history = existsSync9(histPath) ? readFileSync10(histPath, "utf8").split("\n").filter(Boolean).reverse().slice(0, 500) : [];
17825
17697
  const remember2 = (line) => {
17826
17698
  try {
17827
- mkdirSync12(join15(cwd, ".agent"), { recursive: true });
17699
+ mkdirSync12(join14(cwd, ".agent"), { recursive: true });
17828
17700
  appendFileSync(histPath, line + "\n");
17829
17701
  } catch (e) {
17830
17702
  log34.debug("history write failed", e);
@@ -18127,8 +17999,8 @@ ${task}`;
18127
17999
  const wasRaw = process.stdin.isTTY && process.stdin.isRaw;
18128
18000
  if (wasRaw) process.stdin.setRawMode(false);
18129
18001
  try {
18130
- const { spawnSync: spawnSync8 } = await import("child_process");
18131
- const r = spawnSync8("less", ["-R"], { input: text, stdio: ["pipe", "inherit", "inherit"] });
18002
+ const { spawnSync: spawnSync7 } = await import("child_process");
18003
+ const r = spawnSync7("less", ["-R"], { input: text, stdio: ["pipe", "inherit", "inherit"] });
18132
18004
  if (r.error) err(text);
18133
18005
  } finally {
18134
18006
  if (wasRaw) process.stdin.setRawMode(true);
@@ -18148,8 +18020,8 @@ ${task}`;
18148
18020
  keys.length ? ok(`provider keys: ${keys.join(", ")}`) : bad("no provider keys set (ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY)");
18149
18021
  process.env.BODIFY_API_KEY && process.env.BODIFY_APP_ID ? ok(`bodify secrets: ${process.env.BODIFY_APP_ID}`) : warn("bodify secrets: not configured (set BODIFY_API_KEY + BODIFY_APP_ID)");
18150
18022
  {
18151
- const { spawnSync: spawnSync8 } = await import("child_process");
18152
- const has = (cmd) => spawnSync8("which", [cmd]).status === 0;
18023
+ const { spawnSync: spawnSync7 } = await import("child_process");
18024
+ const has = (cmd) => spawnSync7("which", [cmd]).status === 0;
18153
18025
  if (!VoiceIO.available()) warn("voice: keys missing (SONIOX_API_KEY / CARTESIA_API_KEY / CARTESIA_VOICE_ID) \u2014 voice disabled");
18154
18026
  else {
18155
18027
  ok("voice: keys present");
@@ -18170,7 +18042,7 @@ ${task}`;
18170
18042
  try {
18171
18043
  const probe = `${cwd}/.agent/sessions/.doctor-probe`;
18172
18044
  mkdirSync12(`${cwd}/.agent/sessions`, { recursive: true });
18173
- writeFileSync10(probe, "ok");
18045
+ writeFileSync9(probe, "ok");
18174
18046
  unlinkSync5(probe);
18175
18047
  ok(`session store writable (${cwd}/.agent/sessions)`);
18176
18048
  } catch (e) {
@@ -18580,8 +18452,8 @@ ${task}`;
18580
18452
  const wasRaw = process.stdin.isTTY && process.stdin.isRaw;
18581
18453
  if (wasRaw) process.stdin.setRawMode(false);
18582
18454
  try {
18583
- const { spawnSync: spawnSync8 } = await import("child_process");
18584
- spawnSync8(ed, [idx], { stdio: "inherit" });
18455
+ const { spawnSync: spawnSync7 } = await import("child_process");
18456
+ spawnSync7(ed, [idx], { stdio: "inherit" });
18585
18457
  } finally {
18586
18458
  if (wasRaw) process.stdin.setRawMode(true);
18587
18459
  }
@@ -18931,11 +18803,11 @@ ${task}`;
18931
18803
  return;
18932
18804
  }
18933
18805
  const md = exportMarkdown(session.meta, shown);
18934
- const name = a[0] ? extname(a[0]) ? a[0] : a[0] + ".md" : join15(".agent", "exports", `${session.meta.id}.md`);
18806
+ const name = a[0] ? extname(a[0]) ? a[0] : a[0] + ".md" : join14(".agent", "exports", `${session.meta.id}.md`);
18935
18807
  const path = resolve4(cwd, name);
18936
18808
  try {
18937
18809
  mkdirSync12(dirname5(path), { recursive: true });
18938
- writeFileSync10(path, md);
18810
+ writeFileSync9(path, md);
18939
18811
  err(green(` \u2713 exported \u2192 ${path}
18940
18812
  `) + dim(` ${shown.length} message(s) \xB7 ${md.length} chars
18941
18813
  `));
@@ -19017,7 +18889,7 @@ ${task}`;
19017
18889
  });
19018
18890
  const listDir = (absDir) => {
19019
18891
  try {
19020
- return readdirSync4(join15(cwd, absDir.replace(/^\/+/, "")), { withFileTypes: true }).map((d) => ({ name: d.name, dir: d.isDirectory() }));
18892
+ return readdirSync4(join14(cwd, absDir.replace(/^\/+/, "")), { withFileTypes: true }).map((d) => ({ name: d.name, dir: d.isDirectory() }));
19021
18893
  } catch (e) {
19022
18894
  log34.debug("completion readdir failed", absDir, e);
19023
18895
  return null;
@@ -19202,7 +19074,7 @@ ${out}
19202
19074
  return false;
19203
19075
  }
19204
19076
  const fakeVoice = process.env.AGENTX_VOICE_FAKE ? fakeVoiceParts(process.env.AGENTX_VOICE_FAKE) : null;
19205
- voiceDiag = new JsonlDiagSink(join15(store.dir, `${session.meta.id}.voice.jsonl`));
19077
+ voiceDiag = new JsonlDiagSink(join14(store.dir, `${session.meta.id}.voice.jsonl`));
19206
19078
  voiceIO = new VoiceIO({
19207
19079
  ...fakeVoice ?? {},
19208
19080
  onDiag: (ev) => voiceDiag?.push(ev),
@@ -19605,7 +19477,7 @@ ${out}
19605
19477
  }
19606
19478
  async function duplexServe(args, ai, cfg, cwd) {
19607
19479
  const out = (o) => process.stdout.write(JSON.stringify(o) + "\n");
19608
- const mounted = await mountMcp(cfg, new McpOAuth({ storePath: join15(cwd, ".agent", "mcp-auth.json") }));
19480
+ const mounted = await mountMcp(cfg, new McpOAuth({ storePath: join14(cwd, ".agent", "mcp-auth.json") }));
19609
19481
  installCancelGuards(mounted);
19610
19482
  const agent = await makeAgent(args, ai, cfg, mcpAgentTools(mounted, { quiet: true }), mounted.map((m) => m.name));
19611
19483
  const { host: _h, stream: _s, signal: _g, providerOptions: _po, ...wo } = agent.options;
@@ -19787,7 +19659,7 @@ async function main() {
19787
19659
  }
19788
19660
  });
19789
19661
  if (args.task) {
19790
- const mounted = await mountMcp(cfg, new McpOAuth({ storePath: join15(cwd, ".agent", "mcp-auth.json") }));
19662
+ const mounted = await mountMcp(cfg, new McpOAuth({ storePath: join14(cwd, ".agent", "mcp-auth.json") }));
19791
19663
  const agent = await makeAgent(args, ai, cfg, mcpAgentTools(mounted), mounted.map((m) => m.name));
19792
19664
  const store = new SessionStore(cwd);
19793
19665
  const session = startSession(args, store, agent, cwd);