open-agents-ai 0.169.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 +1111 -834
  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
  }
@@ -27819,9 +28095,9 @@ ${transcript}`
27819
28095
  });
27820
28096
 
27821
28097
  // packages/orchestrator/dist/nexusBackend.js
27822
- 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";
27823
28099
  import { watch as fsWatch } from "node:fs";
27824
- import { join as join46 } from "node:path";
28100
+ import { join as join47 } from "node:path";
27825
28101
  import { tmpdir as tmpdir7 } from "node:os";
27826
28102
  import { randomBytes as randomBytes11 } from "node:crypto";
27827
28103
  var NexusAgenticBackend;
@@ -27971,8 +28247,8 @@ var init_nexusBackend = __esm({
27971
28247
  * Falls back to unary + word-split if streaming setup fails.
27972
28248
  */
27973
28249
  async *chatCompletionStream(request) {
27974
- const streamFile = join46(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
27975
- writeFileSync10(streamFile, "", "utf8");
28250
+ const streamFile = join47(tmpdir7(), `nexus-stream-${randomBytes11(6).toString("hex")}.jsonl`);
28251
+ writeFileSync11(streamFile, "", "utf8");
27976
28252
  const daemonArgs = {
27977
28253
  model: this.model,
27978
28254
  messages: JSON.stringify(request.messages),
@@ -27992,7 +28268,7 @@ var init_nexusBackend = __esm({
27992
28268
  } catch (sendErr) {
27993
28269
  this.consecutiveFailures++;
27994
28270
  try {
27995
- unlinkSync4(streamFile);
28271
+ unlinkSync5(streamFile);
27996
28272
  } catch {
27997
28273
  }
27998
28274
  throw sendErr;
@@ -28007,7 +28283,7 @@ var init_nexusBackend = __esm({
28007
28283
  }
28008
28284
  if (!isStreaming) {
28009
28285
  try {
28010
- unlinkSync4(streamFile);
28286
+ unlinkSync5(streamFile);
28011
28287
  } catch {
28012
28288
  }
28013
28289
  let parsed;
@@ -28163,7 +28439,7 @@ var init_nexusBackend = __esm({
28163
28439
  }
28164
28440
  } finally {
28165
28441
  try {
28166
- unlinkSync4(streamFile);
28442
+ unlinkSync5(streamFile);
28167
28443
  } catch {
28168
28444
  }
28169
28445
  }
@@ -29006,9 +29282,9 @@ __export(listen_exports, {
29006
29282
  isVideoPath: () => isVideoPath,
29007
29283
  waitForTranscribeCli: () => waitForTranscribeCli
29008
29284
  });
29009
- import { spawn as spawn16, execSync as execSync24 } from "node:child_process";
29010
- import { existsSync as existsSync31, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readdirSync as readdirSync7 } from "node:fs";
29011
- 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";
29012
29288
  import { homedir as homedir10 } from "node:os";
29013
29289
  import { fileURLToPath as fileURLToPath8 } from "node:url";
29014
29290
  import { EventEmitter } from "node:events";
@@ -29028,7 +29304,7 @@ function findMicCaptureCommand() {
29028
29304
  const platform6 = process.platform;
29029
29305
  if (platform6 === "linux") {
29030
29306
  try {
29031
- execSync24("which arecord", { stdio: "pipe" });
29307
+ execSync25("which arecord", { stdio: "pipe" });
29032
29308
  return {
29033
29309
  cmd: "arecord",
29034
29310
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -29038,7 +29314,7 @@ function findMicCaptureCommand() {
29038
29314
  }
29039
29315
  if (platform6 === "darwin") {
29040
29316
  try {
29041
- execSync24("which sox", { stdio: "pipe" });
29317
+ execSync25("which sox", { stdio: "pipe" });
29042
29318
  return {
29043
29319
  cmd: "sox",
29044
29320
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -29047,7 +29323,7 @@ function findMicCaptureCommand() {
29047
29323
  }
29048
29324
  }
29049
29325
  try {
29050
- execSync24("which ffmpeg", { stdio: "pipe" });
29326
+ execSync25("which ffmpeg", { stdio: "pipe" });
29051
29327
  if (platform6 === "linux") {
29052
29328
  return {
29053
29329
  cmd: "ffmpeg",
@@ -29094,39 +29370,39 @@ function findMicCaptureCommand() {
29094
29370
  function findLiveWhisperScript() {
29095
29371
  const thisDir = dirname14(fileURLToPath8(import.meta.url));
29096
29372
  const candidates = [
29097
- join47(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
29098
- join47(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
29099
- 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"),
29100
29376
  // npm install layout — scripts bundled alongside dist
29101
- join47(thisDir, "../scripts/live-whisper.py"),
29102
- join47(thisDir, "../../scripts/live-whisper.py")
29377
+ join48(thisDir, "../scripts/live-whisper.py"),
29378
+ join48(thisDir, "../../scripts/live-whisper.py")
29103
29379
  ];
29104
29380
  for (const p of candidates) {
29105
- if (existsSync31(p))
29381
+ if (existsSync32(p))
29106
29382
  return p;
29107
29383
  }
29108
29384
  try {
29109
- const globalRoot = execSync24("npm root -g", {
29385
+ const globalRoot = execSync25("npm root -g", {
29110
29386
  encoding: "utf-8",
29111
29387
  timeout: 5e3,
29112
29388
  stdio: ["pipe", "pipe", "pipe"]
29113
29389
  }).trim();
29114
29390
  const candidates2 = [
29115
- join47(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
29116
- 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")
29117
29393
  ];
29118
29394
  for (const p of candidates2) {
29119
- if (existsSync31(p))
29395
+ if (existsSync32(p))
29120
29396
  return p;
29121
29397
  }
29122
29398
  } catch {
29123
29399
  }
29124
- const nvmBase = join47(homedir10(), ".nvm", "versions", "node");
29125
- if (existsSync31(nvmBase)) {
29400
+ const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
29401
+ if (existsSync32(nvmBase)) {
29126
29402
  try {
29127
- for (const ver of readdirSync7(nvmBase)) {
29128
- const p = join47(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
29129
- 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))
29130
29406
  return p;
29131
29407
  }
29132
29408
  } catch {
@@ -29139,12 +29415,12 @@ function ensureTranscribeCliBackground() {
29139
29415
  return;
29140
29416
  _bgInstallPromise = (async () => {
29141
29417
  try {
29142
- const globalRoot = execSync24("npm root -g", {
29418
+ const globalRoot = execSync25("npm root -g", {
29143
29419
  encoding: "utf-8",
29144
29420
  timeout: 5e3,
29145
29421
  stdio: ["pipe", "pipe", "pipe"]
29146
29422
  }).trim();
29147
- if (existsSync31(join47(globalRoot, "transcribe-cli", "dist", "index.js"))) {
29423
+ if (existsSync32(join48(globalRoot, "transcribe-cli", "dist", "index.js"))) {
29148
29424
  return true;
29149
29425
  }
29150
29426
  } catch {
@@ -29345,7 +29621,7 @@ var init_listen = __esm({
29345
29621
  }
29346
29622
  if (!this.transcribeCliAvailable) {
29347
29623
  try {
29348
- execSync24("which transcribe-cli", { stdio: "pipe" });
29624
+ execSync25("which transcribe-cli", { stdio: "pipe" });
29349
29625
  this.transcribeCliAvailable = true;
29350
29626
  } catch {
29351
29627
  this.transcribeCliAvailable = false;
@@ -29362,29 +29638,29 @@ var init_listen = __esm({
29362
29638
  } catch {
29363
29639
  }
29364
29640
  try {
29365
- const globalRoot = execSync24("npm root -g", {
29641
+ const globalRoot = execSync25("npm root -g", {
29366
29642
  encoding: "utf-8",
29367
29643
  timeout: 5e3,
29368
29644
  stdio: ["pipe", "pipe", "pipe"]
29369
29645
  }).trim();
29370
- const tcPath = join47(globalRoot, "transcribe-cli");
29371
- if (existsSync31(join47(tcPath, "dist", "index.js"))) {
29646
+ const tcPath = join48(globalRoot, "transcribe-cli");
29647
+ if (existsSync32(join48(tcPath, "dist", "index.js"))) {
29372
29648
  const { createRequire: createRequire4 } = await import("node:module");
29373
29649
  const req = createRequire4(import.meta.url);
29374
- return req(join47(tcPath, "dist", "index.js"));
29650
+ return req(join48(tcPath, "dist", "index.js"));
29375
29651
  }
29376
29652
  } catch {
29377
29653
  }
29378
- const nvmBase = join47(homedir10(), ".nvm", "versions", "node");
29379
- if (existsSync31(nvmBase)) {
29654
+ const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
29655
+ if (existsSync32(nvmBase)) {
29380
29656
  try {
29381
- const { readdirSync: readdirSync19 } = await import("node:fs");
29382
- for (const ver of readdirSync19(nvmBase)) {
29383
- const tcPath = join47(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
29384
- 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"))) {
29385
29661
  const { createRequire: createRequire4 } = await import("node:module");
29386
29662
  const req = createRequire4(import.meta.url);
29387
- return req(join47(tcPath, "dist", "index.js"));
29663
+ return req(join48(tcPath, "dist", "index.js"));
29388
29664
  }
29389
29665
  }
29390
29666
  } catch {
@@ -29412,7 +29688,7 @@ var init_listen = __esm({
29412
29688
  }
29413
29689
  if (!tc) {
29414
29690
  try {
29415
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29691
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29416
29692
  this.transcribeCliAvailable = null;
29417
29693
  tc = await this.loadTranscribeCli();
29418
29694
  } catch {
@@ -29595,7 +29871,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29595
29871
  }
29596
29872
  if (!tc) {
29597
29873
  try {
29598
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29874
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29599
29875
  this.transcribeCliAvailable = null;
29600
29876
  tc = await this.loadTranscribeCli();
29601
29877
  } catch {
@@ -29649,7 +29925,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29649
29925
  }
29650
29926
  if (!tc) {
29651
29927
  try {
29652
- execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29928
+ execSync25("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29653
29929
  this.transcribeCliAvailable = null;
29654
29930
  tc = await this.loadTranscribeCli();
29655
29931
  } catch {
@@ -29665,11 +29941,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
29665
29941
  wordTimestamps: false
29666
29942
  });
29667
29943
  if (outputDir) {
29668
- const { basename: basename17 } = await import("node:path");
29669
- const transcriptDir = join47(outputDir, ".oa", "transcripts");
29670
- mkdirSync10(transcriptDir, { recursive: true });
29671
- const outFile = join47(transcriptDir, `${basename17(filePath)}.txt`);
29672
- 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");
29673
29949
  }
29674
29950
  return {
29675
29951
  text: result.text,
@@ -31917,7 +32193,7 @@ var require_websocket = __commonJS({
31917
32193
  var http = __require("http");
31918
32194
  var net = __require("net");
31919
32195
  var tls = __require("tls");
31920
- var { randomBytes: randomBytes15, createHash: createHash5 } = __require("crypto");
32196
+ var { randomBytes: randomBytes15, createHash: createHash6 } = __require("crypto");
31921
32197
  var { Duplex, Readable } = __require("stream");
31922
32198
  var { URL: URL3 } = __require("url");
31923
32199
  var PerMessageDeflate = require_permessage_deflate();
@@ -32577,7 +32853,7 @@ var require_websocket = __commonJS({
32577
32853
  abortHandshake(websocket, socket, "Invalid Upgrade header");
32578
32854
  return;
32579
32855
  }
32580
- const digest = createHash5("sha1").update(key + GUID).digest("base64");
32856
+ const digest = createHash6("sha1").update(key + GUID).digest("base64");
32581
32857
  if (res.headers["sec-websocket-accept"] !== digest) {
32582
32858
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
32583
32859
  return;
@@ -32944,7 +33220,7 @@ var require_websocket_server = __commonJS({
32944
33220
  var EventEmitter7 = __require("events");
32945
33221
  var http = __require("http");
32946
33222
  var { Duplex } = __require("stream");
32947
- var { createHash: createHash5 } = __require("crypto");
33223
+ var { createHash: createHash6 } = __require("crypto");
32948
33224
  var extension = require_extension();
32949
33225
  var PerMessageDeflate = require_permessage_deflate();
32950
33226
  var subprotocol = require_subprotocol();
@@ -33245,7 +33521,7 @@ var require_websocket_server = __commonJS({
33245
33521
  );
33246
33522
  }
33247
33523
  if (this._state > RUNNING) return abortHandshake(socket, 503);
33248
- const digest = createHash5("sha1").update(key + GUID).digest("base64");
33524
+ const digest = createHash6("sha1").update(key + GUID).digest("base64");
33249
33525
  const headers = [
33250
33526
  "HTTP/1.1 101 Switching Protocols",
33251
33527
  "Upgrade: websocket",
@@ -34156,7 +34432,7 @@ var init_render = __esm({
34156
34432
 
34157
34433
  // packages/cli/dist/tui/voice-session.js
34158
34434
  import { createServer as createServer2 } from "node:http";
34159
- import { spawn as spawn17, execSync as execSync25 } from "node:child_process";
34435
+ import { spawn as spawn17, execSync as execSync26 } from "node:child_process";
34160
34436
  import { EventEmitter as EventEmitter2 } from "node:events";
34161
34437
  function generateFrontendHTML() {
34162
34438
  return `<!DOCTYPE html>
@@ -34889,8 +35165,8 @@ import { EventEmitter as EventEmitter3 } from "node:events";
34889
35165
  import { randomBytes as randomBytes12 } from "node:crypto";
34890
35166
  import { URL as URL2 } from "node:url";
34891
35167
  import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
34892
- 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";
34893
- 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";
34894
35170
  function cleanForwardHeaders(raw, targetHost) {
34895
35171
  const out = {};
34896
35172
  for (const [key, value] of Object.entries(raw)) {
@@ -34918,10 +35194,10 @@ function fmtTokens(n) {
34918
35194
  }
34919
35195
  function readExposeState(stateDir) {
34920
35196
  try {
34921
- const path = join48(stateDir, STATE_FILE_NAME);
34922
- if (!existsSync32(path))
35197
+ const path = join49(stateDir, STATE_FILE_NAME);
35198
+ if (!existsSync33(path))
34923
35199
  return null;
34924
- const raw = readFileSync23(path, "utf8");
35200
+ const raw = readFileSync24(path, "utf8");
34925
35201
  const data = JSON.parse(raw);
34926
35202
  if (!data.pid || !data.tunnelUrl || !data.authKey || !data.proxyPort)
34927
35203
  return null;
@@ -34932,14 +35208,14 @@ function readExposeState(stateDir) {
34932
35208
  }
34933
35209
  function writeExposeState(stateDir, state) {
34934
35210
  try {
34935
- mkdirSync11(stateDir, { recursive: true });
34936
- 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));
34937
35213
  } catch {
34938
35214
  }
34939
35215
  }
34940
35216
  function removeExposeState(stateDir) {
34941
35217
  try {
34942
- unlinkSync5(join48(stateDir, STATE_FILE_NAME));
35218
+ unlinkSync6(join49(stateDir, STATE_FILE_NAME));
34943
35219
  } catch {
34944
35220
  }
34945
35221
  }
@@ -35028,10 +35304,10 @@ async function collectSystemMetricsAsync() {
35028
35304
  }
35029
35305
  function readP2PExposeState(stateDir) {
35030
35306
  try {
35031
- const path = join48(stateDir, P2P_STATE_FILE_NAME);
35032
- if (!existsSync32(path))
35307
+ const path = join49(stateDir, P2P_STATE_FILE_NAME);
35308
+ if (!existsSync33(path))
35033
35309
  return null;
35034
- const raw = readFileSync23(path, "utf8");
35310
+ const raw = readFileSync24(path, "utf8");
35035
35311
  const data = JSON.parse(raw);
35036
35312
  if (!data.peerId || !data.authKey)
35037
35313
  return null;
@@ -35042,14 +35318,14 @@ function readP2PExposeState(stateDir) {
35042
35318
  }
35043
35319
  function writeP2PExposeState(stateDir, state) {
35044
35320
  try {
35045
- mkdirSync11(stateDir, { recursive: true });
35046
- 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));
35047
35323
  } catch {
35048
35324
  }
35049
35325
  }
35050
35326
  function removeP2PExposeState(stateDir) {
35051
35327
  try {
35052
- unlinkSync5(join48(stateDir, P2P_STATE_FILE_NAME));
35328
+ unlinkSync6(join49(stateDir, P2P_STATE_FILE_NAME));
35053
35329
  } catch {
35054
35330
  }
35055
35331
  }
@@ -35897,10 +36173,10 @@ ${this.formatConnectionInfo()}`);
35897
36173
  throw new Error(`Expose failed: ${exposeResult.error}`);
35898
36174
  }
35899
36175
  const nexusDir = this._nexusTool.getNexusDir();
35900
- const statusPath = join48(nexusDir, "status.json");
36176
+ const statusPath = join49(nexusDir, "status.json");
35901
36177
  for (let i = 0; i < 80; i++) {
35902
36178
  try {
35903
- const raw = readFileSync23(statusPath, "utf8");
36179
+ const raw = readFileSync24(statusPath, "utf8");
35904
36180
  if (raw.length > 10) {
35905
36181
  const status = JSON.parse(raw);
35906
36182
  if (status.connected && status.peerId) {
@@ -35931,9 +36207,9 @@ ${this.formatConnectionInfo()}`);
35931
36207
  });
35932
36208
  }
35933
36209
  try {
35934
- const invocDir = join48(nexusDir, "invocations");
35935
- if (existsSync32(invocDir)) {
35936
- 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;
35937
36213
  this._stats.totalRequests = this._prevInvocCount;
35938
36214
  }
35939
36215
  } catch {
@@ -35961,13 +36237,13 @@ ${this.formatConnectionInfo()}`);
35961
36237
  if (!state)
35962
36238
  return null;
35963
36239
  const nexusDir = nexusTool.getNexusDir();
35964
- const statusPath = join48(nexusDir, "status.json");
36240
+ const statusPath = join49(nexusDir, "status.json");
35965
36241
  try {
35966
- if (!existsSync32(statusPath)) {
36242
+ if (!existsSync33(statusPath)) {
35967
36243
  removeP2PExposeState(stateDir);
35968
36244
  return null;
35969
36245
  }
35970
- const status = JSON.parse(readFileSync23(statusPath, "utf8"));
36246
+ const status = JSON.parse(readFileSync24(statusPath, "utf8"));
35971
36247
  if (!status.connected || !status.peerId) {
35972
36248
  removeP2PExposeState(stateDir);
35973
36249
  return null;
@@ -36020,10 +36296,10 @@ ${this.formatConnectionInfo()}`);
36020
36296
  let lastMeteringLineCount = 0;
