open-agents-ai 0.168.0 → 0.170.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 (2) hide show
  1. package/dist/index.js +1115 -836
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10483,8 +10483,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
10483
10483
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
10484
10484
  const filePath = join16(dir, `${name}.json`);
10485
10485
  if (existsSync13(filePath)) {
10486
- const { unlinkSync: unlinkSync11 } = __require("node:fs");
10487
- unlinkSync11(filePath);
10486
+ const { unlinkSync: unlinkSync12 } = __require("node:fs");
10487
+ unlinkSync12(filePath);
10488
10488
  return true;
10489
10489
  }
10490
10490
  return false;
@@ -11659,8 +11659,8 @@ async function loadTranscribeCli() {
11659
11659
  const nvmBase = join19(homedir6(), ".nvm", "versions", "node");
11660
11660
  if (existsSync16(nvmBase)) {
11661
11661
  try {
11662
- const { readdirSync: readdirSync19 } = await import("node:fs");
11663
- for (const ver of readdirSync19(nvmBase)) {
11662
+ const { readdirSync: readdirSync20 } = await import("node:fs");
11663
+ for (const ver of readdirSync20(nvmBase)) {
11664
11664
  const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
11665
11665
  if (existsSync16(join19(tcPath, "dist", "index.js"))) {
11666
11666
  const { createRequire: createRequire4 } = await import("node:module");
@@ -12713,13 +12713,13 @@ Justification: ${justification || "(none provided)"}`,
12713
12713
  }
12714
12714
  const snapshot = JSON.stringify(this.selfState, null, 2);
12715
12715
  try {
12716
- const { createHash: createHash5 } = await import("node:crypto");
12716
+ const { createHash: createHash6 } = await import("node:crypto");
12717
12717
  const snapshotDir = join21(this.cwd, ".oa", "identity", "snapshots");
12718
12718
  await mkdir5(snapshotDir, { recursive: true });
12719
12719
  const version = this.selfState.version;
12720
12720
  const snapshotPath = join21(snapshotDir, `v${version}.json`);
12721
12721
  await writeFile9(snapshotPath, snapshot, "utf8");
12722
- const hash = createHash5("sha256").update(snapshot).digest("hex");
12722
+ const hash = createHash6("sha256").update(snapshot).digest("hex");
12723
12723
  await writeFile9(join21(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
12724
12724
  let ipfsCid = "";
12725
12725
  try {
@@ -12852,8 +12852,8 @@ New: ${newNarrative.slice(0, 200)}...`,
12852
12852
  }
12853
12853
  // ── Helpers ──────────────────────────────────────────────────────────────
12854
12854
  createDefaultState() {
12855
- const { createHash: createHash5 } = __require("node:crypto");
12856
- const machineId = createHash5("sha256").update(this.cwd).digest("hex").slice(0, 12);
12855
+ const { createHash: createHash6 } = __require("node:crypto");
12856
+ const machineId = createHash6("sha256").update(this.cwd).digest("hex").slice(0, 12);
12857
12857
  return {
12858
12858
  self_id: `oa-${machineId}`,
12859
12859
  version: 1,
@@ -13402,9 +13402,9 @@ print("${sentinel}")
13402
13402
  if (!this.proc || this.proc.killed) {
13403
13403
  return { success: false, path: "" };
13404
13404
  }
13405
- const { mkdirSync: mkdirSync24, writeFileSync: writeFileSync23 } = await import("node:fs");
13405
+ const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = await import("node:fs");
13406
13406
  const sessionDir = join22(this.cwd, ".oa", "rlm");
13407
- mkdirSync24(sessionDir, { recursive: true });
13407
+ mkdirSync25(sessionDir, { recursive: true });
13408
13408
  const sessionPath = join22(sessionDir, "session.json");
13409
13409
  try {
13410
13410
  const inspectCode = `
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13428
13428
  trajectoryCount: this.trajectory.length,
13429
13429
  subCallCount: this.subCallCount
13430
13430
  };
13431
- writeFileSync23(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13431
+ writeFileSync24(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13432
13432
  return { success: true, path: sessionPath };
13433
13433
  }
13434
13434
  } catch {
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13440
13440
  * what was previously computed. */
13441
13441
  async loadSessionInfo() {
13442
13442
  try {
13443
- const { readFileSync: readFileSync38, existsSync: existsSync50 } = await import("node:fs");
13443
+ const { readFileSync: readFileSync39, existsSync: existsSync51 } = await import("node:fs");
13444
13444
  const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
13445
- if (!existsSync50(sessionPath))
13445
+ if (!existsSync51(sessionPath))
13446
13446
  return null;
13447
- return JSON.parse(readFileSync38(sessionPath, "utf8"));
13447
+ return JSON.parse(readFileSync39(sessionPath, "utf8"));
13448
13448
  } catch {
13449
13449
  return null;
13450
13450
  }
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
13621
13621
  const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
13622
13622
  let lessons = [];
13623
13623
  try {
13624
- const { readdirSync: readdirSync19, readFileSync: readFileSync38 } = await import("node:fs");
13625
- const files = readdirSync19(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
13624
+ const { readdirSync: readdirSync20, readFileSync: readFileSync39 } = await import("node:fs");
13625
+ const files = readdirSync20(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
13626
13626
  for (const file of files) {
13627
- const lines = readFileSync38(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13627
+ const lines = readFileSync39(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13628
13628
  for (const line of lines) {
13629
13629
  try {
13630
13630
  const entry = JSON.parse(line);
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14008
14008
  * Optionally filter by task type for phase-aware context (FSM paper insight).
14009
14009
  */
14010
14010
  getTopMemoriesSync(k = 5, taskType) {
14011
- const { readFileSync: readFileSync38, existsSync: existsSync50 } = __require("node:fs");
14011
+ const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
14012
14012
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14013
14013
  const storeFile = join23(metaDir, "store.json");
14014
- if (!existsSync50(storeFile))
14014
+ if (!existsSync51(storeFile))
14015
14015
  return "";
14016
14016
  let store = [];
14017
14017
  try {
14018
- store = JSON.parse(readFileSync38(storeFile, "utf8"));
14018
+ store = JSON.parse(readFileSync39(storeFile, "utf8"));
14019
14019
  } catch {
14020
14020
  return "";
14021
14021
  }
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14037
14037
  /** Update memory scores based on task outcome. Called after task completion.
14038
14038
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
14039
14039
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
14040
- const { readFileSync: readFileSync38, writeFileSync: writeFileSync23, existsSync: existsSync50, mkdirSync: mkdirSync24 } = __require("node:fs");
14040
+ const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
14041
14041
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14042
14042
  const storeFile = join23(metaDir, "store.json");
14043
- if (!existsSync50(storeFile))
14043
+ if (!existsSync51(storeFile))
14044
14044
  return;
14045
14045
  let store = [];
14046
14046
  try {
14047
- store = JSON.parse(readFileSync38(storeFile, "utf8"));
14047
+ store = JSON.parse(readFileSync39(storeFile, "utf8"));
14048
14048
  } catch {
14049
14049
  return;
14050
14050
  }
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14068
14068
  updated = true;
14069
14069
  }
14070
14070
  if (updated) {
14071
- mkdirSync24(metaDir, { recursive: true });
14072
- writeFileSync23(storeFile, JSON.stringify(store, null, 2));
14071
+ mkdirSync25(metaDir, { recursive: true });
14072
+ writeFileSync24(storeFile, JSON.stringify(store, null, 2));
14073
14073
  }
14074
14074
  }
14075
14075
  // ── Storage ──────────────────────────────────────────────────────────
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14491
14491
  // Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
14492
14492
  /** Retrieve top-K strategies for context injection. Returns "" if none. */
14493
14493
  getRelevantStrategiesSync(k = 3, taskType) {
14494
- const { readFileSync: readFileSync38, existsSync: existsSync50 } = __require("node:fs");
14494
+ const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
14495
14495
  const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
14496
- if (!existsSync50(archiveFile))
14496
+ if (!existsSync51(archiveFile))
14497
14497
  return "";
14498
14498
  let variants = [];
14499
14499
  try {
14500
- variants = JSON.parse(readFileSync38(archiveFile, "utf8"));
14500
+ variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
14501
14501
  } catch {
14502
14502
  return "";
14503
14503
  }
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14515
14515
  }
14516
14516
  /** Archive a strategy variant synchronously (for task completion path) */
14517
14517
  archiveVariantSync(strategy, outcome, tags = []) {
14518
- const { readFileSync: readFileSync38, writeFileSync: writeFileSync23, existsSync: existsSync50, mkdirSync: mkdirSync24 } = __require("node:fs");
14518
+ const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
14519
14519
  const dir = join25(this.cwd, ".oa", "arche");
14520
14520
  const archiveFile = join25(dir, "variants.json");
14521
14521
  let variants = [];
14522
14522
  try {
14523
- if (existsSync50(archiveFile))
14524
- variants = JSON.parse(readFileSync38(archiveFile, "utf8"));
14523
+ if (existsSync51(archiveFile))
14524
+ variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
14525
14525
  } catch {
14526
14526
  }
14527
14527
  variants.push({
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14536
14536
  });
14537
14537
  if (variants.length > 50)
14538
14538
  variants = variants.slice(-50);
14539
- mkdirSync24(dir, { recursive: true });
14540
- writeFileSync23(archiveFile, JSON.stringify(variants, null, 2));
14539
+ mkdirSync25(dir, { recursive: true });
14540
+ writeFileSync24(archiveFile, JSON.stringify(variants, null, 2));
14541
14541
  }
14542
14542
  async saveArchive(variants) {
14543
14543
  const dir = join25(this.cwd, ".oa", "arche");
@@ -21201,19 +21201,293 @@ var init_environment_snapshot = __esm({
21201
21201
  }
21202
21202
  });
21203
21203
 
21204
+ // packages/execution/dist/tools/video-understand.js
21205
+ import { execSync as execSync24 } from "node:child_process";
21206
+ import { existsSync as existsSync27, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync20, readdirSync as readdirSync7, unlinkSync as unlinkSync4 } from "node:fs";
21207
+ import { join as join41, basename as basename10 } from "node:path";
21208
+ import { createHash as createHash2 } from "node:crypto";
21209
+ function isYouTubeUrl2(url) {
21210
+ return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
21211
+ }
21212
+ function ensureYtDlp2() {
21213
+ try {
21214
+ execSync24("yt-dlp --version", { timeout: 5e3, stdio: "pipe" });
21215
+ return true;
21216
+ } catch {
21217
+ try {
21218
+ execSync24("pip3 install --break-system-packages yt-dlp 2>/dev/null || pip3 install --user yt-dlp 2>/dev/null", { timeout: 6e4, stdio: "pipe" });
21219
+ return true;
21220
+ } catch {
21221
+ return false;
21222
+ }
21223
+ }
21224
+ }
21225
+ function ensureFfmpeg() {
21226
+ try {
21227
+ execSync24("ffmpeg -version", { timeout: 3e3, stdio: "pipe" });
21228
+ return true;
21229
+ } catch {
21230
+ return false;
21231
+ }
21232
+ }
21233
+ function imageHash(imagePath) {
21234
+ try {
21235
+ const data = readFileSync20(imagePath);
21236
+ return createHash2("md5").update(data).digest("hex").slice(0, 12);
21237
+ } catch {
21238
+ return "unknown";
21239
+ }
21240
+ }
21241
+ function deduplicateFrames(frames, similarityThreshold = 0) {
21242
+ if (frames.length <= 1)
21243
+ return frames;
21244
+ let prevHash = "";
21245
+ for (const frame of frames) {
21246
+ if (frame.hash === prevHash) {
21247
+ frame.isDuplicate = true;
21248
+ }
21249
+ prevHash = frame.hash;
21250
+ }
21251
+ return frames;
21252
+ }
21253
+ function formatTime2(seconds) {
21254
+ const m = Math.floor(seconds / 60);
21255
+ const s = Math.floor(seconds % 60);
21256
+ const ms = Math.floor(seconds % 1 * 10);
21257
+ return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${ms}`;
21258
+ }
21259
+ var VideoUnderstandTool;
21260
+ var init_video_understand = __esm({
21261
+ "packages/execution/dist/tools/video-understand.js"() {
21262
+ "use strict";
21263
+ VideoUnderstandTool = class {
21264
+ name = "video_understand";
21265
+ description = "Analyze a video from URL or local file. Produces timestamped transcript aligned with keyframe descriptions. Supports YouTube URLs and direct video files. Pipeline: download \u2192 transcribe (Whisper) \u2192 extract keyframes (scene detection) \u2192 describe frames \u2192 align timestamps \u2192 save structured output.";
21266
+ parameters = {
21267
+ type: "object",
21268
+ properties: {
21269
+ url: { type: "string", description: "YouTube URL or direct video URL" },
21270
+ path: { type: "string", description: "Local video file path (alternative to url)" },
21271
+ model: { type: "string", description: "Whisper model: tiny, base, small, medium (default: base)" },
21272
+ frame_interval: { type: "number", description: "Seconds between forced frame samples (default: 30)" },
21273
+ scene_threshold: { type: "number", description: "Scene change sensitivity 0-1 (default: 0.1)" },
21274
+ skip_frames: { type: "boolean", description: "Skip frame extraction (audio-only, default: false)" }
21275
+ },
21276
+ required: []
21277
+ };
21278
+ workingDir;
21279
+ constructor(workingDir) {
21280
+ this.workingDir = workingDir;
21281
+ }
21282
+ async execute(args) {
21283
+ const start = performance.now();
21284
+ const url = args["url"];
21285
+ const localPath = args["path"];
21286
+ const whisperModel = String(args["model"] ?? "base");
21287
+ const frameInterval = Number(args["frame_interval"] ?? 30);
21288
+ const sceneThreshold = Number(args["scene_threshold"] ?? 0.1);
21289
+ const skipFrames = Boolean(args["skip_frames"]);
21290
+ if (!url && !localPath) {
21291
+ return { success: false, output: "", error: "url or path required", durationMs: performance.now() - start };
21292
+ }
21293
+ const outDir = join41(this.workingDir, ".oa", "video-analysis");
21294
+ mkdirSync9(outDir, { recursive: true });
21295
+ const tmpDir = join41(outDir, `tmp-${Date.now()}`);
21296
+ mkdirSync9(tmpDir, { recursive: true });
21297
+ try {
21298
+ let videoPath;
21299
+ let audioPath;
21300
+ let title;
21301
+ if (url) {
21302
+ if (isYouTubeUrl2(url)) {
21303
+ if (!ensureYtDlp2()) {
21304
+ return { success: false, output: "", error: "yt-dlp required but not available. Install: pip3 install yt-dlp", durationMs: performance.now() - start };
21305
+ }
21306
+ try {
21307
+ execSync24(`yt-dlp -f "worst[ext=mp4]" -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
21308
+ } catch {
21309
+ execSync24(`yt-dlp -f worst -o "${join41(tmpDir, "video.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
21310
+ }
21311
+ execSync24(`yt-dlp -x --audio-format mp3 --audio-quality 5 -o "${join41(tmpDir, "audio.%(ext)s")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
21312
+ try {
21313
+ title = execSync24(`yt-dlp --get-title "${url}"`, { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
21314
+ } catch {
21315
+ }
21316
+ } else {
21317
+ execSync24(`curl -sL -o "${join41(tmpDir, "video.mp4")}" "${url}"`, { timeout: 3e5, stdio: "pipe" });
21318
+ execSync24(`ffmpeg -i "${join41(tmpDir, "video.mp4")}" -vn -acodec libmp3lame -q:a 5 "${join41(tmpDir, "audio.mp3")}" -y`, { timeout: 12e4, stdio: "pipe" });
21319
+ }
21320
+ videoPath = readdirSync7(tmpDir).find((f) => f.startsWith("video")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("video"))) : join41(tmpDir, "video.mp4");
21321
+ audioPath = readdirSync7(tmpDir).find((f) => f.startsWith("audio")) ? join41(tmpDir, readdirSync7(tmpDir).find((f) => f.startsWith("audio"))) : join41(tmpDir, "audio.mp3");
21322
+ } else {
21323
+ videoPath = localPath;
21324
+ audioPath = join41(tmpDir, "audio.mp3");
21325
+ execSync24(`ffmpeg -i "${videoPath}" -vn -acodec libmp3lame -q:a 5 "${audioPath}" -y`, { timeout: 12e4, stdio: "pipe" });
21326
+ }
21327
+ let segments = [];
21328
+ let language = "en";
21329
+ let duration = 0;
21330
+ try {
21331
+ const jsonOut = join41(tmpDir, "transcript.json");
21332
+ execSync24(`transcribe-cli transcribe "${audioPath}" --model ${whisperModel} --format json -o "${tmpDir}"`, { timeout: 6e5, stdio: "pipe" });
21333
+ const jsonFile = readdirSync7(tmpDir).find((f) => f.endsWith(".json") && f !== "result.json");
21334
+ if (jsonFile) {
21335
+ const data = JSON.parse(readFileSync20(join41(tmpDir, jsonFile), "utf-8"));
21336
+ segments = (data.segments || []).map((s) => ({
21337
+ start: s.start ?? 0,
21338
+ end: s.end ?? 0,
21339
+ text: (s.text || "").trim(),
21340
+ speaker: s.speaker
21341
+ }));
21342
+ language = data.language || "en";
21343
+ duration = data.duration || 0;
21344
+ }
21345
+ } catch (err) {
21346
+ segments = [];
21347
+ }
21348
+ let frames = [];
21349
+ if (!skipFrames && ensureFfmpeg() && existsSync27(videoPath)) {
21350
+ const framesDir = join41(tmpDir, "frames");
21351
+ mkdirSync9(framesDir, { recursive: true });
21352
+ const fps = 25;
21353
+ const intervalFrames = Math.max(1, frameInterval * fps);
21354
+ try {
21355
+ execSync24(`ffmpeg -i "${videoPath}" -vf "select='gt(scene\\,${sceneThreshold})+not(mod(n\\,${intervalFrames}))',showinfo" -vsync vfr "${join41(framesDir, "frame_%04d.jpg")}" -y`, { timeout: 3e5, stdio: "pipe" });
21356
+ } catch {
21357
+ }
21358
+ const frameFiles = readdirSync7(framesDir).filter((f) => f.endsWith(".jpg")).sort();
21359
+ for (let i = 0; i < frameFiles.length; i++) {
21360
+ const framePath = join41(framesDir, frameFiles[i]);
21361
+ const hash = imageHash(framePath);
21362
+ const timestamp2 = duration > 0 ? i / Math.max(1, frameFiles.length - 1) * duration : i * frameInterval;
21363
+ frames.push({
21364
+ path: framePath,
21365
+ timestamp: timestamp2,
21366
+ hash,
21367
+ isDuplicate: false
21368
+ });
21369
+ }
21370
+ deduplicateFrames(frames);
21371
+ const permanentDir = join41(outDir, `frames-${Date.now()}`);
21372
+ mkdirSync9(permanentDir, { recursive: true });
21373
+ for (const frame of frames.filter((f) => !f.isDuplicate)) {
21374
+ const dest = join41(permanentDir, basename10(frame.path));
21375
+ try {
21376
+ writeFileSync9(dest, readFileSync20(frame.path));
21377
+ frame.path = dest;
21378
+ } catch {
21379
+ }
21380
+ }
21381
+ }
21382
+ const uniqueFrames = frames.filter((f) => !f.isDuplicate);
21383
+ const alignedTimeline = segments.map((seg) => {
21384
+ const mid = (seg.start + seg.end) / 2;
21385
+ let nearestFrame;
21386
+ let minDist = Infinity;
21387
+ for (const frame of uniqueFrames) {
21388
+ const dist = Math.abs(frame.timestamp - mid);
21389
+ if (dist < minDist) {
21390
+ minDist = dist;
21391
+ nearestFrame = frame;
21392
+ }
21393
+ }
21394
+ return {
21395
+ start: seg.start,
21396
+ end: seg.end,
21397
+ speech: seg.text,
21398
+ frameDescription: nearestFrame?.description,
21399
+ frameOcr: nearestFrame?.ocrText
21400
+ };
21401
+ });
21402
+ const result = {
21403
+ source: url || localPath || "unknown",
21404
+ title,
21405
+ duration,
21406
+ language,
21407
+ segments,
21408
+ frames: frames.filter((f) => !f.isDuplicate),
21409
+ alignedTimeline
21410
+ };
21411
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
21412
+ const resultFile = join41(outDir, `understanding-${timestamp}.json`);
21413
+ writeFileSync9(resultFile, JSON.stringify(result, null, 2), "utf-8");
21414
+ try {
21415
+ const memDir = join41(this.workingDir, ".oa", "memory");
21416
+ mkdirSync9(memDir, { recursive: true });
21417
+ const memFile = join41(memDir, "video-analyses.json");
21418
+ let entries = [];
21419
+ try {
21420
+ entries = JSON.parse(readFileSync20(memFile, "utf-8"));
21421
+ } catch {
21422
+ }
21423
+ entries.push({
21424
+ source: url || localPath,
21425
+ title,
21426
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
21427
+ duration,
21428
+ language,
21429
+ segmentCount: segments.length,
21430
+ frameCount: uniqueFrames.length,
21431
+ resultPath: resultFile,
21432
+ summary: segments.slice(0, 3).map((s) => s.text).join(" ").slice(0, 200)
21433
+ });
21434
+ if (entries.length > 30)
21435
+ entries = entries.slice(-30);
21436
+ writeFileSync9(memFile, JSON.stringify(entries, null, 2), "utf-8");
21437
+ } catch {
21438
+ }
21439
+ const lines = [];
21440
+ lines.push(`# Video Analysis${title ? `: ${title}` : ""}`);
21441
+ lines.push(`Source: ${url || localPath}`);
21442
+ lines.push(`Duration: ${duration.toFixed(1)}s | Language: ${language} | Segments: ${segments.length} | Frames: ${uniqueFrames.length}`);
21443
+ lines.push(`Saved: ${resultFile}`);
21444
+ lines.push("");
21445
+ lines.push("## Transcript");
21446
+ for (const seg of segments) {
21447
+ lines.push(`[${formatTime2(seg.start)} \u2192 ${formatTime2(seg.end)}] ${seg.text}`);
21448
+ }
21449
+ if (uniqueFrames.length > 0) {
21450
+ lines.push("");
21451
+ lines.push(`## Frames (${uniqueFrames.length} unique, ${frames.length - uniqueFrames.length} duplicates removed)`);
21452
+ for (const frame of uniqueFrames) {
21453
+ lines.push(` [${formatTime2(frame.timestamp)}] ${basename10(frame.path)}${frame.description ? ` \u2014 ${frame.description}` : ""}`);
21454
+ }
21455
+ }
21456
+ try {
21457
+ execSync24(`rm -rf "${tmpDir}"`, { timeout: 1e4, stdio: "pipe" });
21458
+ } catch {
21459
+ }
21460
+ return {
21461
+ success: true,
21462
+ output: lines.join("\n"),
21463
+ durationMs: performance.now() - start
21464
+ };
21465
+ } catch (err) {
21466
+ return {
21467
+ success: false,
21468
+ output: "",
21469
+ error: `Video analysis failed: ${err instanceof Error ? err.message : String(err)}`,
21470
+ durationMs: performance.now() - start
21471
+ };
21472
+ }
21473
+ }
21474
+ };
21475
+ }
21476
+ });
21477
+
21204
21478
  // packages/execution/dist/venv-paths.js
21205
- import { join as join41 } from "node:path";
21479
+ import { join as join42 } from "node:path";
21206
21480
  function venvPython(venvDir) {
21207
- return isWin ? join41(venvDir, "Scripts", "python.exe") : join41(venvDir, "bin", "python");
21481
+ return isWin ? join42(venvDir, "Scripts", "python.exe") : join42(venvDir, "bin", "python");
21208
21482
  }
21209
21483
  function venvPip(venvDir) {
21210
- return isWin ? join41(venvDir, "Scripts", "pip.exe") : join41(venvDir, "bin", "pip");
21484
+ return isWin ? join42(venvDir, "Scripts", "pip.exe") : join42(venvDir, "bin", "pip");
21211
21485
  }
21212
21486
  function venvBinDir(venvDir) {
21213
- return isWin ? join41(venvDir, "Scripts") : join41(venvDir, "bin");
21487
+ return isWin ? join42(venvDir, "Scripts") : join42(venvDir, "bin");
21214
21488
  }
21215
21489
  function venvExe(venvDir, name) {
21216
- return isWin ? join41(venvDir, "Scripts", `${name}.exe`) : join41(venvDir, "bin", name);
21490
+ return isWin ? join42(venvDir, "Scripts", `${name}.exe`) : join42(venvDir, "bin", name);
21217
21491
  }
21218
21492
  var isWin;
21219
21493
  var init_venv_paths = __esm({
@@ -21224,14 +21498,14 @@ var init_venv_paths = __esm({
21224
21498
  });
21225
21499
 
21226
21500
  // packages/execution/dist/tools/fortemi-bridge.js
21227
- import { existsSync as existsSync27, readFileSync as readFileSync20 } from "node:fs";
21228
- import { join as join42 } from "node:path";
21501
+ import { existsSync as existsSync28, readFileSync as readFileSync21 } from "node:fs";
21502
+ import { join as join43 } from "node:path";
21229
21503
  function loadBridgeState(repoRoot) {
21230
- const bridgeFile = join42(repoRoot, ".oa", "fortemi-bridge.json");
21231
- if (!existsSync27(bridgeFile))
21504
+ const bridgeFile = join43(repoRoot, ".oa", "fortemi-bridge.json");
21505
+ if (!existsSync28(bridgeFile))
21232
21506
  return null;
21233
21507
  try {
21234
- return JSON.parse(readFileSync20(bridgeFile, "utf8"));
21508
+ return JSON.parse(readFileSync21(bridgeFile, "utf8"));
21235
21509
  } catch {
21236
21510
  return null;
21237
21511
  }
@@ -21479,7 +21753,7 @@ var init_gitWorktree = __esm({
21479
21753
  });
21480
21754
 
21481
21755
  // packages/execution/dist/patchApplier.js
21482
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync9, existsSync as existsSync28, mkdirSync as mkdirSync9 } from "node:fs";
21756
+ import { readFileSync as readFileSync22, writeFileSync as writeFileSync10, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
21483
21757
  import { dirname as dirname12 } from "node:path";
21484
21758
  import { spawn as spawn15 } from "node:child_process";
21485
21759
  async function applyPatch(patch) {
@@ -21495,22 +21769,22 @@ async function applyPatch(patch) {
21495
21769
  }
21496
21770
  }
21497
21771
  function applyBlockReplace(patch) {
21498
- const original = readFileSync21(patch.filePath, "utf-8");
21772
+ const original = readFileSync22(patch.filePath, "utf-8");
21499
21773
  if (!original.includes(patch.oldContent)) {
21500
21774
  throw new Error(`Block not found in "${patch.filePath}": the oldContent string was not found in the file.`);
21501
21775
  }
21502
21776
  const updated = original.replace(patch.oldContent, patch.newContent);
21503
- writeFileSync9(patch.filePath, updated, "utf-8");
21777
+ writeFileSync10(patch.filePath, updated, "utf-8");
21504
21778
  }
21505
21779
  function applyRewrite(patch) {
21506
- writeFileSync9(patch.filePath, patch.newContent, "utf-8");
21780
+ writeFileSync10(patch.filePath, patch.newContent, "utf-8");
21507
21781
  }
21508
21782
  function applyNewFile(patch) {
21509
- if (existsSync28(patch.filePath)) {
21783
+ if (existsSync29(patch.filePath)) {
21510
21784
  throw new Error(`Cannot create new file: "${patch.filePath}" already exists.`);
21511
21785
  }
21512
- mkdirSync9(dirname12(patch.filePath), { recursive: true });
21513
- writeFileSync9(patch.filePath, patch.newContent, "utf-8");
21786
+ mkdirSync10(dirname12(patch.filePath), { recursive: true });
21787
+ writeFileSync10(patch.filePath, patch.newContent, "utf-8");
21514
21788
  }
21515
21789
  async function applyUnifiedDiff(patch) {
21516
21790
  const { filePath, diff } = patch;
@@ -22041,6 +22315,7 @@ __export(dist_exports, {
22041
22315
  ToolExecutor: () => ToolExecutor,
22042
22316
  TranscribeFileTool: () => TranscribeFileTool,
22043
22317
  TranscribeUrlTool: () => TranscribeUrlTool,
22318
+ VideoUnderstandTool: () => VideoUnderstandTool,
22044
22319
  VisionTool: () => VisionTool,
22045
22320
  WebCrawlTool: () => WebCrawlTool,
22046
22321
  WebFetchTool: () => WebFetchTool,
@@ -22175,6 +22450,7 @@ var init_dist2 = __esm({
22175
22450
  init_process_health();
22176
22451
  init_full_sub_agent();
22177
22452
  init_environment_snapshot();
22453
+ init_video_understand();
22178
22454
  init_venv_paths();
22179
22455
  init_nexus();
22180
22456
  init_fortemi_bridge();
@@ -22862,17 +23138,17 @@ var init_dist3 = __esm({
22862
23138
  });
22863
23139
 
22864
23140
  // packages/orchestrator/dist/promptLoader.js
22865
- import { readFileSync as readFileSync22, existsSync as existsSync29 } from "node:fs";
22866
- import { join as join43, dirname as dirname13 } from "node:path";
23141
+ import { readFileSync as readFileSync23, existsSync as existsSync30 } from "node:fs";
23142
+ import { join as join44, dirname as dirname13 } from "node:path";
22867
23143
  import { fileURLToPath as fileURLToPath7 } from "node:url";
22868
23144
  function loadPrompt(promptPath, vars) {
22869
23145
  let content = cache.get(promptPath);
22870
23146
  if (content === void 0) {
22871
- const fullPath = join43(PROMPTS_DIR, promptPath);
22872
- if (!existsSync29(fullPath)) {
23147
+ const fullPath = join44(PROMPTS_DIR, promptPath);
23148
+ if (!existsSync30(fullPath)) {
22873
23149
  throw new Error(`Prompt file not found: ${fullPath}`);
22874
23150
  }
22875
- content = readFileSync22(fullPath, "utf-8");
23151
+ content = readFileSync23(fullPath, "utf-8");
22876
23152
  cache.set(promptPath, content);
22877
23153
  }
22878
23154
  if (!vars)
@@ -22885,7 +23161,7 @@ var init_promptLoader = __esm({
22885
23161
  "use strict";
22886
23162
  __filename = fileURLToPath7(import.meta.url);
22887
23163
  __dirname4 = dirname13(__filename);
22888
- PROMPTS_DIR = join43(__dirname4, "..", "prompts");
23164
+ PROMPTS_DIR = join44(__dirname4, "..", "prompts");
22889
23165
  cache = /* @__PURE__ */ new Map();
22890
23166
  }
22891
23167
  });
@@ -23265,7 +23541,7 @@ var init_code_retriever = __esm({
23265
23541
  import { execFile as execFile6 } from "node:child_process";
23266
23542
  import { promisify as promisify5 } from "node:util";
23267
23543
  import { readFile as readFile20, readdir as readdir5, stat as stat3 } from "node:fs/promises";
23268
- import { join as join44, extname as extname8 } from "node:path";
23544
+ import { join as join45, extname as extname8 } from "node:path";
23269
23545
  async function searchByPath(pathPattern, options) {
23270
23546
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
23271
23547
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -23407,7 +23683,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
23407
23683
  continue;
23408
23684
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
23409
23685
  continue;
23410
- const absPath = join44(dir, entry.name);
23686
+ const absPath = join45(dir, entry.name);
23411
23687
  if (entry.isDirectory()) {
23412
23688
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
23413
23689
  } else if (entry.isFile()) {
@@ -23714,7 +23990,7 @@ var init_graphExpand = __esm({
23714
23990
 
23715
23991
  // packages/retrieval/dist/snippetPacker.js
23716
23992
  import { readFile as readFile21 } from "node:fs/promises";
23717
- import { join as join45 } from "node:path";
23993
+ import { join as join46 } from "node:path";
23718
23994
  async function packSnippets(requests, opts = {}) {
23719
23995
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
23720
23996
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -23740,7 +24016,7 @@ async function packSnippets(requests, opts = {}) {
23740
24016
  return { packed, dropped, totalTokens };
23741
24017
  }
23742
24018
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
23743
- const absPath = req.filePath.startsWith("/") ? req.filePath : join45(repoRoot, req.filePath);
24019
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join46(repoRoot, req.filePath);
23744
24020
  let content;
23745
24021
  try {
23746
24022
  content = await readFile21(absPath, "utf-8");
@@ -26473,10 +26749,10 @@ ${marker}` : marker);
26473
26749
  if (!this._workingDirectory)
26474
26750
  return;
26475
26751
  try {
26476
- const { mkdirSync: mkdirSync24, writeFileSync: writeFileSync23 } = __require("node:fs");
26477
- const { join: join70 } = __require("node:path");
26478
- const sessionDir = join70(this._workingDirectory, ".oa", "session", this._sessionId);
26479
- mkdirSync24(sessionDir, { recursive: true });
26752
+ const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = __require("node:fs");
26753
+ const { join: join71 } = __require("node:path");
26754
+ const sessionDir = join71(this._workingDirectory, ".oa", "session", this._sessionId);
26755
+ mkdirSync25(sessionDir, { recursive: true });
26480
26756
  const checkpoint = {
26481
26757
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
26482
26758
  sessionId: this._sessionId,
@@ -26488,7 +26764,7 @@ ${marker}` : marker);
26488
26764
  memexEntryCount: this._memexArchive.size,
26489
26765
  fileRegistrySize: this._fileRegistry.size
26490
26766
  };
26491
- writeFileSync23(join70(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
26767
+ writeFileSync24(join71(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
26492
26768
  } catch {
26493
26769
  }
26494
26770
  }
@@ -27564,7 +27840,6 @@ ${transcript}`
27564
27840
  continue;
27565
27841
  }
27566
27842
  if (chunk.type === "content" && chunk.content) {
27567
- content += chunk.content;
27568
27843
  const fragment = chunk.content;
27569
27844
  let kind;
27570
27845
  if (chunk.thinking) {
@@ -27582,6 +27857,9 @@ ${transcript}`
27582
27857
  inThinkTag = false;
27583
27858
  kind = "content";
27584
27859
  }
27860
+ if (kind === "content") {
27861
+ content += fragment;
27862
+ }
27585
27863
  this.emit({
27586
27864
  type: "stream_token",
27587
27865
  content: fragment,
@@ -27817,9 +28095,9 @@ ${transcript}`
27817
28095
  });
27818
28096
 
27819
28097
  // packages/orchestrator/dist/nexusBackend.js
27820
- import { existsSync as existsSync30, statSync as statSync10, openSync, readSync, closeSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync10 } from "node:fs";
28098
+ import { existsSync as existsSync31, statSync as statSync10, openSync, readSync, closeSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync11 } from "node:fs";
27821
28099
  import { watch as fsWatch } from "node:fs";
27822
- import { join as join46 } from "node:path";
28100
+ import { join as join47 } from "node:path";
27823
28101
  import { tmpdir as tmpdir7 } from "node:os";
27824
28102
  import { randomBytes as randomBytes11 } from "node:crypto";
27825
28103
  var NexusAgenticBackend;
@@ -27969,8 +28247,8 @@ var init_nexusBackend = __esm({
27969
28247
  * Falls back to unary + word-split if streaming setup fails.
27970
28248
  */
27971
28249
  async *chatCompletionStream(request) {
27972
- const streamFile = join46(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
27973
- writeFileSync10(streamFile, "", "utf8");
28250
+ const streamFile = join47(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
28251
+ writeFileSync11(streamFile, "", "utf8");
27974
28252
  const daemonArgs = {
27975
28253
  model: this.model,
27976
28254
  messages: JSON.stringify(request.messages),
@@ -27990,7 +28268,7 @@ var init_nexusBackend = __esm({
27990
28268
  } catch (sendErr) {
27991
28269
  this.consecutiveFailures++;
27992
28270
  try {
27993
- unlinkSync4(streamFile);
28271
+ unlinkSync5(streamFile);
27994
28272
  } catch {
27995
28273
  }
27996
28274
  throw sendErr;
@@ -28005,7 +28283,7 @@ var init_nexusBackend = __esm({
28005
28283
  }
28006
28284
  if (!isStreaming) {
28007
28285
  try {
28008
- unlinkSync4(streamFile);
28286
+ unlinkSync5(streamFile);
28009
28287
  } catch {
28010
28288
  }
28011
28289
  let parsed;
@@ -28161,7 +28439,7 @@ var init_nexusBackend = __esm({
28161
28439
  }
28162
28440
  } finally {
28163
28441
  try {
28164
- unlinkSync4(streamFile);
28442
+ unlinkSync5(streamFile);
28165
28443
  } catch {
28166
28444
  }
28167
28445
  }
@@ -29004,9 +29282,9 @@ __export(listen_exports, {
29004
29282
  isVideoPath: () => isVideoPath,
29005
29283
  waitForTranscribeCli: () => waitForTranscribeCli
29006
29284
  });
29007
- import { spawn as spawn16, execSync as execSync24 } from "node:child_process";
29008
- import { existsSync as existsSync31, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readdirSync as readdirSync7 } from "node:fs";
29009
- import { join as join47, dirname as dirname14 } from "node:path";
29285
+ import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
29286
+ import { existsSync as existsSync32, mkdirSync as mkdirSync11, writeFileSync as writeFileSync12, readdirSync as readdirSync8 } from "node:fs";
29287
+ import { join as join48, dirname as dirname14 } from "node:path";
29010
29288
  import { homedir as homedir10 } from "node:os";
29011
29289
  import { fileURLToPath as fileURLToPath8 } from "node:url";
29012
29290
  import { EventEmitter } from "node:events";
@@ -29026,7 +29304,7 @@ function findMicCaptureCommand() {
29026
29304
  const platform6 = process.platform;
29027
29305
  if (platform6 === "linux") {
29028
29306
  try {
29029
- execSync24("which arecord", { stdio: "pipe" });
29307
+ execSync25("which arecord", { stdio: "pipe" });
29030
29308
  return {
29031
29309
  cmd: "arecord",
29032
29310
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -29036,7 +29314,7 @@ function findMicCaptureCommand() {
29036
29314
  }
29037
29315
  if (platform6 === "darwin") {
29038
29316
  try {
29039
- execSync24("which sox", { stdio: "pipe" });
29317
+ execSync25("which sox", { stdio: "pipe" });
29040
29318
  return {
29041
29319
  cmd: "sox",
29042
29320
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -29045,7 +29323,7 @@ function findMicCaptureCommand() {
29045
29323
  }
29046
29324
  }
29047
29325
  try {
29048
- execSync24("which ffmpeg", { stdio: "pipe" });
29326
+ execSync25("which ffmpeg", { stdio: "pipe" });
29049
29327
  if (platform6 === "linux") {
29050
29328
  return {
29051
29329
  cmd: "ffmpeg",
@@ -29092,39 +29370,39 @@ function findMicCaptureCommand() {
29092
29370
  function findLiveWhisperScript() {
29093
29371
  const thisDir = dirname14(fileURLToPath8(import.meta.url));
29094
29372
  const candidates = [
29095
- join47(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
29096
- join47(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
29097
- join47(thisDir, "../../execution/scripts/live-whisper.py"),
29373
+ join48(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
29374
+ join48(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
29375
+ join48(thisDir, "../../execution/scripts/live-whisper.py"),
29098
29376
  // npm install layout — scripts bundled alongside dist
29099
- join47(thisDir, "../scripts/live-whisper.py"),
29100
- join47(thisDir, "../../scripts/live-whisper.py")
29377
+ join48(thisDir, "../scripts/live-whisper.py"),
29378
+ join48(thisDir, "../../scripts/live-whisper.py")
29101
29379
  ];
29102
29380
  for (const p of candidates) {
29103
- if (existsSync31(p))
29381
+ if (existsSync32(p))
29104
29382
  return p;
29105
29383
  }
29106
29384
  try {
29107
- const globalRoot = execSync24("npm root -g", {
29385
+ const globalRoot = execSync25("npm root -g", {
29108
29386
  encoding: "utf-8",
29109
29387
  timeout: 5e3,
29110
29388
  stdio: ["pipe", "pipe", "pipe"]
29111
29389
  }).trim();
29112
29390
  const candidates2 = [
29113
- join47(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
29114
- join47(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
29391
+ join48(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
29392
+ join48(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
29115
29393
  ];
29116
29394
  for (const p of candidates2) {
29117
- if (existsSync31(p))
29395
+ if (existsSync32(p))
29118
29396
  return p;
29119
29397
  }
29120
29398
  } catch {
29121
29399
  }
29122
- const nvmBase = join47(homedir10(), ".nvm", "versions", "node");
29123
- if (existsSync31(nvmBase)) {
29400
+ const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
29401
+ if (existsSync32(nvmBase)) {
29124
29402
  try {
29125
- for (const ver of readdirSync7(nvmBase)) {
29126
- const p = join47(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
29127
- if (existsSync31(p))
29403
+ for (const ver of readdirSync8(nvmBase)) {
29404
+ const p = join48(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
29405
+ if (existsSync32(p))
29128
29406
  return p;
29129
29407
  }
29130
29408
  } catch {
@@ -29137,12 +29415,12 @@ function ensureTranscribeCliBackground() {
29137
29415
  return;
29138
29416
  _bgInstallPromise = (async () => {
29139
29417
  try {
29140
- const globalRoot = execSync24("npm root -g", {
29418
+ const globalRoot = execSync25("npm root -g", {
29141
29419
  encoding: "utf-8",
29142
29420
  timeout: 5e3,
29143
29421
  stdio: ["pipe", "pipe", "pipe"]
29144
29422
  }).trim();
29145
- if (existsSync31(join47(globalRoot, "transcribe-cli", "dist", "index.js"))) {
29423
+ if (existsSync32(join48(globalRoot, "transcribe-cli", "dist", "index.js"))) {
29146
29424
  return true;
29147
29425
  }
29148
29426
  } catch {
@@ -29343,7 +29621,7 @@ var init_listen = __esm({
29343
29621
  }
29344
29622
  if (!this.transcribeCliAvailable) {
29345
29623
  try {
29346
- execSync24("which transcribe-cli", { stdio: "pipe" });
29624
+ execSync25("which transcribe-cli", { stdio: "pipe" });
29347
29625
  this.transcribeCliAvailable = true;
29348
29626
  } catch {
29349
29627
  this.transcribeCliAvailable = false;
@@ -29360,29 +29638,29 @@ var init_listen = __esm({
29360
29638
  } catch {
29361
29639
  }
29362
29640
  try {
29363
- const globalRoot = execSync24("npm root -g", {
29641
+ const globalRoot = execSync25("npm root -g", {
29364
29642
  encoding: "utf-8",
29365
29643
  timeout: 5e3,
29366
29644
  stdio: ["pipe", "pipe", "pipe"]
29367
29645
  }).trim();
29368
- const tcPath = join47(globalRoot, "transcribe-cli");
29369
- if (existsSync31(join47(tcPath, "dist", "index.js"))) {
29646
+ const tcPath = join48(globalRoot, "transcribe-cli");
29647
+ if (existsSync32(join48(tcPath, "dist", "index.js"))) {
29370
29648
  const { createRequire: createRequire4 } = await import("node:module");
29371
29649
  const req = createRequire4(import.meta.url);
29372
- return req(join47(tcPath, "dist", "index.js"));
29650
+ return req(join48(tcPath, "dist", "index.js"));
29373
29651
  }
29374
29652
  } catch {
29375
29653
  }
29376
- const nvmBase = join47(homedir10(), ".nvm", "versions", "node");
29377
- if (existsSync31(nvmBase)) {
29654
+ const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
29655
+ if (existsSync32(nvmBase)) {
29378
29656
  try {
29379
- const { readdirSync: readdirSync19 } = await import("node:fs");
29380
- for (const ver of readdirSync19(nvmBase)) {
29381
- const tcPath = join47(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
29382
- if (existsSync31(join47(tcPath, "dist", "index.js"))) {
29657
+ const { readdirSync: readdirSync20 } = await import("node:fs");
29658
+ for (const ver of readdirSync20(nvmBase)) {
29659
+ const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
29660
+ if (existsSync32(join48(tcPath, "dist", "index.js"))) {
29383
29661
  const { createRequire: createRequire4 } = await import("node:module");
29384
29662
  const req = createRequire4(import.meta.url);
29385
- return req(join47(tcPath, "dist", "index.js"));
29663
+ return req(join48(tcPath, "dist", "index.js"));
29386
29664
  }
29387
29665
  }
29388
29666
  } catch {
@@ -29410,7 +29688,7 @@ var init_listen = __esm({
29410
29688
  }
29411
29689
  if (!tc) {
29412
29690
  try {
29413
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29691
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29414
29692
  this.transcribeCliAvailable = null;
29415
29693
  tc = await this.loadTranscribeCli();
29416
29694
  } catch {
@@ -29593,7 +29871,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29593
29871
  }
29594
29872
  if (!tc) {
29595
29873
  try {
29596
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29874
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29597
29875
  this.transcribeCliAvailable = null;
29598
29876
  tc = await this.loadTranscribeCli();
29599
29877
  } catch {
@@ -29647,7 +29925,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29647
29925
  }
29648
29926
  if (!tc) {
29649
29927
  try {
29650
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29928
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29651
29929
  this.transcribeCliAvailable = null;
29652
29930
  tc = await this.loadTranscribeCli();
29653
29931
  } catch {
@@ -29663,11 +29941,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
29663
29941
  wordTimestamps: false
29664
29942
  });
29665
29943
  if (outputDir) {
29666
- const { basename: basename17 } = await import("node:path");
29667
- const transcriptDir = join47(outputDir, ".oa", "transcripts");
29668
- mkdirSync10(transcriptDir, { recursive: true });
29669
- const outFile = join47(transcriptDir, `${basename17(filePath)}.txt`);
29670
- writeFileSync11(outFile, result.text, "utf-8");
29944
+ const { basename: basename18 } = await import("node:path");
29945
+ const transcriptDir = join48(outputDir, ".oa", "transcripts");
29946
+ mkdirSync11(transcriptDir, { recursive: true });
29947
+ const outFile = join48(transcriptDir, `${basename18(filePath)}.txt`);
29948
+ writeFileSync12(outFile, result.text, "utf-8");
29671
29949
  }
29672
29950
  return {
29673
29951
  text: result.text,
@@ -31915,7 +32193,7 @@ var require_websocket = __commonJS({
31915
32193
  var http = __require("http");
31916
32194
  var net = __require("net");
31917
32195
  var tls = __require("tls");
31918
- var { randomBytes: randomBytes15, createHash: createHash5 } = __require("crypto");
32196
+ var { randomBytes: randomBytes15, createHash: createHash6 } = __require("crypto");
31919
32197
  var { Duplex, Readable } = __require("stream");
31920
32198
  var { URL: URL3 } = __require("url");
31921
32199
  var PerMessageDeflate = require_permessage_deflate();
@@ -32575,7 +32853,7 @@ var require_websocket = __commonJS({
32575
32853
  abortHandshake(websocket, socket, "Invalid Upgrade header");
32576
32854
  return;
32577
32855
  }
32578
- const digest = createHash5("sha1").update(key + GUID).digest("base64");
32856
+ const digest = createHash6("sha1").update(key + GUID).digest("base64");
32579
32857
  if (res.headers["sec-websocket-accept"] !== digest) {
32580
32858
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
32581
32859
  return;
@@ -32942,7 +33220,7 @@ var require_websocket_server = __commonJS({
32942
33220
  var EventEmitter7 = __require("events");
32943
33221
  var http = __require("http");
32944
33222
  var { Duplex } = __require("stream");
32945
- var { createHash: createHash5 } = __require("crypto");
33223
+ var { createHash: createHash6 } = __require("crypto");
32946
33224
  var extension = require_extension();
32947
33225
  var PerMessageDeflate = require_permessage_deflate();
32948
33226
  var subprotocol = require_subprotocol();
@@ -33243,7 +33521,7 @@ var require_websocket_server = __commonJS({
33243
33521
  );
33244
33522
  }
33245
33523
  if (this._state > RUNNING) return abortHandshake(socket, 503);
33246
- const digest = createHash5("sha1").update(key + GUID).digest("base64");
33524
+ const digest = createHash6("sha1").update(key + GUID).digest("base64");
33247
33525
  const headers = [
33248
33526
  "HTTP/1.1 101 Switching Protocols",
33249
33527
  "Upgrade: websocket",
@@ -34154,7 +34432,7 @@ var init_render = __esm({
34154
34432
 
34155
34433
  // packages/cli/dist/tui/voice-session.js
34156
34434
  import { createServer as createServer2 } from "node:http";
34157
- import { spawn as spawn17, execSync as execSync25 } from "node:child_process";
34435
+ import { spawn as spawn17, execSync as execSync26 } from "node:child_process";
34158
34436
  import { EventEmitter as EventEmitter2 } from "node:events";
34159
34437
  function generateFrontendHTML() {
34160
34438
  return `<!DOCTYPE html>
@@ -34887,8 +35165,8 @@ import { EventEmitter as EventEmitter3 } from "node:events";
34887
35165
  import { randomBytes as randomBytes12 } from "node:crypto";
34888
35166
  import { URL as URL2 } from "node:url";
34889
35167
  import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
34890
- import { existsSync as existsSync32, readFileSync as readFileSync23, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, mkdirSync as mkdirSync11, readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
34891
- import { join as join48 } from "node:path";
35168
+ import { existsSync as existsSync33, readFileSync as readFileSync24, writeFileSync as writeFileSync13, unlinkSync as unlinkSync6, mkdirSync as mkdirSync12, readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
35169
+ import { join as join49 } from "node:path";
34892
35170
  function cleanForwardHeaders(raw, targetHost) {
34893
35171
  const out = {};
34894
35172
  for (const [key, value] of Object.entries(raw)) {
@@ -34916,10 +35194,10 @@ function fmtTokens(n) {
34916
35194
  }
34917
35195
  function readExposeState(stateDir) {
34918
35196
  try {
34919
- const path = join48(stateDir, STATE_FILE_NAME);
34920
- if (!existsSync32(path))
35197
+ const path = join49(stateDir, STATE_FILE_NAME);
35198
+ if (!existsSync33(path))
34921
35199
  return null;
34922
- const raw = readFileSync23(path, "utf8");
35200
+ const raw = readFileSync24(path, "utf8");
34923
35201
  const data = JSON.parse(raw);
34924
35202
  if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort)
34925
35203
  return null;
@@ -34930,14 +35208,14 @@ function readExposeState(stateDir) {
34930
35208
  }
34931
35209
  function writeExposeState(stateDir, state) {
34932
35210
  try {
34933
- mkdirSync11(stateDir, { recursive: true });
34934
- writeFileSync12(join48(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
35211
+ mkdirSync12(stateDir, { recursive: true });
35212
+ writeFileSync13(join49(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
34935
35213
  } catch {
34936
35214
  }
34937
35215
  }
34938
35216
  function removeExposeState(stateDir) {
34939
35217
  try {
34940
- unlinkSync5(join48(stateDir, STATE_FILE_NAME));
35218
+ unlinkSync6(join49(stateDir, STATE_FILE_NAME));
34941
35219
  } catch {
34942
35220
  }
34943
35221
  }
@@ -35026,10 +35304,10 @@ async function collectSystemMetricsAsync() {
35026
35304
  }
35027
35305
  function readP2PExposeState(stateDir) {
35028
35306
  try {
35029
- const path = join48(stateDir, P2P_STATE_FILE_NAME);
35030
- if (!existsSync32(path))
35307
+ const path = join49(stateDir, P2P_STATE_FILE_NAME);
35308
+ if (!existsSync33(path))
35031
35309
  return null;
35032
- const raw = readFileSync23(path, "utf8");
35310
+ const raw = readFileSync24(path, "utf8");
35033
35311
  const data = JSON.parse(raw);
35034
35312
  if (!data.peerId || !data.authKey)
35035
35313
  return null;
@@ -35040,14 +35318,14 @@ function readP2PExposeState(stateDir) {
35040
35318
  }
35041
35319
  function writeP2PExposeState(stateDir, state) {
35042
35320
  try {
35043
- mkdirSync11(stateDir, { recursive: true });
35044
- writeFileSync12(join48(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
35321
+ mkdirSync12(stateDir, { recursive: true });
35322
+ writeFileSync13(join49(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
35045
35323
  } catch {
35046
35324
  }
35047
35325
  }
35048
35326
  function removeP2PExposeState(stateDir) {
35049
35327
  try {
35050
- unlinkSync5(join48(stateDir, P2P_STATE_FILE_NAME));
35328
+ unlinkSync6(join49(stateDir, P2P_STATE_FILE_NAME));
35051
35329
  } catch {
35052
35330
  }
35053
35331
  }
@@ -35895,10 +36173,10 @@ ${this.formatConnectionInfo()}`);
35895
36173
  throw new Error(`Expose failed: ${exposeResult.error}`);
35896
36174
  }
35897
36175
  const nexusDir = this._nexusTool.getNexusDir();
35898
- const statusPath = join48(nexusDir, "status.json");
36176
+ const statusPath = join49(nexusDir, "status.json");
35899
36177
  for (let i = 0; i < 80; i++) {
35900
36178
  try {
35901
- const raw = readFileSync23(statusPath, "utf8");
36179
+ const raw = readFileSync24(statusPath, "utf8");
35902
36180
  if (raw.length > 10) {
35903
36181
  const status = JSON.parse(raw);
35904
36182
  if (status.connected && status.peerId) {
@@ -35929,9 +36207,9 @@ ${this.formatConnectionInfo()}`);
35929
36207
  });
35930
36208
  }
35931
36209
  try {
35932
- const invocDir = join48(nexusDir, "invocations");
35933
- if (existsSync32(invocDir)) {
35934
- this._prevInvocCount = readdirSync8(invocDir).filter((f) => f.endsWith(".json")).length;
36210
+ const invocDir = join49(nexusDir, "invocations");
36211
+ if (existsSync33(invocDir)) {
36212
+ this._prevInvocCount = readdirSync9(invocDir).filter((f) => f.endsWith(".json")).length;
35935
36213
  this._stats.totalRequests = this._prevInvocCount;
35936
36214
  }
35937
36215
  } catch {
@@ -35959,13 +36237,13 @@ ${this.formatConnectionInfo()}`);
35959
36237
  if (!state)
35960
36238
  return null;
35961
36239
  const nexusDir = nexusTool.getNexusDir();
35962
- const statusPath = join48(nexusDir, "status.json");
36240
+ const statusPath = join49(nexusDir, "status.json");
35963
36241
  try {
35964
- if (!existsSync32(statusPath)) {
36242
+ if (!existsSync33(statusPath)) {
35965
36243
  removeP2PExposeState(stateDir);
35966
36244
  return null;
35967
36245
  }
35968
- const status = JSON.parse(readFileSync23(statusPath, "utf8"));
36246
+ const status = JSON.parse(readFileSync24(statusPath, "utf8"));
35969
36247
  if (!status.connected || !status.peerId) {
35970
36248
  removeP2PExposeState(stateDir);
35971
36249
  return null;
@@ -36018,10 +36296,10 @@ ${this.formatConnectionInfo()}`);
36018
36296
  let lastMeteringLineCount = 0;
36019
36297
  this._activityPollTimer = setInterval(() => {
36020
36298
  try {
36021
- const invocDir = join48(nexusDir, "invocations");
36022
- if (!existsSync32(invocDir))
36299
+ const invocDir = join49(nexusDir, "invocations");
36300
+ if (!existsSync33(invocDir))
36023
36301
  return;
36024
- const files = readdirSync8(invocDir).filter((f) => f.endsWith(".json"));
36302
+ const files = readdirSync9(invocDir).filter((f) => f.endsWith(".json"));
36025
36303
  const invocCount = files.length;
36026
36304
  const newRequests = invocCount - this._prevInvocCount;
36027
36305
  if (newRequests > 0) {
@@ -36034,17 +36312,17 @@ ${this.formatConnectionInfo()}`);
36034
36312
  let recentActive = 0;
36035
36313
  for (const f of files.slice(-10)) {
36036
36314
  try {
36037
- const st = statSync11(join48(invocDir, f));
36315
+ const st = statSync11(join49(invocDir, f));
36038
36316
  if (now - st.mtimeMs < 1e4)
36039
36317
  recentActive++;
36040
36318
  } catch {
36041
36319
  }
36042
36320
  }
36043
- const meteringFile = join48(nexusDir, "metering.jsonl");
36321
+ const meteringFile = join49(nexusDir, "metering.jsonl");
36044
36322
  let meteringLines = lastMeteringLineCount;
36045
36323
  try {
36046
- if (existsSync32(meteringFile)) {
36047
- const content = readFileSync23(meteringFile, "utf8");
36324
+ if (existsSync33(meteringFile)) {
36325
+ const content = readFileSync24(meteringFile, "utf8");
36048
36326
  meteringLines = content.split("\n").filter((l) => l.trim()).length;
36049
36327
  }
36050
36328
  } catch {
@@ -36070,9 +36348,9 @@ ${this.formatConnectionInfo()}`);
36070
36348
  this._activityPollTimer.unref();
36071
36349
  this._pollTimer = setInterval(() => {
36072
36350
  try {
36073
- const statusPath = join48(nexusDir, "status.json");
36074
- if (existsSync32(statusPath)) {
36075
- const status = JSON.parse(readFileSync23(statusPath, "utf8"));
36351
+ const statusPath = join49(nexusDir, "status.json");
36352
+ if (existsSync33(statusPath)) {
36353
+ const status = JSON.parse(readFileSync24(statusPath, "utf8"));
36076
36354
  if (status.peerId && !this._peerId) {
36077
36355
  this._peerId = status.peerId;
36078
36356
  }
@@ -36081,9 +36359,9 @@ ${this.formatConnectionInfo()}`);
36081
36359
  } catch {
36082
36360
  }
36083
36361
  try {
36084
- const invocDir = join48(nexusDir, "invocations");
36085
- if (existsSync32(invocDir)) {
36086
- const files = readdirSync8(invocDir);
36362
+ const invocDir = join49(nexusDir, "invocations");
36363
+ if (existsSync33(invocDir)) {
36364
+ const files = readdirSync9(invocDir);
36087
36365
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
36088
36366
  if (invocCount > this._stats.totalRequests) {
36089
36367
  this._stats.totalRequests = invocCount;
@@ -36093,9 +36371,9 @@ ${this.formatConnectionInfo()}`);
36093
36371
  } catch {
36094
36372
  }
36095
36373
  try {
36096
- const meteringFile = join48(nexusDir, "metering.jsonl");
36097
- if (existsSync32(meteringFile)) {
36098
- const content = readFileSync23(meteringFile, "utf8");
36374
+ const meteringFile = join49(nexusDir, "metering.jsonl");
36375
+ if (existsSync33(meteringFile)) {
36376
+ const content = readFileSync24(meteringFile, "utf8");
36099
36377
  if (content.length > lastMeteringSize) {
36100
36378
  const newContent = content.slice(lastMeteringSize);
36101
36379
  lastMeteringSize = content.length;
@@ -36303,9 +36581,9 @@ var init_types = __esm({
36303
36581
  });
36304
36582
 
36305
36583
  // packages/cli/dist/tui/p2p/secret-vault.js
36306
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
36307
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync13, existsSync as existsSync33, mkdirSync as mkdirSync12 } from "node:fs";
36308
- import { join as join49, dirname as dirname15 } from "node:path";
36584
+ import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as createHash3 } from "node:crypto";
36585
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync14, existsSync as existsSync34, mkdirSync as mkdirSync13 } from "node:fs";
36586
+ import { join as join50, dirname as dirname15 } from "node:path";
36309
36587
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
36310
36588
  var init_secret_vault = __esm({
36311
36589
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -36517,18 +36795,18 @@ var init_secret_vault = __esm({
36517
36795
  const tag = cipher.getAuthTag();
36518
36796
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
36519
36797
  const dir = dirname15(this.storePath);
36520
- if (!existsSync33(dir))
36521
- mkdirSync12(dir, { recursive: true });
36522
- writeFileSync13(this.storePath, blob, { mode: 384 });
36798
+ if (!existsSync34(dir))
36799
+ mkdirSync13(dir, { recursive: true });
36800
+ writeFileSync14(this.storePath, blob, { mode: 384 });
36523
36801
  }
36524
36802
  /**
36525
36803
  * Load vault from disk, decrypting with the given passphrase.
36526
36804
  * Returns the number of secrets loaded.
36527
36805
  */
36528
36806
  load(passphrase) {
36529
- if (!this.storePath || !existsSync33(this.storePath))
36807
+ if (!this.storePath || !existsSync34(this.storePath))
36530
36808
  return 0;
36531
- const blob = readFileSync24(this.storePath);
36809
+ const blob = readFileSync25(this.storePath);
36532
36810
  if (blob.length < SALT_LEN + IV_LEN + 16) {
36533
36811
  throw new Error("Vault file is corrupted (too small)");
36534
36812
  }
@@ -36554,7 +36832,7 @@ var init_secret_vault = __esm({
36554
36832
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
36555
36833
  fingerprint() {
36556
36834
  const names = Array.from(this.secrets.keys()).sort();
36557
- const hash = createHash2("sha256");
36835
+ const hash = createHash3("sha256");
36558
36836
  for (const name of names) {
36559
36837
  hash.update(name + ":");
36560
36838
  hash.update(this.secrets.get(name).value);
@@ -36569,7 +36847,7 @@ var init_secret_vault = __esm({
36569
36847
  // packages/cli/dist/tui/p2p/peer-mesh.js
36570
36848
  import { EventEmitter as EventEmitter4 } from "node:events";
36571
36849
  import { createServer as createServer4 } from "node:http";
36572
- import { randomBytes as randomBytes14, createHash as createHash3, generateKeyPairSync } from "node:crypto";
36850
+ import { randomBytes as randomBytes14, createHash as createHash4, generateKeyPairSync } from "node:crypto";
36573
36851
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
36574
36852
  var init_peer_mesh = __esm({
36575
36853
  "packages/cli/dist/tui/p2p/peer-mesh.js"() {
@@ -36618,7 +36896,7 @@ var init_peer_mesh = __esm({
36618
36896
  const { publicKey, privateKey } = generateKeyPairSync("ed25519");
36619
36897
  this.publicKey = publicKey.export({ type: "spki", format: "der" });
36620
36898
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
36621
- this.peerId = createHash3("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
36899
+ this.peerId = createHash4("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
36622
36900
  this.capabilities = options.capabilities;
36623
36901
  this.displayName = options.displayName;
36624
36902
  this._authKey = options.authKey ?? randomBytes14(24).toString("base64url");
@@ -37649,26 +37927,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
37649
37927
  async function fetchPeerModels(peerId, authKey) {
37650
37928
  try {
37651
37929
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
37652
- const { existsSync: existsSync50, readFileSync: readFileSync38 } = await import("node:fs");
37653
- const { join: join70 } = await import("node:path");
37930
+ const { existsSync: existsSync51, readFileSync: readFileSync39 } = await import("node:fs");
37931
+ const { join: join71 } = await import("node:path");
37654
37932
  const cwd4 = process.cwd();
37655
37933
  const nexusTool = new NexusTool2(cwd4);
37656
37934
  const nexusDir = nexusTool.getNexusDir();
37657
37935
  let isLocalPeer = false;
37658
37936
  try {
37659
- const statusPath = join70(nexusDir, "status.json");
37660
- if (existsSync50(statusPath)) {
37661
- const status = JSON.parse(readFileSync38(statusPath, "utf8"));
37937
+ const statusPath = join71(nexusDir, "status.json");
37938
+ if (existsSync51(statusPath)) {
37939
+ const status = JSON.parse(readFileSync39(statusPath, "utf8"));
37662
37940
  if (status.peerId === peerId)
37663
37941
  isLocalPeer = true;
37664
37942
  }
37665
37943
  } catch {
37666
37944
  }
37667
37945
  if (isLocalPeer) {
37668
- const pricingPath = join70(nexusDir, "pricing.json");
37669
- if (existsSync50(pricingPath)) {
37946
+ const pricingPath = join71(nexusDir, "pricing.json");
37947
+ if (existsSync51(pricingPath)) {
37670
37948
  try {
37671
- const pricing = JSON.parse(readFileSync38(pricingPath, "utf8"));
37949
+ const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
37672
37950
  const localModels = (pricing.models || []).map((m) => ({
37673
37951
  name: m.model || "unknown",
37674
37952
  size: m.parameterSize || "",
@@ -37682,10 +37960,10 @@ async function fetchPeerModels(peerId, authKey) {
37682
37960
  }
37683
37961
  }
37684
37962
  }
37685
- const cachePath = join70(nexusDir, "peer-models-cache.json");
37686
- if (existsSync50(cachePath)) {
37963
+ const cachePath = join71(nexusDir, "peer-models-cache.json");
37964
+ if (existsSync51(cachePath)) {
37687
37965
  try {
37688
- const cache4 = JSON.parse(readFileSync38(cachePath, "utf8"));
37966
+ const cache4 = JSON.parse(readFileSync39(cachePath, "utf8"));
37689
37967
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
37690
37968
  const age = Date.now() - new Date(cache4.cachedAt).getTime();
37691
37969
  if (age < 5 * 60 * 1e3) {
@@ -37800,10 +38078,10 @@ async function fetchPeerModels(peerId, authKey) {
37800
38078
  } catch {
37801
38079
  }
37802
38080
  if (isLocalPeer) {
37803
- const pricingPath = join70(nexusDir, "pricing.json");
37804
- if (existsSync50(pricingPath)) {
38081
+ const pricingPath = join71(nexusDir, "pricing.json");
38082
+ if (existsSync51(pricingPath)) {
37805
38083
  try {
37806
- const pricing = JSON.parse(readFileSync38(pricingPath, "utf8"));
38084
+ const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
37807
38085
  return (pricing.models || []).map((m) => ({
37808
38086
  name: m.model || "unknown",
37809
38087
  size: m.parameterSize || "",
@@ -38083,17 +38361,17 @@ var init_render2 = __esm({
38083
38361
  });
38084
38362
 
38085
38363
  // packages/prompts/dist/promptLoader.js
38086
- import { readFileSync as readFileSync25, existsSync as existsSync34 } from "node:fs";
38087
- import { join as join50, dirname as dirname16 } from "node:path";
38364
+ import { readFileSync as readFileSync26, existsSync as existsSync35 } from "node:fs";
38365
+ import { join as join51, dirname as dirname16 } from "node:path";
38088
38366
  import { fileURLToPath as fileURLToPath9 } from "node:url";
38089
38367
  function loadPrompt2(promptPath, vars) {
38090
38368
  let content = cache2.get(promptPath);
38091
38369
  if (content === void 0) {
38092
- const fullPath = join50(PROMPTS_DIR2, promptPath);
38093
- if (!existsSync34(fullPath)) {
38370
+ const fullPath = join51(PROMPTS_DIR2, promptPath);
38371
+ if (!existsSync35(fullPath)) {
38094
38372
  throw new Error(`Prompt file not found: ${fullPath}`);
38095
38373
  }
38096
- content = readFileSync25(fullPath, "utf-8");
38374
+ content = readFileSync26(fullPath, "utf-8");
38097
38375
  cache2.set(promptPath, content);
38098
38376
  }
38099
38377
  if (!vars)
@@ -38106,9 +38384,9 @@ var init_promptLoader2 = __esm({
38106
38384
  "use strict";
38107
38385
  __filename2 = fileURLToPath9(import.meta.url);
38108
38386
  __dirname5 = dirname16(__filename2);
38109
- devPath = join50(__dirname5, "..", "templates");
38110
- publishedPath = join50(__dirname5, "..", "prompts", "templates");
38111
- PROMPTS_DIR2 = existsSync34(devPath) ? devPath : publishedPath;
38387
+ devPath = join51(__dirname5, "..", "templates");
38388
+ publishedPath = join51(__dirname5, "..", "prompts", "templates");
38389
+ PROMPTS_DIR2 = existsSync35(devPath) ? devPath : publishedPath;
38112
38390
  cache2 = /* @__PURE__ */ new Map();
38113
38391
  }
38114
38392
  });
@@ -38219,7 +38497,7 @@ var init_task_templates = __esm({
38219
38497
  });
38220
38498
 
38221
38499
  // packages/prompts/dist/index.js
38222
- import { join as join51, dirname as dirname17 } from "node:path";
38500
+ import { join as join52, dirname as dirname17 } from "node:path";
38223
38501
  import { fileURLToPath as fileURLToPath10 } from "node:url";
38224
38502
  var _dir, _packageRoot;
38225
38503
  var init_dist6 = __esm({
@@ -38230,7 +38508,7 @@ var init_dist6 = __esm({
38230
38508
  init_task_templates();
38231
38509
  init_render2();
38232
38510
  _dir = dirname17(fileURLToPath10(import.meta.url));
38233
- _packageRoot = join51(_dir, "..");
38511
+ _packageRoot = join52(_dir, "..");
38234
38512
  }
38235
38513
  });
38236
38514
 
@@ -38263,21 +38541,21 @@ __export(oa_directory_exports, {
38263
38541
  writeIndexData: () => writeIndexData,
38264
38542
  writeIndexMeta: () => writeIndexMeta
38265
38543
  });
38266
- import { existsSync as existsSync35, mkdirSync as mkdirSync13, readFileSync as readFileSync26, writeFileSync as writeFileSync14, readdirSync as readdirSync9, statSync as statSync12, unlinkSync as unlinkSync6 } from "node:fs";
38267
- import { join as join52, relative as relative3, basename as basename10, extname as extname9 } from "node:path";
38544
+ import { existsSync as existsSync36, mkdirSync as mkdirSync14, readFileSync as readFileSync27, writeFileSync as writeFileSync15, readdirSync as readdirSync10, statSync as statSync12, unlinkSync as unlinkSync7 } from "node:fs";
38545
+ import { join as join53, relative as relative3, basename as basename11, extname as extname9 } from "node:path";
38268
38546
  import { homedir as homedir11 } from "node:os";
38269
38547
  function initOaDirectory(repoRoot) {
38270
- const oaPath = join52(repoRoot, OA_DIR);
38548
+ const oaPath = join53(repoRoot, OA_DIR);
38271
38549
  for (const sub of SUBDIRS) {
38272
- mkdirSync13(join52(oaPath, sub), { recursive: true });
38550
+ mkdirSync14(join53(oaPath, sub), { recursive: true });
38273
38551
  }
38274
38552
  try {
38275
- const gitignorePath = join52(repoRoot, ".gitignore");
38553
+ const gitignorePath = join53(repoRoot, ".gitignore");
38276
38554
  const settingsPattern = ".oa/settings.json";
38277
- if (existsSync35(gitignorePath)) {
38278
- const content = readFileSync26(gitignorePath, "utf-8");
38555
+ if (existsSync36(gitignorePath)) {
38556
+ const content = readFileSync27(gitignorePath, "utf-8");
38279
38557
  if (!content.includes(settingsPattern)) {
38280
- writeFileSync14(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
38558
+ writeFileSync15(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
38281
38559
  }
38282
38560
  }
38283
38561
  } catch {
@@ -38285,41 +38563,41 @@ function initOaDirectory(repoRoot) {
38285
38563
  return oaPath;
38286
38564
  }
38287
38565
  function hasOaDirectory(repoRoot) {
38288
- return existsSync35(join52(repoRoot, OA_DIR, "index"));
38566
+ return existsSync36(join53(repoRoot, OA_DIR, "index"));
38289
38567
  }
38290
38568
  function loadProjectSettings(repoRoot) {
38291
- const settingsPath = join52(repoRoot, OA_DIR, "settings.json");
38569
+ const settingsPath = join53(repoRoot, OA_DIR, "settings.json");
38292
38570
  try {
38293
- if (existsSync35(settingsPath)) {
38294
- return JSON.parse(readFileSync26(settingsPath, "utf-8"));
38571
+ if (existsSync36(settingsPath)) {
38572
+ return JSON.parse(readFileSync27(settingsPath, "utf-8"));
38295
38573
  }
38296
38574
  } catch {
38297
38575
  }
38298
38576
  return {};
38299
38577
  }
38300
38578
  function saveProjectSettings(repoRoot, settings) {
38301
- const oaPath = join52(repoRoot, OA_DIR);
38302
- mkdirSync13(oaPath, { recursive: true });
38579
+ const oaPath = join53(repoRoot, OA_DIR);
38580
+ mkdirSync14(oaPath, { recursive: true });
38303
38581
  const existing = loadProjectSettings(repoRoot);
38304
38582
  const merged = { ...existing, ...settings };
38305
- writeFileSync14(join52(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38583
+ writeFileSync15(join53(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38306
38584
  }
38307
38585
  function loadGlobalSettings() {
38308
- const settingsPath = join52(homedir11(), ".open-agents", "settings.json");
38586
+ const settingsPath = join53(homedir11(), ".open-agents", "settings.json");
38309
38587
  try {
38310
- if (existsSync35(settingsPath)) {
38311
- return JSON.parse(readFileSync26(settingsPath, "utf-8"));
38588
+ if (existsSync36(settingsPath)) {
38589
+ return JSON.parse(readFileSync27(settingsPath, "utf-8"));
38312
38590
  }
38313
38591
  } catch {
38314
38592
  }
38315
38593
  return {};
38316
38594
  }
38317
38595
  function saveGlobalSettings(settings) {
38318
- const dir = join52(homedir11(), ".open-agents");
38319
- mkdirSync13(dir, { recursive: true });
38596
+ const dir = join53(homedir11(), ".open-agents");
38597
+ mkdirSync14(dir, { recursive: true });
38320
38598
  const existing = loadGlobalSettings();
38321
38599
  const merged = { ...existing, ...settings };
38322
- writeFileSync14(join52(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38600
+ writeFileSync15(join53(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38323
38601
  }
38324
38602
  function resolveSettings(repoRoot) {
38325
38603
  const global = loadGlobalSettings();
@@ -38334,12 +38612,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38334
38612
  while (dir && !visited.has(dir)) {
38335
38613
  visited.add(dir);
38336
38614
  for (const name of CONTEXT_FILES) {
38337
- const filePath = join52(dir, name);
38615
+ const filePath = join53(dir, name);
38338
38616
  const normalizedName = name.toLowerCase();
38339
- if (existsSync35(filePath) && !seen.has(filePath)) {
38617
+ if (existsSync36(filePath) && !seen.has(filePath)) {
38340
38618
  seen.add(filePath);
38341
38619
  try {
38342
- let content = readFileSync26(filePath, "utf-8");
38620
+ let content = readFileSync27(filePath, "utf-8");
38343
38621
  if (content.length > maxContentLen) {
38344
38622
  content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
38345
38623
  }
@@ -38353,11 +38631,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38353
38631
  }
38354
38632
  }
38355
38633
  }
38356
- const projectMap = join52(dir, OA_DIR, "context", "project-map.md");
38357
- if (existsSync35(projectMap) && !seen.has(projectMap)) {
38634
+ const projectMap = join53(dir, OA_DIR, "context", "project-map.md");
38635
+ if (existsSync36(projectMap) && !seen.has(projectMap)) {
38358
38636
  seen.add(projectMap);
38359
38637
  try {
38360
- let content = readFileSync26(projectMap, "utf-8");
38638
+ let content = readFileSync27(projectMap, "utf-8");
38361
38639
  if (content.length > maxContentLen) {
38362
38640
  content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
38363
38641
  }
@@ -38369,7 +38647,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38369
38647
  } catch {
38370
38648
  }
38371
38649
  }
38372
- const parent = join52(dir, "..");
38650
+ const parent = join53(dir, "..");
38373
38651
  if (parent === dir)
38374
38652
  break;
38375
38653
  dir = parent;
@@ -38387,34 +38665,34 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38387
38665
  return found;
38388
38666
  }
38389
38667
  function readIndexMeta(repoRoot) {
38390
- const metaPath = join52(repoRoot, OA_DIR, "index", "meta.json");
38668
+ const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
38391
38669
  try {
38392
- return JSON.parse(readFileSync26(metaPath, "utf-8"));
38670
+ return JSON.parse(readFileSync27(metaPath, "utf-8"));
38393
38671
  } catch {
38394
38672
  return null;
38395
38673
  }
38396
38674
  }
38397
38675
  function writeIndexMeta(repoRoot, meta) {
38398
- const metaPath = join52(repoRoot, OA_DIR, "index", "meta.json");
38399
- mkdirSync13(join52(repoRoot, OA_DIR, "index"), { recursive: true });
38400
- writeFileSync14(metaPath, JSON.stringify(meta, null, 2), "utf-8");
38676
+ const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
38677
+ mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
38678
+ writeFileSync15(metaPath, JSON.stringify(meta, null, 2), "utf-8");
38401
38679
  }
38402
38680
  function readIndexData(repoRoot, filename) {
38403
- const filePath = join52(repoRoot, OA_DIR, "index", filename);
38681
+ const filePath = join53(repoRoot, OA_DIR, "index", filename);
38404
38682
  try {
38405
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38683
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38406
38684
  } catch {
38407
38685
  return null;
38408
38686
  }
38409
38687
  }
38410
38688
  function writeIndexData(repoRoot, filename, data) {
38411
- const filePath = join52(repoRoot, OA_DIR, "index", filename);
38412
- mkdirSync13(join52(repoRoot, OA_DIR, "index"), { recursive: true });
38413
- writeFileSync14(filePath, JSON.stringify(data, null, 2), "utf-8");
38689
+ const filePath = join53(repoRoot, OA_DIR, "index", filename);
38690
+ mkdirSync14(join53(repoRoot, OA_DIR, "index"), { recursive: true });
38691
+ writeFileSync15(filePath, JSON.stringify(data, null, 2), "utf-8");
38414
38692
  }
38415
38693
  function generateProjectMap(repoRoot) {
38416
38694
  const sections = [];
38417
- const repoName2 = basename10(repoRoot);
38695
+ const repoName2 = basename11(repoRoot);
38418
38696
  sections.push(`# Project Map: ${repoName2}
38419
38697
  `);
38420
38698
  sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -38458,28 +38736,28 @@ ${tree}\`\`\`
38458
38736
  sections.push("");
38459
38737
  }
38460
38738
  const content = sections.join("\n");
38461
- const contextDir = join52(repoRoot, OA_DIR, "context");
38462
- mkdirSync13(contextDir, { recursive: true });
38463
- writeFileSync14(join52(contextDir, "project-map.md"), content, "utf-8");
38739
+ const contextDir = join53(repoRoot, OA_DIR, "context");
38740
+ mkdirSync14(contextDir, { recursive: true });
38741
+ writeFileSync15(join53(contextDir, "project-map.md"), content, "utf-8");
38464
38742
  return content;
38465
38743
  }
38466
38744
  function saveSession(repoRoot, session) {
38467
- const historyDir = join52(repoRoot, OA_DIR, "history");
38468
- mkdirSync13(historyDir, { recursive: true });
38469
- writeFileSync14(join52(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
38745
+ const historyDir = join53(repoRoot, OA_DIR, "history");
38746
+ mkdirSync14(historyDir, { recursive: true });
38747
+ writeFileSync15(join53(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
38470
38748
  }
38471
38749
  function loadRecentSessions(repoRoot, limit = 5) {
38472
- const historyDir = join52(repoRoot, OA_DIR, "history");
38473
- if (!existsSync35(historyDir))
38750
+ const historyDir = join53(repoRoot, OA_DIR, "history");
38751
+ if (!existsSync36(historyDir))
38474
38752
  return [];
38475
38753
  try {
38476
- const files = readdirSync9(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
38477
- const stat5 = statSync12(join52(historyDir, f));
38754
+ const files = readdirSync10(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
38755
+ const stat5 = statSync12(join53(historyDir, f));
38478
38756
  return { file: f, mtime: stat5.mtimeMs };
38479
38757
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
38480
38758
  return files.map((f) => {
38481
38759
  try {
38482
- return JSON.parse(readFileSync26(join52(historyDir, f.file), "utf-8"));
38760
+ return JSON.parse(readFileSync27(join53(historyDir, f.file), "utf-8"));
38483
38761
  } catch {
38484
38762
  return null;
38485
38763
  }
@@ -38489,18 +38767,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
38489
38767
  }
38490
38768
  }
38491
38769
  function savePendingTask(repoRoot, task) {
38492
- const historyDir = join52(repoRoot, OA_DIR, "history");
38493
- mkdirSync13(historyDir, { recursive: true });
38494
- writeFileSync14(join52(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
38770
+ const historyDir = join53(repoRoot, OA_DIR, "history");
38771
+ mkdirSync14(historyDir, { recursive: true });
38772
+ writeFileSync15(join53(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
38495
38773
  }
38496
38774
  function loadPendingTask(repoRoot) {
38497
- const filePath = join52(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
38775
+ const filePath = join53(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
38498
38776
  try {
38499
- if (!existsSync35(filePath))
38777
+ if (!existsSync36(filePath))
38500
38778
  return null;
38501
- const data = JSON.parse(readFileSync26(filePath, "utf-8"));
38779
+ const data = JSON.parse(readFileSync27(filePath, "utf-8"));
38502
38780
  try {
38503
- unlinkSync6(filePath);
38781
+ unlinkSync7(filePath);
38504
38782
  } catch {
38505
38783
  }
38506
38784
  return data;
@@ -38509,13 +38787,13 @@ function loadPendingTask(repoRoot) {
38509
38787
  }
38510
38788
  }
38511
38789
  function saveSessionContext(repoRoot, entry) {
38512
- const contextDir = join52(repoRoot, OA_DIR, "context");
38513
- mkdirSync13(contextDir, { recursive: true });
38514
- const filePath = join52(contextDir, CONTEXT_SAVE_FILE);
38790
+ const contextDir = join53(repoRoot, OA_DIR, "context");
38791
+ mkdirSync14(contextDir, { recursive: true });
38792
+ const filePath = join53(contextDir, CONTEXT_SAVE_FILE);
38515
38793
  let ctx;
38516
38794
  try {
38517
- if (existsSync35(filePath)) {
38518
- ctx = JSON.parse(readFileSync26(filePath, "utf-8"));
38795
+ if (existsSync36(filePath)) {
38796
+ ctx = JSON.parse(readFileSync27(filePath, "utf-8"));
38519
38797
  } else {
38520
38798
  ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
38521
38799
  }
@@ -38527,14 +38805,14 @@ function saveSessionContext(repoRoot, entry) {
38527
38805
  ctx.entries = ctx.entries.slice(-ctx.maxEntries);
38528
38806
  }
38529
38807
  ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
38530
- writeFileSync14(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
38808
+ writeFileSync15(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
38531
38809
  }
38532
38810
  function loadSessionContext(repoRoot) {
38533
- const filePath = join52(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
38811
+ const filePath = join53(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
38534
38812
  try {
38535
- if (!existsSync35(filePath))
38813
+ if (!existsSync36(filePath))
38536
38814
  return null;
38537
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38815
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38538
38816
  } catch {
38539
38817
  return null;
38540
38818
  }
@@ -38580,12 +38858,12 @@ function detectManifests(repoRoot) {
38580
38858
  { file: "docker-compose.yaml", type: "Docker Compose" }
38581
38859
  ];
38582
38860
  for (const check of checks) {
38583
- const filePath = join52(repoRoot, check.file);
38584
- if (existsSync35(filePath)) {
38861
+ const filePath = join53(repoRoot, check.file);
38862
+ if (existsSync36(filePath)) {
38585
38863
  let name;
38586
38864
  if (check.nameField) {
38587
38865
  try {
38588
- const data = JSON.parse(readFileSync26(filePath, "utf-8"));
38866
+ const data = JSON.parse(readFileSync27(filePath, "utf-8"));
38589
38867
  name = data[check.nameField];
38590
38868
  } catch {
38591
38869
  }
@@ -38614,7 +38892,7 @@ function findKeyFiles(repoRoot) {
38614
38892
  { pattern: "CLAUDE.md", description: "Claude Code context" }
38615
38893
  ];
38616
38894
  for (const check of checks) {
38617
- if (existsSync35(join52(repoRoot, check.pattern))) {
38895
+ if (existsSync36(join53(repoRoot, check.pattern))) {
38618
38896
  keyFiles.push({ path: check.pattern, description: check.description });
38619
38897
  }
38620
38898
  }
@@ -38625,7 +38903,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38625
38903
  return "";
38626
38904
  let result = "";
38627
38905
  try {
38628
- const entries = readdirSync9(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
38906
+ const entries = readdirSync10(root, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") || e.name === ".github").filter((e) => !SKIP_DIRS.has(e.name)).sort((a, b) => {
38629
38907
  if (a.isDirectory() && !b.isDirectory())
38630
38908
  return -1;
38631
38909
  if (!a.isDirectory() && b.isDirectory())
@@ -38640,12 +38918,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38640
38918
  if (entry.isDirectory()) {
38641
38919
  let fileCount = 0;
38642
38920
  try {
38643
- fileCount = readdirSync9(join52(root, entry.name)).filter((f) => !f.startsWith(".")).length;
38921
+ fileCount = readdirSync10(join53(root, entry.name)).filter((f) => !f.startsWith(".")).length;
38644
38922
  } catch {
38645
38923
  }
38646
38924
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
38647
38925
  `;
38648
- result += buildDirTree(join52(root, entry.name), maxDepth, childPrefix, depth + 1);
38926
+ result += buildDirTree(join53(root, entry.name), maxDepth, childPrefix, depth + 1);
38649
38927
  } else if (depth < maxDepth) {
38650
38928
  result += `${prefix}${connector}${entry.name}
38651
38929
  `;
@@ -38657,17 +38935,17 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38657
38935
  }
38658
38936
  function loadUsageFile(filePath) {
38659
38937
  try {
38660
- if (existsSync35(filePath)) {
38661
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38938
+ if (existsSync36(filePath)) {
38939
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38662
38940
  }
38663
38941
  } catch {
38664
38942
  }
38665
38943
  return { records: [] };
38666
38944
  }
38667
38945
  function saveUsageFile(filePath, data) {
38668
- const dir = join52(filePath, "..");
38669
- mkdirSync13(dir, { recursive: true });
38670
- writeFileSync14(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38946
+ const dir = join53(filePath, "..");
38947
+ mkdirSync14(dir, { recursive: true });
38948
+ writeFileSync15(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
38671
38949
  }
38672
38950
  function recordUsage(kind, value, opts) {
38673
38951
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -38695,15 +38973,15 @@ function recordUsage(kind, value, opts) {
38695
38973
  }
38696
38974
  saveUsageFile(filePath, data);
38697
38975
  };
38698
- update(join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38976
+ update(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38699
38977
  if (opts?.repoRoot) {
38700
- update(join52(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38978
+ update(join53(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38701
38979
  }
38702
38980
  }
38703
38981
  function loadUsageHistory(kind, repoRoot) {
38704
- const globalPath = join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
38982
+ const globalPath = join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
38705
38983
  const globalData = loadUsageFile(globalPath);
38706
- const localData = repoRoot ? loadUsageFile(join52(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
38984
+ const localData = repoRoot ? loadUsageFile(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
38707
38985
  const map = /* @__PURE__ */ new Map();
38708
38986
  for (const r of globalData.records) {
38709
38987
  if (r.kind !== kind)
@@ -38734,9 +39012,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
38734
39012
  saveUsageFile(filePath, data);
38735
39013
  }
38736
39014
  };
38737
- remove(join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
39015
+ remove(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38738
39016
  if (repoRoot) {
38739
- remove(join52(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
39017
+ remove(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38740
39018
  }
38741
39019
  }
38742
39020
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -38784,10 +39062,10 @@ var init_oa_directory = __esm({
38784
39062
 
38785
39063
  // packages/cli/dist/tui/setup.js
38786
39064
  import * as readline from "node:readline";
38787
- import { execSync as execSync26, spawn as spawn19, exec as exec2 } from "node:child_process";
39065
+ import { execSync as execSync27, spawn as spawn19, exec as exec2 } from "node:child_process";
38788
39066
  import { promisify as promisify6 } from "node:util";
38789
- import { existsSync as existsSync36, writeFileSync as writeFileSync15, readFileSync as readFileSync27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync14 } from "node:fs";
38790
- import { join as join53 } from "node:path";
39067
+ import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
39068
+ import { join as join54 } from "node:path";
38791
39069
  import { homedir as homedir12, platform as platform2 } from "node:os";
38792
39070
  function detectSystemSpecs() {
38793
39071
  let totalRamGB = 0;
@@ -38795,7 +39073,7 @@ function detectSystemSpecs() {
38795
39073
  let gpuVramGB = 0;
38796
39074
  let gpuName = "";
38797
39075
  try {
38798
- const memInfo = execSync26("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
39076
+ const memInfo = execSync27("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
38799
39077
  encoding: "utf8",
38800
39078
  timeout: 5e3
38801
39079
  });
@@ -38815,7 +39093,7 @@ function detectSystemSpecs() {
38815
39093
  } catch {
38816
39094
  }
38817
39095
  try {
38818
- const nvidiaSmi = execSync26("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
39096
+ const nvidiaSmi = execSync27("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
38819
39097
  const lines = nvidiaSmi.trim().split("\n");
38820
39098
  if (lines.length > 0) {
38821
39099
  for (const line of lines) {
@@ -38994,7 +39272,7 @@ function ensureCurl() {
38994
39272
  for (const s of strategies) {
38995
39273
  if (hasCmd(s.check)) {
38996
39274
  try {
38997
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39275
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
38998
39276
  if (hasCmd("curl")) {
38999
39277
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
39000
39278
  `);
@@ -39008,7 +39286,7 @@ function ensureCurl() {
39008
39286
  }
39009
39287
  if (plat === "darwin") {
39010
39288
  try {
39011
- execSync26("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
39289
+ execSync27("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
39012
39290
  if (hasCmd("curl"))
39013
39291
  return true;
39014
39292
  } catch {
@@ -39043,7 +39321,7 @@ function installOllamaLinux() {
39043
39321
 
39044
39322
  `);
39045
39323
  try {
39046
- execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
39324
+ execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
39047
39325
  stdio: "inherit",
39048
39326
  timeout: 3e5
39049
39327
  });
@@ -39071,10 +39349,10 @@ async function installOllamaMac(_rl) {
39071
39349
 
39072
39350
  `);
39073
39351
  try {
39074
- execSync26('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
39352
+ execSync27('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
39075
39353
  if (!hasCmd("brew")) {
39076
39354
  try {
39077
- const brewPrefix = existsSync36("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
39355
+ const brewPrefix = existsSync37("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
39078
39356
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
39079
39357
  } catch {
39080
39358
  }
@@ -39104,7 +39382,7 @@ async function installOllamaMac(_rl) {
39104
39382
 
39105
39383
  `);
39106
39384
  try {
39107
- execSync26("brew install ollama", {
39385
+ execSync27("brew install ollama", {
39108
39386
  stdio: "inherit",
39109
39387
  timeout: 3e5
39110
39388
  });
@@ -39131,7 +39409,7 @@ function installOllamaWindows() {
39131
39409
 
39132
39410
  `);
39133
39411
  try {
39134
- execSync26('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
39412
+ execSync27('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
39135
39413
  stdio: "inherit",
39136
39414
  timeout: 3e5
39137
39415
  });
@@ -39212,7 +39490,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
39212
39490
  }
39213
39491
  function pullModelWithAutoUpdate(tag) {
39214
39492
  try {
39215
- execSync26(`ollama pull ${tag}`, {
39493
+ execSync27(`ollama pull ${tag}`, {
39216
39494
  stdio: "inherit",
39217
39495
  timeout: 36e5
39218
39496
  // 1 hour max
@@ -39232,7 +39510,7 @@ function pullModelWithAutoUpdate(tag) {
39232
39510
 
39233
39511
  `);
39234
39512
  try {
39235
- execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
39513
+ execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
39236
39514
  stdio: "inherit",
39237
39515
  timeout: 3e5
39238
39516
  // 5 min max for install
@@ -39243,7 +39521,7 @@ function pullModelWithAutoUpdate(tag) {
39243
39521
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
39244
39522
 
39245
39523
  `);
39246
- execSync26(`ollama pull ${tag}`, {
39524
+ execSync27(`ollama pull ${tag}`, {
39247
39525
  stdio: "inherit",
39248
39526
  timeout: 36e5
39249
39527
  });
@@ -39345,7 +39623,7 @@ function ensurePython3() {
39345
39623
  if (plat === "darwin") {
39346
39624
  if (hasCmd("brew")) {
39347
39625
  try {
39348
- execSync26("brew install python3", { stdio: "inherit", timeout: 3e5 });
39626
+ execSync27("brew install python3", { stdio: "inherit", timeout: 3e5 });
39349
39627
  if (hasCmd("python3")) {
39350
39628
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
39351
39629
  `);
@@ -39358,7 +39636,7 @@ function ensurePython3() {
39358
39636
  for (const s of strategies) {
39359
39637
  if (hasCmd(s.check)) {
39360
39638
  try {
39361
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39639
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
39362
39640
  if (hasCmd("python3") || hasCmd("python")) {
39363
39641
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
39364
39642
  `);
@@ -39374,11 +39652,11 @@ function ensurePython3() {
39374
39652
  }
39375
39653
  function checkPythonVenv() {
39376
39654
  try {
39377
- execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39655
+ execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39378
39656
  return true;
39379
39657
  } catch {
39380
39658
  try {
39381
- execSync26("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
39659
+ execSync27("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
39382
39660
  return true;
39383
39661
  } catch {
39384
39662
  return false;
@@ -39397,7 +39675,7 @@ function ensurePythonVenv() {
39397
39675
  for (const s of strategies) {
39398
39676
  if (hasCmd(s.check)) {
39399
39677
  try {
39400
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39678
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
39401
39679
  if (checkPythonVenv()) {
39402
39680
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
39403
39681
  `);
@@ -39828,12 +40106,12 @@ async function doSetup(config, rl) {
39828
40106
  `PARAMETER num_predict ${numPredict}`,
39829
40107
  `PARAMETER stop "<|endoftext|>"`
39830
40108
  ].join("\n");
39831
- const modelDir2 = join53(homedir12(), ".open-agents", "models");
39832
- mkdirSync14(modelDir2, { recursive: true });
39833
- const modelfilePath = join53(modelDir2, `Modelfile.${customName}`);
39834
- writeFileSync15(modelfilePath, modelfileContent + "\n", "utf8");
40109
+ const modelDir2 = join54(homedir12(), ".open-agents", "models");
40110
+ mkdirSync15(modelDir2, { recursive: true });
40111
+ const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
40112
+ writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
39835
40113
  process.stdout.write(` ${c2.dim("Creating model...")} `);
39836
- execSync26(`ollama create ${customName} -f ${modelfilePath}`, {
40114
+ execSync27(`ollama create ${customName} -f ${modelfilePath}`, {
39837
40115
  stdio: "pipe",
39838
40116
  timeout: 12e4
39839
40117
  });
@@ -39876,7 +40154,7 @@ async function isModelAvailable(config) {
39876
40154
  }
39877
40155
  function isFirstRun() {
39878
40156
  try {
39879
- return !existsSync36(join53(homedir12(), ".open-agents", "config.json"));
40157
+ return !existsSync37(join54(homedir12(), ".open-agents", "config.json"));
39880
40158
  } catch {
39881
40159
  return true;
39882
40160
  }
@@ -39884,7 +40162,7 @@ function isFirstRun() {
39884
40162
  function hasCmd(cmd) {
39885
40163
  try {
39886
40164
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
39887
- execSync26(whichCmd, { stdio: "pipe", timeout: 3e3 });
40165
+ execSync27(whichCmd, { stdio: "pipe", timeout: 3e3 });
39888
40166
  return true;
39889
40167
  } catch {
39890
40168
  return false;
@@ -39913,11 +40191,11 @@ function detectPkgManager() {
39913
40191
  return null;
39914
40192
  }
39915
40193
  function getVenvDir() {
39916
- return join53(homedir12(), ".open-agents", "venv");
40194
+ return join54(homedir12(), ".open-agents", "venv");
39917
40195
  }
39918
40196
  function hasVenvModule() {
39919
40197
  try {
39920
- execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
40198
+ execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39921
40199
  return true;
39922
40200
  } catch {
39923
40201
  return false;
@@ -39926,9 +40204,9 @@ function hasVenvModule() {
39926
40204
  function ensureVenv(log) {
39927
40205
  const venvDir = getVenvDir();
39928
40206
  const isWin2 = process.platform === "win32";
39929
- const pipPath = isWin2 ? join53(venvDir, "Scripts", "pip.exe") : join53(venvDir, "bin", "pip");
40207
+ const pipPath = isWin2 ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
39930
40208
  const pythonCmd = isWin2 ? "python" : "python3";
39931
- if (existsSync36(pipPath))
40209
+ if (existsSync37(pipPath))
39932
40210
  return venvDir;
39933
40211
  log("Creating Python venv for vision deps...");
39934
40212
  if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
@@ -39940,10 +40218,10 @@ function ensureVenv(log) {
39940
40218
  return null;
39941
40219
  }
39942
40220
  try {
39943
- mkdirSync14(join53(homedir12(), ".open-agents"), { recursive: true });
40221
+ mkdirSync15(join54(homedir12(), ".open-agents"), { recursive: true });
39944
40222
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
39945
- execSync26(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
39946
- execSync26(`"${pipPath}" install --upgrade pip`, {
40223
+ execSync27(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
40224
+ execSync27(`"${pipPath}" install --upgrade pip`, {
39947
40225
  stdio: "pipe",
39948
40226
  timeout: 6e4
39949
40227
  });
@@ -39956,7 +40234,7 @@ function ensureVenv(log) {
39956
40234
  }
39957
40235
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39958
40236
  try {
39959
- execSync26(`sudo -n ${cmd}`, {
40237
+ execSync27(`sudo -n ${cmd}`, {
39960
40238
  stdio: "pipe",
39961
40239
  timeout: timeoutMs,
39962
40240
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -39969,7 +40247,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39969
40247
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
39970
40248
  try {
39971
40249
  const escaped = cmd.replace(/'/g, "'\\''");
39972
- execSync26(`sudo -S bash -c '${escaped}'`, {
40250
+ execSync27(`sudo -S bash -c '${escaped}'`, {
39973
40251
  input: password + "\n",
39974
40252
  stdio: ["pipe", "pipe", "pipe"],
39975
40253
  timeout: timeoutMs,
@@ -40076,7 +40354,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40076
40354
  ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
40077
40355
  } else {
40078
40356
  try {
40079
- execSync26(batchCmd, { stdio: "pipe", timeout: 18e4 });
40357
+ execSync27(batchCmd, { stdio: "pipe", timeout: 18e4 });
40080
40358
  ok = true;
40081
40359
  } catch {
40082
40360
  ok = false;
@@ -40113,7 +40391,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40113
40391
  const venvCmds = {
40114
40392
  apt: () => {
40115
40393
  try {
40116
- const pyVer = execSync26(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
40394
+ const pyVer = execSync27(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
40117
40395
  return `apt-get install -y python3-venv python${pyVer}-venv`;
40118
40396
  } catch {
40119
40397
  return "apt-get install -y python3-venv";
@@ -40134,19 +40412,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40134
40412
  }
40135
40413
  }
40136
40414
  const venvDir = getVenvDir();
40137
- const venvBin = join53(venvDir, "bin");
40138
- const venvMoondream = join53(venvBin, "moondream-station");
40415
+ const venvBin = join54(venvDir, "bin");
40416
+ const venvMoondream = join54(venvBin, "moondream-station");
40139
40417
  const venv = ensureVenv(log);
40140
- if (venv && !hasCmd("moondream-station") && !existsSync36(venvMoondream)) {
40141
- const venvPip2 = join53(venvBin, "pip");
40418
+ if (venv && !hasCmd("moondream-station") && !existsSync37(venvMoondream)) {
40419
+ const venvPip2 = join54(venvBin, "pip");
40142
40420
  log("Installing moondream-station in ~/.open-agents/venv...");
40143
40421
  try {
40144
- execSync26(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
40145
- if (existsSync36(venvMoondream)) {
40422
+ execSync27(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
40423
+ if (existsSync37(venvMoondream)) {
40146
40424
  log("moondream-station installed successfully.");
40147
40425
  } else {
40148
40426
  try {
40149
- const check = execSync26(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
40427
+ const check = execSync27(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
40150
40428
  if (check.includes("moondream")) {
40151
40429
  log("moondream-station package installed.");
40152
40430
  }
@@ -40159,11 +40437,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40159
40437
  }
40160
40438
  }
40161
40439
  if (venv) {
40162
- const venvPython2 = join53(venvBin, "python");
40163
- const venvPip2 = join53(venvBin, "pip");
40440
+ const venvPython2 = join54(venvBin, "python");
40441
+ const venvPip2 = join54(venvBin, "pip");
40164
40442
  let ocrStackInstalled = false;
40165
40443
  try {
40166
- execSync26(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
40444
+ execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
40167
40445
  ocrStackInstalled = true;
40168
40446
  } catch {
40169
40447
  }
@@ -40171,9 +40449,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40171
40449
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
40172
40450
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
40173
40451
  try {
40174
- execSync26(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
40452
+ execSync27(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
40175
40453
  try {
40176
- execSync26(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
40454
+ execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
40177
40455
  log("OCR Python stack installed successfully.");
40178
40456
  } catch {
40179
40457
  log("OCR Python stack install completed but import verification failed.");
@@ -40207,7 +40485,7 @@ function ensureCloudflaredBackground(onInfo) {
40207
40485
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
40208
40486
  const cfArch = archMap[arch2] ?? "amd64";
40209
40487
  try {
40210
- execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
40488
+ execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
40211
40489
  if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
40212
40490
  process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
40213
40491
  }
@@ -40218,7 +40496,7 @@ function ensureCloudflaredBackground(onInfo) {
40218
40496
  } catch {
40219
40497
  }
40220
40498
  try {
40221
- execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
40499
+ execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
40222
40500
  if (hasCmd("cloudflared")) {
40223
40501
  log("cloudflared installed.");
40224
40502
  return true;
@@ -40227,7 +40505,7 @@ function ensureCloudflaredBackground(onInfo) {
40227
40505
  }
40228
40506
  } else if (os === "darwin") {
40229
40507
  try {
40230
- execSync26("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
40508
+ execSync27("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
40231
40509
  if (hasCmd("cloudflared")) {
40232
40510
  log("cloudflared installed via Homebrew.");
40233
40511
  return true;
@@ -40304,10 +40582,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
40304
40582
  `PARAMETER num_predict ${numPredict}`,
40305
40583
  `PARAMETER stop "<|endoftext|>"`
40306
40584
  ].join("\n");
40307
- const modelDir2 = join53(homedir12(), ".open-agents", "models");
40308
- mkdirSync14(modelDir2, { recursive: true });
40309
- const modelfilePath = join53(modelDir2, `Modelfile.${customName}`);
40310
- writeFileSync15(modelfilePath, modelfileContent + "\n", "utf8");
40585
+ const modelDir2 = join54(homedir12(), ".open-agents", "models");
40586
+ mkdirSync15(modelDir2, { recursive: true });
40587
+ const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
40588
+ writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
40311
40589
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
40312
40590
  timeout: 12e4
40313
40591
  });
@@ -40369,7 +40647,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
40369
40647
  }
40370
40648
  async function ensureNeovim() {
40371
40649
  try {
40372
- const nvimPath = execSync26("which nvim 2>/dev/null || where nvim 2>nul", {
40650
+ const nvimPath = execSync27("which nvim 2>/dev/null || where nvim 2>nul", {
40373
40651
  encoding: "utf8",
40374
40652
  stdio: "pipe",
40375
40653
  timeout: 5e3
@@ -40381,24 +40659,24 @@ async function ensureNeovim() {
40381
40659
  const platform6 = process.platform;
40382
40660
  const arch2 = process.arch;
40383
40661
  if (platform6 === "linux") {
40384
- const binDir = join53(homedir12(), ".local", "bin");
40385
- const nvimDest = join53(binDir, "nvim");
40662
+ const binDir = join54(homedir12(), ".local", "bin");
40663
+ const nvimDest = join54(binDir, "nvim");
40386
40664
  try {
40387
- mkdirSync14(binDir, { recursive: true });
40665
+ mkdirSync15(binDir, { recursive: true });
40388
40666
  } catch {
40389
40667
  }
40390
40668
  const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
40391
40669
  const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
40392
40670
  console.log(` Downloading Neovim (${appImageName})...`);
40393
40671
  try {
40394
- execSync26(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
40395
- execSync26(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
40672
+ execSync27(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
40673
+ execSync27(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
40396
40674
  } catch (err) {
40397
40675
  console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
40398
40676
  return null;
40399
40677
  }
40400
40678
  try {
40401
- const ver = execSync26(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
40679
+ const ver = execSync27(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
40402
40680
  console.log(` Installed: ${ver}`);
40403
40681
  } catch {
40404
40682
  console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
@@ -40413,8 +40691,8 @@ async function ensureNeovim() {
40413
40691
  if (hasCmd("brew")) {
40414
40692
  console.log(" Installing Neovim via Homebrew...");
40415
40693
  try {
40416
- execSync26("brew install neovim", { stdio: "inherit", timeout: 12e4 });
40417
- const nvimPath = execSync26("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
40694
+ execSync27("brew install neovim", { stdio: "inherit", timeout: 12e4 });
40695
+ const nvimPath = execSync27("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
40418
40696
  return nvimPath || null;
40419
40697
  } catch {
40420
40698
  console.log(" brew install neovim failed.");
@@ -40428,7 +40706,7 @@ async function ensureNeovim() {
40428
40706
  if (hasCmd("choco")) {
40429
40707
  console.log(" Installing Neovim via Chocolatey...");
40430
40708
  try {
40431
- execSync26("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
40709
+ execSync27("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
40432
40710
  return "nvim";
40433
40711
  } catch {
40434
40712
  console.log(" choco install neovim failed.");
@@ -40437,7 +40715,7 @@ async function ensureNeovim() {
40437
40715
  if (hasCmd("winget")) {
40438
40716
  console.log(" Installing Neovim via winget...");
40439
40717
  try {
40440
- execSync26("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
40718
+ execSync27("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
40441
40719
  stdio: "inherit",
40442
40720
  timeout: 12e4
40443
40721
  });
@@ -40453,9 +40731,9 @@ async function ensureNeovim() {
40453
40731
  }
40454
40732
  function ensurePathInShellRc(binDir) {
40455
40733
  const shell = process.env.SHELL ?? "";
40456
- const rcFile = shell.includes("zsh") ? join53(homedir12(), ".zshrc") : join53(homedir12(), ".bashrc");
40734
+ const rcFile = shell.includes("zsh") ? join54(homedir12(), ".zshrc") : join54(homedir12(), ".bashrc");
40457
40735
  try {
40458
- const rcContent = existsSync36(rcFile) ? readFileSync27(rcFile, "utf8") : "";
40736
+ const rcContent = existsSync37(rcFile) ? readFileSync28(rcFile, "utf8") : "";
40459
40737
  if (rcContent.includes(binDir))
40460
40738
  return;
40461
40739
  const exportLine = `
@@ -41170,7 +41448,7 @@ var init_tui_select = __esm({
41170
41448
  });
41171
41449
 
41172
41450
  // packages/cli/dist/tui/drop-panel.js
41173
- import { existsSync as existsSync37 } from "node:fs";
41451
+ import { existsSync as existsSync38 } from "node:fs";
41174
41452
  import { extname as extname10, resolve as resolve29 } from "node:path";
41175
41453
  function ansi4(code, text) {
41176
41454
  return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
@@ -41285,7 +41563,7 @@ function showDropPanel(opts) {
41285
41563
  filePath = decodeURIComponent(filePath.slice(7));
41286
41564
  }
41287
41565
  filePath = resolve29(filePath);
41288
- if (!existsSync37(filePath)) {
41566
+ if (!existsSync38(filePath)) {
41289
41567
  errorMsg = `File not found: ${filePath}`;
41290
41568
  render();
41291
41569
  return;
@@ -41356,10 +41634,10 @@ var init_drop_panel = __esm({
41356
41634
  });
41357
41635
 
41358
41636
  // packages/cli/dist/tui/neovim-mode.js
41359
- import { existsSync as existsSync38, unlinkSync as unlinkSync7 } from "node:fs";
41637
+ import { existsSync as existsSync39, unlinkSync as unlinkSync8 } from "node:fs";
41360
41638
  import { tmpdir as tmpdir8 } from "node:os";
41361
- import { join as join54 } from "node:path";
41362
- import { execSync as execSync27 } from "node:child_process";
41639
+ import { join as join55 } from "node:path";
41640
+ import { execSync as execSync28 } from "node:child_process";
41363
41641
  function isNeovimActive() {
41364
41642
  return _state !== null && !_state.cleanedUp;
41365
41643
  }
@@ -41377,7 +41655,7 @@ async function startNeovimMode(opts) {
41377
41655
  }
41378
41656
  let nvimPath;
41379
41657
  try {
41380
- nvimPath = execSync27("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
41658
+ nvimPath = execSync28("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
41381
41659
  if (!nvimPath)
41382
41660
  throw new Error();
41383
41661
  } catch {
@@ -41406,10 +41684,10 @@ async function startNeovimMode(opts) {
41406
41684
  );
41407
41685
  } catch {
41408
41686
  }
41409
- const socketPath = join54(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
41687
+ const socketPath = join55(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
41410
41688
  try {
41411
- if (existsSync38(socketPath))
41412
- unlinkSync7(socketPath);
41689
+ if (existsSync39(socketPath))
41690
+ unlinkSync8(socketPath);
41413
41691
  } catch {
41414
41692
  }
41415
41693
  const ptyCols = opts.cols;
@@ -41635,13 +41913,13 @@ function resizeNeovim(cols, contentRows) {
41635
41913
  }
41636
41914
  async function connectRPC(state, neovimPkg, cols) {
41637
41915
  let attempts = 0;
41638
- while (!existsSync38(state.socketPath) && attempts < 30) {
41916
+ while (!existsSync39(state.socketPath) && attempts < 30) {
41639
41917
  await new Promise((r) => setTimeout(r, 200));
41640
41918
  attempts++;
41641
41919
  if (state.cleanedUp)
41642
41920
  return;
41643
41921
  }
41644
- if (!existsSync38(state.socketPath))
41922
+ if (!existsSync39(state.socketPath))
41645
41923
  return;
41646
41924
  const nvim = neovimPkg.attach({ socket: state.socketPath });
41647
41925
  state.nvim = nvim;
@@ -41778,8 +42056,8 @@ function doCleanup(state) {
41778
42056
  state.pty = null;
41779
42057
  }
41780
42058
  try {
41781
- if (existsSync38(state.socketPath))
41782
- unlinkSync7(state.socketPath);
42059
+ if (existsSync39(state.socketPath))
42060
+ unlinkSync8(state.socketPath);
41783
42061
  } catch {
41784
42062
  }
41785
42063
  if (state.stdinHandler) {
@@ -41835,10 +42113,10 @@ __export(voice_exports, {
41835
42113
  registerCustomOnnxModel: () => registerCustomOnnxModel,
41836
42114
  resetNarrationContext: () => resetNarrationContext
41837
42115
  });
41838
- import { existsSync as existsSync39, mkdirSync as mkdirSync15, writeFileSync as writeFileSync16, readFileSync as readFileSync28, unlinkSync as unlinkSync8, readdirSync as readdirSync10, renameSync, statSync as statSync13 } from "node:fs";
41839
- import { join as join55, dirname as dirname18 } from "node:path";
42116
+ import { existsSync as existsSync40, mkdirSync as mkdirSync16, writeFileSync as writeFileSync17, readFileSync as readFileSync29, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
42117
+ import { join as join56, dirname as dirname18 } from "node:path";
41840
42118
  import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
41841
- import { execSync as execSync28, spawn as nodeSpawn } from "node:child_process";
42119
+ import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
41842
42120
  import { createRequire } from "node:module";
41843
42121
  function sanitizeForTTS(text) {
41844
42122
  return text.replace(/^#{1,6}\s+/gm, "").replace(/\*{1,3}([^*]+)\*{1,3}/g, "$1").replace(/_{1,3}([^_]+)_{1,3}/g, "$1").replace(/~~([^~]+)~~/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/```[\s\S]*?```/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/^[\s]*[-*+]\s+/gm, "").replace(/^[\s]*\d+\.\s+/gm, "").replace(/^>\s+/gm, "").replace(/^[-*_]{3,}$/gm, "").replace(/\[[ xX]\]\s*/g, "").replace(/[\u{1F600}-\u{1F64F}]/gu, "").replace(/[\u{1F300}-\u{1F5FF}]/gu, "").replace(/[\u{1F680}-\u{1F6FF}]/gu, "").replace(/[\u{1F1E0}-\u{1F1FF}]/gu, "").replace(/[\u{2600}-\u{26FF}]/gu, "").replace(/[\u{2700}-\u{27BF}]/gu, "").replace(/[\u{FE00}-\u{FE0F}]/gu, "").replace(/[\u{1F900}-\u{1F9FF}]/gu, "").replace(/[\u{1FA00}-\u{1FA6F}]/gu, "").replace(/[\u{1FA70}-\u{1FAFF}]/gu, "").replace(/[\u{200D}]/gu, "").replace(/[\u{20E3}]/gu, "").replace(/[✓✔✗✘✕✖⚠️⏸⏹⏵●○◆◇■□▪▫►▼▲◀⬆⬇⬅➡↑↓←→⇐⇒⇑⇓]/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐░▒▓█⠀-⣿]/g, "").replace(/\s{2,}/g, " ").trim();
@@ -41861,40 +42139,40 @@ function listVoiceModels() {
41861
42139
  }));
41862
42140
  }
41863
42141
  function voiceDir() {
41864
- return join55(homedir13(), ".open-agents", "voice");
42142
+ return join56(homedir13(), ".open-agents", "voice");
41865
42143
  }
41866
42144
  function modelsDir() {
41867
- return join55(voiceDir(), "models");
42145
+ return join56(voiceDir(), "models");
41868
42146
  }
41869
42147
  function modelDir(id) {
41870
- return join55(modelsDir(), id);
42148
+ return join56(modelsDir(), id);
41871
42149
  }
41872
42150
  function modelOnnxPath(id) {
41873
- return join55(modelDir(id), "model.onnx");
42151
+ return join56(modelDir(id), "model.onnx");
41874
42152
  }
41875
42153
  function modelConfigPath(id) {
41876
- return join55(modelDir(id), "config.json");
42154
+ return join56(modelDir(id), "config.json");
41877
42155
  }
41878
42156
  function luxttsVenvDir() {
41879
- return join55(voiceDir(), "luxtts-venv");
42157
+ return join56(voiceDir(), "luxtts-venv");
41880
42158
  }
41881
42159
  function luxttsVenvPy() {
41882
- return platform3() === "win32" ? join55(luxttsVenvDir(), "Scripts", "python.exe") : join55(luxttsVenvDir(), "bin", "python3");
42160
+ return platform3() === "win32" ? join56(luxttsVenvDir(), "Scripts", "python.exe") : join56(luxttsVenvDir(), "bin", "python3");
41883
42161
  }
41884
42162
  function luxttsRepoDir() {
41885
- return join55(voiceDir(), "LuxTTS");
42163
+ return join56(voiceDir(), "LuxTTS");
41886
42164
  }
41887
42165
  function luxttsCloneRefsDir() {
41888
- return join55(voiceDir(), "clone-refs");
42166
+ return join56(voiceDir(), "clone-refs");
41889
42167
  }
41890
42168
  function luxttsInferScript() {
41891
- return join55(voiceDir(), "luxtts-infer.py");
42169
+ return join56(voiceDir(), "luxtts-infer.py");
41892
42170
  }
41893
42171
  function writeDetectTorchScript(targetPath) {
41894
- if (existsSync39(targetPath))
42172
+ if (existsSync40(targetPath))
41895
42173
  return;
41896
42174
  try {
41897
- mkdirSync15(dirname18(targetPath), { recursive: true });
42175
+ mkdirSync16(dirname18(targetPath), { recursive: true });
41898
42176
  } catch {
41899
42177
  }
41900
42178
  const script = `#!/usr/bin/env python3
@@ -41967,7 +42245,7 @@ def main():
41967
42245
  if __name__ == "__main__": main()
41968
42246
  `;
41969
42247
  try {
41970
- writeFileSync16(targetPath, script, { mode: 493 });
42248
+ writeFileSync17(targetPath, script, { mode: 493 });
41971
42249
  } catch {
41972
42250
  }
41973
42251
  }
@@ -42777,8 +43055,8 @@ var init_voice = __esm({
42777
43055
  const refsDir = luxttsCloneRefsDir();
42778
43056
  const targets = ["glados", "overwatch"];
42779
43057
  for (const modelId of targets) {
42780
- const refFile = join55(refsDir, `${modelId}-ref.wav`);
42781
- if (existsSync39(refFile))
43058
+ const refFile = join56(refsDir, `${modelId}-ref.wav`);
43059
+ if (existsSync40(refFile))
42782
43060
  continue;
42783
43061
  try {
42784
43062
  await this.generateCloneRef(modelId);
@@ -42857,24 +43135,24 @@ var init_voice = __esm({
42857
43135
  }
42858
43136
  p = p.replace(/\\ /g, " ");
42859
43137
  if (p.startsWith("~/") || p === "~") {
42860
- p = join55(homedir13(), p.slice(1));
43138
+ p = join56(homedir13(), p.slice(1));
42861
43139
  }
42862
- if (!existsSync39(p)) {
43140
+ if (!existsSync40(p)) {
42863
43141
  return `File not found: ${p}
42864
43142
  (original input: ${audioPath})`;
42865
43143
  }
42866
43144
  audioPath = p;
42867
43145
  const refsDir = luxttsCloneRefsDir();
42868
- if (!existsSync39(refsDir))
42869
- mkdirSync15(refsDir, { recursive: true });
43146
+ if (!existsSync40(refsDir))
43147
+ mkdirSync16(refsDir, { recursive: true });
42870
43148
  const ext = audioPath.split(".").pop() || "wav";
42871
43149
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
42872
43150
  const ts = Date.now().toString(36);
42873
43151
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
42874
- const destPath = join55(refsDir, destFilename);
43152
+ const destPath = join56(refsDir, destFilename);
42875
43153
  try {
42876
- const data = readFileSync28(audioPath);
42877
- writeFileSync16(destPath, data);
43154
+ const data = readFileSync29(audioPath);
43155
+ writeFileSync17(destPath, data);
42878
43156
  } catch (err) {
42879
43157
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
42880
43158
  }
@@ -42914,9 +43192,9 @@ var init_voice = __esm({
42914
43192
  return `Failed to synthesize reference audio from ${source.label}.`;
42915
43193
  }
42916
43194
  const refsDir = luxttsCloneRefsDir();
42917
- if (!existsSync39(refsDir))
42918
- mkdirSync15(refsDir, { recursive: true });
42919
- const destPath = join55(refsDir, `${sourceModelId}-ref.wav`);
43195
+ if (!existsSync40(refsDir))
43196
+ mkdirSync16(refsDir, { recursive: true });
43197
+ const destPath = join56(refsDir, `${sourceModelId}-ref.wav`);
42920
43198
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
42921
43199
  this.writeWav(audioData, sampleRate, destPath);
42922
43200
  this.luxttsCloneRef = destPath;
@@ -42932,23 +43210,23 @@ var init_voice = __esm({
42932
43210
  // -------------------------------------------------------------------------
42933
43211
  /** Metadata file for friendly names of clone refs */
42934
43212
  static cloneMetaFile() {
42935
- return join55(luxttsCloneRefsDir(), "meta.json");
43213
+ return join56(luxttsCloneRefsDir(), "meta.json");
42936
43214
  }
42937
43215
  loadCloneMeta() {
42938
43216
  const p = _VoiceEngine.cloneMetaFile();
42939
- if (!existsSync39(p))
43217
+ if (!existsSync40(p))
42940
43218
  return {};
42941
43219
  try {
42942
- return JSON.parse(readFileSync28(p, "utf8"));
43220
+ return JSON.parse(readFileSync29(p, "utf8"));
42943
43221
  } catch {
42944
43222
  return {};
42945
43223
  }
42946
43224
  }
42947
43225
  saveCloneMeta(meta) {
42948
43226
  const dir = luxttsCloneRefsDir();
42949
- if (!existsSync39(dir))
42950
- mkdirSync15(dir, { recursive: true });
42951
- writeFileSync16(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
43227
+ if (!existsSync40(dir))
43228
+ mkdirSync16(dir, { recursive: true });
43229
+ writeFileSync17(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
42952
43230
  }
42953
43231
  /** Audio file extensions recognized as clone references */
42954
43232
  static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
@@ -42958,15 +43236,15 @@ var init_voice = __esm({
42958
43236
  */
42959
43237
  listCloneRefs() {
42960
43238
  const dir = luxttsCloneRefsDir();
42961
- if (!existsSync39(dir))
43239
+ if (!existsSync40(dir))
42962
43240
  return [];
42963
43241
  const meta = this.loadCloneMeta();
42964
- const files = readdirSync10(dir).filter((f) => {
43242
+ const files = readdirSync11(dir).filter((f) => {
42965
43243
  const ext = f.split(".").pop()?.toLowerCase() ?? "";
42966
43244
  return _VoiceEngine.AUDIO_EXTS.has(ext);
42967
43245
  });
42968
43246
  return files.map((f) => {
42969
- const p = join55(dir, f);
43247
+ const p = join56(dir, f);
42970
43248
  let size = 0;
42971
43249
  try {
42972
43250
  size = statSync13(p).size;
@@ -42983,11 +43261,11 @@ var init_voice = __esm({
42983
43261
  }
42984
43262
  /** Delete a clone reference file by filename. Returns true if deleted. */
42985
43263
  deleteCloneRef(filename) {
42986
- const p = join55(luxttsCloneRefsDir(), filename);
42987
- if (!existsSync39(p))
43264
+ const p = join56(luxttsCloneRefsDir(), filename);
43265
+ if (!existsSync40(p))
42988
43266
  return false;
42989
43267
  try {
42990
- unlinkSync8(p);
43268
+ unlinkSync9(p);
42991
43269
  const meta = this.loadCloneMeta();
42992
43270
  delete meta[filename];
42993
43271
  this.saveCloneMeta(meta);
@@ -43008,8 +43286,8 @@ var init_voice = __esm({
43008
43286
  }
43009
43287
  /** Set the active clone reference by filename. */
43010
43288
  setActiveCloneRef(filename) {
43011
- const p = join55(luxttsCloneRefsDir(), filename);
43012
- if (!existsSync39(p))
43289
+ const p = join56(luxttsCloneRefsDir(), filename);
43290
+ if (!existsSync40(p))
43013
43291
  return `File not found: ${filename}`;
43014
43292
  this.luxttsCloneRef = p;
43015
43293
  return `Active clone voice set to: ${filename}`;
@@ -43265,7 +43543,7 @@ var init_voice = __esm({
43265
43543
  }
43266
43544
  if (prefetchedWav) {
43267
43545
  try {
43268
- unlinkSync8(prefetchedWav.path);
43546
+ unlinkSync9(prefetchedWav.path);
43269
43547
  } catch {
43270
43548
  }
43271
43549
  }
@@ -43334,11 +43612,11 @@ var init_voice = __esm({
43334
43612
  }
43335
43613
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
43336
43614
  }
43337
- const wavPath = join55(tmpdir9(), `oa-voice-${Date.now()}.wav`);
43615
+ const wavPath = join56(tmpdir9(), `oa-voice-${Date.now()}.wav`);
43338
43616
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
43339
43617
  await this.playWav(wavPath);
43340
43618
  try {
43341
- unlinkSync8(wavPath);
43619
+ unlinkSync9(wavPath);
43342
43620
  } catch {
43343
43621
  }
43344
43622
  }
@@ -43451,7 +43729,7 @@ var init_voice = __esm({
43451
43729
  buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
43452
43730
  pos += 2;
43453
43731
  }
43454
- writeFileSync16(path, buffer);
43732
+ writeFileSync17(path, buffer);
43455
43733
  }
43456
43734
  // -------------------------------------------------------------------------
43457
43735
  // Phonemization
@@ -43529,7 +43807,7 @@ var init_voice = __esm({
43529
43807
  return buffer;
43530
43808
  }
43531
43809
  writeWav(samples, sampleRate, path) {
43532
- writeFileSync16(path, this.buildWavBuffer(samples, sampleRate));
43810
+ writeFileSync17(path, this.buildWavBuffer(samples, sampleRate));
43533
43811
  }
43534
43812
  // -------------------------------------------------------------------------
43535
43813
  // Audio playback (system default speakers)
@@ -43579,7 +43857,7 @@ var init_voice = __esm({
43579
43857
  }
43580
43858
  for (const player of ["paplay", "pw-play", "aplay"]) {
43581
43859
  try {
43582
- execSync28(`which ${player}`, { stdio: "pipe" });
43860
+ execSync29(`which ${player}`, { stdio: "pipe" });
43583
43861
  return [player, path];
43584
43862
  } catch {
43585
43863
  }
@@ -43608,7 +43886,7 @@ var init_voice = __esm({
43608
43886
  return this.python3Path;
43609
43887
  for (const bin of ["python3", "python"]) {
43610
43888
  try {
43611
- const path = execSync28(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43889
+ const path = execSync29(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43612
43890
  if (path) {
43613
43891
  this.python3Path = path;
43614
43892
  return path;
@@ -43674,7 +43952,7 @@ var init_voice = __esm({
43674
43952
  return false;
43675
43953
  }
43676
43954
  try {
43677
- execSync28(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43955
+ execSync29(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43678
43956
  this.mlxInstalled = true;
43679
43957
  return true;
43680
43958
  } catch {
@@ -43727,7 +44005,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43727
44005
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
43728
44006
  const mlxVoice = model.mlxVoice ?? "af_heart";
43729
44007
  const mlxLangCode = model.mlxLangCode ?? "a";
43730
- const wavPath = join55(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
44008
+ const wavPath = join56(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
43731
44009
  const pyScript = [
43732
44010
  "import sys, json",
43733
44011
  "from mlx_audio.tts import generate as tts_gen",
@@ -43735,20 +44013,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43735
44013
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43736
44014
  ].join("; ");
43737
44015
  try {
43738
- execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
44016
+ execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43739
44017
  } catch (err) {
43740
44018
  try {
43741
44019
  const safeText = cleaned.replace(/'/g, "'\\''");
43742
- execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
44020
+ execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43743
44021
  } catch (err2) {
43744
44022
  return;
43745
44023
  }
43746
44024
  }
43747
- if (!existsSync39(wavPath))
44025
+ if (!existsSync40(wavPath))
43748
44026
  return;
43749
44027
  if (volume !== 1) {
43750
44028
  try {
43751
- const wavData = readFileSync28(wavPath);
44029
+ const wavData = readFileSync29(wavPath);
43752
44030
  if (wavData.length > 44) {
43753
44031
  const header = wavData.subarray(0, 44);
43754
44032
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -43756,14 +44034,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43756
44034
  samples[i] = Math.round(samples[i] * volume);
43757
44035
  }
43758
44036
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
43759
- writeFileSync16(wavPath, scaled);
44037
+ writeFileSync17(wavPath, scaled);
43760
44038
  }
43761
44039
  } catch {
43762
44040
  }
43763
44041
  }
43764
44042
  if (this.onPCMOutput) {
43765
44043
  try {
43766
- const wavData = readFileSync28(wavPath);
44044
+ const wavData = readFileSync29(wavPath);
43767
44045
  if (wavData.length > 44) {
43768
44046
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
43769
44047
  const sampleRate = wavData.readUInt32LE(24);
@@ -43774,7 +44052,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43774
44052
  }
43775
44053
  await this.playWav(wavPath);
43776
44054
  try {
43777
- unlinkSync8(wavPath);
44055
+ unlinkSync9(wavPath);
43778
44056
  } catch {
43779
44057
  }
43780
44058
  }
@@ -43795,7 +44073,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43795
44073
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
43796
44074
  const mlxVoice = model.mlxVoice ?? "af_heart";
43797
44075
  const mlxLangCode = model.mlxLangCode ?? "a";
43798
- const wavPath = join55(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
44076
+ const wavPath = join56(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
43799
44077
  const pyScript = [
43800
44078
  "import sys, json",
43801
44079
  "from mlx_audio.tts import generate as tts_gen",
@@ -43803,20 +44081,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43803
44081
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43804
44082
  ].join("; ");
43805
44083
  try {
43806
- execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
44084
+ execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43807
44085
  } catch {
43808
44086
  try {
43809
44087
  const safeText = cleaned.replace(/'/g, "'\\''");
43810
- execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
44088
+ execSync29(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43811
44089
  } catch {
43812
44090
  return null;
43813
44091
  }
43814
44092
  }
43815
- if (!existsSync39(wavPath))
44093
+ if (!existsSync40(wavPath))
43816
44094
  return null;
43817
44095
  try {
43818
- const data = readFileSync28(wavPath);
43819
- unlinkSync8(wavPath);
44096
+ const data = readFileSync29(wavPath);
44097
+ unlinkSync9(wavPath);
43820
44098
  return data;
43821
44099
  } catch {
43822
44100
  return null;
@@ -43838,7 +44116,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43838
44116
  }
43839
44117
  const venvDir = luxttsVenvDir();
43840
44118
  const venvPy = luxttsVenvPy();
43841
- if (existsSync39(venvPy)) {
44119
+ if (existsSync40(venvPy)) {
43842
44120
  try {
43843
44121
  await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
43844
44122
  let hasCudaSys = false;
@@ -43852,7 +44130,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43852
44130
  if (torchCheck === "cpu") {
43853
44131
  renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
43854
44132
  try {
43855
- const detectScript = join55(voiceDir(), "detect-torch.py");
44133
+ const detectScript = join56(voiceDir(), "detect-torch.py");
43856
44134
  writeDetectTorchScript(detectScript);
43857
44135
  let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
43858
44136
  try {
@@ -43877,7 +44155,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43877
44155
  }
43878
44156
  }
43879
44157
  renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
43880
- if (!existsSync39(venvDir)) {
44158
+ if (!existsSync40(venvDir)) {
43881
44159
  renderInfo(" Creating Python virtual environment...");
43882
44160
  try {
43883
44161
  await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
@@ -43886,7 +44164,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43886
44164
  }
43887
44165
  }
43888
44166
  {
43889
- const detectScript = join55(voiceDir(), "detect-torch.py");
44167
+ const detectScript = join56(voiceDir(), "detect-torch.py");
43890
44168
  writeDetectTorchScript(detectScript);
43891
44169
  let pipArgsStr = "torch torchaudio";
43892
44170
  let torchDesc = "unknown platform";
@@ -43923,10 +44201,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43923
44201
  }
43924
44202
  }
43925
44203
  const repoDir = luxttsRepoDir();
43926
- if (!existsSync39(join55(repoDir, "zipvoice", "luxvoice.py"))) {
44204
+ if (!existsSync40(join56(repoDir, "zipvoice", "luxvoice.py"))) {
43927
44205
  renderInfo(" Cloning LuxTTS repository...");
43928
44206
  try {
43929
- if (existsSync39(repoDir)) {
44207
+ if (existsSync40(repoDir)) {
43930
44208
  const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
43931
44209
  await this.asyncShell(rmCmd, 3e4);
43932
44210
  }
@@ -43965,7 +44243,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43965
44243
  renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
43966
44244
  }
43967
44245
  }
43968
- const isJetson = isArm && (existsSync39("/etc/nv_tegra_release") || existsSync39("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
44246
+ const isJetson = isArm && (existsSync40("/etc/nv_tegra_release") || existsSync40("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
43969
44247
  const installSteps = isArm ? [
43970
44248
  // ARM: install individually so we get clear error messages per package.
43971
44249
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
@@ -44033,14 +44311,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
44033
44311
  }
44034
44312
  /** Auto-detect an existing clone reference in the refs directory */
44035
44313
  autoDetectCloneRef() {
44036
- if (this.luxttsCloneRef && existsSync39(this.luxttsCloneRef))
44314
+ if (this.luxttsCloneRef && existsSync40(this.luxttsCloneRef))
44037
44315
  return;
44038
44316
  const refsDir = luxttsCloneRefsDir();
44039
- if (!existsSync39(refsDir))
44317
+ if (!existsSync40(refsDir))
44040
44318
  return;
44041
44319
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
44042
- const p = join55(refsDir, name);
44043
- if (existsSync39(p)) {
44320
+ const p = join56(refsDir, name);
44321
+ if (existsSync40(p)) {
44044
44322
  this.luxttsCloneRef = p;
44045
44323
  return;
44046
44324
  }
@@ -44140,15 +44418,15 @@ if __name__ == '__main__':
44140
44418
  main()
44141
44419
  `;
44142
44420
  const scriptPath2 = luxttsInferScript();
44143
- mkdirSync15(voiceDir(), { recursive: true });
44144
- writeFileSync16(scriptPath2, script);
44421
+ mkdirSync16(voiceDir(), { recursive: true });
44422
+ writeFileSync17(scriptPath2, script);
44145
44423
  }
44146
44424
  /** Ensure the LuxTTS daemon is running, spawn if needed */
44147
44425
  async ensureLuxttsDaemon() {
44148
44426
  if (this._luxttsDaemon && !this._luxttsDaemon.killed)
44149
44427
  return true;
44150
44428
  const venvPy = luxttsVenvPy();
44151
- if (!existsSync39(venvPy))
44429
+ if (!existsSync40(venvPy))
44152
44430
  return false;
44153
44431
  return new Promise((resolve34) => {
44154
44432
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
@@ -44232,7 +44510,7 @@ if __name__ == '__main__':
44232
44510
  * Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
44233
44511
  */
44234
44512
  async synthesizeLuxttsWav(text, speedFactor = 1) {
44235
- if (!this.luxttsCloneRef || !existsSync39(this.luxttsCloneRef))
44513
+ if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
44236
44514
  return null;
44237
44515
  const cleaned = text.replace(/\*/g, "").trim();
44238
44516
  if (!cleaned)
@@ -44240,7 +44518,7 @@ if __name__ == '__main__':
44240
44518
  const ready = await this.ensureLuxttsDaemon();
44241
44519
  if (!ready)
44242
44520
  return null;
44243
- const wavPath = join55(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
44521
+ const wavPath = join56(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
44244
44522
  try {
44245
44523
  await this.luxttsRequest({
44246
44524
  action: "synthesize",
@@ -44252,17 +44530,17 @@ if __name__ == '__main__':
44252
44530
  } catch {
44253
44531
  return null;
44254
44532
  }
44255
- return existsSync39(wavPath) ? wavPath : null;
44533
+ return existsSync40(wavPath) ? wavPath : null;
44256
44534
  }
44257
44535
  /**
44258
44536
  * Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
44259
44537
  * Cleans up the WAV file after playback.
44260
44538
  */
44261
44539
  async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
44262
- if (!existsSync39(wavPath))
44540
+ if (!existsSync40(wavPath))
44263
44541
  return;
44264
44542
  try {
44265
- const wavData = readFileSync28(wavPath);
44543
+ const wavData = readFileSync29(wavPath);
44266
44544
  if (wavData.length > 44) {
44267
44545
  const sampleRate = wavData.readUInt32LE(24);
44268
44546
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -44277,13 +44555,13 @@ if __name__ == '__main__':
44277
44555
  }
44278
44556
  const header = wavData.subarray(0, 44);
44279
44557
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
44280
- writeFileSync16(wavPath, scaled);
44558
+ writeFileSync17(wavPath, scaled);
44281
44559
  }
44282
44560
  } catch {
44283
44561
  }
44284
44562
  if (pitchFactor !== 1) {
44285
44563
  try {
44286
- const wavData = readFileSync28(wavPath);
44564
+ const wavData = readFileSync29(wavPath);
44287
44565
  if (wavData.length > 44) {
44288
44566
  const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
44289
44567
  const float32 = new Float32Array(int16.length);
@@ -44298,7 +44576,7 @@ if __name__ == '__main__':
44298
44576
  }
44299
44577
  if (this.onPCMOutput) {
44300
44578
  try {
44301
- const wavData = readFileSync28(wavPath);
44579
+ const wavData = readFileSync29(wavPath);
44302
44580
  if (wavData.length > 44) {
44303
44581
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
44304
44582
  const sampleRate = wavData.readUInt32LE(24);
@@ -44309,7 +44587,7 @@ if __name__ == '__main__':
44309
44587
  }
44310
44588
  if (stereoDelayMs > 0) {
44311
44589
  try {
44312
- const wavData = readFileSync28(wavPath);
44590
+ const wavData = readFileSync29(wavPath);
44313
44591
  if (wavData.length > 44) {
44314
44592
  const sampleRate = wavData.readUInt32LE(24);
44315
44593
  const numChannels = wavData.readUInt16LE(22);
@@ -44329,7 +44607,7 @@ if __name__ == '__main__':
44329
44607
  await this.playWav(wavPath);
44330
44608
  await this.sleep(150);
44331
44609
  try {
44332
- unlinkSync8(wavPath);
44610
+ unlinkSync9(wavPath);
44333
44611
  } catch {
44334
44612
  }
44335
44613
  }
@@ -44345,7 +44623,7 @@ if __name__ == '__main__':
44345
44623
  * Used for Telegram voice messages and WebSocket streaming.
44346
44624
  */
44347
44625
  async synthesizeLuxttsToBuffer(text) {
44348
- if (!this.luxttsCloneRef || !existsSync39(this.luxttsCloneRef))
44626
+ if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
44349
44627
  return null;
44350
44628
  const cleaned = text.replace(/\*/g, "").trim();
44351
44629
  if (!cleaned)
@@ -44353,7 +44631,7 @@ if __name__ == '__main__':
44353
44631
  const ready = await this.ensureLuxttsDaemon();
44354
44632
  if (!ready)
44355
44633
  return null;
44356
- const wavPath = join55(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
44634
+ const wavPath = join56(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
44357
44635
  try {
44358
44636
  await this.luxttsRequest({
44359
44637
  action: "synthesize",
@@ -44365,11 +44643,11 @@ if __name__ == '__main__':
44365
44643
  } catch {
44366
44644
  return null;
44367
44645
  }
44368
- if (!existsSync39(wavPath))
44646
+ if (!existsSync40(wavPath))
44369
44647
  return null;
44370
44648
  try {
44371
- const data = readFileSync28(wavPath);
44372
- unlinkSync8(wavPath);
44649
+ const data = readFileSync29(wavPath);
44650
+ unlinkSync9(wavPath);
44373
44651
  return data;
44374
44652
  } catch {
44375
44653
  return null;
@@ -44382,40 +44660,40 @@ if __name__ == '__main__':
44382
44660
  if (this.ort)
44383
44661
  return;
44384
44662
  const arch2 = process.arch;
44385
- mkdirSync15(voiceDir(), { recursive: true });
44386
- const pkgPath = join55(voiceDir(), "package.json");
44663
+ mkdirSync16(voiceDir(), { recursive: true });
44664
+ const pkgPath = join56(voiceDir(), "package.json");
44387
44665
  const expectedDeps = {
44388
44666
  "onnxruntime-node": "^1.21.0",
44389
44667
  "phonemizer": "^1.2.1"
44390
44668
  };
44391
- if (existsSync39(pkgPath)) {
44669
+ if (existsSync40(pkgPath)) {
44392
44670
  try {
44393
- const existing = JSON.parse(readFileSync28(pkgPath, "utf8"));
44671
+ const existing = JSON.parse(readFileSync29(pkgPath, "utf8"));
44394
44672
  if (!existing.dependencies?.["phonemizer"]) {
44395
44673
  existing.dependencies = { ...existing.dependencies, ...expectedDeps };
44396
- writeFileSync16(pkgPath, JSON.stringify(existing, null, 2));
44674
+ writeFileSync17(pkgPath, JSON.stringify(existing, null, 2));
44397
44675
  }
44398
44676
  } catch {
44399
44677
  }
44400
44678
  }
44401
- if (!existsSync39(pkgPath)) {
44402
- writeFileSync16(pkgPath, JSON.stringify({
44679
+ if (!existsSync40(pkgPath)) {
44680
+ writeFileSync17(pkgPath, JSON.stringify({
44403
44681
  name: "open-agents-voice",
44404
44682
  private: true,
44405
44683
  dependencies: expectedDeps
44406
44684
  }, null, 2));
44407
44685
  }
44408
- const voiceRequire = createRequire(join55(voiceDir(), "index.js"));
44686
+ const voiceRequire = createRequire(join56(voiceDir(), "index.js"));
44409
44687
  const probeOnnx = async () => {
44410
44688
  try {
44411
- const output = await this.asyncShell(`NODE_PATH="${join55(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
44689
+ const output = await this.asyncShell(`NODE_PATH="${join56(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
44412
44690
  return output.trim() === "OK";
44413
44691
  } catch {
44414
44692
  return false;
44415
44693
  }
44416
44694
  };
44417
- const onnxNodeModules = join55(voiceDir(), "node_modules", "onnxruntime-node");
44418
- const onnxInstalled = existsSync39(onnxNodeModules);
44695
+ const onnxNodeModules = join56(voiceDir(), "node_modules", "onnxruntime-node");
44696
+ const onnxInstalled = existsSync40(onnxNodeModules);
44419
44697
  if (onnxInstalled && !await probeOnnx()) {
44420
44698
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch2}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
44421
44699
  }
@@ -44465,18 +44743,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44465
44743
  const dir = modelDir(id);
44466
44744
  const onnxPath = modelOnnxPath(id);
44467
44745
  const configPath = modelConfigPath(id);
44468
- if (existsSync39(onnxPath) && existsSync39(configPath))
44746
+ if (existsSync40(onnxPath) && existsSync40(configPath))
44469
44747
  return;
44470
- mkdirSync15(dir, { recursive: true });
44471
- if (!existsSync39(configPath)) {
44748
+ mkdirSync16(dir, { recursive: true });
44749
+ if (!existsSync40(configPath)) {
44472
44750
  renderInfo(`Downloading ${model.label} voice config...`);
44473
44751
  const configResp = await fetch(model.configUrl);
44474
44752
  if (!configResp.ok)
44475
44753
  throw new Error(`Failed to download config: HTTP ${configResp.status}`);
44476
44754
  const configText = await configResp.text();
44477
- writeFileSync16(configPath, configText);
44755
+ writeFileSync17(configPath, configText);
44478
44756
  }
44479
- if (!existsSync39(onnxPath)) {
44757
+ if (!existsSync40(onnxPath)) {
44480
44758
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
44481
44759
  const onnxResp = await fetch(model.onnxUrl);
44482
44760
  if (!onnxResp.ok)
@@ -44501,7 +44779,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44501
44779
  }
44502
44780
  }
44503
44781
  const fullBuffer = Buffer.concat(chunks);
44504
- writeFileSync16(onnxPath, fullBuffer);
44782
+ writeFileSync17(onnxPath, fullBuffer);
44505
44783
  renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
44506
44784
  }
44507
44785
  }
@@ -44513,10 +44791,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44513
44791
  throw new Error("ONNX runtime not loaded");
44514
44792
  const onnxPath = modelOnnxPath(this.modelId);
44515
44793
  const configPath = modelConfigPath(this.modelId);
44516
- if (!existsSync39(onnxPath) || !existsSync39(configPath)) {
44794
+ if (!existsSync40(onnxPath) || !existsSync40(configPath)) {
44517
44795
  throw new Error(`Model files not found for ${this.modelId}`);
44518
44796
  }
44519
- this.config = JSON.parse(readFileSync28(configPath, "utf8"));
44797
+ this.config = JSON.parse(readFileSync29(configPath, "utf8"));
44520
44798
  this.session = await this.ort.InferenceSession.create(onnxPath, {
44521
44799
  executionProviders: ["cpu"],
44522
44800
  graphOptimizationLevel: "all"
@@ -44543,8 +44821,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44543
44821
  // packages/cli/dist/tui/commands.js
44544
44822
  import * as nodeOs from "node:os";
44545
44823
  import { execSync as nodeExecSync } from "node:child_process";
44546
- import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync16, readdirSync as readdirSync11, statSync as statSync14, rmSync } from "node:fs";
44547
- import { join as join56 } from "node:path";
44824
+ import { existsSync as existsSync41, readFileSync as readFileSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
44825
+ import { join as join57 } from "node:path";
44548
44826
  function safeLog(text) {
44549
44827
  if (isNeovimActive()) {
44550
44828
  writeToNeovimOutput(text + "\n");
@@ -45153,22 +45431,22 @@ async function handleSlashCommand(input, ctx) {
45153
45431
  let content = "";
45154
45432
  let metadata = {};
45155
45433
  if (shareType === "tool") {
45156
- const toolDir = join56(ctx.repoRoot, ".oa", "tools");
45157
- const toolFile = join56(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
45158
- if (!existsSync40(toolFile)) {
45434
+ const toolDir = join57(ctx.repoRoot, ".oa", "tools");
45435
+ const toolFile = join57(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
45436
+ if (!existsSync41(toolFile)) {
45159
45437
  renderWarning(`Tool not found: ${toolFile}`);
45160
45438
  return "handled";
45161
45439
  }
45162
- content = readFileSync29(toolFile, "utf8");
45440
+ content = readFileSync30(toolFile, "utf8");
45163
45441
  metadata = { type: "tool", name: shareName };
45164
45442
  } else if (shareType === "skill") {
45165
- const skillDir = join56(ctx.repoRoot, ".oa", "skills", shareName);
45166
- const skillFile = join56(skillDir, "SKILL.md");
45167
- if (!existsSync40(skillFile)) {
45443
+ const skillDir = join57(ctx.repoRoot, ".oa", "skills", shareName);
45444
+ const skillFile = join57(skillDir, "SKILL.md");
45445
+ if (!existsSync41(skillFile)) {
45168
45446
  renderWarning(`Skill not found: ${skillFile}`);
45169
45447
  return "handled";
45170
45448
  }
45171
- content = readFileSync29(skillFile, "utf8");
45449
+ content = readFileSync30(skillFile, "utf8");
45172
45450
  metadata = { type: "skill", name: shareName };
45173
45451
  } else {
45174
45452
  renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
@@ -45207,9 +45485,9 @@ async function handleSlashCommand(input, ctx) {
45207
45485
  const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
45208
45486
  const nexus = new NexusTool2(ctx.repoRoot);
45209
45487
  await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
45210
- const regFile = join56(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
45211
- if (existsSync40(regFile)) {
45212
- const reg = JSON.parse(readFileSync29(regFile, "utf8"));
45488
+ const regFile = join57(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
45489
+ if (existsSync41(regFile)) {
45490
+ const reg = JSON.parse(readFileSync30(regFile, "utf8"));
45213
45491
  const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
45214
45492
  if (pinned) {
45215
45493
  renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
@@ -45262,33 +45540,33 @@ async function handleSlashCommand(input, ctx) {
45262
45540
  lines.push(`
45263
45541
  ${c2.bold("IPFS / Helia Status")}
45264
45542
  `);
45265
- const ipfsDir = join56(ctx.repoRoot, ".oa", "ipfs");
45266
- const ipfsLocalDir = join56(ipfsDir, "local");
45543
+ const ipfsDir = join57(ctx.repoRoot, ".oa", "ipfs");
45544
+ const ipfsLocalDir = join57(ipfsDir, "local");
45267
45545
  let ipfsFiles = 0;
45268
45546
  let ipfsBytes = 0;
45269
45547
  let heliaBlocks = 0;
45270
45548
  let heliaBytes = 0;
45271
45549
  try {
45272
- if (existsSync40(ipfsLocalDir)) {
45273
- const files = readdirSync11(ipfsLocalDir).filter((f) => f.endsWith(".json"));
45550
+ if (existsSync41(ipfsLocalDir)) {
45551
+ const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
45274
45552
  ipfsFiles = files.length;
45275
45553
  for (const f of files) {
45276
45554
  try {
45277
- ipfsBytes += statSync14(join56(ipfsLocalDir, f)).size;
45555
+ ipfsBytes += statSync14(join57(ipfsLocalDir, f)).size;
45278
45556
  } catch {
45279
45557
  }
45280
45558
  }
45281
45559
  }
45282
- const heliaBlockDir = join56(ipfsDir, "blocks");
45283
- if (existsSync40(heliaBlockDir)) {
45560
+ const heliaBlockDir = join57(ipfsDir, "blocks");
45561
+ if (existsSync41(heliaBlockDir)) {
45284
45562
  const walkDir = (dir) => {
45285
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45563
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45286
45564
  if (entry.isDirectory())
45287
- walkDir(join56(dir, entry.name));
45565
+ walkDir(join57(dir, entry.name));
45288
45566
  else {
45289
45567
  heliaBlocks++;
45290
45568
  try {
45291
- heliaBytes += statSync14(join56(dir, entry.name)).size;
45569
+ heliaBytes += statSync14(join57(dir, entry.name)).size;
45292
45570
  } catch {
45293
45571
  }
45294
45572
  }
@@ -45304,9 +45582,9 @@ async function handleSlashCommand(input, ctx) {
45304
45582
  lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
45305
45583
  lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
45306
45584
  try {
45307
- const statusFile = join56(ctx.repoRoot, ".oa", "nexus", "status.json");
45308
- if (existsSync40(statusFile)) {
45309
- const status = JSON.parse(readFileSync29(statusFile, "utf8"));
45585
+ const statusFile = join57(ctx.repoRoot, ".oa", "nexus", "status.json");
45586
+ if (existsSync41(statusFile)) {
45587
+ const status = JSON.parse(readFileSync30(statusFile, "utf8"));
45310
45588
  if (status.peerId) {
45311
45589
  lines.push(`
45312
45590
  ${c2.bold("Peer Info")}`);
@@ -45325,11 +45603,11 @@ async function handleSlashCommand(input, ctx) {
45325
45603
  ${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
45326
45604
  lines.push(`
45327
45605
  ${c2.bold("Identity Kernel")}`);
45328
- const idDir = join56(ctx.repoRoot, ".oa", "identity");
45606
+ const idDir = join57(ctx.repoRoot, ".oa", "identity");
45329
45607
  try {
45330
- const stateFile = join56(idDir, "self-state.json");
45331
- if (existsSync40(stateFile)) {
45332
- const state = JSON.parse(readFileSync29(stateFile, "utf8"));
45608
+ const stateFile = join57(idDir, "self-state.json");
45609
+ if (existsSync41(stateFile)) {
45610
+ const state = JSON.parse(readFileSync30(stateFile, "utf8"));
45333
45611
  lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
45334
45612
  if (state.narrative_summary) {
45335
45613
  lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
@@ -45338,9 +45616,9 @@ async function handleSlashCommand(input, ctx) {
45338
45616
  const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
45339
45617
  lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
45340
45618
  }
45341
- const cidFile = join56(idDir, "cids.json");
45342
- if (existsSync40(cidFile)) {
45343
- const cids = JSON.parse(readFileSync29(cidFile, "utf8"));
45619
+ const cidFile = join57(idDir, "cids.json");
45620
+ if (existsSync41(cidFile)) {
45621
+ const cids = JSON.parse(readFileSync30(cidFile, "utf8"));
45344
45622
  const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
45345
45623
  if (lastCid)
45346
45624
  lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
@@ -45353,9 +45631,9 @@ async function handleSlashCommand(input, ctx) {
45353
45631
  lines.push(`
45354
45632
  ${c2.bold("Memory Sentiment")}`);
45355
45633
  try {
45356
- const metaFile = join56(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
45357
- if (existsSync40(metaFile)) {
45358
- const store = JSON.parse(readFileSync29(metaFile, "utf8"));
45634
+ const metaFile = join57(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
45635
+ if (existsSync41(metaFile)) {
45636
+ const store = JSON.parse(readFileSync30(metaFile, "utf8"));
45359
45637
  const active = store.filter((m) => m.type !== "quarantine");
45360
45638
  const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
45361
45639
  const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
@@ -45373,8 +45651,8 @@ async function handleSlashCommand(input, ctx) {
45373
45651
  } catch {
45374
45652
  }
45375
45653
  try {
45376
- const dbPath = join56(ctx.repoRoot, ".oa", "memory", "structured.db");
45377
- if (existsSync40(dbPath)) {
45654
+ const dbPath = join57(ctx.repoRoot, ".oa", "memory", "structured.db");
45655
+ if (existsSync41(dbPath)) {
45378
45656
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
45379
45657
  const db = initDb2(dbPath);
45380
45658
  const memStore = new ProceduralMemoryStore2(db);
@@ -45395,8 +45673,8 @@ async function handleSlashCommand(input, ctx) {
45395
45673
  lines.push(`
45396
45674
  ${c2.bold("Storage Overview")}
45397
45675
  `);
45398
- const oaDir = join56(ctx.repoRoot, ".oa");
45399
- if (!existsSync40(oaDir)) {
45676
+ const oaDir = join57(ctx.repoRoot, ".oa");
45677
+ if (!existsSync41(oaDir)) {
45400
45678
  lines.push(` ${c2.dim("No .oa/ directory found.")}`);
45401
45679
  safeLog(lines.join("\n") + "\n");
45402
45680
  return "handled";
@@ -45405,8 +45683,8 @@ async function handleSlashCommand(input, ctx) {
45405
45683
  const categories = {};
45406
45684
  const walkStorage = (dir, category) => {
45407
45685
  try {
45408
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45409
- const full = join56(dir, entry.name);
45686
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45687
+ const full = join57(dir, entry.name);
45410
45688
  if (entry.isDirectory()) {
45411
45689
  const subCat = category || entry.name;
45412
45690
  walkStorage(full, subCat);
@@ -45439,13 +45717,13 @@ async function handleSlashCommand(input, ctx) {
45439
45717
  const sensitiveFound = [];
45440
45718
  const checkSensitive = (dir) => {
45441
45719
  try {
45442
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45720
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45443
45721
  const name = entry.name.toLowerCase();
45444
45722
  if (sensitivePatterns.some((p) => name.includes(p))) {
45445
- sensitiveFound.push(join56(dir, entry.name).replace(oaDir + "/", ""));
45723
+ sensitiveFound.push(join57(dir, entry.name).replace(oaDir + "/", ""));
45446
45724
  }
45447
45725
  if (entry.isDirectory())
45448
- checkSensitive(join56(dir, entry.name));
45726
+ checkSensitive(join57(dir, entry.name));
45449
45727
  }
45450
45728
  } catch {
45451
45729
  }
@@ -45473,8 +45751,8 @@ async function handleSlashCommand(input, ctx) {
45473
45751
  renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
45474
45752
  return "handled";
45475
45753
  }
45476
- const resolvedPath = join56(ctx.repoRoot, filePath);
45477
- if (!existsSync40(resolvedPath)) {
45754
+ const resolvedPath = join57(ctx.repoRoot, filePath);
45755
+ if (!existsSync41(resolvedPath)) {
45478
45756
  renderWarning(`File not found: ${resolvedPath}`);
45479
45757
  return "handled";
45480
45758
  }
@@ -45490,9 +45768,9 @@ async function handleSlashCommand(input, ctx) {
45490
45768
  }
45491
45769
  try {
45492
45770
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
45493
- const dbDir = join56(ctx.repoRoot, ".oa", "memory");
45494
- mkdirSync16(dbDir, { recursive: true });
45495
- const db = initDb2(join56(dbDir, "structured.db"));
45771
+ const dbDir = join57(ctx.repoRoot, ".oa", "memory");
45772
+ mkdirSync17(dbDir, { recursive: true });
45773
+ const db = initDb2(join57(dbDir, "structured.db"));
45496
45774
  const memStore = new ProceduralMemoryStore2(db);
45497
45775
  if (isAudio) {
45498
45776
  renderInfo(`Transcribing: ${filePath}...`);
@@ -45533,7 +45811,7 @@ async function handleSlashCommand(input, ctx) {
45533
45811
  return "handled";
45534
45812
  }
45535
45813
  } else {
45536
- content = readFileSync29(resolvedPath, "utf8");
45814
+ content = readFileSync30(resolvedPath, "utf8");
45537
45815
  }
45538
45816
  if (!content.trim()) {
45539
45817
  renderWarning("No content extracted.");
@@ -45572,9 +45850,9 @@ async function handleSlashCommand(input, ctx) {
45572
45850
  }
45573
45851
  case "fortemi": {
45574
45852
  const fortemiSubCmd = (arg || "").trim().toLowerCase();
45575
- const fortemiDir = join56(ctx.repoRoot, "..", "fortemi-react");
45576
- const altFortemiDir = join56(nodeOs.homedir(), "fortemi-react");
45577
- const fDir = existsSync40(fortemiDir) ? fortemiDir : existsSync40(altFortemiDir) ? altFortemiDir : null;
45853
+ const fortemiDir = join57(ctx.repoRoot, "..", "fortemi-react");
45854
+ const altFortemiDir = join57(nodeOs.homedir(), "fortemi-react");
45855
+ const fDir = existsSync41(fortemiDir) ? fortemiDir : existsSync41(altFortemiDir) ? altFortemiDir : null;
45578
45856
  if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
45579
45857
  if (!fDir) {
45580
45858
  renderWarning("fortemi-react not found adjacent or in home directory.");
@@ -45589,14 +45867,14 @@ async function handleSlashCommand(input, ctx) {
45589
45867
  // 24h
45590
45868
  nonce: Math.random().toString(36).slice(2, 10)
45591
45869
  };
45592
- const jwtFile = join56(ctx.repoRoot, ".oa", "fortemi-jwt.json");
45593
- mkdirSync16(join56(ctx.repoRoot, ".oa"), { recursive: true });
45594
- writeFileSync17(jwtFile, JSON.stringify(jwtPayload, null, 2));
45870
+ const jwtFile = join57(ctx.repoRoot, ".oa", "fortemi-jwt.json");
45871
+ mkdirSync17(join57(ctx.repoRoot, ".oa"), { recursive: true });
45872
+ writeFileSync18(jwtFile, JSON.stringify(jwtPayload, null, 2));
45595
45873
  renderInfo(`Launching fortemi-react from ${fDir}...`);
45596
45874
  try {
45597
45875
  const { spawn: spawn21 } = __require("node:child_process");
45598
45876
  const child = spawn21("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
45599
- cwd: join56(fDir, "apps", "standalone"),
45877
+ cwd: join57(fDir, "apps", "standalone"),
45600
45878
  stdio: "ignore",
45601
45879
  detached: true,
45602
45880
  env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
@@ -45605,8 +45883,8 @@ async function handleSlashCommand(input, ctx) {
45605
45883
  renderInfo("Fortemi-React starting on http://localhost:3000");
45606
45884
  renderInfo(`JWT saved to ${jwtFile}`);
45607
45885
  renderInfo("Memory operations will proxy to fortemi when available.");
45608
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45609
- writeFileSync17(bridgeFile, JSON.stringify({
45886
+ const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45887
+ writeFileSync18(bridgeFile, JSON.stringify({
45610
45888
  url: "http://localhost:3000",
45611
45889
  pid: child.pid,
45612
45890
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -45618,12 +45896,12 @@ async function handleSlashCommand(input, ctx) {
45618
45896
  return "handled";
45619
45897
  }
45620
45898
  if (fortemiSubCmd === "status") {
45621
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45622
- if (!existsSync40(bridgeFile)) {
45899
+ const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45900
+ if (!existsSync41(bridgeFile)) {
45623
45901
  renderInfo("Fortemi bridge: not connected. Run /fortemi start");
45624
45902
  return "handled";
45625
45903
  }
45626
- const bridge = JSON.parse(readFileSync29(bridgeFile, "utf8"));
45904
+ const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
45627
45905
  let alive = false;
45628
45906
  try {
45629
45907
  process.kill(bridge.pid, 0);
@@ -45643,15 +45921,15 @@ async function handleSlashCommand(input, ctx) {
45643
45921
  lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
45644
45922
  lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
45645
45923
  lines.push(` Started: ${bridge.startedAt}`);
45646
- lines.push(` JWT: ${existsSync40(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
45924
+ lines.push(` JWT: ${existsSync41(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
45647
45925
  lines.push("");
45648
45926
  safeLog(lines.join("\n"));
45649
45927
  return "handled";
45650
45928
  }
45651
45929
  if (fortemiSubCmd === "stop") {
45652
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45653
- if (existsSync40(bridgeFile)) {
45654
- const bridge = JSON.parse(readFileSync29(bridgeFile, "utf8"));
45930
+ const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45931
+ if (existsSync41(bridgeFile)) {
45932
+ const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
45655
45933
  try {
45656
45934
  process.kill(bridge.pid, "SIGTERM");
45657
45935
  } catch {
@@ -47030,13 +47308,13 @@ async function showCohereDashboard(ctx) {
47030
47308
  } else if (idResult.key === "view") {
47031
47309
  await ik.execute({ operation: "hydrate" });
47032
47310
  } else if (idResult.key === "history") {
47033
- const snapDir = join56(ctx.repoRoot, ".oa", "identity", "snapshots");
47034
- if (existsSync40(snapDir)) {
47035
- const snaps = readdirSync11(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
47311
+ const snapDir = join57(ctx.repoRoot, ".oa", "identity", "snapshots");
47312
+ if (existsSync41(snapDir)) {
47313
+ const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
47036
47314
  const snapItems = snaps.slice(0, 20).map((f) => ({
47037
47315
  key: f,
47038
47316
  label: f.replace(".json", ""),
47039
- detail: `${formatFileSize(statSync14(join56(snapDir, f)).size)}`
47317
+ detail: `${formatFileSize(statSync14(join57(snapDir, f)).size)}`
47040
47318
  }));
47041
47319
  if (snapItems.length > 0) {
47042
47320
  await tuiSelect({
@@ -47351,13 +47629,13 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
47351
47629
  if (!jsonDrop.confirmed || !jsonDrop.path) {
47352
47630
  continue;
47353
47631
  }
47354
- const { basename: basename17, join: pathJoin } = await import("node:path");
47355
- const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync24, existsSync: exists } = await import("node:fs");
47632
+ const { basename: basename18, join: pathJoin } = await import("node:path");
47633
+ const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync25, existsSync: exists } = await import("node:fs");
47356
47634
  const { homedir: homedir18 } = await import("node:os");
47357
- const modelName = basename17(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
47635
+ const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
47358
47636
  const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
47359
47637
  if (!exists(destDir))
47360
- mkdirSync24(destDir, { recursive: true });
47638
+ mkdirSync25(destDir, { recursive: true });
47361
47639
  copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
47362
47640
  copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
47363
47641
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -47502,7 +47780,7 @@ async function handleVoiceList(ctx, focusFilename) {
47502
47780
  const src = srcPath.trim();
47503
47781
  try {
47504
47782
  const { existsSync: fe, copyFileSync: cpf, mkdirSync: mkd } = __require("node:fs");
47505
- const { basename: basename17, join: pjoin } = __require("node:path");
47783
+ const { basename: basename18, join: pjoin } = __require("node:path");
47506
47784
  if (!fe(src)) {
47507
47785
  renderError(`File not found: ${src}`);
47508
47786
  helpers.render();
@@ -47510,7 +47788,7 @@ async function handleVoiceList(ctx, focusFilename) {
47510
47788
  }
47511
47789
  const refsDir = pjoin(__require("node:os").homedir(), ".open-agents", "voice", "clone-refs");
47512
47790
  mkd(refsDir, { recursive: true });
47513
- const destName = basename17(src);
47791
+ const destName = basename18(src);
47514
47792
  const dest = pjoin(refsDir, destName);
47515
47793
  cpf(src, dest);
47516
47794
  renderInfo(`Imported "${destName}" \u2192 ${dest}`);
@@ -47849,11 +48127,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
47849
48127
  const models = await fetchModels(peerUrl, authKey);
47850
48128
  if (models.length > 0) {
47851
48129
  try {
47852
- const { writeFileSync: writeFileSync23, mkdirSync: mkdirSync24 } = await import("node:fs");
47853
- const { join: join70, dirname: dirname22 } = await import("node:path");
47854
- const cachePath = join70(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
47855
- mkdirSync24(dirname22(cachePath), { recursive: true });
47856
- writeFileSync23(cachePath, JSON.stringify({
48130
+ const { writeFileSync: writeFileSync24, mkdirSync: mkdirSync25 } = await import("node:fs");
48131
+ const { join: join71, dirname: dirname22 } = await import("node:path");
48132
+ const cachePath = join71(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
48133
+ mkdirSync25(dirname22(cachePath), { recursive: true });
48134
+ writeFileSync24(cachePath, JSON.stringify({
47857
48135
  peerId,
47858
48136
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
47859
48137
  models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
@@ -47902,7 +48180,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
47902
48180
  }
47903
48181
  }
47904
48182
  async function handleParallel(arg, ctx) {
47905
- const { execSync: execSync33 } = await import("node:child_process");
48183
+ const { execSync: execSync34 } = await import("node:child_process");
47906
48184
  const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
47907
48185
  const isRemote = ctx.config.backendType === "nexus";
47908
48186
  if (isRemote) {
@@ -47926,7 +48204,7 @@ async function handleParallel(arg, ctx) {
47926
48204
  }
47927
48205
  let systemdVal = "";
47928
48206
  try {
47929
- const out = execSync33("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
48207
+ const out = execSync34("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
47930
48208
  const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
47931
48209
  if (match)
47932
48210
  systemdVal = match[1];
@@ -47955,7 +48233,7 @@ async function handleParallel(arg, ctx) {
47955
48233
  }
47956
48234
  const isSystemd = (() => {
47957
48235
  try {
47958
- const out = execSync33("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
48236
+ const out = execSync34("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
47959
48237
  return out === "active" || out === "inactive";
47960
48238
  } catch {
47961
48239
  return false;
@@ -47969,10 +48247,10 @@ async function handleParallel(arg, ctx) {
47969
48247
  const overrideContent = `[Service]
47970
48248
  Environment="OLLAMA_NUM_PARALLEL=${n}"
47971
48249
  `;
47972
- execSync33(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
47973
- execSync33(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
47974
- execSync33("sudo systemctl daemon-reload", { stdio: "pipe" });
47975
- execSync33("sudo systemctl restart ollama.service", { stdio: "pipe" });
48250
+ execSync34(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
48251
+ execSync34(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
48252
+ execSync34("sudo systemctl daemon-reload", { stdio: "pipe" });
48253
+ execSync34("sudo systemctl restart ollama.service", { stdio: "pipe" });
47976
48254
  let ready = false;
47977
48255
  for (let i = 0; i < 30 && !ready; i++) {
47978
48256
  await new Promise((r) => setTimeout(r, 500));
@@ -47999,7 +48277,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
47999
48277
  renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
48000
48278
  try {
48001
48279
  try {
48002
- execSync33("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
48280
+ execSync34("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
48003
48281
  } catch {
48004
48282
  }
48005
48283
  await new Promise((r) => setTimeout(r, 1e3));
@@ -48052,17 +48330,17 @@ async function handleUpdate(subcommand, ctx) {
48052
48330
  try {
48053
48331
  const { createRequire: createRequire4 } = await import("node:module");
48054
48332
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
48055
- const { dirname: dirname22, join: join70 } = await import("node:path");
48056
- const { existsSync: existsSync50 } = await import("node:fs");
48333
+ const { dirname: dirname22, join: join71 } = await import("node:path");
48334
+ const { existsSync: existsSync51 } = await import("node:fs");
48057
48335
  const req = createRequire4(import.meta.url);
48058
48336
  const thisDir = dirname22(fileURLToPath14(import.meta.url));
48059
48337
  const candidates = [
48060
- join70(thisDir, "..", "package.json"),
48061
- join70(thisDir, "..", "..", "package.json"),
48062
- join70(thisDir, "..", "..", "..", "package.json")
48338
+ join71(thisDir, "..", "package.json"),
48339
+ join71(thisDir, "..", "..", "package.json"),
48340
+ join71(thisDir, "..", "..", "..", "package.json")
48063
48341
  ];
48064
48342
  for (const pkgPath of candidates) {
48065
- if (existsSync50(pkgPath)) {
48343
+ if (existsSync51(pkgPath)) {
48066
48344
  const pkg = req(pkgPath);
48067
48345
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
48068
48346
  currentVersion = pkg.version ?? "0.0.0";
@@ -48802,18 +49080,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
48802
49080
  const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
48803
49081
  let copied = false;
48804
49082
  try {
48805
- const { execSync: execSync33 } = __require("node:child_process");
49083
+ const { execSync: execSync34 } = __require("node:child_process");
48806
49084
  const platform6 = process.platform;
48807
49085
  if (platform6 === "darwin") {
48808
- execSync33("pbcopy", { input: cmd, timeout: 3e3 });
49086
+ execSync34("pbcopy", { input: cmd, timeout: 3e3 });
48809
49087
  copied = true;
48810
49088
  } else if (platform6 === "win32") {
48811
- execSync33("clip", { input: cmd, timeout: 3e3 });
49089
+ execSync34("clip", { input: cmd, timeout: 3e3 });
48812
49090
  copied = true;
48813
49091
  } else {
48814
49092
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
48815
49093
  try {
48816
- execSync33(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
49094
+ execSync34(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
48817
49095
  copied = true;
48818
49096
  break;
48819
49097
  } catch {
@@ -48900,9 +49178,9 @@ var init_commands = __esm({
48900
49178
  });
48901
49179
 
48902
49180
  // packages/cli/dist/tui/project-context.js
48903
- import { existsSync as existsSync41, readFileSync as readFileSync30, readdirSync as readdirSync12 } from "node:fs";
48904
- import { join as join57, basename as basename11 } from "node:path";
48905
- import { execSync as execSync29 } from "node:child_process";
49181
+ import { existsSync as existsSync42, readFileSync as readFileSync31, readdirSync as readdirSync13 } from "node:fs";
49182
+ import { join as join58, basename as basename12 } from "node:path";
49183
+ import { execSync as execSync30 } from "node:child_process";
48906
49184
  import { homedir as homedir15, platform as platform4, release } from "node:os";
48907
49185
  function getModelTier(modelName) {
48908
49186
  const m = modelName.toLowerCase();
@@ -48936,10 +49214,10 @@ function loadProjectMap(repoRoot) {
48936
49214
  if (!hasOaDirectory(repoRoot)) {
48937
49215
  initOaDirectory(repoRoot);
48938
49216
  }
48939
- const mapPath2 = join57(repoRoot, OA_DIR, "context", "project-map.md");
48940
- if (existsSync41(mapPath2)) {
49217
+ const mapPath2 = join58(repoRoot, OA_DIR, "context", "project-map.md");
49218
+ if (existsSync42(mapPath2)) {
48941
49219
  try {
48942
- const content = readFileSync30(mapPath2, "utf-8");
49220
+ const content = readFileSync31(mapPath2, "utf-8");
48943
49221
  return content;
48944
49222
  } catch {
48945
49223
  }
@@ -48948,19 +49226,19 @@ function loadProjectMap(repoRoot) {
48948
49226
  }
48949
49227
  function getGitInfo(repoRoot) {
48950
49228
  try {
48951
- execSync29("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
49229
+ execSync30("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
48952
49230
  } catch {
48953
49231
  return "";
48954
49232
  }
48955
49233
  const lines = [];
48956
49234
  try {
48957
- const branch = execSync29("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
49235
+ const branch = execSync30("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48958
49236
  if (branch)
48959
49237
  lines.push(`Branch: ${branch}`);
48960
49238
  } catch {
48961
49239
  }
48962
49240
  try {
48963
- const status = execSync29("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
49241
+ const status = execSync30("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48964
49242
  if (status) {
48965
49243
  const changed = status.split("\n").length;
48966
49244
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -48970,7 +49248,7 @@ function getGitInfo(repoRoot) {
48970
49248
  } catch {
48971
49249
  }
48972
49250
  try {
48973
- const log = execSync29("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
49251
+ const log = execSync30("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48974
49252
  if (log)
48975
49253
  lines.push(`Recent commits:
48976
49254
  ${log}`);
@@ -48980,33 +49258,33 @@ ${log}`);
48980
49258
  }
48981
49259
  function loadMemoryContext(repoRoot) {
48982
49260
  const sections = [];
48983
- const oaMemDir = join57(repoRoot, OA_DIR, "memory");
49261
+ const oaMemDir = join58(repoRoot, OA_DIR, "memory");
48984
49262
  const oaEntries = loadMemoryDir(oaMemDir, "project");
48985
49263
  if (oaEntries)
48986
49264
  sections.push(oaEntries);
48987
- const legacyMemDir = join57(repoRoot, ".open-agents", "memory");
48988
- if (legacyMemDir !== oaMemDir && existsSync41(legacyMemDir)) {
49265
+ const legacyMemDir = join58(repoRoot, ".open-agents", "memory");
49266
+ if (legacyMemDir !== oaMemDir && existsSync42(legacyMemDir)) {
48989
49267
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
48990
49268
  if (legacyEntries)
48991
49269
  sections.push(legacyEntries);
48992
49270
  }
48993
- const globalMemDir = join57(homedir15(), ".open-agents", "memory");
49271
+ const globalMemDir = join58(homedir15(), ".open-agents", "memory");
48994
49272
  const globalEntries = loadMemoryDir(globalMemDir, "global");
48995
49273
  if (globalEntries)
48996
49274
  sections.push(globalEntries);
48997
49275
  return sections.join("\n\n");
48998
49276
  }
48999
49277
  function loadMemoryDir(memDir, scope) {
49000
- if (!existsSync41(memDir))
49278
+ if (!existsSync42(memDir))
49001
49279
  return "";
49002
49280
  const lines = [];
49003
49281
  try {
49004
- const files = readdirSync12(memDir).filter((f) => f.endsWith(".json"));
49282
+ const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
49005
49283
  for (const file of files.slice(0, 10)) {
49006
49284
  try {
49007
- const raw = readFileSync30(join57(memDir, file), "utf-8");
49285
+ const raw = readFileSync31(join58(memDir, file), "utf-8");
49008
49286
  const entries = JSON.parse(raw);
49009
- const topic = basename11(file, ".json");
49287
+ const topic = basename12(file, ".json");
49010
49288
  const keys = Object.keys(entries);
49011
49289
  if (keys.length === 0)
49012
49290
  continue;
@@ -50523,22 +50801,22 @@ var init_banner = __esm({
50523
50801
  });
50524
50802
 
50525
50803
  // packages/cli/dist/tui/carousel-descriptors.js
50526
- import { existsSync as existsSync42, readFileSync as readFileSync31, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "node:fs";
50527
- import { join as join58, basename as basename12 } from "node:path";
50804
+ import { existsSync as existsSync43, readFileSync as readFileSync32, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync14 } from "node:fs";
50805
+ import { join as join59, basename as basename13 } from "node:path";
50528
50806
  function loadToolProfile(repoRoot) {
50529
- const filePath = join58(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
50807
+ const filePath = join59(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
50530
50808
  try {
50531
- if (!existsSync42(filePath))
50809
+ if (!existsSync43(filePath))
50532
50810
  return null;
50533
- return JSON.parse(readFileSync31(filePath, "utf-8"));
50811
+ return JSON.parse(readFileSync32(filePath, "utf-8"));
50534
50812
  } catch {
50535
50813
  return null;
50536
50814
  }
50537
50815
  }
50538
50816
  function saveToolProfile(repoRoot, profile) {
50539
- const contextDir = join58(repoRoot, OA_DIR, "context");
50540
- mkdirSync17(contextDir, { recursive: true });
50541
- writeFileSync18(join58(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
50817
+ const contextDir = join59(repoRoot, OA_DIR, "context");
50818
+ mkdirSync18(contextDir, { recursive: true });
50819
+ writeFileSync19(join59(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
50542
50820
  }
50543
50821
  function categorizeToolCall(toolName) {
50544
50822
  for (const cat of TOOL_CATEGORIES) {
@@ -50596,25 +50874,25 @@ function weightedColor(profile) {
50596
50874
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
50597
50875
  }
50598
50876
  function loadCachedDescriptors(repoRoot) {
50599
- const filePath = join58(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
50877
+ const filePath = join59(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
50600
50878
  try {
50601
- if (!existsSync42(filePath))
50879
+ if (!existsSync43(filePath))
50602
50880
  return null;
50603
- const cached = JSON.parse(readFileSync31(filePath, "utf-8"));
50881
+ const cached = JSON.parse(readFileSync32(filePath, "utf-8"));
50604
50882
  return cached.phrases.length > 0 ? cached.phrases : null;
50605
50883
  } catch {
50606
50884
  return null;
50607
50885
  }
50608
50886
  }
50609
50887
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
50610
- const contextDir = join58(repoRoot, OA_DIR, "context");
50611
- mkdirSync17(contextDir, { recursive: true });
50888
+ const contextDir = join59(repoRoot, OA_DIR, "context");
50889
+ mkdirSync18(contextDir, { recursive: true });
50612
50890
  const cached = {
50613
50891
  phrases,
50614
50892
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
50615
50893
  sourceHash
50616
50894
  };
50617
- writeFileSync18(join58(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
50895
+ writeFileSync19(join59(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
50618
50896
  }
50619
50897
  function generateDescriptors(repoRoot) {
50620
50898
  const profile = loadToolProfile(repoRoot);
@@ -50625,7 +50903,7 @@ function generateDescriptors(repoRoot) {
50625
50903
  extractFromSessions(repoRoot, tags);
50626
50904
  extractFromMemory(repoRoot, tags);
50627
50905
  extractFromToolProfile(profile, tags);
50628
- const repoName2 = basename12(repoRoot);
50906
+ const repoName2 = basename13(repoRoot);
50629
50907
  if (repoName2 && !tags.includes(repoName2)) {
50630
50908
  tags.push(repoName2);
50631
50909
  }
@@ -50662,11 +50940,11 @@ function generateDescriptors(repoRoot) {
50662
50940
  return phrases;
50663
50941
  }
50664
50942
  function extractFromPackageJson(repoRoot, tags) {
50665
- const pkgPath = join58(repoRoot, "package.json");
50943
+ const pkgPath = join59(repoRoot, "package.json");
50666
50944
  try {
50667
- if (!existsSync42(pkgPath))
50945
+ if (!existsSync43(pkgPath))
50668
50946
  return;
50669
- const pkg = JSON.parse(readFileSync31(pkgPath, "utf-8"));
50947
+ const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
50670
50948
  if (pkg.name && typeof pkg.name === "string") {
50671
50949
  const parts = pkg.name.replace(/^@/, "").split("/");
50672
50950
  for (const p of parts)
@@ -50710,7 +50988,7 @@ function extractFromManifests(repoRoot, tags) {
50710
50988
  { file: ".github/workflows", tag: "ci/cd" }
50711
50989
  ];
50712
50990
  for (const check of manifestChecks) {
50713
- if (existsSync42(join58(repoRoot, check.file))) {
50991
+ if (existsSync43(join59(repoRoot, check.file))) {
50714
50992
  tags.push(check.tag);
50715
50993
  }
50716
50994
  }
@@ -50732,16 +51010,16 @@ function extractFromSessions(repoRoot, tags) {
50732
51010
  }
50733
51011
  }
50734
51012
  function extractFromMemory(repoRoot, tags) {
50735
- const memoryDir = join58(repoRoot, OA_DIR, "memory");
51013
+ const memoryDir = join59(repoRoot, OA_DIR, "memory");
50736
51014
  try {
50737
- if (!existsSync42(memoryDir))
51015
+ if (!existsSync43(memoryDir))
50738
51016
  return;
50739
- const files = readdirSync13(memoryDir).filter((f) => f.endsWith(".json"));
51017
+ const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
50740
51018
  for (const file of files) {
50741
51019
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
50742
51020
  tags.push(topic);
50743
51021
  try {
50744
- const data = JSON.parse(readFileSync31(join58(memoryDir, file), "utf-8"));
51022
+ const data = JSON.parse(readFileSync32(join59(memoryDir, file), "utf-8"));
50745
51023
  if (data && typeof data === "object") {
50746
51024
  const keys = Object.keys(data).slice(0, 3);
50747
51025
  for (const key of keys) {
@@ -51182,7 +51460,7 @@ var init_stream_renderer = __esm({
51182
51460
  if (this.lineBuffer.length > 0) {
51183
51461
  this.flushPartial(kind);
51184
51462
  }
51185
- }, 80);
51463
+ }, 150);
51186
51464
  }
51187
51465
  cancelFlush() {
51188
51466
  if (this.flushTimer) {
@@ -51374,13 +51652,13 @@ var init_stream_renderer = __esm({
51374
51652
  });
51375
51653
 
51376
51654
  // packages/cli/dist/tui/edit-history.js
51377
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync18 } from "node:fs";
51378
- import { join as join59 } from "node:path";
51655
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync19 } from "node:fs";
51656
+ import { join as join60 } from "node:path";
51379
51657
  function createEditHistoryLogger(repoRoot, sessionId) {
51380
- const historyDir = join59(repoRoot, ".oa", "history");
51381
- const logPath2 = join59(historyDir, "edits.jsonl");
51658
+ const historyDir = join60(repoRoot, ".oa", "history");
51659
+ const logPath2 = join60(historyDir, "edits.jsonl");
51382
51660
  try {
51383
- mkdirSync18(historyDir, { recursive: true });
51661
+ mkdirSync19(historyDir, { recursive: true });
51384
51662
  } catch {
51385
51663
  }
51386
51664
  function logToolCall(toolName, toolArgs, success) {
@@ -51489,17 +51767,17 @@ var init_edit_history = __esm({
51489
51767
  });
51490
51768
 
51491
51769
  // packages/cli/dist/tui/promptLoader.js
51492
- import { readFileSync as readFileSync32, existsSync as existsSync43 } from "node:fs";
51493
- import { join as join60, dirname as dirname19 } from "node:path";
51770
+ import { readFileSync as readFileSync33, existsSync as existsSync44 } from "node:fs";
51771
+ import { join as join61, dirname as dirname19 } from "node:path";
51494
51772
  import { fileURLToPath as fileURLToPath11 } from "node:url";
51495
51773
  function loadPrompt3(promptPath, vars) {
51496
51774
  let content = cache3.get(promptPath);
51497
51775
  if (content === void 0) {
51498
- const fullPath = join60(PROMPTS_DIR3, promptPath);
51499
- if (!existsSync43(fullPath)) {
51776
+ const fullPath = join61(PROMPTS_DIR3, promptPath);
51777
+ if (!existsSync44(fullPath)) {
51500
51778
  throw new Error(`Prompt file not found: ${fullPath}`);
51501
51779
  }
51502
- content = readFileSync32(fullPath, "utf-8");
51780
+ content = readFileSync33(fullPath, "utf-8");
51503
51781
  cache3.set(promptPath, content);
51504
51782
  }
51505
51783
  if (!vars)
@@ -51512,23 +51790,23 @@ var init_promptLoader3 = __esm({
51512
51790
  "use strict";
51513
51791
  __filename3 = fileURLToPath11(import.meta.url);
51514
51792
  __dirname6 = dirname19(__filename3);
51515
- devPath2 = join60(__dirname6, "..", "..", "prompts");
51516
- publishedPath2 = join60(__dirname6, "..", "prompts");
51517
- PROMPTS_DIR3 = existsSync43(devPath2) ? devPath2 : publishedPath2;
51793
+ devPath2 = join61(__dirname6, "..", "..", "prompts");
51794
+ publishedPath2 = join61(__dirname6, "..", "prompts");
51795
+ PROMPTS_DIR3 = existsSync44(devPath2) ? devPath2 : publishedPath2;
51518
51796
  cache3 = /* @__PURE__ */ new Map();
51519
51797
  }
51520
51798
  });
51521
51799
 
51522
51800
  // packages/cli/dist/tui/dream-engine.js
51523
- import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readFileSync as readFileSync33, existsSync as existsSync44, cpSync, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
51524
- import { join as join61, basename as basename13 } from "node:path";
51525
- import { execSync as execSync30 } from "node:child_process";
51801
+ import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync20, readFileSync as readFileSync34, existsSync as existsSync45, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
51802
+ import { join as join62, basename as basename14 } from "node:path";
51803
+ import { execSync as execSync31 } from "node:child_process";
51526
51804
  function loadAutoresearchMemory(repoRoot) {
51527
- const memoryPath = join61(repoRoot, ".oa", "memory", "autoresearch.json");
51528
- if (!existsSync44(memoryPath))
51805
+ const memoryPath = join62(repoRoot, ".oa", "memory", "autoresearch.json");
51806
+ if (!existsSync45(memoryPath))
51529
51807
  return "";
51530
51808
  try {
51531
- const raw = readFileSync33(memoryPath, "utf-8");
51809
+ const raw = readFileSync34(memoryPath, "utf-8");
51532
51810
  const data = JSON.parse(raw);
51533
51811
  const sections = [];
51534
51812
  for (const key of AUTORESEARCH_MEMORY_KEYS) {
@@ -51718,14 +51996,14 @@ var init_dream_engine = __esm({
51718
51996
  const content = String(args["content"] ?? "");
51719
51997
  if (!rawPath)
51720
51998
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
51721
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join61(this.autoresearchDir, basename13(rawPath)) : join61(this.autoresearchDir, rawPath);
51999
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
51722
52000
  if (!targetPath.startsWith(this.autoresearchDir)) {
51723
52001
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
51724
52002
  }
51725
52003
  try {
51726
- const dir = join61(targetPath, "..");
51727
- mkdirSync19(dir, { recursive: true });
51728
- writeFileSync19(targetPath, content, "utf-8");
52004
+ const dir = join62(targetPath, "..");
52005
+ mkdirSync20(dir, { recursive: true });
52006
+ writeFileSync20(targetPath, content, "utf-8");
51729
52007
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
51730
52008
  } catch (err) {
51731
52009
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51753,20 +52031,20 @@ var init_dream_engine = __esm({
51753
52031
  const rawPath = String(args["path"] ?? "");
51754
52032
  const oldStr = String(args["old_string"] ?? "");
51755
52033
  const newStr = String(args["new_string"] ?? "");
51756
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join61(this.autoresearchDir, basename13(rawPath)) : join61(this.autoresearchDir, rawPath);
52034
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join62(this.autoresearchDir, basename14(rawPath)) : join62(this.autoresearchDir, rawPath);
51757
52035
  if (!targetPath.startsWith(this.autoresearchDir)) {
51758
52036
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
51759
52037
  }
51760
52038
  try {
51761
- if (!existsSync44(targetPath)) {
52039
+ if (!existsSync45(targetPath)) {
51762
52040
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
51763
52041
  }
51764
- let content = readFileSync33(targetPath, "utf-8");
52042
+ let content = readFileSync34(targetPath, "utf-8");
51765
52043
  if (!content.includes(oldStr)) {
51766
52044
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
51767
52045
  }
51768
52046
  content = content.replace(oldStr, newStr);
51769
- writeFileSync19(targetPath, content, "utf-8");
52047
+ writeFileSync20(targetPath, content, "utf-8");
51770
52048
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
51771
52049
  } catch (err) {
51772
52050
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51807,14 +52085,14 @@ var init_dream_engine = __esm({
51807
52085
  const content = String(args["content"] ?? "");
51808
52086
  if (!rawPath)
51809
52087
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
51810
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join61(this.dreamsDir, basename13(rawPath)) : join61(this.dreamsDir, rawPath);
52088
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
51811
52089
  if (!targetPath.startsWith(this.dreamsDir)) {
51812
52090
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
51813
52091
  }
51814
52092
  try {
51815
- const dir = join61(targetPath, "..");
51816
- mkdirSync19(dir, { recursive: true });
51817
- writeFileSync19(targetPath, content, "utf-8");
52093
+ const dir = join62(targetPath, "..");
52094
+ mkdirSync20(dir, { recursive: true });
52095
+ writeFileSync20(targetPath, content, "utf-8");
51818
52096
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
51819
52097
  } catch (err) {
51820
52098
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51842,20 +52120,20 @@ var init_dream_engine = __esm({
51842
52120
  const rawPath = String(args["path"] ?? "");
51843
52121
  const oldStr = String(args["old_string"] ?? "");
51844
52122
  const newStr = String(args["new_string"] ?? "");
51845
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join61(this.dreamsDir, basename13(rawPath)) : join61(this.dreamsDir, rawPath);
52123
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join62(this.dreamsDir, basename14(rawPath)) : join62(this.dreamsDir, rawPath);
51846
52124
  if (!targetPath.startsWith(this.dreamsDir)) {
51847
52125
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
51848
52126
  }
51849
52127
  try {
51850
- if (!existsSync44(targetPath)) {
52128
+ if (!existsSync45(targetPath)) {
51851
52129
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
51852
52130
  }
51853
- let content = readFileSync33(targetPath, "utf-8");
52131
+ let content = readFileSync34(targetPath, "utf-8");
51854
52132
  if (!content.includes(oldStr)) {
51855
52133
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
51856
52134
  }
51857
52135
  content = content.replace(oldStr, newStr);
51858
- writeFileSync19(targetPath, content, "utf-8");
52136
+ writeFileSync20(targetPath, content, "utf-8");
51859
52137
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
51860
52138
  } catch (err) {
51861
52139
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51886,7 +52164,7 @@ var init_dream_engine = __esm({
51886
52164
  }
51887
52165
  }
51888
52166
  try {
51889
- const output = execSync30(cmd, {
52167
+ const output = execSync31(cmd, {
51890
52168
  cwd: this.repoRoot,
51891
52169
  timeout: 3e4,
51892
52170
  encoding: "utf-8",
@@ -51909,7 +52187,7 @@ var init_dream_engine = __esm({
51909
52187
  constructor(config, repoRoot) {
51910
52188
  this.config = config;
51911
52189
  this.repoRoot = repoRoot;
51912
- this.dreamsDir = join61(repoRoot, ".oa", "dreams");
52190
+ this.dreamsDir = join62(repoRoot, ".oa", "dreams");
51913
52191
  this.state = {
51914
52192
  mode: "default",
51915
52193
  active: false,
@@ -51940,7 +52218,7 @@ var init_dream_engine = __esm({
51940
52218
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
51941
52219
  results: []
51942
52220
  };
51943
- mkdirSync19(this.dreamsDir, { recursive: true });
52221
+ mkdirSync20(this.dreamsDir, { recursive: true });
51944
52222
  this.saveDreamState();
51945
52223
  try {
51946
52224
  for (let cycle = 1; cycle <= totalCycles; cycle++) {
@@ -51993,8 +52271,8 @@ ${result.summary}`;
51993
52271
  if (mode !== "default" || cycle === totalCycles) {
51994
52272
  renderDreamContraction(cycle);
51995
52273
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
51996
- const summaryPath = join61(this.dreamsDir, `cycle-${cycle}-summary.md`);
51997
- writeFileSync19(summaryPath, cycleSummary, "utf-8");
52274
+ const summaryPath = join62(this.dreamsDir, `cycle-${cycle}-summary.md`);
52275
+ writeFileSync20(summaryPath, cycleSummary, "utf-8");
51998
52276
  }
51999
52277
  if (mode === "lucid" && !this.abortController.signal.aborted) {
52000
52278
  this.saveVersionCheckpoint(cycle);
@@ -52206,7 +52484,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
52206
52484
  }
52207
52485
  /** Build role-specific tool sets for swarm agents */
52208
52486
  buildSwarmTools(role, _workspace) {
52209
- const autoresearchDir = join61(this.repoRoot, ".oa", "autoresearch");
52487
+ const autoresearchDir = join62(this.repoRoot, ".oa", "autoresearch");
52210
52488
  const taskComplete = this.createSwarmTaskCompleteTool(role);
52211
52489
  switch (role) {
52212
52490
  case "researcher": {
@@ -52570,7 +52848,7 @@ INSTRUCTIONS:
52570
52848
  2. Summarize the key learnings and next steps
52571
52849
 
52572
52850
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
52573
- const reportPath = join61(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
52851
+ const reportPath = join62(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
52574
52852
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
52575
52853
 
52576
52854
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -52592,8 +52870,8 @@ ${summaryResult}
52592
52870
  *Generated by open-agents autoresearch swarm*
52593
52871
  `;
52594
52872
  try {
52595
- mkdirSync19(this.dreamsDir, { recursive: true });
52596
- writeFileSync19(reportPath, report, "utf-8");
52873
+ mkdirSync20(this.dreamsDir, { recursive: true });
52874
+ writeFileSync20(reportPath, report, "utf-8");
52597
52875
  } catch {
52598
52876
  }
52599
52877
  renderSwarmComplete(workspace);
@@ -52659,29 +52937,29 @@ ${summaryResult}
52659
52937
  }
52660
52938
  /** Save workspace backup for lucid mode */
52661
52939
  saveVersionCheckpoint(cycle) {
52662
- const checkpointDir = join61(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
52940
+ const checkpointDir = join62(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
52663
52941
  try {
52664
- mkdirSync19(checkpointDir, { recursive: true });
52942
+ mkdirSync20(checkpointDir, { recursive: true });
52665
52943
  try {
52666
- const gitStatus = execSync30("git status --porcelain", {
52944
+ const gitStatus = execSync31("git status --porcelain", {
52667
52945
  cwd: this.repoRoot,
52668
52946
  encoding: "utf-8",
52669
52947
  timeout: 1e4
52670
52948
  });
52671
- const gitDiff = execSync30("git diff", {
52949
+ const gitDiff = execSync31("git diff", {
52672
52950
  cwd: this.repoRoot,
52673
52951
  encoding: "utf-8",
52674
52952
  timeout: 1e4
52675
52953
  });
52676
- const gitHash = execSync30("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
52954
+ const gitHash = execSync31("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
52677
52955
  cwd: this.repoRoot,
52678
52956
  encoding: "utf-8",
52679
52957
  timeout: 5e3
52680
52958
  }).trim();
52681
- writeFileSync19(join61(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
52682
- writeFileSync19(join61(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
52683
- writeFileSync19(join61(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
52684
- writeFileSync19(join61(checkpointDir, "checkpoint.json"), JSON.stringify({
52959
+ writeFileSync20(join62(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
52960
+ writeFileSync20(join62(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
52961
+ writeFileSync20(join62(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
52962
+ writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({
52685
52963
  cycle,
52686
52964
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
52687
52965
  gitHash,
@@ -52689,7 +52967,7 @@ ${summaryResult}
52689
52967
  }, null, 2), "utf-8");
52690
52968
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
52691
52969
  } catch {
52692
- writeFileSync19(join61(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
52970
+ writeFileSync20(join62(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
52693
52971
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
52694
52972
  }
52695
52973
  } catch (err) {
@@ -52726,7 +53004,7 @@ Each proposal includes implementation entrypoints and estimated effort.
52726
53004
  /** Update the master proposal index */
52727
53005
  updateProposalIndex() {
52728
53006
  try {
52729
- const files = readdirSync14(this.dreamsDir).filter((f) => f.endsWith(".md") && f !== "PROPOSAL-INDEX.md" && f !== "dream-state.json").sort();
53007
+ const files = readdirSync15(this.dreamsDir).filter((f) => f.endsWith(".md") && f !== "PROPOSAL-INDEX.md" && f !== "dream-state.json").sort();
52730
53008
  const index = `# Dream Proposals Index
52731
53009
 
52732
53010
  **Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -52747,14 +53025,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
52747
53025
  ---
52748
53026
  *Auto-generated by open-agents dream engine*
52749
53027
  `;
52750
- writeFileSync19(join61(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
53028
+ writeFileSync20(join62(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
52751
53029
  } catch {
52752
53030
  }
52753
53031
  }
52754
53032
  /** Save dream state for resume/inspection */
52755
53033
  saveDreamState() {
52756
53034
  try {
52757
- writeFileSync19(join61(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
53035
+ writeFileSync20(join62(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
52758
53036
  } catch {
52759
53037
  }
52760
53038
  }
@@ -53128,8 +53406,8 @@ var init_bless_engine = __esm({
53128
53406
  });
53129
53407
 
53130
53408
  // packages/cli/dist/tui/dmn-engine.js
53131
- import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync20, mkdirSync as mkdirSync20, readdirSync as readdirSync15, unlinkSync as unlinkSync9 } from "node:fs";
53132
- import { join as join62, basename as basename14 } from "node:path";
53409
+ import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync21, mkdirSync as mkdirSync21, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
53410
+ import { join as join63, basename as basename15 } from "node:path";
53133
53411
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
53134
53412
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
53135
53413
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -53249,9 +53527,9 @@ var init_dmn_engine = __esm({
53249
53527
  constructor(config, repoRoot) {
53250
53528
  this.config = config;
53251
53529
  this.repoRoot = repoRoot;
53252
- this.stateDir = join62(repoRoot, ".oa", "dmn");
53253
- this.historyDir = join62(repoRoot, ".oa", "dmn", "cycles");
53254
- mkdirSync20(this.historyDir, { recursive: true });
53530
+ this.stateDir = join63(repoRoot, ".oa", "dmn");
53531
+ this.historyDir = join63(repoRoot, ".oa", "dmn", "cycles");
53532
+ mkdirSync21(this.historyDir, { recursive: true });
53255
53533
  this.loadState();
53256
53534
  }
53257
53535
  get stats() {
@@ -53840,16 +54118,16 @@ OUTPUT: Call task_complete with JSON:
53840
54118
  async gatherMemoryTopics() {
53841
54119
  const topics = [];
53842
54120
  const dirs = [
53843
- join62(this.repoRoot, ".oa", "memory"),
53844
- join62(this.repoRoot, ".open-agents", "memory")
54121
+ join63(this.repoRoot, ".oa", "memory"),
54122
+ join63(this.repoRoot, ".open-agents", "memory")
53845
54123
  ];
53846
54124
  for (const dir of dirs) {
53847
- if (!existsSync45(dir))
54125
+ if (!existsSync46(dir))
53848
54126
  continue;
53849
54127
  try {
53850
- const files = readdirSync15(dir).filter((f) => f.endsWith(".json"));
54128
+ const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
53851
54129
  for (const f of files) {
53852
- const topic = basename14(f, ".json");
54130
+ const topic = basename15(f, ".json");
53853
54131
  if (!topics.includes(topic))
53854
54132
  topics.push(topic);
53855
54133
  }
@@ -53860,29 +54138,29 @@ OUTPUT: Call task_complete with JSON:
53860
54138
  }
53861
54139
  // ── State persistence ─────────────────────────────────────────────────
53862
54140
  loadState() {
53863
- const path = join62(this.stateDir, "state.json");
53864
- if (existsSync45(path)) {
54141
+ const path = join63(this.stateDir, "state.json");
54142
+ if (existsSync46(path)) {
53865
54143
  try {
53866
- this.state = JSON.parse(readFileSync34(path, "utf-8"));
54144
+ this.state = JSON.parse(readFileSync35(path, "utf-8"));
53867
54145
  } catch {
53868
54146
  }
53869
54147
  }
53870
54148
  }
53871
54149
  saveState() {
53872
54150
  try {
53873
- writeFileSync20(join62(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
54151
+ writeFileSync21(join63(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
53874
54152
  } catch {
53875
54153
  }
53876
54154
  }
53877
54155
  saveCycleResult(result) {
53878
54156
  try {
53879
54157
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
53880
- writeFileSync20(join62(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
53881
- const files = readdirSync15(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
54158
+ writeFileSync21(join63(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
54159
+ const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
53882
54160
  if (files.length > 50) {
53883
54161
  for (const old of files.slice(0, files.length - 50)) {
53884
54162
  try {
53885
- unlinkSync9(join62(this.historyDir, old));
54163
+ unlinkSync10(join63(this.historyDir, old));
53886
54164
  } catch {
53887
54165
  }
53888
54166
  }
@@ -53895,8 +54173,8 @@ OUTPUT: Call task_complete with JSON:
53895
54173
  });
53896
54174
 
53897
54175
  // packages/cli/dist/tui/snr-engine.js
53898
- import { existsSync as existsSync46, readdirSync as readdirSync16, readFileSync as readFileSync35 } from "node:fs";
53899
- import { join as join63, basename as basename15 } from "node:path";
54176
+ import { existsSync as existsSync47, readdirSync as readdirSync17, readFileSync as readFileSync36 } from "node:fs";
54177
+ import { join as join64, basename as basename16 } from "node:path";
53900
54178
  function computeDPrime(signalScores, noiseScores) {
53901
54179
  if (signalScores.length === 0 || noiseScores.length === 0)
53902
54180
  return 0;
@@ -54136,20 +54414,20 @@ Call task_complete with the JSON array when done.`, onEvent)
54136
54414
  loadMemoryEntries(topics) {
54137
54415
  const entries = [];
54138
54416
  const dirs = [
54139
- join63(this.repoRoot, ".oa", "memory"),
54140
- join63(this.repoRoot, ".open-agents", "memory")
54417
+ join64(this.repoRoot, ".oa", "memory"),
54418
+ join64(this.repoRoot, ".open-agents", "memory")
54141
54419
  ];
54142
54420
  for (const dir of dirs) {
54143
- if (!existsSync46(dir))
54421
+ if (!existsSync47(dir))
54144
54422
  continue;
54145
54423
  try {
54146
- const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
54424
+ const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
54147
54425
  for (const f of files) {
54148
- const topic = basename15(f, ".json");
54426
+ const topic = basename16(f, ".json");
54149
54427
  if (topics.length > 0 && !topics.includes(topic))
54150
54428
  continue;
54151
54429
  try {
54152
- const data = JSON.parse(readFileSync35(join63(dir, f), "utf-8"));
54430
+ const data = JSON.parse(readFileSync36(join64(dir, f), "utf-8"));
54153
54431
  for (const [key, val] of Object.entries(data)) {
54154
54432
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
54155
54433
  entries.push({ topic, key, value });
@@ -54716,8 +54994,8 @@ var init_tool_policy = __esm({
54716
54994
  });
54717
54995
 
54718
54996
  // packages/cli/dist/tui/telegram-bridge.js
54719
- import { mkdirSync as mkdirSync21, existsSync as existsSync47, unlinkSync as unlinkSync10, readdirSync as readdirSync17, statSync as statSync15 } from "node:fs";
54720
- import { join as join64, resolve as resolve30 } from "node:path";
54997
+ import { mkdirSync as mkdirSync22, existsSync as existsSync48, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
54998
+ import { join as join65, resolve as resolve30 } from "node:path";
54721
54999
  import { writeFile as writeFileAsync } from "node:fs/promises";
54722
55000
  function convertMarkdownToTelegramHTML(md) {
54723
55001
  let html = md;
@@ -55045,7 +55323,7 @@ with summary "no_reply" to silently skip without responding.
55045
55323
  this.polling = true;
55046
55324
  this.abortController = new AbortController();
55047
55325
  try {
55048
- mkdirSync21(this.mediaCacheDir, { recursive: true });
55326
+ mkdirSync22(this.mediaCacheDir, { recursive: true });
55049
55327
  } catch {
55050
55328
  }
55051
55329
  this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
@@ -55482,7 +55760,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
55482
55760
  return null;
55483
55761
  const buffer = Buffer.from(await res.arrayBuffer());
55484
55762
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
55485
- const localPath = join64(this.mediaCacheDir, fileName);
55763
+ const localPath = join65(this.mediaCacheDir, fileName);
55486
55764
  await writeFileAsync(localPath, buffer);
55487
55765
  return localPath;
55488
55766
  } catch {
@@ -55570,7 +55848,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
55570
55848
  for (const [key, entry] of this.mediaCache) {
55571
55849
  if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
55572
55850
  try {
55573
- unlinkSync10(entry.localPath);
55851
+ unlinkSync11(entry.localPath);
55574
55852
  } catch {
55575
55853
  }
55576
55854
  this.mediaCache.delete(key);
@@ -56498,7 +56776,7 @@ __export(text_selection_exports, {
56498
56776
  stripAnsi: () => stripAnsi3,
56499
56777
  visibleLength: () => visibleLength
56500
56778
  });
56501
- import { execSync as execSync31 } from "node:child_process";
56779
+ import { execSync as execSync32 } from "node:child_process";
56502
56780
  function stripAnsi3(s) {
56503
56781
  return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
56504
56782
  }
@@ -56509,16 +56787,16 @@ function copyText(text) {
56509
56787
  try {
56510
56788
  const platform6 = process.platform;
56511
56789
  if (platform6 === "darwin") {
56512
- execSync31("pbcopy", { input: text, timeout: 3e3 });
56790
+ execSync32("pbcopy", { input: text, timeout: 3e3 });
56513
56791
  return true;
56514
56792
  }
56515
56793
  if (platform6 === "win32") {
56516
- execSync31("clip", { input: text, timeout: 3e3 });
56794
+ execSync32("clip", { input: text, timeout: 3e3 });
56517
56795
  return true;
56518
56796
  }
56519
56797
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
56520
56798
  try {
56521
- execSync31(tool, { input: text, timeout: 3e3 });
56799
+ execSync32(tool, { input: text, timeout: 3e3 });
56522
56800
  return true;
56523
56801
  } catch {
56524
56802
  continue;
@@ -56527,10 +56805,10 @@ function copyText(text) {
56527
56805
  if (!_clipboardAutoInstallAttempted) {
56528
56806
  _clipboardAutoInstallAttempted = true;
56529
56807
  try {
56530
- execSync31("which apt-get", { timeout: 2e3, stdio: "pipe" });
56808
+ execSync32("which apt-get", { timeout: 2e3, stdio: "pipe" });
56531
56809
  try {
56532
- execSync31("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
56533
- execSync31("xclip -selection clipboard", { input: text, timeout: 3e3 });
56810
+ execSync32("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
56811
+ execSync32("xclip -selection clipboard", { input: text, timeout: 3e3 });
56534
56812
  return true;
56535
56813
  } catch {
56536
56814
  }
@@ -56838,7 +57116,7 @@ var init_text_selection = __esm({
56838
57116
  });
56839
57117
 
56840
57118
  // packages/cli/dist/tui/status-bar.js
56841
- import { readFileSync as readFileSync36 } from "node:fs";
57119
+ import { readFileSync as readFileSync37 } from "node:fs";
56842
57120
  function setTerminalTitle(task, version) {
56843
57121
  if (!process.stdout.isTTY)
56844
57122
  return;
@@ -57520,7 +57798,7 @@ var init_status_bar = __esm({
57520
57798
  if (nexusDir) {
57521
57799
  try {
57522
57800
  const metricsPath = nexusDir + "/remote-metrics.json";
57523
- const raw = readFileSync36(metricsPath, "utf8");
57801
+ const raw = readFileSync37(metricsPath, "utf8");
57524
57802
  const cached = JSON.parse(raw);
57525
57803
  if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
57526
57804
  const m = cached.data;
@@ -59119,12 +59397,12 @@ var init_mouse_filter = __esm({
59119
59397
  import * as readline2 from "node:readline";
59120
59398
  import { Writable } from "node:stream";
59121
59399
  import { cwd } from "node:process";
59122
- import { resolve as resolve31, join as join65, dirname as dirname20, extname as extname11 } from "node:path";
59400
+ import { resolve as resolve31, join as join66, dirname as dirname20, extname as extname11 } from "node:path";
59123
59401
  import { createRequire as createRequire2 } from "node:module";
59124
59402
  import { fileURLToPath as fileURLToPath12 } from "node:url";
59125
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync21, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync18, mkdirSync as mkdirSync22 } from "node:fs";
59126
- import { existsSync as existsSync48 } from "node:fs";
59127
- import { execSync as execSync32 } from "node:child_process";
59403
+ import { readFileSync as readFileSync38, writeFileSync as writeFileSync22, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync19, mkdirSync as mkdirSync23 } from "node:fs";
59404
+ import { existsSync as existsSync49 } from "node:fs";
59405
+ import { execSync as execSync33 } from "node:child_process";
59128
59406
  import { homedir as homedir16 } from "node:os";
59129
59407
  function formatTimeAgo(date) {
59130
59408
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -59144,12 +59422,12 @@ function getVersion3() {
59144
59422
  const require2 = createRequire2(import.meta.url);
59145
59423
  const thisDir = dirname20(fileURLToPath12(import.meta.url));
59146
59424
  const candidates = [
59147
- join65(thisDir, "..", "package.json"),
59148
- join65(thisDir, "..", "..", "package.json"),
59149
- join65(thisDir, "..", "..", "..", "package.json")
59425
+ join66(thisDir, "..", "package.json"),
59426
+ join66(thisDir, "..", "..", "package.json"),
59427
+ join66(thisDir, "..", "..", "..", "package.json")
59150
59428
  ];
59151
59429
  for (const pkgPath of candidates) {
59152
- if (existsSync48(pkgPath)) {
59430
+ if (existsSync49(pkgPath)) {
59153
59431
  const pkg = require2(pkgPath);
59154
59432
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
59155
59433
  return pkg.version ?? "0.0.0";
@@ -59282,6 +59560,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
59282
59560
  new SemanticMapTool(repoRoot),
59283
59561
  new RepoMapTool(repoRoot),
59284
59562
  new ProcessHealthTool(),
59563
+ new VideoUnderstandTool(repoRoot),
59285
59564
  // Full OA sub-process — callbacks wired after runner + statusBar created
59286
59565
  (() => {
59287
59566
  _fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
@@ -59383,15 +59662,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
59383
59662
  function gatherMemorySnippets(root) {
59384
59663
  const snippets = [];
59385
59664
  const dirs = [
59386
- join65(root, ".oa", "memory"),
59387
- join65(root, ".open-agents", "memory")
59665
+ join66(root, ".oa", "memory"),
59666
+ join66(root, ".open-agents", "memory")
59388
59667
  ];
59389
59668
  for (const dir of dirs) {
59390
- if (!existsSync48(dir))
59669
+ if (!existsSync49(dir))
59391
59670
  continue;
59392
59671
  try {
59393
- for (const f of readdirSync18(dir).filter((f2) => f2.endsWith(".json"))) {
59394
- const data = JSON.parse(readFileSync37(join65(dir, f), "utf-8"));
59672
+ for (const f of readdirSync19(dir).filter((f2) => f2.endsWith(".json"))) {
59673
+ const data = JSON.parse(readFileSync38(join66(dir, f), "utf-8"));
59395
59674
  for (const val of Object.values(data)) {
59396
59675
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
59397
59676
  if (v.length > 10)
@@ -59548,9 +59827,9 @@ ${metabolismMemories}
59548
59827
  } catch {
59549
59828
  }
59550
59829
  try {
59551
- const archeFile = join65(repoRoot, ".oa", "arche", "variants.json");
59552
- if (existsSync48(archeFile)) {
59553
- const variants = JSON.parse(readFileSync37(archeFile, "utf8"));
59830
+ const archeFile = join66(repoRoot, ".oa", "arche", "variants.json");
59831
+ if (existsSync49(archeFile)) {
59832
+ const variants = JSON.parse(readFileSync38(archeFile, "utf8"));
59554
59833
  if (variants.length > 0) {
59555
59834
  let filtered = variants;
59556
59835
  if (taskType) {
@@ -59687,9 +59966,9 @@ ${lines.join("\n")}
59687
59966
  const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
59688
59967
  let identityInjection = "";
59689
59968
  try {
59690
- const ikStateFile = join65(repoRoot, ".oa", "identity", "self-state.json");
59691
- if (existsSync48(ikStateFile)) {
59692
- const selfState = JSON.parse(readFileSync37(ikStateFile, "utf8"));
59969
+ const ikStateFile = join66(repoRoot, ".oa", "identity", "self-state.json");
59970
+ if (existsSync49(ikStateFile)) {
59971
+ const selfState = JSON.parse(readFileSync38(ikStateFile, "utf8"));
59693
59972
  const lines = [
59694
59973
  `[Identity State v${selfState.version}]`,
59695
59974
  `Self: ${selfState.narrative_summary}`,
@@ -60328,13 +60607,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60328
60607
  });
60329
60608
  }
60330
60609
  try {
60331
- const ikDir = join65(repoRoot, ".oa", "identity");
60332
- const ikFile = join65(ikDir, "self-state.json");
60610
+ const ikDir = join66(repoRoot, ".oa", "identity");
60611
+ const ikFile = join66(ikDir, "self-state.json");
60333
60612
  let ikState;
60334
- if (existsSync48(ikFile)) {
60335
- ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
60613
+ if (existsSync49(ikFile)) {
60614
+ ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
60336
60615
  } else {
60337
- mkdirSync22(ikDir, { recursive: true });
60616
+ mkdirSync23(ikDir, { recursive: true });
60338
60617
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
60339
60618
  ikState = {
60340
60619
  self_id: `oa-${machineId}`,
@@ -60360,7 +60639,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60360
60639
  }
60361
60640
  ikState.session_count = (ikState.session_count || 0) + 1;
60362
60641
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
60363
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
60642
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
60364
60643
  } catch (ikErr) {
60365
60644
  try {
60366
60645
  console.error("[IK-OBSERVE]", ikErr);
@@ -60375,14 +60654,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60375
60654
  } else {
60376
60655
  renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
60377
60656
  try {
60378
- const ikFile = join65(repoRoot, ".oa", "identity", "self-state.json");
60379
- if (existsSync48(ikFile)) {
60380
- const ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
60657
+ const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
60658
+ if (existsSync49(ikFile)) {
60659
+ const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
60381
60660
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
60382
60661
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
60383
60662
  ikState.session_count = (ikState.session_count || 0) + 1;
60384
60663
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
60385
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
60664
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
60386
60665
  }
60387
60666
  } catch {
60388
60667
  }
@@ -60725,7 +61004,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
60725
61004
  let p2pGateway = null;
60726
61005
  let peerMesh = null;
60727
61006
  let inferenceRouter = null;
60728
- const secretVault = new SecretVault(join65(repoRoot, ".oa", "vault.enc"));
61007
+ const secretVault = new SecretVault(join66(repoRoot, ".oa", "vault.enc"));
60729
61008
  let adminSessionKey = null;
60730
61009
  const callSubAgents = /* @__PURE__ */ new Map();
60731
61010
  const streamRenderer = new StreamRenderer();
@@ -60945,13 +61224,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
60945
61224
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
60946
61225
  return [hits, line];
60947
61226
  }
60948
- const HISTORY_DIR = join65(homedir16(), ".open-agents");
60949
- const HISTORY_FILE = join65(HISTORY_DIR, "repl-history");
61227
+ const HISTORY_DIR = join66(homedir16(), ".open-agents");
61228
+ const HISTORY_FILE = join66(HISTORY_DIR, "repl-history");
60950
61229
  const MAX_HISTORY_LINES = 500;
60951
61230
  let savedHistory = [];
60952
61231
  try {
60953
- if (existsSync48(HISTORY_FILE)) {
60954
- const raw = readFileSync37(HISTORY_FILE, "utf8").trim();
61232
+ if (existsSync49(HISTORY_FILE)) {
61233
+ const raw = readFileSync38(HISTORY_FILE, "utf8").trim();
60955
61234
  if (raw)
60956
61235
  savedHistory = raw.split("\n").reverse();
60957
61236
  }
@@ -61031,12 +61310,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61031
61310
  if (!line.trim())
61032
61311
  return;
61033
61312
  try {
61034
- mkdirSync22(HISTORY_DIR, { recursive: true });
61313
+ mkdirSync23(HISTORY_DIR, { recursive: true });
61035
61314
  appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
61036
61315
  if (Math.random() < 0.02) {
61037
- const all = readFileSync37(HISTORY_FILE, "utf8").trim().split("\n");
61316
+ const all = readFileSync38(HISTORY_FILE, "utf8").trim().split("\n");
61038
61317
  if (all.length > MAX_HISTORY_LINES) {
61039
- writeFileSync21(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
61318
+ writeFileSync22(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
61040
61319
  }
61041
61320
  }
61042
61321
  } catch {
@@ -61212,7 +61491,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61212
61491
  } catch {
61213
61492
  }
61214
61493
  try {
61215
- const oaDir = join65(repoRoot, ".oa");
61494
+ const oaDir = join66(repoRoot, ".oa");
61216
61495
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
61217
61496
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
61218
61497
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -61235,7 +61514,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61235
61514
  } catch {
61236
61515
  }
61237
61516
  try {
61238
- const oaDir = join65(repoRoot, ".oa");
61517
+ const oaDir = join66(repoRoot, ".oa");
61239
61518
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
61240
61519
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
61241
61520
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -62119,7 +62398,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62119
62398
  kind,
62120
62399
  targetUrl,
62121
62400
  authKey,
62122
- stateDir: join65(repoRoot, ".oa"),
62401
+ stateDir: join66(repoRoot, ".oa"),
62123
62402
  passthrough: passthrough ?? false,
62124
62403
  loadbalance: loadbalance ?? false,
62125
62404
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -62167,7 +62446,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62167
62446
  await tunnelGateway.stop();
62168
62447
  tunnelGateway = null;
62169
62448
  }
62170
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join65(repoRoot, ".oa") });
62449
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join66(repoRoot, ".oa") });
62171
62450
  newTunnel.on("stats", (stats) => {
62172
62451
  statusBar.setExposeStatus({
62173
62452
  status: stats.status,
@@ -62436,15 +62715,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62436
62715
  writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
62437
62716
  }
62438
62717
  try {
62439
- const nexusDir = join65(repoRoot, OA_DIR, "nexus");
62440
- const pidFile = join65(nexusDir, "daemon.pid");
62441
- if (existsSync48(pidFile)) {
62442
- const pid = parseInt(readFileSync37(pidFile, "utf8").trim(), 10);
62718
+ const nexusDir = join66(repoRoot, OA_DIR, "nexus");
62719
+ const pidFile = join66(nexusDir, "daemon.pid");
62720
+ if (existsSync49(pidFile)) {
62721
+ const pid = parseInt(readFileSync38(pidFile, "utf8").trim(), 10);
62443
62722
  if (pid > 0) {
62444
62723
  try {
62445
62724
  if (process.platform === "win32") {
62446
62725
  try {
62447
- execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62726
+ execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62448
62727
  } catch {
62449
62728
  }
62450
62729
  } else {
@@ -62461,17 +62740,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62461
62740
  } catch {
62462
62741
  }
62463
62742
  try {
62464
- const voiceDir2 = join65(homedir16(), ".open-agents", "voice");
62743
+ const voiceDir2 = join66(homedir16(), ".open-agents", "voice");
62465
62744
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
62466
62745
  for (const pf of voicePidFiles) {
62467
- const pidPath = join65(voiceDir2, pf);
62468
- if (existsSync48(pidPath)) {
62746
+ const pidPath = join66(voiceDir2, pf);
62747
+ if (existsSync49(pidPath)) {
62469
62748
  try {
62470
- const pid = parseInt(readFileSync37(pidPath, "utf8").trim(), 10);
62749
+ const pid = parseInt(readFileSync38(pidPath, "utf8").trim(), 10);
62471
62750
  if (pid > 0) {
62472
62751
  if (process.platform === "win32") {
62473
62752
  try {
62474
- execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62753
+ execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62475
62754
  } catch {
62476
62755
  }
62477
62756
  } else {
@@ -62488,11 +62767,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62488
62767
  } catch {
62489
62768
  }
62490
62769
  try {
62491
- execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
62770
+ execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
62492
62771
  } catch {
62493
62772
  }
62494
- const oaPath = join65(repoRoot, OA_DIR);
62495
- if (existsSync48(oaPath)) {
62773
+ const oaPath = join66(repoRoot, OA_DIR);
62774
+ if (existsSync49(oaPath)) {
62496
62775
  let deleted = false;
62497
62776
  for (let attempt = 0; attempt < 3; attempt++) {
62498
62777
  try {
@@ -62502,14 +62781,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62502
62781
  } catch (err) {
62503
62782
  if (attempt < 2) {
62504
62783
  try {
62505
- execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
62784
+ execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
62506
62785
  } catch {
62507
62786
  }
62508
62787
  } else {
62509
62788
  writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
62510
62789
  if (process.platform === "win32") {
62511
62790
  try {
62512
- execSync32(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
62791
+ execSync33(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
62513
62792
  deleted = true;
62514
62793
  } catch {
62515
62794
  }
@@ -62864,8 +63143,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
62864
63143
  }
62865
63144
  }
62866
63145
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
62867
- const isImage = isImagePath(cleanPath) && existsSync48(resolve31(repoRoot, cleanPath));
62868
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync48(resolve31(repoRoot, cleanPath));
63146
+ const isImage = isImagePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
63147
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync49(resolve31(repoRoot, cleanPath));
62869
63148
  if (activeTask) {
62870
63149
  if (activeTask.runner.isPaused) {
62871
63150
  activeTask.runner.resume();
@@ -62874,7 +63153,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
62874
63153
  if (isImage) {
62875
63154
  try {
62876
63155
  const imgPath = resolve31(repoRoot, cleanPath);
62877
- const imgBuffer = readFileSync37(imgPath);
63156
+ const imgBuffer = readFileSync38(imgPath);
62878
63157
  const base64 = imgBuffer.toString("base64");
62879
63158
  const ext = extname11(cleanPath).toLowerCase();
62880
63159
  const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
@@ -63111,13 +63390,13 @@ NEW TASK: ${fullInput}`;
63111
63390
  writeContent(() => renderError(errMsg));
63112
63391
  if (failureStore) {
63113
63392
  try {
63114
- const { createHash: createHash5 } = await import("node:crypto");
63393
+ const { createHash: createHash6 } = await import("node:crypto");
63115
63394
  failureStore.insert({
63116
63395
  taskId: "",
63117
63396
  sessionId: `${Date.now()}`,
63118
63397
  repoRoot,
63119
63398
  failureType: "runtime-error",
63120
- fingerprint: createHash5("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
63399
+ fingerprint: createHash6("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
63121
63400
  filePath: null,
63122
63401
  errorMessage: errMsg.slice(0, 500),
63123
63402
  context: null,
@@ -63373,13 +63652,13 @@ async function runWithTUI(task, config, repoPath) {
63373
63652
  const handle = startTask(task, config, repoRoot);
63374
63653
  await handle.promise;
63375
63654
  try {
63376
- const ikDir = join65(repoRoot, ".oa", "identity");
63377
- const ikFile = join65(ikDir, "self-state.json");
63655
+ const ikDir = join66(repoRoot, ".oa", "identity");
63656
+ const ikFile = join66(ikDir, "self-state.json");
63378
63657
  let ikState;
63379
- if (existsSync48(ikFile)) {
63380
- ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
63658
+ if (existsSync49(ikFile)) {
63659
+ ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
63381
63660
  } else {
63382
- mkdirSync22(ikDir, { recursive: true });
63661
+ mkdirSync23(ikDir, { recursive: true });
63383
63662
  ikState = {
63384
63663
  self_id: `oa-${Date.now().toString(36)}`,
63385
63664
  version: 1,
@@ -63401,7 +63680,7 @@ async function runWithTUI(task, config, repoPath) {
63401
63680
  ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
63402
63681
  ikState.session_count = (ikState.session_count || 0) + 1;
63403
63682
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
63404
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
63683
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
63405
63684
  } catch (ikErr) {
63406
63685
  }
63407
63686
  try {
@@ -63410,12 +63689,12 @@ async function runWithTUI(task, config, repoPath) {
63410
63689
  ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
63411
63690
  } catch {
63412
63691
  try {
63413
- const archeDir = join65(repoRoot, ".oa", "arche");
63414
- const archeFile = join65(archeDir, "variants.json");
63692
+ const archeDir = join66(repoRoot, ".oa", "arche");
63693
+ const archeFile = join66(archeDir, "variants.json");
63415
63694
  let variants = [];
63416
63695
  try {
63417
- if (existsSync48(archeFile))
63418
- variants = JSON.parse(readFileSync37(archeFile, "utf8"));
63696
+ if (existsSync49(archeFile))
63697
+ variants = JSON.parse(readFileSync38(archeFile, "utf8"));
63419
63698
  } catch {
63420
63699
  }
63421
63700
  variants.push({
@@ -63430,15 +63709,15 @@ async function runWithTUI(task, config, repoPath) {
63430
63709
  });
63431
63710
  if (variants.length > 50)
63432
63711
  variants = variants.slice(-50);
63433
- mkdirSync22(archeDir, { recursive: true });
63434
- writeFileSync21(archeFile, JSON.stringify(variants, null, 2));
63712
+ mkdirSync23(archeDir, { recursive: true });
63713
+ writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
63435
63714
  } catch {
63436
63715
  }
63437
63716
  }
63438
63717
  try {
63439
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63440
- if (existsSync48(metaFile)) {
63441
- const store = JSON.parse(readFileSync37(metaFile, "utf8"));
63718
+ const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
63719
+ if (existsSync49(metaFile)) {
63720
+ const store = JSON.parse(readFileSync38(metaFile, "utf8"));
63442
63721
  const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
63443
63722
  let updated = false;
63444
63723
  for (const item of surfaced) {
@@ -63449,7 +63728,7 @@ async function runWithTUI(task, config, repoPath) {
63449
63728
  updated = true;
63450
63729
  }
63451
63730
  if (updated) {
63452
- writeFileSync21(metaFile, JSON.stringify(store, null, 2));
63731
+ writeFileSync22(metaFile, JSON.stringify(store, null, 2));
63453
63732
  }
63454
63733
  }
63455
63734
  } catch {
@@ -63502,9 +63781,9 @@ Rules:
63502
63781
  try {
63503
63782
  const { initDb: initDb2 } = __require("@open-agents/memory");
63504
63783
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
63505
- const dbDir = join65(repoRoot, ".oa", "memory");
63506
- mkdirSync22(dbDir, { recursive: true });
63507
- const db = initDb2(join65(dbDir, "structured.db"));
63784
+ const dbDir = join66(repoRoot, ".oa", "memory");
63785
+ mkdirSync23(dbDir, { recursive: true });
63786
+ const db = initDb2(join66(dbDir, "structured.db"));
63508
63787
  const memStore = new ProceduralMemoryStore2(db);
63509
63788
  memStore.createWithEmbedding({
63510
63789
  content: content.slice(0, 600),
@@ -63519,12 +63798,12 @@ Rules:
63519
63798
  db.close();
63520
63799
  } catch {
63521
63800
  }
63522
- const metaDir = join65(repoRoot, ".oa", "memory", "metabolism");
63523
- const storeFile = join65(metaDir, "store.json");
63801
+ const metaDir = join66(repoRoot, ".oa", "memory", "metabolism");
63802
+ const storeFile = join66(metaDir, "store.json");
63524
63803
  let store = [];
63525
63804
  try {
63526
- if (existsSync48(storeFile))
63527
- store = JSON.parse(readFileSync37(storeFile, "utf8"));
63805
+ if (existsSync49(storeFile))
63806
+ store = JSON.parse(readFileSync38(storeFile, "utf8"));
63528
63807
  } catch {
63529
63808
  }
63530
63809
  store.push({
@@ -63540,26 +63819,26 @@ Rules:
63540
63819
  });
63541
63820
  if (store.length > 100)
63542
63821
  store = store.slice(-100);
63543
- mkdirSync22(metaDir, { recursive: true });
63544
- writeFileSync21(storeFile, JSON.stringify(store, null, 2));
63822
+ mkdirSync23(metaDir, { recursive: true });
63823
+ writeFileSync22(storeFile, JSON.stringify(store, null, 2));
63545
63824
  }
63546
63825
  }
63547
63826
  } catch {
63548
63827
  }
63549
63828
  try {
63550
- const cohereSettingsFile = join65(repoRoot, ".oa", "settings.json");
63829
+ const cohereSettingsFile = join66(repoRoot, ".oa", "settings.json");
63551
63830
  let cohereActive = false;
63552
63831
  try {
63553
- if (existsSync48(cohereSettingsFile)) {
63554
- const settings = JSON.parse(readFileSync37(cohereSettingsFile, "utf8"));
63832
+ if (existsSync49(cohereSettingsFile)) {
63833
+ const settings = JSON.parse(readFileSync38(cohereSettingsFile, "utf8"));
63555
63834
  cohereActive = settings.cohere === true;
63556
63835
  }
63557
63836
  } catch {
63558
63837
  }
63559
63838
  if (cohereActive) {
63560
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63561
- if (existsSync48(metaFile)) {
63562
- const store = JSON.parse(readFileSync37(metaFile, "utf8"));
63839
+ const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
63840
+ if (existsSync49(metaFile)) {
63841
+ const store = JSON.parse(readFileSync38(metaFile, "utf8"));
63563
63842
  const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
63564
63843
  if (latest && latest.scores?.confidence >= 0.6) {
63565
63844
  try {
@@ -63584,18 +63863,18 @@ Rules:
63584
63863
  }
63585
63864
  } catch (err) {
63586
63865
  try {
63587
- const ikFile = join65(repoRoot, ".oa", "identity", "self-state.json");
63588
- if (existsSync48(ikFile)) {
63589
- const ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
63866
+ const ikFile = join66(repoRoot, ".oa", "identity", "self-state.json");
63867
+ if (existsSync49(ikFile)) {
63868
+ const ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
63590
63869
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
63591
63870
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
63592
63871
  ikState.session_count = (ikState.session_count || 0) + 1;
63593
63872
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
63594
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
63873
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
63595
63874
  }
63596
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63597
- if (existsSync48(metaFile)) {
63598
- const store = JSON.parse(readFileSync37(metaFile, "utf8"));
63875
+ const metaFile = join66(repoRoot, ".oa", "memory", "metabolism", "store.json");
63876
+ if (existsSync49(metaFile)) {
63877
+ const store = JSON.parse(readFileSync38(metaFile, "utf8"));
63599
63878
  const surfaced = store.filter((m) => m.type !== "quarantine" && m.scores?.confidence > 0.15).sort((a, b) => b.scores.utility * b.scores.confidence - a.scores.utility * a.scores.confidence).slice(0, 5);
63600
63879
  for (const item of surfaced) {
63601
63880
  item.accessCount = (item.accessCount || 0) + 1;
@@ -63603,15 +63882,15 @@ Rules:
63603
63882
  item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
63604
63883
  item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
63605
63884
  }
63606
- writeFileSync21(metaFile, JSON.stringify(store, null, 2));
63885
+ writeFileSync22(metaFile, JSON.stringify(store, null, 2));
63607
63886
  }
63608
63887
  try {
63609
- const archeDir = join65(repoRoot, ".oa", "arche");
63610
- const archeFile = join65(archeDir, "variants.json");
63888
+ const archeDir = join66(repoRoot, ".oa", "arche");
63889
+ const archeFile = join66(archeDir, "variants.json");
63611
63890
  let variants = [];
63612
63891
  try {
63613
- if (existsSync48(archeFile))
63614
- variants = JSON.parse(readFileSync37(archeFile, "utf8"));
63892
+ if (existsSync49(archeFile))
63893
+ variants = JSON.parse(readFileSync38(archeFile, "utf8"));
63615
63894
  } catch {
63616
63895
  }
63617
63896
  variants.push({
@@ -63626,8 +63905,8 @@ Rules:
63626
63905
  });
63627
63906
  if (variants.length > 50)
63628
63907
  variants = variants.slice(-50);
63629
- mkdirSync22(archeDir, { recursive: true });
63630
- writeFileSync21(archeFile, JSON.stringify(variants, null, 2));
63908
+ mkdirSync23(archeDir, { recursive: true });
63909
+ writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
63631
63910
  } catch {
63632
63911
  }
63633
63912
  } catch {
@@ -63715,8 +63994,8 @@ var init_run = __esm({
63715
63994
  import { glob } from "glob";
63716
63995
  import ignore from "ignore";
63717
63996
  import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
63718
- import { createHash as createHash4 } from "node:crypto";
63719
- import { join as join66, relative as relative4, extname as extname12, basename as basename16 } from "node:path";
63997
+ import { createHash as createHash5 } from "node:crypto";
63998
+ import { join as join67, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
63720
63999
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
63721
64000
  var init_codebase_indexer = __esm({
63722
64001
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -63760,7 +64039,7 @@ var init_codebase_indexer = __esm({
63760
64039
  const ig = ignore.default();
63761
64040
  if (this.config.respectGitignore) {
63762
64041
  try {
63763
- const gitignoreContent = await readFile23(join66(this.config.rootDir, ".gitignore"), "utf-8");
64042
+ const gitignoreContent = await readFile23(join67(this.config.rootDir, ".gitignore"), "utf-8");
63764
64043
  ig.add(gitignoreContent);
63765
64044
  } catch {
63766
64045
  }
@@ -63775,13 +64054,13 @@ var init_codebase_indexer = __esm({
63775
64054
  for (const relativePath of files) {
63776
64055
  if (ig.ignores(relativePath))
63777
64056
  continue;
63778
- const fullPath = join66(this.config.rootDir, relativePath);
64057
+ const fullPath = join67(this.config.rootDir, relativePath);
63779
64058
  try {
63780
64059
  const fileStat = await stat4(fullPath);
63781
64060
  if (fileStat.size > this.config.maxFileSize)
63782
64061
  continue;
63783
64062
  const content = await readFile23(fullPath);
63784
- const hash = createHash4("sha256").update(content).digest("hex");
64063
+ const hash = createHash5("sha256").update(content).digest("hex");
63785
64064
  const ext = extname12(relativePath);
63786
64065
  indexed.push({
63787
64066
  path: fullPath,
@@ -63798,7 +64077,7 @@ var init_codebase_indexer = __esm({
63798
64077
  }
63799
64078
  buildTree(files) {
63800
64079
  const root = {
63801
- name: basename16(this.config.rootDir),
64080
+ name: basename17(this.config.rootDir),
63802
64081
  path: this.config.rootDir,
63803
64082
  type: "directory",
63804
64083
  children: []
@@ -63821,7 +64100,7 @@ var init_codebase_indexer = __esm({
63821
64100
  if (!child) {
63822
64101
  child = {
63823
64102
  name: part,
63824
- path: join66(current.path, part),
64103
+ path: join67(current.path, part),
63825
64104
  type: "directory",
63826
64105
  children: []
63827
64106
  };
@@ -63904,13 +64183,13 @@ __export(index_repo_exports, {
63904
64183
  indexRepoCommand: () => indexRepoCommand
63905
64184
  });
63906
64185
  import { resolve as resolve32 } from "node:path";
63907
- import { existsSync as existsSync49, statSync as statSync16 } from "node:fs";
64186
+ import { existsSync as existsSync50, statSync as statSync16 } from "node:fs";
63908
64187
  import { cwd as cwd2 } from "node:process";
63909
64188
  async function indexRepoCommand(opts, _config) {
63910
64189
  const repoRoot = resolve32(opts.repoPath ?? cwd2());
63911
64190
  printHeader("Index Repository");
63912
64191
  printInfo(`Indexing: ${repoRoot}`);
63913
- if (!existsSync49(repoRoot)) {
64192
+ if (!existsSync50(repoRoot)) {
63914
64193
  printError(`Path does not exist: ${repoRoot}`);
63915
64194
  process.exit(1);
63916
64195
  }
@@ -64162,7 +64441,7 @@ var config_exports = {};
64162
64441
  __export(config_exports, {
64163
64442
  configCommand: () => configCommand
64164
64443
  });
64165
- import { join as join67, resolve as resolve33 } from "node:path";
64444
+ import { join as join68, resolve as resolve33 } from "node:path";
64166
64445
  import { homedir as homedir17 } from "node:os";
64167
64446
  import { cwd as cwd3 } from "node:process";
64168
64447
  function redactIfSensitive(key, value) {
@@ -64245,7 +64524,7 @@ function handleShow(opts, config) {
64245
64524
  }
64246
64525
  }
64247
64526
  printSection("Config File");
64248
- printInfo(`~/.open-agents/config.json (${join67(homedir17(), ".open-agents", "config.json")})`);
64527
+ printInfo(`~/.open-agents/config.json (${join68(homedir17(), ".open-agents", "config.json")})`);
64249
64528
  printSection("Priority Chain");
64250
64529
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
64251
64530
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -64284,7 +64563,7 @@ function handleSet(opts, _config) {
64284
64563
  const coerced = coerceForSettings(key, value);
64285
64564
  saveProjectSettings(repoRoot, { [key]: coerced });
64286
64565
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
64287
- printInfo(`Saved to ${join67(repoRoot, ".oa", "settings.json")}`);
64566
+ printInfo(`Saved to ${join68(repoRoot, ".oa", "settings.json")}`);
64288
64567
  printInfo("This override applies only when running in this workspace.");
64289
64568
  } catch (err) {
64290
64569
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -64542,8 +64821,8 @@ __export(eval_exports, {
64542
64821
  evalCommand: () => evalCommand
64543
64822
  });
64544
64823
  import { tmpdir as tmpdir10 } from "node:os";
64545
- import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync22 } from "node:fs";
64546
- import { join as join68 } from "node:path";
64824
+ import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23 } from "node:fs";
64825
+ import { join as join69 } from "node:path";
64547
64826
  async function evalCommand(opts, config) {
64548
64827
  const suiteName = opts.suite ?? "basic";
64549
64828
  const suite = SUITES[suiteName];
@@ -64668,9 +64947,9 @@ async function evalCommand(opts, config) {
64668
64947
  process.exit(failed > 0 ? 1 : 0);
64669
64948
  }
64670
64949
  function createTempEvalRepo() {
64671
- const dir = join68(tmpdir10(), `open-agents-eval-${Date.now()}`);
64672
- mkdirSync23(dir, { recursive: true });
64673
- writeFileSync22(join68(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
64950
+ const dir = join69(tmpdir10(), `open-agents-eval-${Date.now()}`);
64951
+ mkdirSync24(dir, { recursive: true });
64952
+ writeFileSync23(join69(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
64674
64953
  return dir;
64675
64954
  }
64676
64955
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -64730,7 +65009,7 @@ init_updater();
64730
65009
  import { parseArgs as nodeParseArgs2 } from "node:util";
64731
65010
  import { createRequire as createRequire3 } from "node:module";
64732
65011
  import { fileURLToPath as fileURLToPath13 } from "node:url";
64733
- import { dirname as dirname21, join as join69 } from "node:path";
65012
+ import { dirname as dirname21, join as join70 } from "node:path";
64734
65013
 
64735
65014
  // packages/cli/dist/cli.js
64736
65015
  import { createInterface } from "node:readline";
@@ -64837,7 +65116,7 @@ init_output();
64837
65116
  function getVersion4() {
64838
65117
  try {
64839
65118
  const require2 = createRequire3(import.meta.url);
64840
- const pkgPath = join69(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
65119
+ const pkgPath = join70(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
64841
65120
  const pkg = require2(pkgPath);
64842
65121
  return pkg.version;
64843
65122
  } catch {