36021
36297
  this._activityPollTimer = setInterval(() => {
36022
36298
  try {
36023
- const invocDir = join48(nexusDir, "invocations");
36024
- if (!existsSync32(invocDir))
36299
+ const invocDir = join49(nexusDir, "invocations");
36300
+ if (!existsSync33(invocDir))
36025
36301
  return;
36026
- const files = readdirSync8(invocDir).filter((f) => f.endsWith(".json"));
36302
+ const files = readdirSync9(invocDir).filter((f) => f.endsWith(".json"));
36027
36303
  const invocCount = files.length;
36028
36304
  const newRequests = invocCount - this._prevInvocCount;
36029
36305
  if (newRequests > 0) {
@@ -36036,17 +36312,17 @@ ${this.formatConnectionInfo()}`);
36036
36312
  let recentActive = 0;
36037
36313
  for (const f of files.slice(-10)) {
36038
36314
  try {
36039
- const st = statSync11(join48(invocDir, f));
36315
+ const st = statSync11(join49(invocDir, f));
36040
36316
  if (now - st.mtimeMs < 1e4)
36041
36317
  recentActive++;
36042
36318
  } catch {
36043
36319
  }
36044
36320
  }
36045
- const meteringFile = join48(nexusDir, "metering.jsonl");
36321
+ const meteringFile = join49(nexusDir, "metering.jsonl");
36046
36322
  let meteringLines = lastMeteringLineCount;
36047
36323
  try {
36048
- if (existsSync32(meteringFile)) {
36049
- const content = readFileSync23(meteringFile, "utf8");
36324
+ if (existsSync33(meteringFile)) {
36325
+ const content = readFileSync24(meteringFile, "utf8");
36050
36326
  meteringLines = content.split("\n").filter((l) => l.trim()).length;
36051
36327
  }
36052
36328
  } catch {
@@ -36072,9 +36348,9 @@ ${this.formatConnectionInfo()}`);
36072
36348
  this._activityPollTimer.unref();
36073
36349
  this._pollTimer = setInterval(() => {
36074
36350
  try {
36075
- const statusPath = join48(nexusDir, "status.json");
36076
- if (existsSync32(statusPath)) {
36077
- 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"));
36078
36354
  if (status.peerId && !this._peerId) {
36079
36355
  this._peerId = status.peerId;
36080
36356
  }
@@ -36083,9 +36359,9 @@ ${this.formatConnectionInfo()}`);
36083
36359
  } catch {
36084
36360
  }
36085
36361
  try {
36086
- const invocDir = join48(nexusDir, "invocations");
36087
- if (existsSync32(invocDir)) {
36088
- const files = readdirSync8(invocDir);
36362
+ const invocDir = join49(nexusDir, "invocations");
36363
+ if (existsSync33(invocDir)) {
36364
+ const files = readdirSync9(invocDir);
36089
36365
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
36090
36366
  if (invocCount > this._stats.totalRequests) {
36091
36367
  this._stats.totalRequests = invocCount;
@@ -36095,9 +36371,9 @@ ${this.formatConnectionInfo()}`);
36095
36371
  } catch {
36096
36372
  }
36097
36373
  try {
36098
- const meteringFile = join48(nexusDir, "metering.jsonl");
36099
- if (existsSync32(meteringFile)) {
36100
- const content = readFileSync23(meteringFile, "utf8");
36374
+ const meteringFile = join49(nexusDir, "metering.jsonl");
36375
+ if (existsSync33(meteringFile)) {
36376
+ const content = readFileSync24(meteringFile, "utf8");
36101
36377
  if (content.length > lastMeteringSize) {
36102
36378
  const newContent = content.slice(lastMeteringSize);
36103
36379
  lastMeteringSize = content.length;
@@ -36305,9 +36581,9 @@ var init_types = __esm({
36305
36581
  });
36306
36582
 
36307
36583
  // packages/cli/dist/tui/p2p/secret-vault.js
36308
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes13, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
36309
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync13, existsSync as existsSync33, mkdirSync as mkdirSync12 } from "node:fs";
36310
- 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";
36311
36587
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
36312
36588
  var init_secret_vault = __esm({
36313
36589
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -36519,18 +36795,18 @@ var init_secret_vault = __esm({
36519
36795
  const tag = cipher.getAuthTag();
36520
36796
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
36521
36797
  const dir = dirname15(this.storePath);
36522
- if (!existsSync33(dir))
36523
- mkdirSync12(dir, { recursive: true });
36524
- writeFileSync13(this.storePath, blob, { mode: 384 });
36798
+ if (!existsSync34(dir))
36799
+ mkdirSync13(dir, { recursive: true });
36800
+ writeFileSync14(this.storePath, blob, { mode: 384 });
36525
36801
  }
36526
36802
  /**
36527
36803
  * Load vault from disk, decrypting with the given passphrase.
36528
36804
  * Returns the number of secrets loaded.
36529
36805
  */
36530
36806
  load(passphrase) {
36531
- if (!this.storePath || !existsSync33(this.storePath))
36807
+ if (!this.storePath || !existsSync34(this.storePath))
36532
36808
  return 0;
36533
- const blob = readFileSync24(this.storePath);
36809
+ const blob = readFileSync25(this.storePath);
36534
36810
  if (blob.length < SALT_LEN + IV_LEN + 16) {
36535
36811
  throw new Error("Vault file is corrupted (too small)");
36536
36812
  }
@@ -36556,7 +36832,7 @@ var init_secret_vault = __esm({
36556
36832
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
36557
36833
  fingerprint() {
36558
36834
  const names = Array.from(this.secrets.keys()).sort();
36559
- const hash = createHash2("sha256");
36835
+ const hash = createHash3("sha256");
36560
36836
  for (const name of names) {
36561
36837
  hash.update(name + ":");
36562
36838
  hash.update(this.secrets.get(name).value);
@@ -36571,7 +36847,7 @@ var init_secret_vault = __esm({
36571
36847
  // packages/cli/dist/tui/p2p/peer-mesh.js
36572
36848
  import { EventEmitter as EventEmitter4 } from "node:events";
36573
36849
  import { createServer as createServer4 } from "node:http";
36574
- import { randomBytes as randomBytes14, createHash as createHash3, generateKeyPairSync } from "node:crypto";
36850
+ import { randomBytes as randomBytes14, createHash as createHash4, generateKeyPairSync } from "node:crypto";
36575
36851
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
36576
36852
  var init_peer_mesh = __esm({
36577
36853
  "packages/cli/dist/tui/p2p/peer-mesh.js"() {
@@ -36620,7 +36896,7 @@ var init_peer_mesh = __esm({
36620
36896
  const { publicKey, privateKey } = generateKeyPairSync("ed25519");
36621
36897
  this.publicKey = publicKey.export({ type: "spki", format: "der" });
36622
36898
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
36623
- 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);
36624
36900
  this.capabilities = options.capabilities;
36625
36901
  this.displayName = options.displayName;
36626
36902
  this._authKey = options.authKey ?? randomBytes14(24).toString("base64url");
@@ -37651,26 +37927,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
37651
37927
  async function fetchPeerModels(peerId, authKey) {
37652
37928
  try {
37653
37929
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
37654
- const { existsSync: existsSync50, readFileSync: readFileSync38 } = await import("node:fs");
37655
- 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");
37656
37932
  const cwd4 = process.cwd();
37657
37933
  const nexusTool = new NexusTool2(cwd4);
37658
37934
  const nexusDir = nexusTool.getNexusDir();
37659
37935
  let isLocalPeer = false;
37660
37936
  try {
37661
- const statusPath = join70(nexusDir, "status.json");
37662
- if (existsSync50(statusPath)) {
37663
- 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"));
37664
37940
  if (status.peerId === peerId)
37665
37941
  isLocalPeer = true;
37666
37942
  }
37667
37943
  } catch {
37668
37944
  }
37669
37945
  if (isLocalPeer) {
37670
- const pricingPath = join70(nexusDir, "pricing.json");
37671
- if (existsSync50(pricingPath)) {
37946
+ const pricingPath = join71(nexusDir, "pricing.json");
37947
+ if (existsSync51(pricingPath)) {
37672
37948
  try {
37673
- const pricing = JSON.parse(readFileSync38(pricingPath, "utf8"));
37949
+ const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
37674
37950
  const localModels = (pricing.models || []).map((m) => ({
37675
37951
  name: m.model || "unknown",
37676
37952
  size: m.parameterSize || "",
@@ -37684,10 +37960,10 @@ async function fetchPeerModels(peerId, authKey) {
37684
37960
  }
37685
37961
  }
37686
37962
  }
37687
- const cachePath = join70(nexusDir, "peer-models-cache.json");
37688
- if (existsSync50(cachePath)) {
37963
+ const cachePath = join71(nexusDir, "peer-models-cache.json");
37964
+ if (existsSync51(cachePath)) {
37689
37965
  try {
37690
- const cache4 = JSON.parse(readFileSync38(cachePath, "utf8"));
37966
+ const cache4 = JSON.parse(readFileSync39(cachePath, "utf8"));
37691
37967
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
37692
37968
  const age = Date.now() - new Date(cache4.cachedAt).getTime();
37693
37969
  if (age < 5 * 60 * 1e3) {
@@ -37802,10 +38078,10 @@ async function fetchPeerModels(peerId, authKey) {
37802
38078
  } catch {
37803
38079
  }
37804
38080
  if (isLocalPeer) {
37805
- const pricingPath = join70(nexusDir, "pricing.json");
37806
- if (existsSync50(pricingPath)) {
38081
+ const pricingPath = join71(nexusDir, "pricing.json");
38082
+ if (existsSync51(pricingPath)) {
37807
38083
  try {
37808
- const pricing = JSON.parse(readFileSync38(pricingPath, "utf8"));
38084
+ const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
37809
38085
  return (pricing.models || []).map((m) => ({
37810
38086
  name: m.model || "unknown",
37811
38087
  size: m.parameterSize || "",
@@ -38085,17 +38361,17 @@ var init_render2 = __esm({
38085
38361
  });
38086
38362
 
38087
38363
  // packages/prompts/dist/promptLoader.js
38088
- import { readFileSync as readFileSync25, existsSync as existsSync34 } from "node:fs";
38089
- 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";
38090
38366
  import { fileURLToPath as fileURLToPath9 } from "node:url";
38091
38367
  function loadPrompt2(promptPath, vars) {
38092
38368
  let content = cache2.get(promptPath);
38093
38369
  if (content === void 0) {
38094
- const fullPath = join50(PROMPTS_DIR2, promptPath);
38095
- if (!existsSync34(fullPath)) {
38370
+ const fullPath = join51(PROMPTS_DIR2, promptPath);
38371
+ if (!existsSync35(fullPath)) {
38096
38372
  throw new Error(`Prompt file not found: ${fullPath}`);
38097
38373
  }
38098
- content = readFileSync25(fullPath, "utf-8");
38374
+ content = readFileSync26(fullPath, "utf-8");
38099
38375
  cache2.set(promptPath, content);
38100
38376
  }
38101
38377
  if (!vars)
@@ -38108,9 +38384,9 @@ var init_promptLoader2 = __esm({
38108
38384
  "use strict";
38109
38385
  __filename2 = fileURLToPath9(import.meta.url);
38110
38386
  __dirname5 = dirname16(__filename2);
38111
- devPath = join50(__dirname5, "..", "templates");
38112
- publishedPath = join50(__dirname5, "..", "prompts", "templates");
38113
- PROMPTS_DIR2 = existsSync34(devPath) ? devPath : publishedPath;
38387
+ devPath = join51(__dirname5, "..", "templates");
38388
+ publishedPath = join51(__dirname5, "..", "prompts", "templates");
38389
+ PROMPTS_DIR2 = existsSync35(devPath) ? devPath : publishedPath;
38114
38390
  cache2 = /* @__PURE__ */ new Map();
38115
38391
  }
38116
38392
  });
@@ -38221,7 +38497,7 @@ var init_task_templates = __esm({
38221
38497
  });
38222
38498
 
38223
38499
  // packages/prompts/dist/index.js
38224
- import { join as join51, dirname as dirname17 } from "node:path";
38500
+ import { join as join52, dirname as dirname17 } from "node:path";
38225
38501
  import { fileURLToPath as fileURLToPath10 } from "node:url";
38226
38502
  var _dir, _packageRoot;
38227
38503
  var init_dist6 = __esm({
@@ -38232,7 +38508,7 @@ var init_dist6 = __esm({
38232
38508
  init_task_templates();
38233
38509
  init_render2();
38234
38510
  _dir = dirname17(fileURLToPath10(import.meta.url));
38235
- _packageRoot = join51(_dir, "..");
38511
+ _packageRoot = join52(_dir, "..");
38236
38512
  }
38237
38513
  });
38238
38514
 
@@ -38265,21 +38541,21 @@ __export(oa_directory_exports, {
38265
38541
  writeIndexData: () => writeIndexData,
38266
38542
  writeIndexMeta: () => writeIndexMeta
38267
38543
  });
38268
- 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";
38269
- 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";
38270
38546
  import { homedir as homedir11 } from "node:os";
38271
38547
  function initOaDirectory(repoRoot) {
38272
- const oaPath = join52(repoRoot, OA_DIR);
38548
+ const oaPath = join53(repoRoot, OA_DIR);
38273
38549
  for (const sub of SUBDIRS) {
38274
- mkdirSync13(join52(oaPath, sub), { recursive: true });
38550
+ mkdirSync14(join53(oaPath, sub), { recursive: true });
38275
38551
  }
38276
38552
  try {
38277
- const gitignorePath = join52(repoRoot, ".gitignore");
38553
+ const gitignorePath = join53(repoRoot, ".gitignore");
38278
38554
  const settingsPattern = ".oa/settings.json";
38279
- if (existsSync35(gitignorePath)) {
38280
- const content = readFileSync26(gitignorePath, "utf-8");
38555
+ if (existsSync36(gitignorePath)) {
38556
+ const content = readFileSync27(gitignorePath, "utf-8");
38281
38557
  if (!content.includes(settingsPattern)) {
38282
- writeFileSync14(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
38558
+ writeFileSync15(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
38283
38559
  }
38284
38560
  }
38285
38561
  } catch {
@@ -38287,41 +38563,41 @@ function initOaDirectory(repoRoot) {
38287
38563
  return oaPath;
38288
38564
  }
38289
38565
  function hasOaDirectory(repoRoot) {
38290
- return existsSync35(join52(repoRoot, OA_DIR, "index"));
38566
+ return existsSync36(join53(repoRoot, OA_DIR, "index"));
38291
38567
  }
38292
38568
  function loadProjectSettings(repoRoot) {
38293
- const settingsPath = join52(repoRoot, OA_DIR, "settings.json");
38569
+ const settingsPath = join53(repoRoot, OA_DIR, "settings.json");
38294
38570
  try {
38295
- if (existsSync35(settingsPath)) {
38296
- return JSON.parse(readFileSync26(settingsPath, "utf-8"));
38571
+ if (existsSync36(settingsPath)) {
38572
+ return JSON.parse(readFileSync27(settingsPath, "utf-8"));
38297
38573
  }
38298
38574
  } catch {
38299
38575
  }
38300
38576
  return {};
38301
38577
  }
38302
38578
  function saveProjectSettings(repoRoot, settings) {
38303
- const oaPath = join52(repoRoot, OA_DIR);
38304
- mkdirSync13(oaPath, { recursive: true });
38579
+ const oaPath = join53(repoRoot, OA_DIR);
38580
+ mkdirSync14(oaPath, { recursive: true });
38305
38581
  const existing = loadProjectSettings(repoRoot);
38306
38582
  const merged = { ...existing, ...settings };
38307
- 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 });
38308
38584
  }
38309
38585
  function loadGlobalSettings() {
38310
- const settingsPath = join52(homedir11(), ".open-agents", "settings.json");
38586
+ const settingsPath = join53(homedir11(), ".open-agents", "settings.json");
38311
38587
  try {
38312
- if (existsSync35(settingsPath)) {
38313
- return JSON.parse(readFileSync26(settingsPath, "utf-8"));
38588
+ if (existsSync36(settingsPath)) {
38589
+ return JSON.parse(readFileSync27(settingsPath, "utf-8"));
38314
38590
  }
38315
38591
  } catch {
38316
38592
  }
38317
38593
  return {};
38318
38594
  }
38319
38595
  function saveGlobalSettings(settings) {
38320
- const dir = join52(homedir11(), ".open-agents");
38321
- mkdirSync13(dir, { recursive: true });
38596
+ const dir = join53(homedir11(), ".open-agents");
38597
+ mkdirSync14(dir, { recursive: true });
38322
38598
  const existing = loadGlobalSettings();
38323
38599
  const merged = { ...existing, ...settings };
38324
- 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 });
38325
38601
  }
38326
38602
  function resolveSettings(repoRoot) {
38327
38603
  const global = loadGlobalSettings();
@@ -38336,12 +38612,12 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38336
38612
  while (dir && !visited.has(dir)) {
38337
38613
  visited.add(dir);
38338
38614
  for (const name of CONTEXT_FILES) {
38339
- const filePath = join52(dir, name);
38615
+ const filePath = join53(dir, name);
38340
38616
  const normalizedName = name.toLowerCase();
38341
- if (existsSync35(filePath) && !seen.has(filePath)) {
38617
+ if (existsSync36(filePath) && !seen.has(filePath)) {
38342
38618
  seen.add(filePath);
38343
38619
  try {
38344
- let content = readFileSync26(filePath, "utf-8");
38620
+ let content = readFileSync27(filePath, "utf-8");
38345
38621
  if (content.length > maxContentLen) {
38346
38622
  content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
38347
38623
  }
@@ -38355,11 +38631,11 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38355
38631
  }
38356
38632
  }
38357
38633
  }
38358
- const projectMap = join52(dir, OA_DIR, "context", "project-map.md");
38359
- if (existsSync35(projectMap) && !seen.has(projectMap)) {
38634
+ const projectMap = join53(dir, OA_DIR, "context", "project-map.md");
38635
+ if (existsSync36(projectMap) && !seen.has(projectMap)) {
38360
38636
  seen.add(projectMap);
38361
38637
  try {
38362
- let content = readFileSync26(projectMap, "utf-8");
38638
+ let content = readFileSync27(projectMap, "utf-8");
38363
38639
  if (content.length > maxContentLen) {
38364
38640
  content = content.slice(0, maxContentLen) + "\n\n...(truncated)";
38365
38641
  }
@@ -38371,7 +38647,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38371
38647
  } catch {
38372
38648
  }
38373
38649
  }
38374
- const parent = join52(dir, "..");
38650
+ const parent = join53(dir, "..");
38375
38651
  if (parent === dir)
38376
38652
  break;
38377
38653
  dir = parent;
@@ -38389,34 +38665,34 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
38389
38665
  return found;
38390
38666
  }
38391
38667
  function readIndexMeta(repoRoot) {
38392
- const metaPath = join52(repoRoot, OA_DIR, "index", "meta.json");
38668
+ const metaPath = join53(repoRoot, OA_DIR, "index", "meta.json");
38393
38669
  try {
38394
- return JSON.parse(readFileSync26(metaPath, "utf-8"));
38670
+ return JSON.parse(readFileSync27(metaPath, "utf-8"));
38395
38671
  } catch {
38396
38672
  return null;
38397
38673
  }
38398
38674
  }
38399
38675
  function writeIndexMeta(repoRoot, meta) {
38400
- const metaPath = join52(repoRoot, OA_DIR, "index", "meta.json");
38401
- mkdirSync13(join52(repoRoot, OA_DIR, "index"), { recursive: true });
38402
- 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");
38403
38679
  }
38404
38680
  function readIndexData(repoRoot, filename) {
38405
- const filePath = join52(repoRoot, OA_DIR, "index", filename);
38681
+ const filePath = join53(repoRoot, OA_DIR, "index", filename);
38406
38682
  try {
38407
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38683
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38408
38684
  } catch {
38409
38685
  return null;
38410
38686
  }
38411
38687
  }
38412
38688
  function writeIndexData(repoRoot, filename, data) {
38413
- const filePath = join52(repoRoot, OA_DIR, "index", filename);
38414
- mkdirSync13(join52(repoRoot, OA_DIR, "index"), { recursive: true });
38415
- 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");
38416
38692
  }
38417
38693
  function generateProjectMap(repoRoot) {
38418
38694
  const sections = [];
38419
- const repoName2 = basename10(repoRoot);
38695
+ const repoName2 = basename11(repoRoot);
38420
38696
  sections.push(`# Project Map: ${repoName2}
38421
38697
  `);
38422
38698
  sections.push(`> Auto-generated by open-agents. Updated: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -38460,28 +38736,28 @@ ${tree}\`\`\`
38460
38736
  sections.push("");
38461
38737
  }
38462
38738
  const content = sections.join("\n");
38463
- const contextDir = join52(repoRoot, OA_DIR, "context");
38464
- mkdirSync13(contextDir, { recursive: true });
38465
- 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");
38466
38742
  return content;
38467
38743
  }
38468
38744
  function saveSession(repoRoot, session) {
38469
- const historyDir = join52(repoRoot, OA_DIR, "history");
38470
- mkdirSync13(historyDir, { recursive: true });
38471
- 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");
38472
38748
  }
38473
38749
  function loadRecentSessions(repoRoot, limit = 5) {
38474
- const historyDir = join52(repoRoot, OA_DIR, "history");
38475
- if (!existsSync35(historyDir))
38750
+ const historyDir = join53(repoRoot, OA_DIR, "history");
38751
+ if (!existsSync36(historyDir))
38476
38752
  return [];
38477
38753
  try {
38478
- const files = readdirSync9(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
38479
- 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));
38480
38756
  return { file: f, mtime: stat5.mtimeMs };
38481
38757
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
38482
38758
  return files.map((f) => {
38483
38759
  try {
38484
- return JSON.parse(readFileSync26(join52(historyDir, f.file), "utf-8"));
38760
+ return JSON.parse(readFileSync27(join53(historyDir, f.file), "utf-8"));
38485
38761
  } catch {
38486
38762
  return null;
38487
38763
  }
@@ -38491,18 +38767,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
38491
38767
  }
38492
38768
  }
38493
38769
  function savePendingTask(repoRoot, task) {
38494
- const historyDir = join52(repoRoot, OA_DIR, "history");
38495
- mkdirSync13(historyDir, { recursive: true });
38496
- 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");
38497
38773
  }
38498
38774
  function loadPendingTask(repoRoot) {
38499
- const filePath = join52(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
38775
+ const filePath = join53(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
38500
38776
  try {
38501
- if (!existsSync35(filePath))
38777
+ if (!existsSync36(filePath))
38502
38778
  return null;
38503
- const data = JSON.parse(readFileSync26(filePath, "utf-8"));
38779
+ const data = JSON.parse(readFileSync27(filePath, "utf-8"));
38504
38780
  try {
38505
- unlinkSync6(filePath);
38781
+ unlinkSync7(filePath);
38506
38782
  } catch {
38507
38783
  }
38508
38784
  return data;
@@ -38511,13 +38787,13 @@ function loadPendingTask(repoRoot) {
38511
38787
  }
38512
38788
  }
38513
38789
  function saveSessionContext(repoRoot, entry) {
38514
- const contextDir = join52(repoRoot, OA_DIR, "context");
38515
- mkdirSync13(contextDir, { recursive: true });
38516
- 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);
38517
38793
  let ctx;
38518
38794
  try {
38519
- if (existsSync35(filePath)) {
38520
- ctx = JSON.parse(readFileSync26(filePath, "utf-8"));
38795
+ if (existsSync36(filePath)) {
38796
+ ctx = JSON.parse(readFileSync27(filePath, "utf-8"));
38521
38797
  } else {
38522
38798
  ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
38523
38799
  }
@@ -38529,14 +38805,14 @@ function saveSessionContext(repoRoot, entry) {
38529
38805
  ctx.entries = ctx.entries.slice(-ctx.maxEntries);
38530
38806
  }
38531
38807
  ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
38532
- writeFileSync14(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
38808
+ writeFileSync15(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
38533
38809
  }
38534
38810
  function loadSessionContext(repoRoot) {
38535
- const filePath = join52(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
38811
+ const filePath = join53(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
38536
38812
  try {
38537
- if (!existsSync35(filePath))
38813
+ if (!existsSync36(filePath))
38538
38814
  return null;
38539
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38815
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38540
38816
  } catch {
38541
38817
  return null;
38542
38818
  }
@@ -38582,12 +38858,12 @@ function detectManifests(repoRoot) {
38582
38858
  { file: "docker-compose.yaml", type: "Docker Compose" }
38583
38859
  ];
38584
38860
  for (const check of checks) {
38585
- const filePath = join52(repoRoot, check.file);
38586
- if (existsSync35(filePath)) {
38861
+ const filePath = join53(repoRoot, check.file);
38862
+ if (existsSync36(filePath)) {
38587
38863
  let name;
38588
38864
  if (check.nameField) {
38589
38865
  try {
38590
- const data = JSON.parse(readFileSync26(filePath, "utf-8"));
38866
+ const data = JSON.parse(readFileSync27(filePath, "utf-8"));
38591
38867
  name = data[check.nameField];
38592
38868
  } catch {
38593
38869
  }
@@ -38616,7 +38892,7 @@ function findKeyFiles(repoRoot) {
38616
38892
  { pattern: "CLAUDE.md", description: "Claude Code context" }
38617
38893
  ];
38618
38894
  for (const check of checks) {
38619
- if (existsSync35(join52(repoRoot, check.pattern))) {
38895
+ if (existsSync36(join53(repoRoot, check.pattern))) {
38620
38896
  keyFiles.push({ path: check.pattern, description: check.description });
38621
38897
  }
38622
38898
  }
@@ -38627,7 +38903,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38627
38903
  return "";
38628
38904
  let result = "";
38629
38905
  try {
38630
- 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) => {
38631
38907
  if (a.isDirectory() && !b.isDirectory())
38632
38908
  return -1;
38633
38909
  if (!a.isDirectory() && b.isDirectory())
@@ -38642,12 +38918,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38642
38918
  if (entry.isDirectory()) {
38643
38919
  let fileCount = 0;
38644
38920
  try {
38645
- fileCount = readdirSync9(join52(root, entry.name)).filter((f) => !f.startsWith(".")).length;
38921
+ fileCount = readdirSync10(join53(root, entry.name)).filter((f) => !f.startsWith(".")).length;
38646
38922
  } catch {
38647
38923
  }
38648
38924
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
38649
38925
  `;
38650
- result += buildDirTree(join52(root, entry.name), maxDepth, childPrefix, depth + 1);
38926
+ result += buildDirTree(join53(root, entry.name), maxDepth, childPrefix, depth + 1);
38651
38927
  } else if (depth < maxDepth) {
38652
38928
  result += `${prefix}${connector}${entry.name}
38653
38929
  `;
@@ -38659,17 +38935,17 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
38659
38935
  }
38660
38936
  function loadUsageFile(filePath) {
38661
38937
  try {
38662
- if (existsSync35(filePath)) {
38663
- return JSON.parse(readFileSync26(filePath, "utf-8"));
38938
+ if (existsSync36(filePath)) {
38939
+ return JSON.parse(readFileSync27(filePath, "utf-8"));
38664
38940
  }
38665
38941
  } catch {
38666
38942
  }
38667
38943
  return { records: [] };
38668
38944
  }
38669
38945
  function saveUsageFile(filePath, data) {
38670
- const dir = join52(filePath, "..");
38671
- mkdirSync13(dir, { recursive: true });
38672
- 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 });
38673
38949
  }
38674
38950
  function recordUsage(kind, value, opts) {
38675
38951
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -38697,15 +38973,15 @@ function recordUsage(kind, value, opts) {
38697
38973
  }
38698
38974
  saveUsageFile(filePath, data);
38699
38975
  };
38700
- update(join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38976
+ update(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38701
38977
  if (opts?.repoRoot) {
38702
- update(join52(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38978
+ update(join53(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38703
38979
  }
38704
38980
  }
38705
38981
  function loadUsageHistory(kind, repoRoot) {
38706
- const globalPath = join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
38982
+ const globalPath = join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE);
38707
38983
  const globalData = loadUsageFile(globalPath);
38708
- 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: [] };
38709
38985
  const map = /* @__PURE__ */ new Map();
38710
38986
  for (const r of globalData.records) {
38711
38987
  if (r.kind !== kind)
@@ -38736,9 +39012,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
38736
39012
  saveUsageFile(filePath, data);
38737
39013
  }
38738
39014
  };
38739
- remove(join52(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
39015
+ remove(join53(homedir11(), ".open-agents", USAGE_HISTORY_FILE));
38740
39016
  if (repoRoot) {
38741
- remove(join52(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
39017
+ remove(join53(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
38742
39018
  }
38743
39019
  }
38744
39020
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -38786,10 +39062,10 @@ var init_oa_directory = __esm({
38786
39062
 
38787
39063
  // packages/cli/dist/tui/setup.js
38788
39064
  import * as readline from "node:readline";
38789
- 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";
38790
39066
  import { promisify as promisify6 } from "node:util";
38791
- import { existsSync as existsSync36, writeFileSync as writeFileSync15, readFileSync as readFileSync27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync14 } from "node:fs";
38792
- 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";
38793
39069
  import { homedir as homedir12, platform as platform2 } from "node:os";
38794
39070
  function detectSystemSpecs() {
38795
39071
  let totalRamGB = 0;
@@ -38797,7 +39073,7 @@ function detectSystemSpecs() {
38797
39073
  let gpuVramGB = 0;
38798
39074
  let gpuName = "";
38799
39075
  try {
38800
- 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", {
38801
39077
  encoding: "utf8",
38802
39078
  timeout: 5e3
38803
39079
  });
@@ -38817,7 +39093,7 @@ function detectSystemSpecs() {
38817
39093
  } catch {
38818
39094
  }
38819
39095
  try {
38820
- 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 });
38821
39097
  const lines = nvidiaSmi.trim().split("\n");
38822
39098
  if (lines.length > 0) {
38823
39099
  for (const line of lines) {
@@ -38996,7 +39272,7 @@ function ensureCurl() {
38996
39272
  for (const s of strategies) {
38997
39273
  if (hasCmd(s.check)) {
38998
39274
  try {
38999
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39275
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
39000
39276
  if (hasCmd("curl")) {
39001
39277
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
39002
39278
  `);
@@ -39010,7 +39286,7 @@ function ensureCurl() {
39010
39286
  }
39011
39287
  if (plat === "darwin") {
39012
39288
  try {
39013
- execSync26("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
39289
+ execSync27("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
39014
39290
  if (hasCmd("curl"))
39015
39291
  return true;
39016
39292
  } catch {
@@ -39045,7 +39321,7 @@ function installOllamaLinux() {
39045
39321
 
39046
39322
  `);
39047
39323
  try {
39048
- execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
39324
+ execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
39049
39325
  stdio: "inherit",
39050
39326
  timeout: 3e5
39051
39327
  });
@@ -39073,10 +39349,10 @@ async function installOllamaMac(_rl) {
39073
39349
 
39074
39350
  `);
39075
39351
  try {
39076
- 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 });
39077
39353
  if (!hasCmd("brew")) {
39078
39354
  try {
39079
- const brewPrefix = existsSync36("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
39355
+ const brewPrefix = existsSync37("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
39080
39356
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
39081
39357
  } catch {
39082
39358
  }
@@ -39106,7 +39382,7 @@ async function installOllamaMac(_rl) {
39106
39382
 
39107
39383
  `);
39108
39384
  try {
39109
- execSync26("brew install ollama", {
39385
+ execSync27("brew install ollama", {
39110
39386
  stdio: "inherit",
39111
39387
  timeout: 3e5
39112
39388
  });
@@ -39133,7 +39409,7 @@ function installOllamaWindows() {
39133
39409
 
39134
39410
  `);
39135
39411
  try {
39136
- execSync26('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
39412
+ execSync27('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
39137
39413
  stdio: "inherit",
39138
39414
  timeout: 3e5
39139
39415
  });
@@ -39214,7 +39490,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
39214
39490
  }
39215
39491
  function pullModelWithAutoUpdate(tag) {
39216
39492
  try {
39217
- execSync26(`ollama pull ${tag}`, {
39493
+ execSync27(`ollama pull ${tag}`, {
39218
39494
  stdio: "inherit",
39219
39495
  timeout: 36e5
39220
39496
  // 1 hour max
@@ -39234,7 +39510,7 @@ function pullModelWithAutoUpdate(tag) {
39234
39510
 
39235
39511
  `);
39236
39512
  try {
39237
- execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
39513
+ execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
39238
39514
  stdio: "inherit",
39239
39515
  timeout: 3e5
39240
39516
  // 5 min max for install
@@ -39245,7 +39521,7 @@ function pullModelWithAutoUpdate(tag) {
39245
39521
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
39246
39522
 
39247
39523
  `);
39248
- execSync26(`ollama pull ${tag}`, {
39524
+ execSync27(`ollama pull ${tag}`, {
39249
39525
  stdio: "inherit",
39250
39526
  timeout: 36e5
39251
39527
  });
@@ -39347,7 +39623,7 @@ function ensurePython3() {
39347
39623
  if (plat === "darwin") {
39348
39624
  if (hasCmd("brew")) {
39349
39625
  try {
39350
- execSync26("brew install python3", { stdio: "inherit", timeout: 3e5 });
39626
+ execSync27("brew install python3", { stdio: "inherit", timeout: 3e5 });
39351
39627
  if (hasCmd("python3")) {
39352
39628
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
39353
39629
  `);
@@ -39360,7 +39636,7 @@ function ensurePython3() {
39360
39636
  for (const s of strategies) {
39361
39637
  if (hasCmd(s.check)) {
39362
39638
  try {
39363
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39639
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
39364
39640
  if (hasCmd("python3") || hasCmd("python")) {
39365
39641
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
39366
39642
  `);
@@ -39376,11 +39652,11 @@ function ensurePython3() {
39376
39652
  }
39377
39653
  function checkPythonVenv() {
39378
39654
  try {
39379
- execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39655
+ execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39380
39656
  return true;
39381
39657
  } catch {
39382
39658
  try {
39383
- execSync26("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
39659
+ execSync27("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
39384
39660
  return true;
39385
39661
  } catch {
39386
39662
  return false;
@@ -39399,7 +39675,7 @@ function ensurePythonVenv() {
39399
39675
  for (const s of strategies) {
39400
39676
  if (hasCmd(s.check)) {
39401
39677
  try {
39402
- execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
39678
+ execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
39403
39679
  if (checkPythonVenv()) {
39404
39680
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
39405
39681
  `);
@@ -39830,12 +40106,12 @@ async function doSetup(config, rl) {
39830
40106
  `PARAMETER num_predict ${numPredict}`,
39831
40107
  `PARAMETER stop "<|endoftext|>"`
39832
40108
  ].join("\n");
39833
- const modelDir2 = join53(homedir12(), ".open-agents", "models");
39834
- mkdirSync14(modelDir2, { recursive: true });
39835
- const modelfilePath = join53(modelDir2, `Modelfile.${customName}`);
39836
- 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");
39837
40113
  process.stdout.write(` ${c2.dim("Creating model...")} `);
39838
- execSync26(`ollama create ${customName} -f ${modelfilePath}`, {
40114
+ execSync27(`ollama create ${customName} -f ${modelfilePath}`, {
39839
40115
  stdio: "pipe",
39840
40116
  timeout: 12e4
39841
40117
  });
@@ -39878,7 +40154,7 @@ async function isModelAvailable(config) {
39878
40154
  }
39879
40155
  function isFirstRun() {
39880
40156
  try {
39881
- return !existsSync36(join53(homedir12(), ".open-agents", "config.json"));
40157
+ return !existsSync37(join54(homedir12(), ".open-agents", "config.json"));
39882
40158
  } catch {
39883
40159
  return true;
39884
40160
  }
@@ -39886,7 +40162,7 @@ function isFirstRun() {
39886
40162
  function hasCmd(cmd) {
39887
40163
  try {
39888
40164
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
39889
- execSync26(whichCmd, { stdio: "pipe", timeout: 3e3 });
40165
+ execSync27(whichCmd, { stdio: "pipe", timeout: 3e3 });
39890
40166
  return true;
39891
40167
  } catch {
39892
40168
  return false;
@@ -39915,11 +40191,11 @@ function detectPkgManager() {
39915
40191
  return null;
39916
40192
  }
39917
40193
  function getVenvDir() {
39918
- return join53(homedir12(), ".open-agents", "venv");
40194
+ return join54(homedir12(), ".open-agents", "venv");
39919
40195
  }
39920
40196
  function hasVenvModule() {
39921
40197
  try {
39922
- execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
40198
+ execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39923
40199
  return true;
39924
40200
  } catch {
39925
40201
  return false;
@@ -39928,9 +40204,9 @@ function hasVenvModule() {
39928
40204
  function ensureVenv(log) {
39929
40205
  const venvDir = getVenvDir();
39930
40206
  const isWin2 = process.platform === "win32";
39931
- 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");
39932
40208
  const pythonCmd = isWin2 ? "python" : "python3";
39933
- if (existsSync36(pipPath))
40209
+ if (existsSync37(pipPath))
39934
40210
  return venvDir;
39935
40211
  log("Creating Python venv for vision deps...");
39936
40212
  if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
@@ -39942,10 +40218,10 @@ function ensureVenv(log) {
39942
40218
  return null;
39943
40219
  }
39944
40220
  try {
39945
- mkdirSync14(join53(homedir12(), ".open-agents"), { recursive: true });
40221
+ mkdirSync15(join54(homedir12(), ".open-agents"), { recursive: true });
39946
40222
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
39947
- execSync26(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
39948
- execSync26(`"${pipPath}" install --upgrade pip`, {
40223
+ execSync27(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
40224
+ execSync27(`"${pipPath}" install --upgrade pip`, {
39949
40225
  stdio: "pipe",
39950
40226
  timeout: 6e4
39951
40227
  });
@@ -39958,7 +40234,7 @@ function ensureVenv(log) {
39958
40234
  }
39959
40235
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39960
40236
  try {
39961
- execSync26(`sudo -n ${cmd}`, {
40237
+ execSync27(`sudo -n ${cmd}`, {
39962
40238
  stdio: "pipe",
39963
40239
  timeout: timeoutMs,
39964
40240
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -39971,7 +40247,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39971
40247
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
39972
40248
  try {
39973
40249
  const escaped = cmd.replace(/'/g, "'\\''");
39974
- execSync26(`sudo -S bash -c '${escaped}'`, {
40250
+ execSync27(`sudo -S bash -c '${escaped}'`, {
39975
40251
  input: password + "\n",
39976
40252
  stdio: ["pipe", "pipe", "pipe"],
39977
40253
  timeout: timeoutMs,
@@ -40078,7 +40354,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40078
40354
  ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
40079
40355
  } else {
40080
40356
  try {
40081
- execSync26(batchCmd, { stdio: "pipe", timeout: 18e4 });
40357
+ execSync27(batchCmd, { stdio: "pipe", timeout: 18e4 });
40082
40358
  ok = true;
40083
40359
  } catch {
40084
40360
  ok = false;
@@ -40115,7 +40391,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40115
40391
  const venvCmds = {
40116
40392
  apt: () => {
40117
40393
  try {
40118
- 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();
40119
40395
  return `apt-get install -y python3-venv python${pyVer}-venv`;
40120
40396
  } catch {
40121
40397
  return "apt-get install -y python3-venv";
@@ -40136,19 +40412,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40136
40412
  }
40137
40413
  }
40138
40414
  const venvDir = getVenvDir();
40139
- const venvBin = join53(venvDir, "bin");
40140
- const venvMoondream = join53(venvBin, "moondream-station");
40415
+ const venvBin = join54(venvDir, "bin");
40416
+ const venvMoondream = join54(venvBin, "moondream-station");
40141
40417
  const venv = ensureVenv(log);
40142
- if (venv && !hasCmd("moondream-station") && !existsSync36(venvMoondream)) {
40143
- const venvPip2 = join53(venvBin, "pip");
40418
+ if (venv && !hasCmd("moondream-station") && !existsSync37(venvMoondream)) {
40419
+ const venvPip2 = join54(venvBin, "pip");
40144
40420
  log("Installing moondream-station in ~/.open-agents/venv...");
40145
40421
  try {
40146
- execSync26(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
40147
- if (existsSync36(venvMoondream)) {
40422
+ execSync27(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
40423
+ if (existsSync37(venvMoondream)) {
40148
40424
  log("moondream-station installed successfully.");
40149
40425
  } else {
40150
40426
  try {
40151
- 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 });
40152
40428
  if (check.includes("moondream")) {
40153
40429
  log("moondream-station package installed.");
40154
40430
  }
@@ -40161,11 +40437,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40161
40437
  }
40162
40438
  }
40163
40439
  if (venv) {
40164
- const venvPython2 = join53(venvBin, "python");
40165
- const venvPip2 = join53(venvBin, "pip");
40440
+ const venvPython2 = join54(venvBin, "python");
40441
+ const venvPip2 = join54(venvBin, "pip");
40166
40442
  let ocrStackInstalled = false;
40167
40443
  try {
40168
- 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 });
40169
40445
  ocrStackInstalled = true;
40170
40446
  } catch {
40171
40447
  }
@@ -40173,9 +40449,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
40173
40449
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
40174
40450
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
40175
40451
  try {
40176
- execSync26(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
40452
+ execSync27(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
40177
40453
  try {
40178
- 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 });
40179
40455
  log("OCR Python stack installed successfully.");
40180
40456
  } catch {
40181
40457
  log("OCR Python stack install completed but import verification failed.");
@@ -40209,7 +40485,7 @@ function ensureCloudflaredBackground(onInfo) {
40209
40485
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
40210
40486
  const cfArch = archMap[arch2] ?? "amd64";
40211
40487
  try {
40212
- 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 });
40213
40489
  if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
40214
40490
  process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
40215
40491
  }
@@ -40220,7 +40496,7 @@ function ensureCloudflaredBackground(onInfo) {
40220
40496
  } catch {
40221
40497
  }
40222
40498
  try {
40223
- 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 });
40224
40500
  if (hasCmd("cloudflared")) {
40225
40501
  log("cloudflared installed.");
40226
40502
  return true;
@@ -40229,7 +40505,7 @@ function ensureCloudflaredBackground(onInfo) {
40229
40505
  }
40230
40506
  } else if (os === "darwin") {
40231
40507
  try {
40232
- execSync26("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
40508
+ execSync27("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
40233
40509
  if (hasCmd("cloudflared")) {
40234
40510
  log("cloudflared installed via Homebrew.");
40235
40511
  return true;
@@ -40306,10 +40582,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
40306
40582
  `PARAMETER num_predict ${numPredict}`,
40307
40583
  `PARAMETER stop "<|endoftext|>"`
40308
40584
  ].join("\n");
40309
- const modelDir2 = join53(homedir12(), ".open-agents", "models");
40310
- mkdirSync14(modelDir2, { recursive: true });
40311
- const modelfilePath = join53(modelDir2, `Modelfile.${customName}`);
40312
- 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");
40313
40589
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
40314
40590
  timeout: 12e4
40315
40591
  });
@@ -40371,7 +40647,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
40371
40647
  }
40372
40648
  async function ensureNeovim() {
40373
40649
  try {
40374
- 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", {
40375
40651
  encoding: "utf8",
40376
40652
  stdio: "pipe",
40377
40653
  timeout: 5e3
@@ -40383,24 +40659,24 @@ async function ensureNeovim() {
40383
40659
  const platform6 = process.platform;
40384
40660
  const arch2 = process.arch;
40385
40661
  if (platform6 === "linux") {
40386
- const binDir = join53(homedir12(), ".local", "bin");
40387
- const nvimDest = join53(binDir, "nvim");
40662
+ const binDir = join54(homedir12(), ".local", "bin");
40663
+ const nvimDest = join54(binDir, "nvim");
40388
40664
  try {
40389
- mkdirSync14(binDir, { recursive: true });
40665
+ mkdirSync15(binDir, { recursive: true });
40390
40666
  } catch {
40391
40667
  }
40392
40668
  const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
40393
40669
  const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
40394
40670
  console.log(` Downloading Neovim (${appImageName})...`);
40395
40671
  try {
40396
- execSync26(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
40397
- 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 });
40398
40674
  } catch (err) {
40399
40675
  console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
40400
40676
  return null;
40401
40677
  }
40402
40678
  try {
40403
- 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];
40404
40680
  console.log(` Installed: ${ver}`);
40405
40681
  } catch {
40406
40682
  console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
@@ -40415,8 +40691,8 @@ async function ensureNeovim() {
40415
40691
  if (hasCmd("brew")) {
40416
40692
  console.log(" Installing Neovim via Homebrew...");
40417
40693
  try {
40418
- execSync26("brew install neovim", { stdio: "inherit", timeout: 12e4 });
40419
- 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();
40420
40696
  return nvimPath || null;
40421
40697
  } catch {
40422
40698
  console.log(" brew install neovim failed.");
@@ -40430,7 +40706,7 @@ async function ensureNeovim() {
40430
40706
  if (hasCmd("choco")) {
40431
40707
  console.log(" Installing Neovim via Chocolatey...");
40432
40708
  try {
40433
- execSync26("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
40709
+ execSync27("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
40434
40710
  return "nvim";
40435
40711
  } catch {
40436
40712
  console.log(" choco install neovim failed.");
@@ -40439,7 +40715,7 @@ async function ensureNeovim() {
40439
40715
  if (hasCmd("winget")) {
40440
40716
  console.log(" Installing Neovim via winget...");
40441
40717
  try {
40442
- execSync26("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
40718
+ execSync27("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
40443
40719
  stdio: "inherit",
40444
40720
  timeout: 12e4
40445
40721
  });
@@ -40455,9 +40731,9 @@ async function ensureNeovim() {
40455
40731
  }
40456
40732
  function ensurePathInShellRc(binDir) {
40457
40733
  const shell = process.env.SHELL ?? "";
40458
- const rcFile = shell.includes("zsh") ? join53(homedir12(), ".zshrc") : join53(homedir12(), ".bashrc");
40734
+ const rcFile = shell.includes("zsh") ? join54(homedir12(), ".zshrc") : join54(homedir12(), ".bashrc");
40459
40735
  try {
40460
- const rcContent = existsSync36(rcFile) ? readFileSync27(rcFile, "utf8") : "";
40736
+ const rcContent = existsSync37(rcFile) ? readFileSync28(rcFile, "utf8") : "";
40461
40737
  if (rcContent.includes(binDir))
40462
40738
  return;
40463
40739
  const exportLine = `
@@ -41172,7 +41448,7 @@ var init_tui_select = __esm({
41172
41448
  });
41173
41449
 
41174
41450
  // packages/cli/dist/tui/drop-panel.js
41175
- import { existsSync as existsSync37 } from "node:fs";
41451
+ import { existsSync as existsSync38 } from "node:fs";
41176
41452
  import { extname as extname10, resolve as resolve29 } from "node:path";
41177
41453
  function ansi4(code, text) {
41178
41454
  return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
@@ -41287,7 +41563,7 @@ function showDropPanel(opts) {
41287
41563
  filePath = decodeURIComponent(filePath.slice(7));
41288
41564
  }
41289
41565
  filePath = resolve29(filePath);
41290
- if (!existsSync37(filePath)) {
41566
+ if (!existsSync38(filePath)) {
41291
41567
  errorMsg = `File not found: ${filePath}`;
41292
41568
  render();
41293
41569
  return;
@@ -41358,10 +41634,10 @@ var init_drop_panel = __esm({
41358
41634
  });
41359
41635
 
41360
41636
  // packages/cli/dist/tui/neovim-mode.js
41361
- import { existsSync as existsSync38, unlinkSync as unlinkSync7 } from "node:fs";
41637
+ import { existsSync as existsSync39, unlinkSync as unlinkSync8 } from "node:fs";
41362
41638
  import { tmpdir as tmpdir8 } from "node:os";
41363
- import { join as join54 } from "node:path";
41364
- 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";
41365
41641
  function isNeovimActive() {
41366
41642
  return _state !== null && !_state.cleanedUp;
41367
41643
  }
@@ -41379,7 +41655,7 @@ async function startNeovimMode(opts) {
41379
41655
  }
41380
41656
  let nvimPath;
41381
41657
  try {
41382
- nvimPath = execSync27("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
41658
+ nvimPath = execSync28("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
41383
41659
  if (!nvimPath)
41384
41660
  throw new Error();
41385
41661
  } catch {
@@ -41408,10 +41684,10 @@ async function startNeovimMode(opts) {
41408
41684
  );
41409
41685
  } catch {
41410
41686
  }
41411
- const socketPath = join54(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
41687
+ const socketPath = join55(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
41412
41688
  try {
41413
- if (existsSync38(socketPath))
41414
- unlinkSync7(socketPath);
41689
+ if (existsSync39(socketPath))
41690
+ unlinkSync8(socketPath);
41415
41691
  } catch {
41416
41692
  }
41417
41693
  const ptyCols = opts.cols;
@@ -41637,13 +41913,13 @@ function resizeNeovim(cols, contentRows) {
41637
41913
  }
41638
41914
  async function connectRPC(state, neovimPkg, cols) {
41639
41915
  let attempts = 0;
41640
- while (!existsSync38(state.socketPath) && attempts < 30) {
41916
+ while (!existsSync39(state.socketPath) && attempts < 30) {
41641
41917
  await new Promise((r) => setTimeout(r, 200));
41642
41918
  attempts++;
41643
41919
  if (state.cleanedUp)
41644
41920
  return;
41645
41921
  }
41646
- if (!existsSync38(state.socketPath))
41922
+ if (!existsSync39(state.socketPath))
41647
41923
  return;
41648
41924
  const nvim = neovimPkg.attach({ socket: state.socketPath });
41649
41925
  state.nvim = nvim;
@@ -41780,8 +42056,8 @@ function doCleanup(state) {
41780
42056
  state.pty = null;
41781
42057
  }
41782
42058
  try {
41783
- if (existsSync38(state.socketPath))
41784
- unlinkSync7(state.socketPath);
42059
+ if (existsSync39(state.socketPath))
42060
+ unlinkSync8(state.socketPath);
41785
42061
  } catch {
41786
42062
  }
41787
42063
  if (state.stdinHandler) {
@@ -41837,10 +42113,10 @@ __export(voice_exports, {
41837
42113
  registerCustomOnnxModel: () => registerCustomOnnxModel,
41838
42114
  resetNarrationContext: () => resetNarrationContext
41839
42115
  });
41840
- 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";
41841
- 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";
41842
42118
  import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
41843
- import { execSync as execSync28, spawn as nodeSpawn } from "node:child_process";
42119
+ import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
41844
42120
  import { createRequire } from "node:module";
41845
42121
  function sanitizeForTTS(text) {
41846
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();
@@ -41863,40 +42139,40 @@ function listVoiceModels() {
41863
42139
  }));
41864
42140
  }
41865
42141
  function voiceDir() {
41866
- return join55(homedir13(), ".open-agents", "voice");
42142
+ return join56(homedir13(), ".open-agents", "voice");
41867
42143
  }
41868
42144
  function modelsDir() {
41869
- return join55(voiceDir(), "models");
42145
+ return join56(voiceDir(), "models");
41870
42146
  }
41871
42147
  function modelDir(id) {
41872
- return join55(modelsDir(), id);
42148
+ return join56(modelsDir(), id);
41873
42149
  }
41874
42150
  function modelOnnxPath(id) {
41875
- return join55(modelDir(id), "model.onnx");
42151
+ return join56(modelDir(id), "model.onnx");
41876
42152
  }
41877
42153
  function modelConfigPath(id) {
41878
- return join55(modelDir(id), "config.json");
42154
+ return join56(modelDir(id), "config.json");
41879
42155
  }
41880
42156
  function luxttsVenvDir() {
41881
- return join55(voiceDir(), "luxtts-venv");
42157
+ return join56(voiceDir(), "luxtts-venv");
41882
42158
  }
41883
42159
  function luxttsVenvPy() {
41884
- 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");
41885
42161
  }
41886
42162
  function luxttsRepoDir() {
41887
- return join55(voiceDir(), "LuxTTS");
42163
+ return join56(voiceDir(), "LuxTTS");
41888
42164
  }
41889
42165
  function luxttsCloneRefsDir() {
41890
- return join55(voiceDir(), "clone-refs");
42166
+ return join56(voiceDir(), "clone-refs");
41891
42167
  }
41892
42168
  function luxttsInferScript() {
41893
- return join55(voiceDir(), "luxtts-infer.py");
42169
+ return join56(voiceDir(), "luxtts-infer.py");
41894
42170
  }
41895
42171
  function writeDetectTorchScript(targetPath) {
41896
- if (existsSync39(targetPath))
42172
+ if (existsSync40(targetPath))
41897
42173
  return;
41898
42174
  try {
41899
- mkdirSync15(dirname18(targetPath), { recursive: true });
42175
+ mkdirSync16(dirname18(targetPath), { recursive: true });
41900
42176
  } catch {
41901
42177
  }
41902
42178
  const script = `#!/usr/bin/env python3
@@ -41969,7 +42245,7 @@ def main():
41969
42245
  if __name__ == "__main__": main()
41970
42246
  `;
41971
42247
  try {
41972
- writeFileSync16(targetPath, script, { mode: 493 });
42248
+ writeFileSync17(targetPath, script, { mode: 493 });
41973
42249
  } catch {
41974
42250
  }
41975
42251
  }
@@ -42779,8 +43055,8 @@ var init_voice = __esm({
42779
43055
  const refsDir = luxttsCloneRefsDir();
42780
43056
  const targets = ["glados", "overwatch"];
42781
43057
  for (const modelId of targets) {
42782
- const refFile = join55(refsDir, `${modelId}-ref.wav`);
42783
- if (existsSync39(refFile))
43058
+ const refFile = join56(refsDir, `${modelId}-ref.wav`);
43059
+ if (existsSync40(refFile))
42784
43060
  continue;
42785
43061
  try {
42786
43062
  await this.generateCloneRef(modelId);
@@ -42859,24 +43135,24 @@ var init_voice = __esm({
42859
43135
  }
42860
43136
  p = p.replace(/\\ /g, " ");
42861
43137
  if (p.startsWith("~/") || p === "~") {
42862
- p = join55(homedir13(), p.slice(1));
43138
+ p = join56(homedir13(), p.slice(1));
42863
43139
  }
42864
- if (!existsSync39(p)) {
43140
+ if (!existsSync40(p)) {
42865
43141
  return `File not found: ${p}
42866
43142
  (original input: ${audioPath})`;
42867
43143
  }
42868
43144
  audioPath = p;
42869
43145
  const refsDir = luxttsCloneRefsDir();
42870
- if (!existsSync39(refsDir))
42871
- mkdirSync15(refsDir, { recursive: true });
43146
+ if (!existsSync40(refsDir))
43147
+ mkdirSync16(refsDir, { recursive: true });
42872
43148
  const ext = audioPath.split(".").pop() || "wav";
42873
43149
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
42874
43150
  const ts = Date.now().toString(36);
42875
43151
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
42876
- const destPath = join55(refsDir, destFilename);
43152
+ const destPath = join56(refsDir, destFilename);
42877
43153
  try {
42878
- const data = readFileSync28(audioPath);
42879
- writeFileSync16(destPath, data);
43154
+ const data = readFileSync29(audioPath);
43155
+ writeFileSync17(destPath, data);
42880
43156
  } catch (err) {
42881
43157
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
42882
43158
  }
@@ -42916,9 +43192,9 @@ var init_voice = __esm({
42916
43192
  return `Failed to synthesize reference audio from ${source.label}.`;
42917
43193
  }
42918
43194
  const refsDir = luxttsCloneRefsDir();
42919
- if (!existsSync39(refsDir))
42920
- mkdirSync15(refsDir, { recursive: true });
42921
- const destPath = join55(refsDir, `${sourceModelId}-ref.wav`);
43195
+ if (!existsSync40(refsDir))
43196
+ mkdirSync16(refsDir, { recursive: true });
43197
+ const destPath = join56(refsDir, `${sourceModelId}-ref.wav`);
42922
43198
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
42923
43199
  this.writeWav(audioData, sampleRate, destPath);
42924
43200
  this.luxttsCloneRef = destPath;
@@ -42934,23 +43210,23 @@ var init_voice = __esm({
42934
43210
  // -------------------------------------------------------------------------
42935
43211
  /** Metadata file for friendly names of clone refs */
42936
43212
  static cloneMetaFile() {
42937
- return join55(luxttsCloneRefsDir(), "meta.json");
43213
+ return join56(luxttsCloneRefsDir(), "meta.json");
42938
43214
  }
42939
43215
  loadCloneMeta() {
42940
43216
  const p = _VoiceEngine.cloneMetaFile();
42941
- if (!existsSync39(p))
43217
+ if (!existsSync40(p))
42942
43218
  return {};
42943
43219
  try {
42944
- return JSON.parse(readFileSync28(p, "utf8"));
43220
+ return JSON.parse(readFileSync29(p, "utf8"));
42945
43221
  } catch {
42946
43222
  return {};
42947
43223
  }
42948
43224
  }
42949
43225
  saveCloneMeta(meta) {
42950
43226
  const dir = luxttsCloneRefsDir();
42951
- if (!existsSync39(dir))
42952
- mkdirSync15(dir, { recursive: true });
42953
- 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));
42954
43230
  }
42955
43231
  /** Audio file extensions recognized as clone references */
42956
43232
  static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
@@ -42960,15 +43236,15 @@ var init_voice = __esm({
42960
43236
  */
42961
43237
  listCloneRefs() {
42962
43238
  const dir = luxttsCloneRefsDir();
42963
- if (!existsSync39(dir))
43239
+ if (!existsSync40(dir))
42964
43240
  return [];
42965
43241
  const meta = this.loadCloneMeta();
42966
- const files = readdirSync10(dir).filter((f) => {
43242
+ const files = readdirSync11(dir).filter((f) => {
42967
43243
  const ext = f.split(".").pop()?.toLowerCase() ?? "";
42968
43244
  return _VoiceEngine.AUDIO_EXTS.has(ext);
42969
43245
  });
42970
43246
  return files.map((f) => {
42971
- const p = join55(dir, f);
43247
+ const p = join56(dir, f);
42972
43248
  let size = 0;
42973
43249
  try {
42974
43250
  size = statSync13(p).size;
@@ -42985,11 +43261,11 @@ var init_voice = __esm({
42985
43261
  }
42986
43262
  /** Delete a clone reference file by filename. Returns true if deleted. */
42987
43263
  deleteCloneRef(filename) {
42988
- const p = join55(luxttsCloneRefsDir(), filename);
42989
- if (!existsSync39(p))
43264
+ const p = join56(luxttsCloneRefsDir(), filename);
43265
+ if (!existsSync40(p))
42990
43266
  return false;
42991
43267
  try {
42992
- unlinkSync8(p);
43268
+ unlinkSync9(p);
42993
43269
  const meta = this.loadCloneMeta();
42994
43270
  delete meta[filename];
42995
43271
  this.saveCloneMeta(meta);
@@ -43010,8 +43286,8 @@ var init_voice = __esm({
43010
43286
  }
43011
43287
  /** Set the active clone reference by filename. */
43012
43288
  setActiveCloneRef(filename) {
43013
- const p = join55(luxttsCloneRefsDir(), filename);
43014
- if (!existsSync39(p))
43289
+ const p = join56(luxttsCloneRefsDir(), filename);
43290
+ if (!existsSync40(p))
43015
43291
  return `File not found: ${filename}`;
43016
43292
  this.luxttsCloneRef = p;
43017
43293
  return `Active clone voice set to: ${filename}`;
@@ -43267,7 +43543,7 @@ var init_voice = __esm({
43267
43543
  }
43268
43544
  if (prefetchedWav) {
43269
43545
  try {
43270
- unlinkSync8(prefetchedWav.path);
43546
+ unlinkSync9(prefetchedWav.path);
43271
43547
  } catch {
43272
43548
  }
43273
43549
  }
@@ -43336,11 +43612,11 @@ var init_voice = __esm({
43336
43612
  }
43337
43613
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
43338
43614
  }
43339
- const wavPath = join55(tmpdir9(), `oa-voice-${Date.now()}.wav`);
43615
+ const wavPath = join56(tmpdir9(), `oa-voice-${Date.now()}.wav`);
43340
43616
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
43341
43617
  await this.playWav(wavPath);
43342
43618
  try {
43343
- unlinkSync8(wavPath);
43619
+ unlinkSync9(wavPath);
43344
43620
  } catch {
43345
43621
  }
43346
43622
  }
@@ -43453,7 +43729,7 @@ var init_voice = __esm({
43453
43729
  buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
43454
43730
  pos += 2;
43455
43731
  }
43456
- writeFileSync16(path, buffer);
43732
+ writeFileSync17(path, buffer);
43457
43733
  }
43458
43734
  // -------------------------------------------------------------------------
43459
43735
  // Phonemization
@@ -43531,7 +43807,7 @@ var init_voice = __esm({
43531
43807
  return buffer;
43532
43808
  }
43533
43809
  writeWav(samples, sampleRate, path) {
43534
- writeFileSync16(path, this.buildWavBuffer(samples, sampleRate));
43810
+ writeFileSync17(path, this.buildWavBuffer(samples, sampleRate));
43535
43811
  }
43536
43812
  // -------------------------------------------------------------------------
43537
43813
  // Audio playback (system default speakers)
@@ -43581,7 +43857,7 @@ var init_voice = __esm({
43581
43857
  }
43582
43858
  for (const player of ["paplay", "pw-play", "aplay"]) {
43583
43859
  try {
43584
- execSync28(`which ${player}`, { stdio: "pipe" });
43860
+ execSync29(`which ${player}`, { stdio: "pipe" });
43585
43861
  return [player, path];
43586
43862
  } catch {
43587
43863
  }
@@ -43610,7 +43886,7 @@ var init_voice = __esm({
43610
43886
  return this.python3Path;
43611
43887
  for (const bin of ["python3", "python"]) {
43612
43888
  try {
43613
- const path = execSync28(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43889
+ const path = execSync29(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43614
43890
  if (path) {
43615
43891
  this.python3Path = path;
43616
43892
  return path;
@@ -43676,7 +43952,7 @@ var init_voice = __esm({
43676
43952
  return false;
43677
43953
  }
43678
43954
  try {
43679
- execSync28(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43955
+ execSync29(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43680
43956
  this.mlxInstalled = true;
43681
43957
  return true;
43682
43958
  } catch {
@@ -43729,7 +44005,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43729
44005
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
43730
44006
  const mlxVoice = model.mlxVoice ?? "af_heart";
43731
44007
  const mlxLangCode = model.mlxLangCode ?? "a";
43732
- const wavPath = join55(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
44008
+ const wavPath = join56(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
43733
44009
  const pyScript = [
43734
44010
  "import sys, json",
43735
44011
  "from mlx_audio.tts import generate as tts_gen",
@@ -43737,20 +44013,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43737
44013
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43738
44014
  ].join("; ");
43739
44015
  try {
43740
- 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() });
43741
44017
  } catch (err) {
43742
44018
  try {
43743
44019
  const safeText = cleaned.replace(/'/g, "'\\''");
43744
- 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() });
43745
44021
  } catch (err2) {
43746
44022
  return;
43747
44023
  }
43748
44024
  }
43749
- if (!existsSync39(wavPath))
44025
+ if (!existsSync40(wavPath))
43750
44026
  return;
43751
44027
  if (volume !== 1) {
43752
44028
  try {
43753
- const wavData = readFileSync28(wavPath);
44029
+ const wavData = readFileSync29(wavPath);
43754
44030
  if (wavData.length > 44) {
43755
44031
  const header = wavData.subarray(0, 44);
43756
44032
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -43758,14 +44034,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43758
44034
  samples[i] = Math.round(samples[i] * volume);
43759
44035
  }
43760
44036
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
43761
- writeFileSync16(wavPath, scaled);
44037
+ writeFileSync17(wavPath, scaled);
43762
44038
  }
43763
44039
  } catch {
43764
44040
  }
43765
44041
  }
43766
44042
  if (this.onPCMOutput) {
43767
44043
  try {
43768
- const wavData = readFileSync28(wavPath);
44044
+ const wavData = readFileSync29(wavPath);
43769
44045
  if (wavData.length > 44) {
43770
44046
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
43771
44047
  const sampleRate = wavData.readUInt32LE(24);
@@ -43776,7 +44052,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43776
44052
  }
43777
44053
  await this.playWav(wavPath);
43778
44054
  try {
43779
- unlinkSync8(wavPath);
44055
+ unlinkSync9(wavPath);
43780
44056
  } catch {
43781
44057
  }
43782
44058
  }
@@ -43797,7 +44073,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43797
44073
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
43798
44074
  const mlxVoice = model.mlxVoice ?? "af_heart";
43799
44075
  const mlxLangCode = model.mlxLangCode ?? "a";
43800
- const wavPath = join55(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
44076
+ const wavPath = join56(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
43801
44077
  const pyScript = [
43802
44078
  "import sys, json",
43803
44079
  "from mlx_audio.tts import generate as tts_gen",
@@ -43805,20 +44081,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43805
44081
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43806
44082
  ].join("; ");
43807
44083
  try {
43808
- 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() });
43809
44085
  } catch {
43810
44086
  try {
43811
44087
  const safeText = cleaned.replace(/'/g, "'\\''");
43812
- 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() });
43813
44089
  } catch {
43814
44090
  return null;
43815
44091
  }
43816
44092
  }
43817
- if (!existsSync39(wavPath))
44093
+ if (!existsSync40(wavPath))
43818
44094
  return null;
43819
44095
  try {
43820
- const data = readFileSync28(wavPath);
43821
- unlinkSync8(wavPath);
44096
+ const data = readFileSync29(wavPath);
44097
+ unlinkSync9(wavPath);
43822
44098
  return data;
43823
44099
  } catch {
43824
44100
  return null;
@@ -43840,7 +44116,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43840
44116
  }
43841
44117
  const venvDir = luxttsVenvDir();
43842
44118
  const venvPy = luxttsVenvPy();
43843
- if (existsSync39(venvPy)) {
44119
+ if (existsSync40(venvPy)) {
43844
44120
  try {
43845
44121
  await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
43846
44122
  let hasCudaSys = false;
@@ -43854,7 +44130,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43854
44130
  if (torchCheck === "cpu") {
43855
44131
  renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
43856
44132
  try {
43857
- const detectScript = join55(voiceDir(), "detect-torch.py");
44133
+ const detectScript = join56(voiceDir(), "detect-torch.py");
43858
44134
  writeDetectTorchScript(detectScript);
43859
44135
  let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
43860
44136
  try {
@@ -43879,7 +44155,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43879
44155
  }
43880
44156
  }
43881
44157
  renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
43882
- if (!existsSync39(venvDir)) {
44158
+ if (!existsSync40(venvDir)) {
43883
44159
  renderInfo(" Creating Python virtual environment...");
43884
44160
  try {
43885
44161
  await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
@@ -43888,7 +44164,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43888
44164
  }
43889
44165
  }
43890
44166
  {
43891
- const detectScript = join55(voiceDir(), "detect-torch.py");
44167
+ const detectScript = join56(voiceDir(), "detect-torch.py");
43892
44168
  writeDetectTorchScript(detectScript);
43893
44169
  let pipArgsStr = "torch torchaudio";
43894
44170
  let torchDesc = "unknown platform";
@@ -43925,10 +44201,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43925
44201
  }
43926
44202
  }
43927
44203
  const repoDir = luxttsRepoDir();
43928
- if (!existsSync39(join55(repoDir, "zipvoice", "luxvoice.py"))) {
44204
+ if (!existsSync40(join56(repoDir, "zipvoice", "luxvoice.py"))) {
43929
44205
  renderInfo(" Cloning LuxTTS repository...");
43930
44206
  try {
43931
- if (existsSync39(repoDir)) {
44207
+ if (existsSync40(repoDir)) {
43932
44208
  const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
43933
44209
  await this.asyncShell(rmCmd, 3e4);
43934
44210
  }
@@ -43967,7 +44243,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43967
44243
  renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
43968
44244
  }
43969
44245
  }
43970
- 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 ?? "") !== "");
43971
44247
  const installSteps = isArm ? [
43972
44248
  // ARM: install individually so we get clear error messages per package.
43973
44249
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
@@ -44035,14 +44311,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
44035
44311
  }
44036
44312
  /** Auto-detect an existing clone reference in the refs directory */
44037
44313
  autoDetectCloneRef() {
44038
- if (this.luxttsCloneRef && existsSync39(this.luxttsCloneRef))
44314
+ if (this.luxttsCloneRef && existsSync40(this.luxttsCloneRef))
44039
44315
  return;
44040
44316
  const refsDir = luxttsCloneRefsDir();
44041
- if (!existsSync39(refsDir))
44317
+ if (!existsSync40(refsDir))
44042
44318
  return;
44043
44319
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
44044
- const p = join55(refsDir, name);
44045
- if (existsSync39(p)) {
44320
+ const p = join56(refsDir, name);
44321
+ if (existsSync40(p)) {
44046
44322
  this.luxttsCloneRef = p;
44047
44323
  return;
44048
44324
  }
@@ -44142,15 +44418,15 @@ if __name__ == '__main__':
44142
44418
  main()
44143
44419
  `;
44144
44420
  const scriptPath2 = luxttsInferScript();
44145
- mkdirSync15(voiceDir(), { recursive: true });
44146
- writeFileSync16(scriptPath2, script);
44421
+ mkdirSync16(voiceDir(), { recursive: true });
44422
+ writeFileSync17(scriptPath2, script);
44147
44423
  }
44148
44424
  /** Ensure the LuxTTS daemon is running, spawn if needed */
44149
44425
  async ensureLuxttsDaemon() {
44150
44426
  if (this._luxttsDaemon && !this._luxttsDaemon.killed)
44151
44427
  return true;
44152
44428
  const venvPy = luxttsVenvPy();
44153
- if (!existsSync39(venvPy))
44429
+ if (!existsSync40(venvPy))
44154
44430
  return false;
44155
44431
  return new Promise((resolve34) => {
44156
44432
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
@@ -44234,7 +44510,7 @@ if __name__ == '__main__':
44234
44510
  * Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
44235
44511
  */
44236
44512
  async synthesizeLuxttsWav(text, speedFactor = 1) {
44237
- if (!this.luxttsCloneRef || !existsSync39(this.luxttsCloneRef))
44513
+ if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
44238
44514
  return null;
44239
44515
  const cleaned = text.replace(/\*/g, "").trim();
44240
44516
  if (!cleaned)
@@ -44242,7 +44518,7 @@ if __name__ == '__main__':
44242
44518
  const ready = await this.ensureLuxttsDaemon();
44243
44519
  if (!ready)
44244
44520
  return null;
44245
- 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`);
44246
44522
  try {
44247
44523
  await this.luxttsRequest({
44248
44524
  action: "synthesize",
@@ -44254,17 +44530,17 @@ if __name__ == '__main__':
44254
44530
  } catch {
44255
44531
  return null;
44256
44532
  }
44257
- return existsSync39(wavPath) ? wavPath : null;
44533
+ return existsSync40(wavPath) ? wavPath : null;
44258
44534
  }
44259
44535
  /**
44260
44536
  * Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
44261
44537
  * Cleans up the WAV file after playback.
44262
44538
  */
44263
44539
  async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
44264
- if (!existsSync39(wavPath))
44540
+ if (!existsSync40(wavPath))
44265
44541
  return;
44266
44542
  try {
44267
- const wavData = readFileSync28(wavPath);
44543
+ const wavData = readFileSync29(wavPath);
44268
44544
  if (wavData.length > 44) {
44269
44545
  const sampleRate = wavData.readUInt32LE(24);
44270
44546
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -44279,13 +44555,13 @@ if __name__ == '__main__':
44279
44555
  }
44280
44556
  const header = wavData.subarray(0, 44);
44281
44557
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
44282
- writeFileSync16(wavPath, scaled);
44558
+ writeFileSync17(wavPath, scaled);
44283
44559
  }
44284
44560
  } catch {
44285
44561
  }
44286
44562
  if (pitchFactor !== 1) {
44287
44563
  try {
44288
- const wavData = readFileSync28(wavPath);
44564
+ const wavData = readFileSync29(wavPath);
44289
44565
  if (wavData.length > 44) {
44290
44566
  const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
44291
44567
  const float32 = new Float32Array(int16.length);
@@ -44300,7 +44576,7 @@ if __name__ == '__main__':
44300
44576
  }
44301
44577
  if (this.onPCMOutput) {
44302
44578
  try {
44303
- const wavData = readFileSync28(wavPath);
44579
+ const wavData = readFileSync29(wavPath);
44304
44580
  if (wavData.length > 44) {
44305
44581
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
44306
44582
  const sampleRate = wavData.readUInt32LE(24);
@@ -44311,7 +44587,7 @@ if __name__ == '__main__':
44311
44587
  }
44312
44588
  if (stereoDelayMs > 0) {
44313
44589
  try {
44314
- const wavData = readFileSync28(wavPath);
44590
+ const wavData = readFileSync29(wavPath);
44315
44591
  if (wavData.length > 44) {
44316
44592
  const sampleRate = wavData.readUInt32LE(24);
44317
44593
  const numChannels = wavData.readUInt16LE(22);
@@ -44331,7 +44607,7 @@ if __name__ == '__main__':
44331
44607
  await this.playWav(wavPath);
44332
44608
  await this.sleep(150);
44333
44609
  try {
44334
- unlinkSync8(wavPath);
44610
+ unlinkSync9(wavPath);
44335
44611
  } catch {
44336
44612
  }
44337
44613
  }
@@ -44347,7 +44623,7 @@ if __name__ == '__main__':
44347
44623
  * Used for Telegram voice messages and WebSocket streaming.
44348
44624
  */
44349
44625
  async synthesizeLuxttsToBuffer(text) {
44350
- if (!this.luxttsCloneRef || !existsSync39(this.luxttsCloneRef))
44626
+ if (!this.luxttsCloneRef || !existsSync40(this.luxttsCloneRef))
44351
44627
  return null;
44352
44628
  const cleaned = text.replace(/\*/g, "").trim();
44353
44629
  if (!cleaned)
@@ -44355,7 +44631,7 @@ if __name__ == '__main__':
44355
44631
  const ready = await this.ensureLuxttsDaemon();
44356
44632
  if (!ready)
44357
44633
  return null;
44358
- const wavPath = join55(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
44634
+ const wavPath = join56(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
44359
44635
  try {
44360
44636
  await this.luxttsRequest({
44361
44637
  action: "synthesize",
@@ -44367,11 +44643,11 @@ if __name__ == '__main__':
44367
44643
  } catch {
44368
44644
  return null;
44369
44645
  }
44370
- if (!existsSync39(wavPath))
44646
+ if (!existsSync40(wavPath))
44371
44647
  return null;
44372
44648
  try {
44373
- const data = readFileSync28(wavPath);
44374
- unlinkSync8(wavPath);
44649
+ const data = readFileSync29(wavPath);
44650
+ unlinkSync9(wavPath);
44375
44651
  return data;
44376
44652
  } catch {
44377
44653
  return null;
@@ -44384,40 +44660,40 @@ if __name__ == '__main__':
44384
44660
  if (this.ort)
44385
44661
  return;
44386
44662
  const arch2 = process.arch;
44387
- mkdirSync15(voiceDir(), { recursive: true });
44388
- const pkgPath = join55(voiceDir(), "package.json");
44663
+ mkdirSync16(voiceDir(), { recursive: true });
44664
+ const pkgPath = join56(voiceDir(), "package.json");
44389
44665
  const expectedDeps = {
44390
44666
  "onnxruntime-node": "^1.21.0",
44391
44667
  "phonemizer": "^1.2.1"
44392
44668
  };
44393
- if (existsSync39(pkgPath)) {
44669
+ if (existsSync40(pkgPath)) {
44394
44670
  try {
44395
- const existing = JSON.parse(readFileSync28(pkgPath, "utf8"));
44671
+ const existing = JSON.parse(readFileSync29(pkgPath, "utf8"));
44396
44672
  if (!existing.dependencies?.["phonemizer"]) {
44397
44673
  existing.dependencies = { ...existing.dependencies, ...expectedDeps };
44398
- writeFileSync16(pkgPath, JSON.stringify(existing, null, 2));
44674
+ writeFileSync17(pkgPath, JSON.stringify(existing, null, 2));
44399
44675
  }
44400
44676
  } catch {
44401
44677
  }
44402
44678
  }
44403
- if (!existsSync39(pkgPath)) {
44404
- writeFileSync16(pkgPath, JSON.stringify({
44679
+ if (!existsSync40(pkgPath)) {
44680
+ writeFileSync17(pkgPath, JSON.stringify({
44405
44681
  name: "open-agents-voice",
44406
44682
  private: true,
44407
44683
  dependencies: expectedDeps
44408
44684
  }, null, 2));
44409
44685
  }
44410
- const voiceRequire = createRequire(join55(voiceDir(), "index.js"));
44686
+ const voiceRequire = createRequire(join56(voiceDir(), "index.js"));
44411
44687
  const probeOnnx = async () => {
44412
44688
  try {
44413
- 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);
44414
44690
  return output.trim() === "OK";
44415
44691
  } catch {
44416
44692
  return false;
44417
44693
  }
44418
44694
  };
44419
- const onnxNodeModules = join55(voiceDir(), "node_modules", "onnxruntime-node");
44420
- const onnxInstalled = existsSync39(onnxNodeModules);
44695
+ const onnxNodeModules = join56(voiceDir(), "node_modules", "onnxruntime-node");
44696
+ const onnxInstalled = existsSync40(onnxNodeModules);
44421
44697
  if (onnxInstalled && !await probeOnnx()) {
44422
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.`);
44423
44699
  }
@@ -44467,18 +44743,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44467
44743
  const dir = modelDir(id);
44468
44744
  const onnxPath = modelOnnxPath(id);
44469
44745
  const configPath = modelConfigPath(id);
44470
- if (existsSync39(onnxPath) && existsSync39(configPath))
44746
+ if (existsSync40(onnxPath) && existsSync40(configPath))
44471
44747
  return;
44472
- mkdirSync15(dir, { recursive: true });
44473
- if (!existsSync39(configPath)) {
44748
+ mkdirSync16(dir, { recursive: true });
44749
+ if (!existsSync40(configPath)) {
44474
44750
  renderInfo(`Downloading ${model.label} voice config...`);
44475
44751
  const configResp = await fetch(model.configUrl);
44476
44752
  if (!configResp.ok)
44477
44753
  throw new Error(`Failed to download config: HTTP ${configResp.status}`);
44478
44754
  const configText = await configResp.text();
44479
- writeFileSync16(configPath, configText);
44755
+ writeFileSync17(configPath, configText);
44480
44756
  }
44481
- if (!existsSync39(onnxPath)) {
44757
+ if (!existsSync40(onnxPath)) {
44482
44758
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
44483
44759
  const onnxResp = await fetch(model.onnxUrl);
44484
44760
  if (!onnxResp.ok)
@@ -44503,7 +44779,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44503
44779
  }
44504
44780
  }
44505
44781
  const fullBuffer = Buffer.concat(chunks);
44506
- writeFileSync16(onnxPath, fullBuffer);
44782
+ writeFileSync17(onnxPath, fullBuffer);
44507
44783
  renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
44508
44784
  }
44509
44785
  }
@@ -44515,10 +44791,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44515
44791
  throw new Error("ONNX runtime not loaded");
44516
44792
  const onnxPath = modelOnnxPath(this.modelId);
44517
44793
  const configPath = modelConfigPath(this.modelId);
44518
- if (!existsSync39(onnxPath) || !existsSync39(configPath)) {
44794
+ if (!existsSync40(onnxPath) || !existsSync40(configPath)) {
44519
44795
  throw new Error(`Model files not found for ${this.modelId}`);
44520
44796
  }
44521
- this.config = JSON.parse(readFileSync28(configPath, "utf8"));
44797
+ this.config = JSON.parse(readFileSync29(configPath, "utf8"));
44522
44798
  this.session = await this.ort.InferenceSession.create(onnxPath, {
44523
44799
  executionProviders: ["cpu"],
44524
44800
  graphOptimizationLevel: "all"
@@ -44545,8 +44821,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
44545
44821
  // packages/cli/dist/tui/commands.js
44546
44822
  import * as nodeOs from "node:os";
44547
44823
  import { execSync as nodeExecSync } from "node:child_process";
44548
- import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync16, readdirSync as readdirSync11, statSync as statSync14, rmSync } from "node:fs";
44549
- 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";
44550
44826
  function safeLog(text) {
44551
44827
  if (isNeovimActive()) {
44552
44828
  writeToNeovimOutput(text + "\n");
@@ -45155,22 +45431,22 @@ async function handleSlashCommand(input, ctx) {
45155
45431
  let content = "";
45156
45432
  let metadata = {};
45157
45433
  if (shareType === "tool") {
45158
- const toolDir = join56(ctx.repoRoot, ".oa", "tools");
45159
- const toolFile = join56(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
45160
- 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)) {
45161
45437
  renderWarning(`Tool not found: ${toolFile}`);
45162
45438
  return "handled";
45163
45439
  }
45164
- content = readFileSync29(toolFile, "utf8");
45440
+ content = readFileSync30(toolFile, "utf8");
45165
45441
  metadata = { type: "tool", name: shareName };
45166
45442
  } else if (shareType === "skill") {
45167
- const skillDir = join56(ctx.repoRoot, ".oa", "skills", shareName);
45168
- const skillFile = join56(skillDir, "SKILL.md");
45169
- if (!existsSync40(skillFile)) {
45443
+ const skillDir = join57(ctx.repoRoot, ".oa", "skills", shareName);
45444
+ const skillFile = join57(skillDir, "SKILL.md");
45445
+ if (!existsSync41(skillFile)) {
45170
45446
  renderWarning(`Skill not found: ${skillFile}`);
45171
45447
  return "handled";
45172
45448
  }
45173
- content = readFileSync29(skillFile, "utf8");
45449
+ content = readFileSync30(skillFile, "utf8");
45174
45450
  metadata = { type: "skill", name: shareName };
45175
45451
  } else {
45176
45452
  renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
@@ -45209,9 +45485,9 @@ async function handleSlashCommand(input, ctx) {
45209
45485
  const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
45210
45486
  const nexus = new NexusTool2(ctx.repoRoot);
45211
45487
  await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
45212
- const regFile = join56(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
45213
- if (existsSync40(regFile)) {
45214
- 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"));
45215
45491
  const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
45216
45492
  if (pinned) {
45217
45493
  renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
@@ -45264,33 +45540,33 @@ async function handleSlashCommand(input, ctx) {
45264
45540
  lines.push(`
45265
45541
  ${c2.bold("IPFS / Helia Status")}
45266
45542
  `);
45267
- const ipfsDir = join56(ctx.repoRoot, ".oa", "ipfs");
45268
- const ipfsLocalDir = join56(ipfsDir, "local");
45543
+ const ipfsDir = join57(ctx.repoRoot, ".oa", "ipfs");
45544
+ const ipfsLocalDir = join57(ipfsDir, "local");
45269
45545
  let ipfsFiles = 0;
45270
45546
  let ipfsBytes = 0;
45271
45547
  let heliaBlocks = 0;
45272
45548
  let heliaBytes = 0;
45273
45549
  try {
45274
- if (existsSync40(ipfsLocalDir)) {
45275
- const files = readdirSync11(ipfsLocalDir).filter((f) => f.endsWith(".json"));
45550
+ if (existsSync41(ipfsLocalDir)) {
45551
+ const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
45276
45552
  ipfsFiles = files.length;
45277
45553
  for (const f of files) {
45278
45554
  try {
45279
- ipfsBytes += statSync14(join56(ipfsLocalDir, f)).size;
45555
+ ipfsBytes += statSync14(join57(ipfsLocalDir, f)).size;
45280
45556
  } catch {
45281
45557
  }
45282
45558
  }
45283
45559
  }
45284
- const heliaBlockDir = join56(ipfsDir, "blocks");
45285
- if (existsSync40(heliaBlockDir)) {
45560
+ const heliaBlockDir = join57(ipfsDir, "blocks");
45561
+ if (existsSync41(heliaBlockDir)) {
45286
45562
  const walkDir = (dir) => {
45287
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45563
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45288
45564
  if (entry.isDirectory())
45289
- walkDir(join56(dir, entry.name));
45565
+ walkDir(join57(dir, entry.name));
45290
45566
  else {
45291
45567
  heliaBlocks++;
45292
45568
  try {
45293
- heliaBytes += statSync14(join56(dir, entry.name)).size;
45569
+ heliaBytes += statSync14(join57(dir, entry.name)).size;
45294
45570
  } catch {
45295
45571
  }
45296
45572
  }
@@ -45306,9 +45582,9 @@ async function handleSlashCommand(input, ctx) {
45306
45582
  lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
45307
45583
  lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
45308
45584
  try {
45309
- const statusFile = join56(ctx.repoRoot, ".oa", "nexus", "status.json");
45310
- if (existsSync40(statusFile)) {
45311
- 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"));
45312
45588
  if (status.peerId) {
45313
45589
  lines.push(`
45314
45590
  ${c2.bold("Peer Info")}`);
@@ -45327,11 +45603,11 @@ async function handleSlashCommand(input, ctx) {
45327
45603
  ${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
45328
45604
  lines.push(`
45329
45605
  ${c2.bold("Identity Kernel")}`);
45330
- const idDir = join56(ctx.repoRoot, ".oa", "identity");
45606
+ const idDir = join57(ctx.repoRoot, ".oa", "identity");
45331
45607
  try {
45332
- const stateFile = join56(idDir, "self-state.json");
45333
- if (existsSync40(stateFile)) {
45334
- 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"));
45335
45611
  lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
45336
45612
  if (state.narrative_summary) {
45337
45613
  lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
@@ -45340,9 +45616,9 @@ async function handleSlashCommand(input, ctx) {
45340
45616
  const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
45341
45617
  lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
45342
45618
  }
45343
- const cidFile = join56(idDir, "cids.json");
45344
- if (existsSync40(cidFile)) {
45345
- 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"));
45346
45622
  const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
45347
45623
  if (lastCid)
45348
45624
  lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
@@ -45355,9 +45631,9 @@ async function handleSlashCommand(input, ctx) {
45355
45631
  lines.push(`
45356
45632
  ${c2.bold("Memory Sentiment")}`);
45357
45633
  try {
45358
- const metaFile = join56(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
45359
- if (existsSync40(metaFile)) {
45360
- 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"));
45361
45637
  const active = store.filter((m) => m.type !== "quarantine");
45362
45638
  const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
45363
45639
  const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
@@ -45375,8 +45651,8 @@ async function handleSlashCommand(input, ctx) {
45375
45651
  } catch {
45376
45652
  }
45377
45653
  try {
45378
- const dbPath = join56(ctx.repoRoot, ".oa", "memory", "structured.db");
45379
- if (existsSync40(dbPath)) {
45654
+ const dbPath = join57(ctx.repoRoot, ".oa", "memory", "structured.db");
45655
+ if (existsSync41(dbPath)) {
45380
45656
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
45381
45657
  const db = initDb2(dbPath);
45382
45658
  const memStore = new ProceduralMemoryStore2(db);
@@ -45397,8 +45673,8 @@ async function handleSlashCommand(input, ctx) {
45397
45673
  lines.push(`
45398
45674
  ${c2.bold("Storage Overview")}
45399
45675
  `);
45400
- const oaDir = join56(ctx.repoRoot, ".oa");
45401
- if (!existsSync40(oaDir)) {
45676
+ const oaDir = join57(ctx.repoRoot, ".oa");
45677
+ if (!existsSync41(oaDir)) {
45402
45678
  lines.push(` ${c2.dim("No .oa/ directory found.")}`);
45403
45679
  safeLog(lines.join("\n") + "\n");
45404
45680
  return "handled";
@@ -45407,8 +45683,8 @@ async function handleSlashCommand(input, ctx) {
45407
45683
  const categories = {};
45408
45684
  const walkStorage = (dir, category) => {
45409
45685
  try {
45410
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45411
- const full = join56(dir, entry.name);
45686
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45687
+ const full = join57(dir, entry.name);
45412
45688
  if (entry.isDirectory()) {
45413
45689
  const subCat = category || entry.name;
45414
45690
  walkStorage(full, subCat);
@@ -45441,13 +45717,13 @@ async function handleSlashCommand(input, ctx) {
45441
45717
  const sensitiveFound = [];
45442
45718
  const checkSensitive = (dir) => {
45443
45719
  try {
45444
- for (const entry of readdirSync11(dir, { withFileTypes: true })) {
45720
+ for (const entry of readdirSync12(dir, { withFileTypes: true })) {
45445
45721
  const name = entry.name.toLowerCase();
45446
45722
  if (sensitivePatterns.some((p) => name.includes(p))) {
45447
- sensitiveFound.push(join56(dir, entry.name).replace(oaDir + "/", ""));
45723
+ sensitiveFound.push(join57(dir, entry.name).replace(oaDir + "/", ""));
45448
45724
  }
45449
45725
  if (entry.isDirectory())
45450
- checkSensitive(join56(dir, entry.name));
45726
+ checkSensitive(join57(dir, entry.name));
45451
45727
  }
45452
45728
  } catch {
45453
45729
  }
@@ -45475,8 +45751,8 @@ async function handleSlashCommand(input, ctx) {
45475
45751
  renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
45476
45752
  return "handled";
45477
45753
  }
45478
- const resolvedPath = join56(ctx.repoRoot, filePath);
45479
- if (!existsSync40(resolvedPath)) {
45754
+ const resolvedPath = join57(ctx.repoRoot, filePath);
45755
+ if (!existsSync41(resolvedPath)) {
45480
45756
  renderWarning(`File not found: ${resolvedPath}`);
45481
45757
  return "handled";
45482
45758
  }
@@ -45492,9 +45768,9 @@ async function handleSlashCommand(input, ctx) {
45492
45768
  }
45493
45769
  try {
45494
45770
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
45495
- const dbDir = join56(ctx.repoRoot, ".oa", "memory");
45496
- mkdirSync16(dbDir, { recursive: true });
45497
- 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"));
45498
45774
  const memStore = new ProceduralMemoryStore2(db);
45499
45775
  if (isAudio) {
45500
45776
  renderInfo(`Transcribing: ${filePath}...`);
@@ -45535,7 +45811,7 @@ async function handleSlashCommand(input, ctx) {
45535
45811
  return "handled";
45536
45812
  }
45537
45813
  } else {
45538
- content = readFileSync29(resolvedPath, "utf8");
45814
+ content = readFileSync30(resolvedPath, "utf8");
45539
45815
  }
45540
45816
  if (!content.trim()) {
45541
45817
  renderWarning("No content extracted.");
@@ -45574,9 +45850,9 @@ async function handleSlashCommand(input, ctx) {
45574
45850
  }
45575
45851
  case "fortemi": {
45576
45852
  const fortemiSubCmd = (arg || "").trim().toLowerCase();
45577
- const fortemiDir = join56(ctx.repoRoot, "..", "fortemi-react");
45578
- const altFortemiDir = join56(nodeOs.homedir(), "fortemi-react");
45579
- 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;
45580
45856
  if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
45581
45857
  if (!fDir) {
45582
45858
  renderWarning("fortemi-react not found adjacent or in home directory.");
@@ -45591,14 +45867,14 @@ async function handleSlashCommand(input, ctx) {
45591
45867
  // 24h
45592
45868
  nonce: Math.random().toString(36).slice(2, 10)
45593
45869
  };
45594
- const jwtFile = join56(ctx.repoRoot, ".oa", "fortemi-jwt.json");
45595
- mkdirSync16(join56(ctx.repoRoot, ".oa"), { recursive: true });
45596
- 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));
45597
45873
  renderInfo(`Launching fortemi-react from ${fDir}...`);
45598
45874
  try {
45599
45875
  const { spawn: spawn21 } = __require("node:child_process");
45600
45876
  const child = spawn21("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
45601
- cwd: join56(fDir, "apps", "standalone"),
45877
+ cwd: join57(fDir, "apps", "standalone"),
45602
45878
  stdio: "ignore",
45603
45879
  detached: true,
45604
45880
  env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
@@ -45607,8 +45883,8 @@ async function handleSlashCommand(input, ctx) {
45607
45883
  renderInfo("Fortemi-React starting on http://localhost:3000");
45608
45884
  renderInfo(`JWT saved to ${jwtFile}`);
45609
45885
  renderInfo("Memory operations will proxy to fortemi when available.");
45610
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45611
- writeFileSync17(bridgeFile, JSON.stringify({
45886
+ const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45887
+ writeFileSync18(bridgeFile, JSON.stringify({
45612
45888
  url: "http://localhost:3000",
45613
45889
  pid: child.pid,
45614
45890
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -45620,12 +45896,12 @@ async function handleSlashCommand(input, ctx) {
45620
45896
  return "handled";
45621
45897
  }
45622
45898
  if (fortemiSubCmd === "status") {
45623
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45624
- if (!existsSync40(bridgeFile)) {
45899
+ const bridgeFile = join57(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45900
+ if (!existsSync41(bridgeFile)) {
45625
45901
  renderInfo("Fortemi bridge: not connected. Run /fortemi start");
45626
45902
  return "handled";
45627
45903
  }
45628
- const bridge = JSON.parse(readFileSync29(bridgeFile, "utf8"));
45904
+ const bridge = JSON.parse(readFileSync30(bridgeFile, "utf8"));
45629
45905
  let alive = false;
45630
45906
  try {
45631
45907
  process.kill(bridge.pid, 0);
@@ -45645,15 +45921,15 @@ async function handleSlashCommand(input, ctx) {
45645
45921
  lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
45646
45922
  lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
45647
45923
  lines.push(` Started: ${bridge.startedAt}`);
45648
- 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")}`);
45649
45925
  lines.push("");
45650
45926
  safeLog(lines.join("\n"));
45651
45927
  return "handled";
45652
45928
  }
45653
45929
  if (fortemiSubCmd === "stop") {
45654
- const bridgeFile = join56(ctx.repoRoot, ".oa", "fortemi-bridge.json");
45655
- if (existsSync40(bridgeFile)) {
45656
- 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"));
45657
45933
  try {
45658
45934
  process.kill(bridge.pid, "SIGTERM");
45659
45935
  } catch {
@@ -47032,13 +47308,13 @@ async function showCohereDashboard(ctx) {
47032
47308
  } else if (idResult.key === "view") {
47033
47309
  await ik.execute({ operation: "hydrate" });
47034
47310
  } else if (idResult.key === "history") {
47035
- const snapDir = join56(ctx.repoRoot, ".oa", "identity", "snapshots");
47036
- if (existsSync40(snapDir)) {
47037
- 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();
47038
47314
  const snapItems = snaps.slice(0, 20).map((f) => ({
47039
47315
  key: f,
47040
47316
  label: f.replace(".json", ""),
47041
- detail: `${formatFileSize(statSync14(join56(snapDir, f)).size)}`
47317
+ detail: `${formatFileSize(statSync14(join57(snapDir, f)).size)}`
47042
47318
  }));
47043
47319
  if (snapItems.length > 0) {
47044
47320
  await tuiSelect({
@@ -47353,13 +47629,13 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
47353
47629
  if (!jsonDrop.confirmed || !jsonDrop.path) {
47354
47630
  continue;
47355
47631
  }
47356
- const { basename: basename17, join: pathJoin } = await import("node:path");
47357
- 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");
47358
47634
  const { homedir: homedir18 } = await import("node:os");
47359
- 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, "-");
47360
47636
  const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
47361
47637
  if (!exists(destDir))
47362
- mkdirSync24(destDir, { recursive: true });
47638
+ mkdirSync25(destDir, { recursive: true });
47363
47639
  copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
47364
47640
  copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
47365
47641
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -47504,7 +47780,7 @@ async function handleVoiceList(ctx, focusFilename) {
47504
47780
  const src = srcPath.trim();
47505
47781
  try {
47506
47782
  const { existsSync: fe, copyFileSync: cpf, mkdirSync: mkd } = __require("node:fs");
47507
- const { basename: basename17, join: pjoin } = __require("node:path");
47783
+ const { basename: basename18, join: pjoin } = __require("node:path");
47508
47784
  if (!fe(src)) {
47509
47785
  renderError(`File not found: ${src}`);
47510
47786
  helpers.render();
@@ -47512,7 +47788,7 @@ async function handleVoiceList(ctx, focusFilename) {
47512
47788
  }
47513
47789
  const refsDir = pjoin(__require("node:os").homedir(), ".open-agents", "voice", "clone-refs");
47514
47790
  mkd(refsDir, { recursive: true });
47515
- const destName = basename17(src);
47791
+ const destName = basename18(src);
47516
47792
  const dest = pjoin(refsDir, destName);
47517
47793
  cpf(src, dest);
47518
47794
  renderInfo(`Imported "${destName}" \u2192 ${dest}`);
@@ -47851,11 +48127,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
47851
48127
  const models = await fetchModels(peerUrl, authKey);
47852
48128
  if (models.length > 0) {
47853
48129
  try {
47854
- const { writeFileSync: writeFileSync23, mkdirSync: mkdirSync24 } = await import("node:fs");
47855
- const { join: join70, dirname: dirname22 } = await import("node:path");
47856
- const cachePath = join70(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
47857
- mkdirSync24(dirname22(cachePath), { recursive: true });
47858
- 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({
47859
48135
  peerId,
47860
48136
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
47861
48137
  models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
@@ -47904,7 +48180,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
47904
48180
  }
47905
48181
  }
47906
48182
  async function handleParallel(arg, ctx) {
47907
- const { execSync: execSync33 } = await import("node:child_process");
48183
+ const { execSync: execSync34 } = await import("node:child_process");
47908
48184
  const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
47909
48185
  const isRemote = ctx.config.backendType === "nexus";
47910
48186
  if (isRemote) {
@@ -47928,7 +48204,7 @@ async function handleParallel(arg, ctx) {
47928
48204
  }
47929
48205
  let systemdVal = "";
47930
48206
  try {
47931
- 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" });
47932
48208
  const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
47933
48209
  if (match)
47934
48210
  systemdVal = match[1];
@@ -47957,7 +48233,7 @@ async function handleParallel(arg, ctx) {
47957
48233
  }
47958
48234
  const isSystemd = (() => {
47959
48235
  try {
47960
- 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();
47961
48237
  return out === "active" || out === "inactive";
47962
48238
  } catch {
47963
48239
  return false;
@@ -47971,10 +48247,10 @@ async function handleParallel(arg, ctx) {
47971
48247
  const overrideContent = `[Service]
47972
48248
  Environment="OLLAMA_NUM_PARALLEL=${n}"
47973
48249
  `;
47974
- execSync33(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
47975
- execSync33(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
47976
- execSync33("sudo systemctl daemon-reload", { stdio: "pipe" });
47977
- 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" });
47978
48254
  let ready = false;
47979
48255
  for (let i = 0; i < 30 && !ready; i++) {
47980
48256
  await new Promise((r) => setTimeout(r, 500));
@@ -48001,7 +48277,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
48001
48277
  renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
48002
48278
  try {
48003
48279
  try {
48004
- execSync33("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
48280
+ execSync34("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
48005
48281
  } catch {
48006
48282
  }
48007
48283
  await new Promise((r) => setTimeout(r, 1e3));
@@ -48054,17 +48330,17 @@ async function handleUpdate(subcommand, ctx) {
48054
48330
  try {
48055
48331
  const { createRequire: createRequire4 } = await import("node:module");
48056
48332
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
48057
- const { dirname: dirname22, join: join70 } = await import("node:path");
48058
- 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");
48059
48335
  const req = createRequire4(import.meta.url);
48060
48336
  const thisDir = dirname22(fileURLToPath14(import.meta.url));
48061
48337
  const candidates = [
48062
- join70(thisDir, "..", "package.json"),
48063
- join70(thisDir, "..", "..", "package.json"),
48064
- join70(thisDir, "..", "..", "..", "package.json")
48338
+ join71(thisDir, "..", "package.json"),
48339
+ join71(thisDir, "..", "..", "package.json"),
48340
+ join71(thisDir, "..", "..", "..", "package.json")
48065
48341
  ];
48066
48342
  for (const pkgPath of candidates) {
48067
- if (existsSync50(pkgPath)) {
48343
+ if (existsSync51(pkgPath)) {
48068
48344
  const pkg = req(pkgPath);
48069
48345
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
48070
48346
  currentVersion = pkg.version ?? "0.0.0";
@@ -48804,18 +49080,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
48804
49080
  const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
48805
49081
  let copied = false;
48806
49082
  try {
48807
- const { execSync: execSync33 } = __require("node:child_process");
49083
+ const { execSync: execSync34 } = __require("node:child_process");
48808
49084
  const platform6 = process.platform;
48809
49085
  if (platform6 === "darwin") {
48810
- execSync33("pbcopy", { input: cmd, timeout: 3e3 });
49086
+ execSync34("pbcopy", { input: cmd, timeout: 3e3 });
48811
49087
  copied = true;
48812
49088
  } else if (platform6 === "win32") {
48813
- execSync33("clip", { input: cmd, timeout: 3e3 });
49089
+ execSync34("clip", { input: cmd, timeout: 3e3 });
48814
49090
  copied = true;
48815
49091
  } else {
48816
49092
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
48817
49093
  try {
48818
- execSync33(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
49094
+ execSync34(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
48819
49095
  copied = true;
48820
49096
  break;
48821
49097
  } catch {
@@ -48902,9 +49178,9 @@ var init_commands = __esm({
48902
49178
  });
48903
49179
 
48904
49180
  // packages/cli/dist/tui/project-context.js
48905
- import { existsSync as existsSync41, readFileSync as readFileSync30, readdirSync as readdirSync12 } from "node:fs";
48906
- import { join as join57, basename as basename11 } from "node:path";
48907
- 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";
48908
49184
  import { homedir as homedir15, platform as platform4, release } from "node:os";
48909
49185
  function getModelTier(modelName) {
48910
49186
  const m = modelName.toLowerCase();
@@ -48938,10 +49214,10 @@ function loadProjectMap(repoRoot) {
48938
49214
  if (!hasOaDirectory(repoRoot)) {
48939
49215
  initOaDirectory(repoRoot);
48940
49216
  }
48941
- const mapPath2 = join57(repoRoot, OA_DIR, "context", "project-map.md");
48942
- if (existsSync41(mapPath2)) {
49217
+ const mapPath2 = join58(repoRoot, OA_DIR, "context", "project-map.md");
49218
+ if (existsSync42(mapPath2)) {
48943
49219
  try {
48944
- const content = readFileSync30(mapPath2, "utf-8");
49220
+ const content = readFileSync31(mapPath2, "utf-8");
48945
49221
  return content;
48946
49222
  } catch {
48947
49223
  }
@@ -48950,19 +49226,19 @@ function loadProjectMap(repoRoot) {
48950
49226
  }
48951
49227
  function getGitInfo(repoRoot) {
48952
49228
  try {
48953
- 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" });
48954
49230
  } catch {
48955
49231
  return "";
48956
49232
  }
48957
49233
  const lines = [];
48958
49234
  try {
48959
- 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();
48960
49236
  if (branch)
48961
49237
  lines.push(`Branch: ${branch}`);
48962
49238
  } catch {
48963
49239
  }
48964
49240
  try {
48965
- 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();
48966
49242
  if (status) {
48967
49243
  const changed = status.split("\n").length;
48968
49244
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -48972,7 +49248,7 @@ function getGitInfo(repoRoot) {
48972
49248
  } catch {
48973
49249
  }
48974
49250
  try {
48975
- 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();
48976
49252
  if (log)
48977
49253
  lines.push(`Recent commits:
48978
49254
  ${log}`);
@@ -48982,33 +49258,33 @@ ${log}`);
48982
49258
  }
48983
49259
  function loadMemoryContext(repoRoot) {
48984
49260
  const sections = [];
48985
- const oaMemDir = join57(repoRoot, OA_DIR, "memory");
49261
+ const oaMemDir = join58(repoRoot, OA_DIR, "memory");
48986
49262
  const oaEntries = loadMemoryDir(oaMemDir, "project");
48987
49263
  if (oaEntries)
48988
49264
  sections.push(oaEntries);
48989
- const legacyMemDir = join57(repoRoot, ".open-agents", "memory");
48990
- if (legacyMemDir !== oaMemDir && existsSync41(legacyMemDir)) {
49265
+ const legacyMemDir = join58(repoRoot, ".open-agents", "memory");
49266
+ if (legacyMemDir !== oaMemDir && existsSync42(legacyMemDir)) {
48991
49267
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
48992
49268
  if (legacyEntries)
48993
49269
  sections.push(legacyEntries);
48994
49270
  }
48995
- const globalMemDir = join57(homedir15(), ".open-agents", "memory");
49271
+ const globalMemDir = join58(homedir15(), ".open-agents", "memory");
48996
49272
  const globalEntries = loadMemoryDir(globalMemDir, "global");
48997
49273
  if (globalEntries)
48998
49274
  sections.push(globalEntries);
48999
49275
  return sections.join("\n\n");
49000
49276
  }
49001
49277
  function loadMemoryDir(memDir, scope) {
49002
- if (!existsSync41(memDir))
49278
+ if (!existsSync42(memDir))
49003
49279
  return "";
49004
49280
  const lines = [];
49005
49281
  try {
49006
- const files = readdirSync12(memDir).filter((f) => f.endsWith(".json"));
49282
+ const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
49007
49283
  for (const file of files.slice(0, 10)) {
49008
49284
  try {
49009
- const raw = readFileSync30(join57(memDir, file), "utf-8");
49285
+ const raw = readFileSync31(join58(memDir, file), "utf-8");
49010
49286
  const entries = JSON.parse(raw);
49011
- const topic = basename11(file, ".json");
49287
+ const topic = basename12(file, ".json");
49012
49288
  const keys = Object.keys(entries);
49013
49289
  if (keys.length === 0)
49014
49290
  continue;
@@ -50525,22 +50801,22 @@ var init_banner = __esm({
50525
50801
  });
50526
50802
 
50527
50803
  // packages/cli/dist/tui/carousel-descriptors.js
50528
- import { existsSync as existsSync42, readFileSync as readFileSync31, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "node:fs";
50529
- 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";
50530
50806
  function loadToolProfile(repoRoot) {
50531
- const filePath = join58(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
50807
+ const filePath = join59(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
50532
50808
  try {
50533
- if (!existsSync42(filePath))
50809
+ if (!existsSync43(filePath))
50534
50810
  return null;
50535
- return JSON.parse(readFileSync31(filePath, "utf-8"));
50811
+ return JSON.parse(readFileSync32(filePath, "utf-8"));
50536
50812
  } catch {
50537
50813
  return null;
50538
50814
  }
50539
50815
  }
50540
50816
  function saveToolProfile(repoRoot, profile) {
50541
- const contextDir = join58(repoRoot, OA_DIR, "context");
50542
- mkdirSync17(contextDir, { recursive: true });
50543
- 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");
50544
50820
  }
50545
50821
  function categorizeToolCall(toolName) {
50546
50822
  for (const cat of TOOL_CATEGORIES) {
@@ -50598,25 +50874,25 @@ function weightedColor(profile) {
50598
50874
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
50599
50875
  }
50600
50876
  function loadCachedDescriptors(repoRoot) {
50601
- const filePath = join58(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
50877
+ const filePath = join59(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
50602
50878
  try {
50603
- if (!existsSync42(filePath))
50879
+ if (!existsSync43(filePath))
50604
50880
  return null;
50605
- const cached = JSON.parse(readFileSync31(filePath, "utf-8"));
50881
+ const cached = JSON.parse(readFileSync32(filePath, "utf-8"));
50606
50882
  return cached.phrases.length > 0 ? cached.phrases : null;
50607
50883
  } catch {
50608
50884
  return null;
50609
50885
  }
50610
50886
  }
50611
50887
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
50612
- const contextDir = join58(repoRoot, OA_DIR, "context");
50613
- mkdirSync17(contextDir, { recursive: true });
50888
+ const contextDir = join59(repoRoot, OA_DIR, "context");
50889
+ mkdirSync18(contextDir, { recursive: true });
50614
50890
  const cached = {
50615
50891
  phrases,
50616
50892
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
50617
50893
  sourceHash
50618
50894
  };
50619
- 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");
50620
50896
  }
50621
50897
  function generateDescriptors(repoRoot) {
50622
50898
  const profile = loadToolProfile(repoRoot);
@@ -50627,7 +50903,7 @@ function generateDescriptors(repoRoot) {
50627
50903
  extractFromSessions(repoRoot, tags);
50628
50904
  extractFromMemory(repoRoot, tags);
50629
50905
  extractFromToolProfile(profile, tags);
50630
- const repoName2 = basename12(repoRoot);
50906
+ const repoName2 = basename13(repoRoot);
50631
50907
  if (repoName2 && !tags.includes(repoName2)) {
50632
50908
  tags.push(repoName2);
50633
50909
  }
@@ -50664,11 +50940,11 @@ function generateDescriptors(repoRoot) {
50664
50940
  return phrases;
50665
50941
  }
50666
50942
  function extractFromPackageJson(repoRoot, tags) {
50667
- const pkgPath = join58(repoRoot, "package.json");
50943
+ const pkgPath = join59(repoRoot, "package.json");
50668
50944
  try {
50669
- if (!existsSync42(pkgPath))
50945
+ if (!existsSync43(pkgPath))
50670
50946
  return;
50671
- const pkg = JSON.parse(readFileSync31(pkgPath, "utf-8"));
50947
+ const pkg = JSON.parse(readFileSync32(pkgPath, "utf-8"));
50672
50948
  if (pkg.name && typeof pkg.name === "string") {
50673
50949
  const parts = pkg.name.replace(/^@/, "").split("/");
50674
50950
  for (const p of parts)
@@ -50712,7 +50988,7 @@ function extractFromManifests(repoRoot, tags) {
50712
50988
  { file: ".github/workflows", tag: "ci/cd" }
50713
50989
  ];
50714
50990
  for (const check of manifestChecks) {
50715
- if (existsSync42(join58(repoRoot, check.file))) {
50991
+ if (existsSync43(join59(repoRoot, check.file))) {
50716
50992
  tags.push(check.tag);
50717
50993
  }
50718
50994
  }
@@ -50734,16 +51010,16 @@ function extractFromSessions(repoRoot, tags) {
50734
51010
  }
50735
51011
  }
50736
51012
  function extractFromMemory(repoRoot, tags) {
50737
- const memoryDir = join58(repoRoot, OA_DIR, "memory");
51013
+ const memoryDir = join59(repoRoot, OA_DIR, "memory");
50738
51014
  try {
50739
- if (!existsSync42(memoryDir))
51015
+ if (!existsSync43(memoryDir))
50740
51016
  return;
50741
- const files = readdirSync13(memoryDir).filter((f) => f.endsWith(".json"));
51017
+ const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
50742
51018
  for (const file of files) {
50743
51019
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
50744
51020
  tags.push(topic);
50745
51021
  try {
50746
- const data = JSON.parse(readFileSync31(join58(memoryDir, file), "utf-8"));
51022
+ const data = JSON.parse(readFileSync32(join59(memoryDir, file), "utf-8"));
50747
51023
  if (data && typeof data === "object") {
50748
51024
  const keys = Object.keys(data).slice(0, 3);
50749
51025
  for (const key of keys) {
@@ -51376,13 +51652,13 @@ var init_stream_renderer = __esm({
51376
51652
  });
51377
51653
 
51378
51654
  // packages/cli/dist/tui/edit-history.js
51379
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync18 } from "node:fs";
51380
- 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";
51381
51657
  function createEditHistoryLogger(repoRoot, sessionId) {
51382
- const historyDir = join59(repoRoot, ".oa", "history");
51383
- const logPath2 = join59(historyDir, "edits.jsonl");
51658
+ const historyDir = join60(repoRoot, ".oa", "history");
51659
+ const logPath2 = join60(historyDir, "edits.jsonl");
51384
51660
  try {
51385
- mkdirSync18(historyDir, { recursive: true });
51661
+ mkdirSync19(historyDir, { recursive: true });
51386
51662
  } catch {
51387
51663
  }
51388
51664
  function logToolCall(toolName, toolArgs, success) {
@@ -51491,17 +51767,17 @@ var init_edit_history = __esm({
51491
51767
  });
51492
51768
 
51493
51769
  // packages/cli/dist/tui/promptLoader.js
51494
- import { readFileSync as readFileSync32, existsSync as existsSync43 } from "node:fs";
51495
- 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";
51496
51772
  import { fileURLToPath as fileURLToPath11 } from "node:url";
51497
51773
  function loadPrompt3(promptPath, vars) {
51498
51774
  let content = cache3.get(promptPath);
51499
51775
  if (content === void 0) {
51500
- const fullPath = join60(PROMPTS_DIR3, promptPath);
51501
- if (!existsSync43(fullPath)) {
51776
+ const fullPath = join61(PROMPTS_DIR3, promptPath);
51777
+ if (!existsSync44(fullPath)) {
51502
51778
  throw new Error(`Prompt file not found: ${fullPath}`);
51503
51779
  }
51504
- content = readFileSync32(fullPath, "utf-8");
51780
+ content = readFileSync33(fullPath, "utf-8");
51505
51781
  cache3.set(promptPath, content);
51506
51782
  }
51507
51783
  if (!vars)
@@ -51514,23 +51790,23 @@ var init_promptLoader3 = __esm({
51514
51790
  "use strict";
51515
51791
  __filename3 = fileURLToPath11(import.meta.url);
51516
51792
  __dirname6 = dirname19(__filename3);
51517
- devPath2 = join60(__dirname6, "..", "..", "prompts");
51518
- publishedPath2 = join60(__dirname6, "..", "prompts");
51519
- PROMPTS_DIR3 = existsSync43(devPath2) ? devPath2 : publishedPath2;
51793
+ devPath2 = join61(__dirname6, "..", "..", "prompts");
51794
+ publishedPath2 = join61(__dirname6, "..", "prompts");
51795
+ PROMPTS_DIR3 = existsSync44(devPath2) ? devPath2 : publishedPath2;
51520
51796
  cache3 = /* @__PURE__ */ new Map();
51521
51797
  }
51522
51798
  });
51523
51799
 
51524
51800
  // packages/cli/dist/tui/dream-engine.js
51525
- import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readFileSync as readFileSync33, existsSync as existsSync44, cpSync, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
51526
- import { join as join61, basename as basename13 } from "node:path";
51527
- 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";
51528
51804
  function loadAutoresearchMemory(repoRoot) {
51529
- const memoryPath = join61(repoRoot, ".oa", "memory", "autoresearch.json");
51530
- if (!existsSync44(memoryPath))
51805
+ const memoryPath = join62(repoRoot, ".oa", "memory", "autoresearch.json");
51806
+ if (!existsSync45(memoryPath))
51531
51807
  return "";
51532
51808
  try {
51533
- const raw = readFileSync33(memoryPath, "utf-8");
51809
+ const raw = readFileSync34(memoryPath, "utf-8");
51534
51810
  const data = JSON.parse(raw);
51535
51811
  const sections = [];
51536
51812
  for (const key of AUTORESEARCH_MEMORY_KEYS) {
@@ -51720,14 +51996,14 @@ var init_dream_engine = __esm({
51720
51996
  const content = String(args["content"] ?? "");
51721
51997
  if (!rawPath)
51722
51998
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
51723
- 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);
51724
52000
  if (!targetPath.startsWith(this.autoresearchDir)) {
51725
52001
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
51726
52002
  }
51727
52003
  try {
51728
- const dir = join61(targetPath, "..");
51729
- mkdirSync19(dir, { recursive: true });
51730
- writeFileSync19(targetPath, content, "utf-8");
52004
+ const dir = join62(targetPath, "..");
52005
+ mkdirSync20(dir, { recursive: true });
52006
+ writeFileSync20(targetPath, content, "utf-8");
51731
52007
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
51732
52008
  } catch (err) {
51733
52009
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51755,20 +52031,20 @@ var init_dream_engine = __esm({
51755
52031
  const rawPath = String(args["path"] ?? "");
51756
52032
  const oldStr = String(args["old_string"] ?? "");
51757
52033
  const newStr = String(args["new_string"] ?? "");
51758
- 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);
51759
52035
  if (!targetPath.startsWith(this.autoresearchDir)) {
51760
52036
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
51761
52037
  }
51762
52038
  try {
51763
- if (!existsSync44(targetPath)) {
52039
+ if (!existsSync45(targetPath)) {
51764
52040
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
51765
52041
  }
51766
- let content = readFileSync33(targetPath, "utf-8");
52042
+ let content = readFileSync34(targetPath, "utf-8");
51767
52043
  if (!content.includes(oldStr)) {
51768
52044
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
51769
52045
  }
51770
52046
  content = content.replace(oldStr, newStr);
51771
- writeFileSync19(targetPath, content, "utf-8");
52047
+ writeFileSync20(targetPath, content, "utf-8");
51772
52048
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
51773
52049
  } catch (err) {
51774
52050
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51809,14 +52085,14 @@ var init_dream_engine = __esm({
51809
52085
  const content = String(args["content"] ?? "");
51810
52086
  if (!rawPath)
51811
52087
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
51812
- 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);
51813
52089
  if (!targetPath.startsWith(this.dreamsDir)) {
51814
52090
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
51815
52091
  }
51816
52092
  try {
51817
- const dir = join61(targetPath, "..");
51818
- mkdirSync19(dir, { recursive: true });
51819
- writeFileSync19(targetPath, content, "utf-8");
52093
+ const dir = join62(targetPath, "..");
52094
+ mkdirSync20(dir, { recursive: true });
52095
+ writeFileSync20(targetPath, content, "utf-8");
51820
52096
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
51821
52097
  } catch (err) {
51822
52098
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51844,20 +52120,20 @@ var init_dream_engine = __esm({
51844
52120
  const rawPath = String(args["path"] ?? "");
51845
52121
  const oldStr = String(args["old_string"] ?? "");
51846
52122
  const newStr = String(args["new_string"] ?? "");
51847
- 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);
51848
52124
  if (!targetPath.startsWith(this.dreamsDir)) {
51849
52125
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
51850
52126
  }
51851
52127
  try {
51852
- if (!existsSync44(targetPath)) {
52128
+ if (!existsSync45(targetPath)) {
51853
52129
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
51854
52130
  }
51855
- let content = readFileSync33(targetPath, "utf-8");
52131
+ let content = readFileSync34(targetPath, "utf-8");
51856
52132
  if (!content.includes(oldStr)) {
51857
52133
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
51858
52134
  }
51859
52135
  content = content.replace(oldStr, newStr);
51860
- writeFileSync19(targetPath, content, "utf-8");
52136
+ writeFileSync20(targetPath, content, "utf-8");
51861
52137
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
51862
52138
  } catch (err) {
51863
52139
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -51888,7 +52164,7 @@ var init_dream_engine = __esm({
51888
52164
  }
51889
52165
  }
51890
52166
  try {
51891
- const output = execSync30(cmd, {
52167
+ const output = execSync31(cmd, {
51892
52168
  cwd: this.repoRoot,
51893
52169
  timeout: 3e4,
51894
52170
  encoding: "utf-8",
@@ -51911,7 +52187,7 @@ var init_dream_engine = __esm({
51911
52187
  constructor(config, repoRoot) {
51912
52188
  this.config = config;
51913
52189
  this.repoRoot = repoRoot;
51914
- this.dreamsDir = join61(repoRoot, ".oa", "dreams");
52190
+ this.dreamsDir = join62(repoRoot, ".oa", "dreams");
51915
52191
  this.state = {
51916
52192
  mode: "default",
51917
52193
  active: false,
@@ -51942,7 +52218,7 @@ var init_dream_engine = __esm({
51942
52218
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
51943
52219
  results: []
51944
52220
  };
51945
- mkdirSync19(this.dreamsDir, { recursive: true });
52221
+ mkdirSync20(this.dreamsDir, { recursive: true });
51946
52222
  this.saveDreamState();
51947
52223
  try {
51948
52224
  for (let cycle = 1; cycle <= totalCycles; cycle++) {
@@ -51995,8 +52271,8 @@ ${result.summary}`;
51995
52271
  if (mode !== "default" || cycle === totalCycles) {
51996
52272
  renderDreamContraction(cycle);
51997
52273
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
51998
- const summaryPath = join61(this.dreamsDir, `cycle-${cycle}-summary.md`);
51999
- writeFileSync19(summaryPath, cycleSummary, "utf-8");
52274
+ const summaryPath = join62(this.dreamsDir, `cycle-${cycle}-summary.md`);
52275
+ writeFileSync20(summaryPath, cycleSummary, "utf-8");
52000
52276
  }
52001
52277
  if (mode === "lucid" && !this.abortController.signal.aborted) {
52002
52278
  this.saveVersionCheckpoint(cycle);
@@ -52208,7 +52484,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
52208
52484
  }
52209
52485
  /** Build role-specific tool sets for swarm agents */
52210
52486
  buildSwarmTools(role, _workspace) {
52211
- const autoresearchDir = join61(this.repoRoot, ".oa", "autoresearch");
52487
+ const autoresearchDir = join62(this.repoRoot, ".oa", "autoresearch");
52212
52488
  const taskComplete = this.createSwarmTaskCompleteTool(role);
52213
52489
  switch (role) {
52214
52490
  case "researcher": {
@@ -52572,7 +52848,7 @@ INSTRUCTIONS:
52572
52848
  2. Summarize the key learnings and next steps
52573
52849
 
52574
52850
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
52575
- const reportPath = join61(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
52851
+ const reportPath = join62(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
52576
52852
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
52577
52853
 
52578
52854
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -52594,8 +52870,8 @@ ${summaryResult}
52594
52870
  *Generated by open-agents autoresearch swarm*
52595
52871
  `;
52596
52872
  try {
52597
- mkdirSync19(this.dreamsDir, { recursive: true });
52598
- writeFileSync19(reportPath, report, "utf-8");
52873
+ mkdirSync20(this.dreamsDir, { recursive: true });
52874
+ writeFileSync20(reportPath, report, "utf-8");
52599
52875
  } catch {
52600
52876
  }
52601
52877
  renderSwarmComplete(workspace);
@@ -52661,29 +52937,29 @@ ${summaryResult}
52661
52937
  }
52662
52938
  /** Save workspace backup for lucid mode */
52663
52939
  saveVersionCheckpoint(cycle) {
52664
- const checkpointDir = join61(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
52940
+ const checkpointDir = join62(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
52665
52941
  try {
52666
- mkdirSync19(checkpointDir, { recursive: true });
52942
+ mkdirSync20(checkpointDir, { recursive: true });
52667
52943
  try {
52668
- const gitStatus = execSync30("git status --porcelain", {
52944
+ const gitStatus = execSync31("git status --porcelain", {
52669
52945
  cwd: this.repoRoot,
52670
52946
  encoding: "utf-8",
52671
52947
  timeout: 1e4
52672
52948
  });
52673
- const gitDiff = execSync30("git diff", {
52949
+ const gitDiff = execSync31("git diff", {
52674
52950
  cwd: this.repoRoot,
52675
52951
  encoding: "utf-8",
52676
52952
  timeout: 1e4
52677
52953
  });
52678
- 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'", {
52679
52955
  cwd: this.repoRoot,
52680
52956
  encoding: "utf-8",
52681
52957
  timeout: 5e3
52682
52958
  }).trim();
52683
- writeFileSync19(join61(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
52684
- writeFileSync19(join61(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
52685
- writeFileSync19(join61(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
52686
- 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({
52687
52963
  cycle,
52688
52964
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
52689
52965
  gitHash,
@@ -52691,7 +52967,7 @@ ${summaryResult}
52691
52967
  }, null, 2), "utf-8");
52692
52968
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
52693
52969
  } catch {
52694
- 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");
52695
52971
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
52696
52972
  }
52697
52973
  } catch (err) {
@@ -52728,7 +53004,7 @@ Each proposal includes implementation entrypoints and estimated effort.
52728
53004
  /** Update the master proposal index */
52729
53005
  updateProposalIndex() {
52730
53006
  try {
52731
- 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();
52732
53008
  const index = `# Dream Proposals Index
52733
53009
 
52734
53010
  **Last updated**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -52749,14 +53025,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
52749
53025
  ---
52750
53026
  *Auto-generated by open-agents dream engine*
52751
53027
  `;
52752
- writeFileSync19(join61(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
53028
+ writeFileSync20(join62(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
52753
53029
  } catch {
52754
53030
  }
52755
53031
  }
52756
53032
  /** Save dream state for resume/inspection */
52757
53033
  saveDreamState() {
52758
53034
  try {
52759
- 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");
52760
53036
  } catch {
52761
53037
  }
52762
53038
  }
@@ -53130,8 +53406,8 @@ var init_bless_engine = __esm({
53130
53406
  });
53131
53407
 
53132
53408
  // packages/cli/dist/tui/dmn-engine.js
53133
- import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync20, mkdirSync as mkdirSync20, readdirSync as readdirSync15, unlinkSync as unlinkSync9 } from "node:fs";
53134
- 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";
53135
53411
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
53136
53412
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
53137
53413
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -53251,9 +53527,9 @@ var init_dmn_engine = __esm({
53251
53527
  constructor(config, repoRoot) {
53252
53528
  this.config = config;
53253
53529
  this.repoRoot = repoRoot;
53254
- this.stateDir = join62(repoRoot, ".oa", "dmn");
53255
- this.historyDir = join62(repoRoot, ".oa", "dmn", "cycles");
53256
- 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 });
53257
53533
  this.loadState();
53258
53534
  }
53259
53535
  get stats() {
@@ -53842,16 +54118,16 @@ OUTPUT: Call task_complete with JSON:
53842
54118
  async gatherMemoryTopics() {
53843
54119
  const topics = [];
53844
54120
  const dirs = [
53845
- join62(this.repoRoot, ".oa", "memory"),
53846
- join62(this.repoRoot, ".open-agents", "memory")
54121
+ join63(this.repoRoot, ".oa", "memory"),
54122
+ join63(this.repoRoot, ".open-agents", "memory")
53847
54123
  ];
53848
54124
  for (const dir of dirs) {
53849
- if (!existsSync45(dir))
54125
+ if (!existsSync46(dir))
53850
54126
  continue;
53851
54127
  try {
53852
- const files = readdirSync15(dir).filter((f) => f.endsWith(".json"));
54128
+ const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
53853
54129
  for (const f of files) {
53854
- const topic = basename14(f, ".json");
54130
+ const topic = basename15(f, ".json");
53855
54131
  if (!topics.includes(topic))
53856
54132
  topics.push(topic);
53857
54133
  }
@@ -53862,29 +54138,29 @@ OUTPUT: Call task_complete with JSON:
53862
54138
  }
53863
54139
  // ── State persistence ─────────────────────────────────────────────────
53864
54140
  loadState() {
53865
- const path = join62(this.stateDir, "state.json");
53866
- if (existsSync45(path)) {
54141
+ const path = join63(this.stateDir, "state.json");
54142
+ if (existsSync46(path)) {
53867
54143
  try {
53868
- this.state = JSON.parse(readFileSync34(path, "utf-8"));
54144
+ this.state = JSON.parse(readFileSync35(path, "utf-8"));
53869
54145
  } catch {
53870
54146
  }
53871
54147
  }
53872
54148
  }
53873
54149
  saveState() {
53874
54150
  try {
53875
- 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");
53876
54152
  } catch {
53877
54153
  }
53878
54154
  }
53879
54155
  saveCycleResult(result) {
53880
54156
  try {
53881
54157
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
53882
- writeFileSync20(join62(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
53883
- 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();
53884
54160
  if (files.length > 50) {
53885
54161
  for (const old of files.slice(0, files.length - 50)) {
53886
54162
  try {
53887
- unlinkSync9(join62(this.historyDir, old));
54163
+ unlinkSync10(join63(this.historyDir, old));
53888
54164
  } catch {
53889
54165
  }
53890
54166
  }
@@ -53897,8 +54173,8 @@ OUTPUT: Call task_complete with JSON:
53897
54173
  });
53898
54174
 
53899
54175
  // packages/cli/dist/tui/snr-engine.js
53900
- import { existsSync as existsSync46, readdirSync as readdirSync16, readFileSync as readFileSync35 } from "node:fs";
53901
- 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";
53902
54178
  function computeDPrime(signalScores, noiseScores) {
53903
54179
  if (signalScores.length === 0 || noiseScores.length === 0)
53904
54180
  return 0;
@@ -54138,20 +54414,20 @@ Call task_complete with the JSON array when done.`, onEvent)
54138
54414
  loadMemoryEntries(topics) {
54139
54415
  const entries = [];
54140
54416
  const dirs = [
54141
- join63(this.repoRoot, ".oa", "memory"),
54142
- join63(this.repoRoot, ".open-agents", "memory")
54417
+ join64(this.repoRoot, ".oa", "memory"),
54418
+ join64(this.repoRoot, ".open-agents", "memory")
54143
54419
  ];
54144
54420
  for (const dir of dirs) {
54145
- if (!existsSync46(dir))
54421
+ if (!existsSync47(dir))
54146
54422
  continue;
54147
54423
  try {
54148
- const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
54424
+ const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
54149
54425
  for (const f of files) {
54150
- const topic = basename15(f, ".json");
54426
+ const topic = basename16(f, ".json");
54151
54427
  if (topics.length > 0 && !topics.includes(topic))
54152
54428
  continue;
54153
54429
  try {
54154
- const data = JSON.parse(readFileSync35(join63(dir, f), "utf-8"));
54430
+ const data = JSON.parse(readFileSync36(join64(dir, f), "utf-8"));
54155
54431
  for (const [key, val] of Object.entries(data)) {
54156
54432
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
54157
54433
  entries.push({ topic, key, value });
@@ -54718,8 +54994,8 @@ var init_tool_policy = __esm({
54718
54994
  });
54719
54995
 
54720
54996
  // packages/cli/dist/tui/telegram-bridge.js
54721
- import { mkdirSync as mkdirSync21, existsSync as existsSync47, unlinkSync as unlinkSync10, readdirSync as readdirSync17, statSync as statSync15 } from "node:fs";
54722
- 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";
54723
54999
  import { writeFile as writeFileAsync } from "node:fs/promises";
54724
55000
  function convertMarkdownToTelegramHTML(md) {
54725
55001
  let html = md;
@@ -55047,7 +55323,7 @@ with summary "no_reply" to silently skip without responding.
55047
55323
  this.polling = true;
55048
55324
  this.abortController = new AbortController();
55049
55325
  try {
55050
- mkdirSync21(this.mediaCacheDir, { recursive: true });
55326
+ mkdirSync22(this.mediaCacheDir, { recursive: true });
55051
55327
  } catch {
55052
55328
  }
55053
55329
  this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
@@ -55484,7 +55760,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
55484
55760
  return null;
55485
55761
  const buffer = Buffer.from(await res.arrayBuffer());
55486
55762
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
55487
- const localPath = join64(this.mediaCacheDir, fileName);
55763
+ const localPath = join65(this.mediaCacheDir, fileName);
55488
55764
  await writeFileAsync(localPath, buffer);
55489
55765
  return localPath;
55490
55766
  } catch {
@@ -55572,7 +55848,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
55572
55848
  for (const [key, entry] of this.mediaCache) {
55573
55849
  if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
55574
55850
  try {
55575
- unlinkSync10(entry.localPath);
55851
+ unlinkSync11(entry.localPath);
55576
55852
  } catch {
55577
55853
  }
55578
55854
  this.mediaCache.delete(key);
@@ -56500,7 +56776,7 @@ __export(text_selection_exports, {
56500
56776
  stripAnsi: () => stripAnsi3,
56501
56777
  visibleLength: () => visibleLength
56502
56778
  });
56503
- import { execSync as execSync31 } from "node:child_process";
56779
+ import { execSync as execSync32 } from "node:child_process";
56504
56780
  function stripAnsi3(s) {
56505
56781
  return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
56506
56782
  }
@@ -56511,16 +56787,16 @@ function copyText(text) {
56511
56787
  try {
56512
56788
  const platform6 = process.platform;
56513
56789
  if (platform6 === "darwin") {
56514
- execSync31("pbcopy", { input: text, timeout: 3e3 });
56790
+ execSync32("pbcopy", { input: text, timeout: 3e3 });
56515
56791
  return true;
56516
56792
  }
56517
56793
  if (platform6 === "win32") {
56518
- execSync31("clip", { input: text, timeout: 3e3 });
56794
+ execSync32("clip", { input: text, timeout: 3e3 });
56519
56795
  return true;
56520
56796
  }
56521
56797
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
56522
56798
  try {
56523
- execSync31(tool, { input: text, timeout: 3e3 });
56799
+ execSync32(tool, { input: text, timeout: 3e3 });
56524
56800
  return true;
56525
56801
  } catch {
56526
56802
  continue;
@@ -56529,10 +56805,10 @@ function copyText(text) {
56529
56805
  if (!_clipboardAutoInstallAttempted) {
56530
56806
  _clipboardAutoInstallAttempted = true;
56531
56807
  try {
56532
- execSync31("which apt-get", { timeout: 2e3, stdio: "pipe" });
56808
+ execSync32("which apt-get", { timeout: 2e3, stdio: "pipe" });
56533
56809
  try {
56534
- execSync31("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
56535
- 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 });
56536
56812
  return true;
56537
56813
  } catch {
56538
56814
  }
@@ -56840,7 +57116,7 @@ var init_text_selection = __esm({
56840
57116
  });
56841
57117
 
56842
57118
  // packages/cli/dist/tui/status-bar.js
56843
- import { readFileSync as readFileSync36 } from "node:fs";
57119
+ import { readFileSync as readFileSync37 } from "node:fs";
56844
57120
  function setTerminalTitle(task, version) {
56845
57121
  if (!process.stdout.isTTY)
56846
57122
  return;
@@ -57522,7 +57798,7 @@ var init_status_bar = __esm({
57522
57798
  if (nexusDir) {
57523
57799
  try {
57524
57800
  const metricsPath = nexusDir + "/remote-metrics.json";
57525
- const raw = readFileSync36(metricsPath, "utf8");
57801
+ const raw = readFileSync37(metricsPath, "utf8");
57526
57802
  const cached = JSON.parse(raw);
57527
57803
  if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
57528
57804
  const m = cached.data;
@@ -59121,12 +59397,12 @@ var init_mouse_filter = __esm({
59121
59397
  import * as readline2 from "node:readline";
59122
59398
  import { Writable } from "node:stream";
59123
59399
  import { cwd } from "node:process";
59124
- 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";
59125
59401
  import { createRequire as createRequire2 } from "node:module";
59126
59402
  import { fileURLToPath as fileURLToPath12 } from "node:url";
59127
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync21, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync18, mkdirSync as mkdirSync22 } from "node:fs";
59128
- import { existsSync as existsSync48 } from "node:fs";
59129
- 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";
59130
59406
  import { homedir as homedir16 } from "node:os";
59131
59407
  function formatTimeAgo(date) {
59132
59408
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -59146,12 +59422,12 @@ function getVersion3() {
59146
59422
  const require2 = createRequire2(import.meta.url);
59147
59423
  const thisDir = dirname20(fileURLToPath12(import.meta.url));
59148
59424
  const candidates = [
59149
- join65(thisDir, "..", "package.json"),
59150
- join65(thisDir, "..", "..", "package.json"),
59151
- join65(thisDir, "..", "..", "..", "package.json")
59425
+ join66(thisDir, "..", "package.json"),
59426
+ join66(thisDir, "..", "..", "package.json"),
59427
+ join66(thisDir, "..", "..", "..", "package.json")
59152
59428
  ];
59153
59429
  for (const pkgPath of candidates) {
59154
- if (existsSync48(pkgPath)) {
59430
+ if (existsSync49(pkgPath)) {
59155
59431
  const pkg = require2(pkgPath);
59156
59432
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
59157
59433
  return pkg.version ?? "0.0.0";
@@ -59284,6 +59560,7 @@ function buildTools(repoRoot, config, contextWindowSize) {
59284
59560
  new SemanticMapTool(repoRoot),
59285
59561
  new RepoMapTool(repoRoot),
59286
59562
  new ProcessHealthTool(),
59563
+ new VideoUnderstandTool(repoRoot),
59287
59564
  // Full OA sub-process — callbacks wired after runner + statusBar created
59288
59565
  (() => {
59289
59566
  _fullSubAgentToolRef = new FullSubAgentTool(repoRoot, config.model, config.backendUrl);
@@ -59385,15 +59662,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
59385
59662
  function gatherMemorySnippets(root) {
59386
59663
  const snippets = [];
59387
59664
  const dirs = [
59388
- join65(root, ".oa", "memory"),
59389
- join65(root, ".open-agents", "memory")
59665
+ join66(root, ".oa", "memory"),
59666
+ join66(root, ".open-agents", "memory")
59390
59667
  ];
59391
59668
  for (const dir of dirs) {
59392
- if (!existsSync48(dir))
59669
+ if (!existsSync49(dir))
59393
59670
  continue;
59394
59671
  try {
59395
- for (const f of readdirSync18(dir).filter((f2) => f2.endsWith(".json"))) {
59396
- 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"));
59397
59674
  for (const val of Object.values(data)) {
59398
59675
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
59399
59676
  if (v.length > 10)
@@ -59550,9 +59827,9 @@ ${metabolismMemories}
59550
59827
  } catch {
59551
59828
  }
59552
59829
  try {
59553
- const archeFile = join65(repoRoot, ".oa", "arche", "variants.json");
59554
- if (existsSync48(archeFile)) {
59555
- 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"));
59556
59833
  if (variants.length > 0) {
59557
59834
  let filtered = variants;
59558
59835
  if (taskType) {
@@ -59689,9 +59966,9 @@ ${lines.join("\n")}
59689
59966
  const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
59690
59967
  let identityInjection = "";
59691
59968
  try {
59692
- const ikStateFile = join65(repoRoot, ".oa", "identity", "self-state.json");
59693
- if (existsSync48(ikStateFile)) {
59694
- 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"));
59695
59972
  const lines = [
59696
59973
  `[Identity State v${selfState.version}]`,
59697
59974
  `Self: ${selfState.narrative_summary}`,
@@ -60330,13 +60607,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60330
60607
  });
60331
60608
  }
60332
60609
  try {
60333
- const ikDir = join65(repoRoot, ".oa", "identity");
60334
- const ikFile = join65(ikDir, "self-state.json");
60610
+ const ikDir = join66(repoRoot, ".oa", "identity");
60611
+ const ikFile = join66(ikDir, "self-state.json");
60335
60612
  let ikState;
60336
- if (existsSync48(ikFile)) {
60337
- ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
60613
+ if (existsSync49(ikFile)) {
60614
+ ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
60338
60615
  } else {
60339
- mkdirSync22(ikDir, { recursive: true });
60616
+ mkdirSync23(ikDir, { recursive: true });
60340
60617
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
60341
60618
  ikState = {
60342
60619
  self_id: `oa-${machineId}`,
@@ -60362,7 +60639,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60362
60639
  }
60363
60640
  ikState.session_count = (ikState.session_count || 0) + 1;
60364
60641
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
60365
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
60642
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
60366
60643
  } catch (ikErr) {
60367
60644
  try {
60368
60645
  console.error("[IK-OBSERVE]", ikErr);
@@ -60377,14 +60654,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
60377
60654
  } else {
60378
60655
  renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
60379
60656
  try {
60380
- const ikFile = join65(repoRoot, ".oa", "identity", "self-state.json");
60381
- if (existsSync48(ikFile)) {
60382
- 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"));
60383
60660
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
60384
60661
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
60385
60662
  ikState.session_count = (ikState.session_count || 0) + 1;
60386
60663
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
60387
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
60664
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
60388
60665
  }
60389
60666
  } catch {
60390
60667
  }
@@ -60727,7 +61004,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
60727
61004
  let p2pGateway = null;
60728
61005
  let peerMesh = null;
60729
61006
  let inferenceRouter = null;
60730
- const secretVault = new SecretVault(join65(repoRoot, ".oa", "vault.enc"));
61007
+ const secretVault = new SecretVault(join66(repoRoot, ".oa", "vault.enc"));
60731
61008
  let adminSessionKey = null;
60732
61009
  const callSubAgents = /* @__PURE__ */ new Map();
60733
61010
  const streamRenderer = new StreamRenderer();
@@ -60947,13 +61224,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
60947
61224
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
60948
61225
  return [hits, line];
60949
61226
  }
60950
- const HISTORY_DIR = join65(homedir16(), ".open-agents");
60951
- 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");
60952
61229
  const MAX_HISTORY_LINES = 500;
60953
61230
  let savedHistory = [];
60954
61231
  try {
60955
- if (existsSync48(HISTORY_FILE)) {
60956
- const raw = readFileSync37(HISTORY_FILE, "utf8").trim();
61232
+ if (existsSync49(HISTORY_FILE)) {
61233
+ const raw = readFileSync38(HISTORY_FILE, "utf8").trim();
60957
61234
  if (raw)
60958
61235
  savedHistory = raw.split("\n").reverse();
60959
61236
  }
@@ -61033,12 +61310,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61033
61310
  if (!line.trim())
61034
61311
  return;
61035
61312
  try {
61036
- mkdirSync22(HISTORY_DIR, { recursive: true });
61313
+ mkdirSync23(HISTORY_DIR, { recursive: true });
61037
61314
  appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
61038
61315
  if (Math.random() < 0.02) {
61039
- const all = readFileSync37(HISTORY_FILE, "utf8").trim().split("\n");
61316
+ const all = readFileSync38(HISTORY_FILE, "utf8").trim().split("\n");
61040
61317
  if (all.length > MAX_HISTORY_LINES) {
61041
- 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");
61042
61319
  }
61043
61320
  }
61044
61321
  } catch {
@@ -61214,7 +61491,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61214
61491
  } catch {
61215
61492
  }
61216
61493
  try {
61217
- const oaDir = join65(repoRoot, ".oa");
61494
+ const oaDir = join66(repoRoot, ".oa");
61218
61495
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
61219
61496
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
61220
61497
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -61237,7 +61514,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
61237
61514
  } catch {
61238
61515
  }
61239
61516
  try {
61240
- const oaDir = join65(repoRoot, ".oa");
61517
+ const oaDir = join66(repoRoot, ".oa");
61241
61518
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
61242
61519
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
61243
61520
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -62121,7 +62398,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62121
62398
  kind,
62122
62399
  targetUrl,
62123
62400
  authKey,
62124
- stateDir: join65(repoRoot, ".oa"),
62401
+ stateDir: join66(repoRoot, ".oa"),
62125
62402
  passthrough: passthrough ?? false,
62126
62403
  loadbalance: loadbalance ?? false,
62127
62404
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -62169,7 +62446,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62169
62446
  await tunnelGateway.stop();
62170
62447
  tunnelGateway = null;
62171
62448
  }
62172
- 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") });
62173
62450
  newTunnel.on("stats", (stats) => {
62174
62451
  statusBar.setExposeStatus({
62175
62452
  status: stats.status,
@@ -62438,15 +62715,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62438
62715
  writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
62439
62716
  }
62440
62717
  try {
62441
- const nexusDir = join65(repoRoot, OA_DIR, "nexus");
62442
- const pidFile = join65(nexusDir, "daemon.pid");
62443
- if (existsSync48(pidFile)) {
62444
- 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);
62445
62722
  if (pid > 0) {
62446
62723
  try {
62447
62724
  if (process.platform === "win32") {
62448
62725
  try {
62449
- execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62726
+ execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62450
62727
  } catch {
62451
62728
  }
62452
62729
  } else {
@@ -62463,17 +62740,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62463
62740
  } catch {
62464
62741
  }
62465
62742
  try {
62466
- const voiceDir2 = join65(homedir16(), ".open-agents", "voice");
62743
+ const voiceDir2 = join66(homedir16(), ".open-agents", "voice");
62467
62744
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
62468
62745
  for (const pf of voicePidFiles) {
62469
- const pidPath = join65(voiceDir2, pf);
62470
- if (existsSync48(pidPath)) {
62746
+ const pidPath = join66(voiceDir2, pf);
62747
+ if (existsSync49(pidPath)) {
62471
62748
  try {
62472
- const pid = parseInt(readFileSync37(pidPath, "utf8").trim(), 10);
62749
+ const pid = parseInt(readFileSync38(pidPath, "utf8").trim(), 10);
62473
62750
  if (pid > 0) {
62474
62751
  if (process.platform === "win32") {
62475
62752
  try {
62476
- execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62753
+ execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
62477
62754
  } catch {
62478
62755
  }
62479
62756
  } else {
@@ -62490,11 +62767,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62490
62767
  } catch {
62491
62768
  }
62492
62769
  try {
62493
- 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" });
62494
62771
  } catch {
62495
62772
  }
62496
- const oaPath = join65(repoRoot, OA_DIR);
62497
- if (existsSync48(oaPath)) {
62773
+ const oaPath = join66(repoRoot, OA_DIR);
62774
+ if (existsSync49(oaPath)) {
62498
62775
  let deleted = false;
62499
62776
  for (let attempt = 0; attempt < 3; attempt++) {
62500
62777
  try {
@@ -62504,14 +62781,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
62504
62781
  } catch (err) {
62505
62782
  if (attempt < 2) {
62506
62783
  try {
62507
- 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" });
62508
62785
  } catch {
62509
62786
  }
62510
62787
  } else {
62511
62788
  writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
62512
62789
  if (process.platform === "win32") {
62513
62790
  try {
62514
- execSync32(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
62791
+ execSync33(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
62515
62792
  deleted = true;
62516
62793
  } catch {
62517
62794
  }
@@ -62866,8 +63143,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
62866
63143
  }
62867
63144
  }
62868
63145
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
62869
- const isImage = isImagePath(cleanPath) && existsSync48(resolve31(repoRoot, cleanPath));
62870
- 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));
62871
63148
  if (activeTask) {
62872
63149
  if (activeTask.runner.isPaused) {
62873
63150
  activeTask.runner.resume();
@@ -62876,7 +63153,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
62876
63153
  if (isImage) {
62877
63154
  try {
62878
63155
  const imgPath = resolve31(repoRoot, cleanPath);
62879
- const imgBuffer = readFileSync37(imgPath);
63156
+ const imgBuffer = readFileSync38(imgPath);
62880
63157
  const base64 = imgBuffer.toString("base64");
62881
63158
  const ext = extname11(cleanPath).toLowerCase();
62882
63159
  const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
@@ -63113,13 +63390,13 @@ NEW TASK: ${fullInput}`;
63113
63390
  writeContent(() => renderError(errMsg));
63114
63391
  if (failureStore) {
63115
63392
  try {
63116
- const { createHash: createHash5 } = await import("node:crypto");
63393
+ const { createHash: createHash6 } = await import("node:crypto");
63117
63394
  failureStore.insert({
63118
63395
  taskId: "",
63119
63396
  sessionId: `${Date.now()}`,
63120
63397
  repoRoot,
63121
63398
  failureType: "runtime-error",
63122
- 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),
63123
63400
  filePath: null,
63124
63401
  errorMessage: errMsg.slice(0, 500),
63125
63402
  context: null,
@@ -63375,13 +63652,13 @@ async function runWithTUI(task, config, repoPath) {
63375
63652
  const handle = startTask(task, config, repoRoot);
63376
63653
  await handle.promise;
63377
63654
  try {
63378
- const ikDir = join65(repoRoot, ".oa", "identity");
63379
- const ikFile = join65(ikDir, "self-state.json");
63655
+ const ikDir = join66(repoRoot, ".oa", "identity");
63656
+ const ikFile = join66(ikDir, "self-state.json");
63380
63657
  let ikState;
63381
- if (existsSync48(ikFile)) {
63382
- ikState = JSON.parse(readFileSync37(ikFile, "utf8"));
63658
+ if (existsSync49(ikFile)) {
63659
+ ikState = JSON.parse(readFileSync38(ikFile, "utf8"));
63383
63660
  } else {
63384
- mkdirSync22(ikDir, { recursive: true });
63661
+ mkdirSync23(ikDir, { recursive: true });
63385
63662
  ikState = {
63386
63663
  self_id: `oa-${Date.now().toString(36)}`,
63387
63664
  version: 1,
@@ -63403,7 +63680,7 @@ async function runWithTUI(task, config, repoPath) {
63403
63680
  ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
63404
63681
  ikState.session_count = (ikState.session_count || 0) + 1;
63405
63682
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
63406
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
63683
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
63407
63684
  } catch (ikErr) {
63408
63685
  }
63409
63686
  try {
@@ -63412,12 +63689,12 @@ async function runWithTUI(task, config, repoPath) {
63412
63689
  ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
63413
63690
  } catch {
63414
63691
  try {
63415
- const archeDir = join65(repoRoot, ".oa", "arche");
63416
- const archeFile = join65(archeDir, "variants.json");
63692
+ const archeDir = join66(repoRoot, ".oa", "arche");
63693
+ const archeFile = join66(archeDir, "variants.json");
63417
63694
  let variants = [];
63418
63695
  try {
63419
- if (existsSync48(archeFile))
63420
- variants = JSON.parse(readFileSync37(archeFile, "utf8"));
63696
+ if (existsSync49(archeFile))
63697
+ variants = JSON.parse(readFileSync38(archeFile, "utf8"));
63421
63698
  } catch {
63422
63699
  }
63423
63700
  variants.push({
@@ -63432,15 +63709,15 @@ async function runWithTUI(task, config, repoPath) {
63432
63709
  });
63433
63710
  if (variants.length > 50)
63434
63711
  variants = variants.slice(-50);
63435
- mkdirSync22(archeDir, { recursive: true });
63436
- writeFileSync21(archeFile, JSON.stringify(variants, null, 2));
63712
+ mkdirSync23(archeDir, { recursive: true });
63713
+ writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
63437
63714
  } catch {
63438
63715
  }
63439
63716
  }
63440
63717
  try {
63441
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63442
- if (existsSync48(metaFile)) {
63443
- 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"));
63444
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);
63445
63722
  let updated = false;
63446
63723
  for (const item of surfaced) {
@@ -63451,7 +63728,7 @@ async function runWithTUI(task, config, repoPath) {
63451
63728
  updated = true;
63452
63729
  }
63453
63730
  if (updated) {
63454
- writeFileSync21(metaFile, JSON.stringify(store, null, 2));
63731
+ writeFileSync22(metaFile, JSON.stringify(store, null, 2));
63455
63732
  }
63456
63733
  }
63457
63734
  } catch {
@@ -63504,9 +63781,9 @@ Rules:
63504
63781
  try {
63505
63782
  const { initDb: initDb2 } = __require("@open-agents/memory");
63506
63783
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
63507
- const dbDir = join65(repoRoot, ".oa", "memory");
63508
- mkdirSync22(dbDir, { recursive: true });
63509
- 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"));
63510
63787
  const memStore = new ProceduralMemoryStore2(db);
63511
63788
  memStore.createWithEmbedding({
63512
63789
  content: content.slice(0, 600),
@@ -63521,12 +63798,12 @@ Rules:
63521
63798
  db.close();
63522
63799
  } catch {
63523
63800
  }
63524
- const metaDir = join65(repoRoot, ".oa", "memory", "metabolism");
63525
- const storeFile = join65(metaDir, "store.json");
63801
+ const metaDir = join66(repoRoot, ".oa", "memory", "metabolism");
63802
+ const storeFile = join66(metaDir, "store.json");
63526
63803
  let store = [];
63527
63804
  try {
63528
- if (existsSync48(storeFile))
63529
- store = JSON.parse(readFileSync37(storeFile, "utf8"));
63805
+ if (existsSync49(storeFile))
63806
+ store = JSON.parse(readFileSync38(storeFile, "utf8"));
63530
63807
  } catch {
63531
63808
  }
63532
63809
  store.push({
@@ -63542,26 +63819,26 @@ Rules:
63542
63819
  });
63543
63820
  if (store.length > 100)
63544
63821
  store = store.slice(-100);
63545
- mkdirSync22(metaDir, { recursive: true });
63546
- writeFileSync21(storeFile, JSON.stringify(store, null, 2));
63822
+ mkdirSync23(metaDir, { recursive: true });
63823
+ writeFileSync22(storeFile, JSON.stringify(store, null, 2));
63547
63824
  }
63548
63825
  }
63549
63826
  } catch {
63550
63827
  }
63551
63828
  try {
63552
- const cohereSettingsFile = join65(repoRoot, ".oa", "settings.json");
63829
+ const cohereSettingsFile = join66(repoRoot, ".oa", "settings.json");
63553
63830
  let cohereActive = false;
63554
63831
  try {
63555
- if (existsSync48(cohereSettingsFile)) {
63556
- const settings = JSON.parse(readFileSync37(cohereSettingsFile, "utf8"));
63832
+ if (existsSync49(cohereSettingsFile)) {
63833
+ const settings = JSON.parse(readFileSync38(cohereSettingsFile, "utf8"));
63557
63834
  cohereActive = settings.cohere === true;
63558
63835
  }
63559
63836
  } catch {
63560
63837
  }
63561
63838
  if (cohereActive) {
63562
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63563
- if (existsSync48(metaFile)) {
63564
- 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"));
63565
63842
  const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
63566
63843
  if (latest && latest.scores?.confidence >= 0.6) {
63567
63844
  try {
@@ -63586,18 +63863,18 @@ Rules:
63586
63863
  }
63587
63864
  } catch (err) {
63588
63865
  try {
63589
- const ikFile = join65(repoRoot, ".oa", "identity", "self-state.json");
63590
- if (existsSync48(ikFile)) {
63591
- 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"));
63592
63869
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
63593
63870
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
63594
63871
  ikState.session_count = (ikState.session_count || 0) + 1;
63595
63872
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
63596
- writeFileSync21(ikFile, JSON.stringify(ikState, null, 2));
63873
+ writeFileSync22(ikFile, JSON.stringify(ikState, null, 2));
63597
63874
  }
63598
- const metaFile = join65(repoRoot, ".oa", "memory", "metabolism", "store.json");
63599
- if (existsSync48(metaFile)) {
63600
- 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"));
63601
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);
63602
63879
  for (const item of surfaced) {
63603
63880
  item.accessCount = (item.accessCount || 0) + 1;
@@ -63605,15 +63882,15 @@ Rules:
63605
63882
  item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
63606
63883
  item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
63607
63884
  }
63608
- writeFileSync21(metaFile, JSON.stringify(store, null, 2));
63885
+ writeFileSync22(metaFile, JSON.stringify(store, null, 2));
63609
63886
  }
63610
63887
  try {
63611
- const archeDir = join65(repoRoot, ".oa", "arche");
63612
- const archeFile = join65(archeDir, "variants.json");
63888
+ const archeDir = join66(repoRoot, ".oa", "arche");
63889
+ const archeFile = join66(archeDir, "variants.json");
63613
63890
  let variants = [];
63614
63891
  try {
63615
- if (existsSync48(archeFile))
63616
- variants = JSON.parse(readFileSync37(archeFile, "utf8"));
63892
+ if (existsSync49(archeFile))
63893
+ variants = JSON.parse(readFileSync38(archeFile, "utf8"));
63617
63894
  } catch {
63618
63895
  }
63619
63896
  variants.push({
@@ -63628,8 +63905,8 @@ Rules:
63628
63905
  });
63629
63906
  if (variants.length > 50)
63630
63907
  variants = variants.slice(-50);
63631
- mkdirSync22(archeDir, { recursive: true });
63632
- writeFileSync21(archeFile, JSON.stringify(variants, null, 2));
63908
+ mkdirSync23(archeDir, { recursive: true });
63909
+ writeFileSync22(archeFile, JSON.stringify(variants, null, 2));
63633
63910
  } catch {
63634
63911
  }
63635
63912
  } catch {
@@ -63717,8 +63994,8 @@ var init_run = __esm({
63717
63994
  import { glob } from "glob";
63718
63995
  import ignore from "ignore";
63719
63996
  import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
63720
- import { createHash as createHash4 } from "node:crypto";
63721
- 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";
63722
63999
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
63723
64000
  var init_codebase_indexer = __esm({
63724
64001
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -63762,7 +64039,7 @@ var init_codebase_indexer = __esm({
63762
64039
  const ig = ignore.default();
63763
64040
  if (this.config.respectGitignore) {
63764
64041
  try {
63765
- const gitignoreContent = await readFile23(join66(this.config.rootDir, ".gitignore"), "utf-8");
64042
+ const gitignoreContent = await readFile23(join67(this.config.rootDir, ".gitignore"), "utf-8");
63766
64043
  ig.add(gitignoreContent);
63767
64044
  } catch {
63768
64045
  }
@@ -63777,13 +64054,13 @@ var init_codebase_indexer = __esm({
63777
64054
  for (const relativePath of files) {
63778
64055
  if (ig.ignores(relativePath))
63779
64056
  continue;
63780
- const fullPath = join66(this.config.rootDir, relativePath);
64057
+ const fullPath = join67(this.config.rootDir, relativePath);
63781
64058
  try {
63782
64059
  const fileStat = await stat4(fullPath);
63783
64060
  if (fileStat.size > this.config.maxFileSize)
63784
64061
  continue;
63785
64062
  const content = await readFile23(fullPath);
63786
- const hash = createHash4("sha256").update(content).digest("hex");
64063
+ const hash = createHash5("sha256").update(content).digest("hex");
63787
64064
  const ext = extname12(relativePath);
63788
64065
  indexed.push({
63789
64066
  path: fullPath,
@@ -63800,7 +64077,7 @@ var init_codebase_indexer = __esm({
63800
64077
  }
63801
64078
  buildTree(files) {
63802
64079
  const root = {
63803
- name: basename16(this.config.rootDir),
64080
+ name: basename17(this.config.rootDir),
63804
64081
  path: this.config.rootDir,
63805
64082
  type: "directory",
63806
64083
  children: []
@@ -63823,7 +64100,7 @@ var init_codebase_indexer = __esm({
63823
64100
  if (!child) {
63824
64101
  child = {
63825
64102
  name: part,
63826
- path: join66(current.path, part),
64103
+ path: join67(current.path, part),
63827
64104
  type: "directory",
63828
64105
  children: []
63829
64106
  };
@@ -63906,13 +64183,13 @@ __export(index_repo_exports, {
63906
64183
  indexRepoCommand: () => indexRepoCommand
63907
64184
  });
63908
64185
  import { resolve as resolve32 } from "node:path";
63909
- import { existsSync as existsSync49, statSync as statSync16 } from "node:fs";
64186
+ import { existsSync as existsSync50, statSync as statSync16 } from "node:fs";
63910
64187
  import { cwd as cwd2 } from "node:process";
63911
64188
  async function indexRepoCommand(opts, _config) {
63912
64189
  const repoRoot = resolve32(opts.repoPath ?? cwd2());
63913
64190
  printHeader("Index Repository");
63914
64191
  printInfo(`Indexing: ${repoRoot}`);
63915
- if (!existsSync49(repoRoot)) {
64192
+ if (!existsSync50(repoRoot)) {
63916
64193
  printError(`Path does not exist: ${repoRoot}`);
63917
64194
  process.exit(1);
63918
64195
  }
@@ -64164,7 +64441,7 @@ var config_exports = {};
64164
64441
  __export(config_exports, {
64165
64442
  configCommand: () => configCommand
64166
64443
  });
64167
- import { join as join67, resolve as resolve33 } from "node:path";
64444
+ import { join as join68, resolve as resolve33 } from "node:path";
64168
64445
  import { homedir as homedir17 } from "node:os";
64169
64446
  import { cwd as cwd3 } from "node:process";
64170
64447
  function redactIfSensitive(key, value) {
@@ -64247,7 +64524,7 @@ function handleShow(opts, config) {
64247
64524
  }
64248
64525
  }
64249
64526
  printSection("Config File");
64250
- printInfo(`~/.open-agents/config.json (${join67(homedir17(), ".open-agents", "config.json")})`);
64527
+ printInfo(`~/.open-agents/config.json (${join68(homedir17(), ".open-agents", "config.json")})`);
64251
64528
  printSection("Priority Chain");
64252
64529
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
64253
64530
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -64286,7 +64563,7 @@ function handleSet(opts, _config) {
64286
64563
  const coerced = coerceForSettings(key, value);
64287
64564
  saveProjectSettings(repoRoot, { [key]: coerced });
64288
64565
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
64289
- printInfo(`Saved to ${join67(repoRoot, ".oa", "settings.json")}`);
64566
+ printInfo(`Saved to ${join68(repoRoot, ".oa", "settings.json")}`);
64290
64567
  printInfo("This override applies only when running in this workspace.");
64291
64568
  } catch (err) {
64292
64569
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -64544,8 +64821,8 @@ __export(eval_exports, {
64544
64821
  evalCommand: () => evalCommand
64545
64822
  });
64546
64823
  import { tmpdir as tmpdir10 } from "node:os";
64547
- import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync22 } from "node:fs";
64548
- 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";
64549
64826
  async function evalCommand(opts, config) {
64550
64827
  const suiteName = opts.suite ?? "basic";
64551
64828
  const suite = SUITES[suiteName];
@@ -64670,9 +64947,9 @@ async function evalCommand(opts, config) {
64670
64947
  process.exit(failed > 0 ? 1 : 0);
64671
64948
  }
64672
64949
  function createTempEvalRepo() {
64673
- const dir = join68(tmpdir10(), `open-agents-eval-${Date.now()}`);
64674
- mkdirSync23(dir, { recursive: true });
64675
- 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");
64676
64953
  return dir;
64677
64954
  }
64678
64955
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -64732,7 +65009,7 @@ init_updater();
64732
65009
  import { parseArgs as nodeParseArgs2 } from "node:util";
64733
65010
  import { createRequire as createRequire3 } from "node:module";
64734
65011
  import { fileURLToPath as fileURLToPath13 } from "node:url";
64735
- import { dirname as dirname21, join as join69 } from "node:path";
65012
+ import { dirname as dirname21, join as join70 } from "node:path";
64736
65013
 
64737
65014
  // packages/cli/dist/cli.js
64738
65015
  import { createInterface } from "node:readline";
@@ -64839,7 +65116,7 @@ init_output();
64839
65116
  function getVersion4() {
64840
65117
  try {
64841
65118
  const require2 = createRequire3(import.meta.url);
64842
- const pkgPath = join69(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
65119
+ const pkgPath = join70(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
64843
65120
  const pkg = require2(pkgPath);
64844
65121
  return pkg.version;
64845
65122
  } catch {