open-agents-ai 0.185.23 → 0.185.24

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 +1046 -682
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13741,9 +13741,9 @@ print("${sentinel}")
13741
13741
  if (!this.proc || this.proc.killed) {
13742
13742
  return { success: false, path: "" };
13743
13743
  }
13744
- const { mkdirSync: mkdirSync30, writeFileSync: writeFileSync29 } = await import("node:fs");
13744
+ const { mkdirSync: mkdirSync31, writeFileSync: writeFileSync30 } = await import("node:fs");
13745
13745
  const sessionDir = join22(this.cwd, ".oa", "rlm");
13746
- mkdirSync30(sessionDir, { recursive: true });
13746
+ mkdirSync31(sessionDir, { recursive: true });
13747
13747
  const sessionPath = join22(sessionDir, "session.json");
13748
13748
  try {
13749
13749
  const inspectCode = `
@@ -13767,7 +13767,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13767
13767
  trajectoryCount: this.trajectory.length,
13768
13768
  subCallCount: this.subCallCount
13769
13769
  };
13770
- writeFileSync29(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13770
+ writeFileSync30(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13771
13771
  return { success: true, path: sessionPath };
13772
13772
  }
13773
13773
  } catch {
@@ -13779,11 +13779,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13779
13779
  * what was previously computed. */
13780
13780
  async loadSessionInfo() {
13781
13781
  try {
13782
- const { readFileSync: readFileSync44, existsSync: existsSync56 } = await import("node:fs");
13782
+ const { readFileSync: readFileSync45, existsSync: existsSync57 } = await import("node:fs");
13783
13783
  const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
13784
- if (!existsSync56(sessionPath))
13784
+ if (!existsSync57(sessionPath))
13785
13785
  return null;
13786
- return JSON.parse(readFileSync44(sessionPath, "utf8"));
13786
+ return JSON.parse(readFileSync45(sessionPath, "utf8"));
13787
13787
  } catch {
13788
13788
  return null;
13789
13789
  }
@@ -13960,10 +13960,10 @@ var init_memory_metabolism = __esm({
13960
13960
  const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
13961
13961
  let lessons = [];
13962
13962
  try {
13963
- const { readdirSync: readdirSync23, readFileSync: readFileSync44 } = await import("node:fs");
13963
+ const { readdirSync: readdirSync23, readFileSync: readFileSync45 } = await import("node:fs");
13964
13964
  const files = readdirSync23(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
13965
13965
  for (const file of files) {
13966
- const lines = readFileSync44(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13966
+ const lines = readFileSync45(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13967
13967
  for (const line of lines) {
13968
13968
  try {
13969
13969
  const entry = JSON.parse(line);
@@ -14347,14 +14347,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14347
14347
  * Optionally filter by task type for phase-aware context (FSM paper insight).
14348
14348
  */
14349
14349
  getTopMemoriesSync(k = 5, taskType) {
14350
- const { readFileSync: readFileSync44, existsSync: existsSync56 } = __require("node:fs");
14350
+ const { readFileSync: readFileSync45, existsSync: existsSync57 } = __require("node:fs");
14351
14351
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14352
14352
  const storeFile = join23(metaDir, "store.json");
14353
- if (!existsSync56(storeFile))
14353
+ if (!existsSync57(storeFile))
14354
14354
  return "";
14355
14355
  let store = [];
14356
14356
  try {
14357
- store = JSON.parse(readFileSync44(storeFile, "utf8"));
14357
+ store = JSON.parse(readFileSync45(storeFile, "utf8"));
14358
14358
  } catch {
14359
14359
  return "";
14360
14360
  }
@@ -14376,14 +14376,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14376
14376
  /** Update memory scores based on task outcome. Called after task completion.
14377
14377
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
14378
14378
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
14379
- const { readFileSync: readFileSync44, writeFileSync: writeFileSync29, existsSync: existsSync56, mkdirSync: mkdirSync30 } = __require("node:fs");
14379
+ const { readFileSync: readFileSync45, writeFileSync: writeFileSync30, existsSync: existsSync57, mkdirSync: mkdirSync31 } = __require("node:fs");
14380
14380
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14381
14381
  const storeFile = join23(metaDir, "store.json");
14382
- if (!existsSync56(storeFile))
14382
+ if (!existsSync57(storeFile))
14383
14383
  return;
14384
14384
  let store = [];
14385
14385
  try {
14386
- store = JSON.parse(readFileSync44(storeFile, "utf8"));
14386
+ store = JSON.parse(readFileSync45(storeFile, "utf8"));
14387
14387
  } catch {
14388
14388
  return;
14389
14389
  }
@@ -14407,8 +14407,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14407
14407
  updated = true;
14408
14408
  }
14409
14409
  if (updated) {
14410
- mkdirSync30(metaDir, { recursive: true });
14411
- writeFileSync29(storeFile, JSON.stringify(store, null, 2));
14410
+ mkdirSync31(metaDir, { recursive: true });
14411
+ writeFileSync30(storeFile, JSON.stringify(store, null, 2));
14412
14412
  }
14413
14413
  }
14414
14414
  // ── Storage ──────────────────────────────────────────────────────────
@@ -14830,13 +14830,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14830
14830
  // Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
14831
14831
  /** Retrieve top-K strategies for context injection. Returns "" if none. */
14832
14832
  getRelevantStrategiesSync(k = 3, taskType) {
14833
- const { readFileSync: readFileSync44, existsSync: existsSync56 } = __require("node:fs");
14833
+ const { readFileSync: readFileSync45, existsSync: existsSync57 } = __require("node:fs");
14834
14834
  const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
14835
- if (!existsSync56(archiveFile))
14835
+ if (!existsSync57(archiveFile))
14836
14836
  return "";
14837
14837
  let variants = [];
14838
14838
  try {
14839
- variants = JSON.parse(readFileSync44(archiveFile, "utf8"));
14839
+ variants = JSON.parse(readFileSync45(archiveFile, "utf8"));
14840
14840
  } catch {
14841
14841
  return "";
14842
14842
  }
@@ -14854,13 +14854,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14854
14854
  }
14855
14855
  /** Archive a strategy variant synchronously (for task completion path) */
14856
14856
  archiveVariantSync(strategy, outcome, tags = []) {
14857
- const { readFileSync: readFileSync44, writeFileSync: writeFileSync29, existsSync: existsSync56, mkdirSync: mkdirSync30 } = __require("node:fs");
14857
+ const { readFileSync: readFileSync45, writeFileSync: writeFileSync30, existsSync: existsSync57, mkdirSync: mkdirSync31 } = __require("node:fs");
14858
14858
  const dir = join25(this.cwd, ".oa", "arche");
14859
14859
  const archiveFile = join25(dir, "variants.json");
14860
14860
  let variants = [];
14861
14861
  try {
14862
- if (existsSync56(archiveFile))
14863
- variants = JSON.parse(readFileSync44(archiveFile, "utf8"));
14862
+ if (existsSync57(archiveFile))
14863
+ variants = JSON.parse(readFileSync45(archiveFile, "utf8"));
14864
14864
  } catch {
14865
14865
  }
14866
14866
  variants.push({
@@ -14875,8 +14875,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14875
14875
  });
14876
14876
  if (variants.length > 50)
14877
14877
  variants = variants.slice(-50);
14878
- mkdirSync30(dir, { recursive: true });
14879
- writeFileSync29(archiveFile, JSON.stringify(variants, null, 2));
14878
+ mkdirSync31(dir, { recursive: true });
14879
+ writeFileSync30(archiveFile, JSON.stringify(variants, null, 2));
14880
14880
  }
14881
14881
  async saveArchive(variants) {
14882
14882
  const dir = join25(this.cwd, ".oa", "arche");
@@ -15840,9 +15840,9 @@ var init_vision = __esm({
15840
15840
  if (ollamaResult)
15841
15841
  return ollamaResult;
15842
15842
  try {
15843
- const { execSync: execSync34 } = await import("node:child_process");
15843
+ const { execSync: execSync35 } = await import("node:child_process");
15844
15844
  try {
15845
- execSync34("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
15845
+ execSync35("pip3 install --user moondream 2>/dev/null || pip install --user moondream 2>/dev/null", {
15846
15846
  timeout: 12e4,
15847
15847
  stdio: "pipe"
15848
15848
  });
@@ -15855,7 +15855,7 @@ var init_vision = __esm({
15855
15855
  } catch {
15856
15856
  }
15857
15857
  try {
15858
- execSync34("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
15858
+ execSync35("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
15859
15859
  const retryOllama = await this.tryOllamaVision(buffer, filename, action, prompt, length, start);
15860
15860
  if (retryOllama)
15861
15861
  return retryOllama;
@@ -15963,8 +15963,8 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
15963
15963
  const errText = await res.text().catch(() => "");
15964
15964
  if (res.status === 404 || /not found|does not exist/i.test(errText)) {
15965
15965
  try {
15966
- const { execSync: execSync34 } = await import("node:child_process");
15967
- execSync34("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
15966
+ const { execSync: execSync35 } = await import("node:child_process");
15967
+ execSync35("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
15968
15968
  res = await fetch(`${ollamaHost}/api/generate`, {
15969
15969
  method: "POST",
15970
15970
  headers: { "Content-Type": "application/json" },
@@ -27351,10 +27351,10 @@ ${marker}` : marker);
27351
27351
  if (!this._workingDirectory)
27352
27352
  return;
27353
27353
  try {
27354
- const { mkdirSync: mkdirSync30, writeFileSync: writeFileSync29 } = __require("node:fs");
27355
- const { join: join76 } = __require("node:path");
27356
- const sessionDir = join76(this._workingDirectory, ".oa", "session", this._sessionId);
27357
- mkdirSync30(sessionDir, { recursive: true });
27354
+ const { mkdirSync: mkdirSync31, writeFileSync: writeFileSync30 } = __require("node:fs");
27355
+ const { join: join77 } = __require("node:path");
27356
+ const sessionDir = join77(this._workingDirectory, ".oa", "session", this._sessionId);
27357
+ mkdirSync31(sessionDir, { recursive: true });
27358
27358
  const checkpoint = {
27359
27359
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
27360
27360
  sessionId: this._sessionId,
@@ -27366,7 +27366,7 @@ ${marker}` : marker);
27366
27366
  memexEntryCount: this._memexArchive.size,
27367
27367
  fileRegistrySize: this._fileRegistry.size
27368
27368
  };
27369
- writeFileSync29(join76(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
27369
+ writeFileSync30(join77(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
27370
27370
  } catch {
27371
27371
  }
27372
27372
  }
@@ -38906,26 +38906,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
38906
38906
  async function fetchPeerModels(peerId, authKey) {
38907
38907
  try {
38908
38908
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
38909
- const { existsSync: existsSync56, readFileSync: readFileSync44 } = await import("node:fs");
38910
- const { join: join76 } = await import("node:path");
38909
+ const { existsSync: existsSync57, readFileSync: readFileSync45 } = await import("node:fs");
38910
+ const { join: join77 } = await import("node:path");
38911
38911
  const cwd4 = process.cwd();
38912
38912
  const nexusTool = new NexusTool2(cwd4);
38913
38913
  const nexusDir = nexusTool.getNexusDir();
38914
38914
  let isLocalPeer = false;
38915
38915
  try {
38916
- const statusPath = join76(nexusDir, "status.json");
38917
- if (existsSync56(statusPath)) {
38918
- const status = JSON.parse(readFileSync44(statusPath, "utf8"));
38916
+ const statusPath = join77(nexusDir, "status.json");
38917
+ if (existsSync57(statusPath)) {
38918
+ const status = JSON.parse(readFileSync45(statusPath, "utf8"));
38919
38919
  if (status.peerId === peerId)
38920
38920
  isLocalPeer = true;
38921
38921
  }
38922
38922
  } catch {
38923
38923
  }
38924
38924
  if (isLocalPeer) {
38925
- const pricingPath = join76(nexusDir, "pricing.json");
38926
- if (existsSync56(pricingPath)) {
38925
+ const pricingPath = join77(nexusDir, "pricing.json");
38926
+ if (existsSync57(pricingPath)) {
38927
38927
  try {
38928
- const pricing = JSON.parse(readFileSync44(pricingPath, "utf8"));
38928
+ const pricing = JSON.parse(readFileSync45(pricingPath, "utf8"));
38929
38929
  const localModels = (pricing.models || []).map((m) => ({
38930
38930
  name: m.model || "unknown",
38931
38931
  size: m.parameterSize || "",
@@ -38939,10 +38939,10 @@ async function fetchPeerModels(peerId, authKey) {
38939
38939
  }
38940
38940
  }
38941
38941
  }
38942
- const cachePath = join76(nexusDir, "peer-models-cache.json");
38943
- if (existsSync56(cachePath)) {
38942
+ const cachePath = join77(nexusDir, "peer-models-cache.json");
38943
+ if (existsSync57(cachePath)) {
38944
38944
  try {
38945
- const cache4 = JSON.parse(readFileSync44(cachePath, "utf8"));
38945
+ const cache4 = JSON.parse(readFileSync45(cachePath, "utf8"));
38946
38946
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
38947
38947
  const age = Date.now() - new Date(cache4.cachedAt).getTime();
38948
38948
  if (age < 5 * 60 * 1e3) {
@@ -39057,10 +39057,10 @@ async function fetchPeerModels(peerId, authKey) {
39057
39057
  } catch {
39058
39058
  }
39059
39059
  if (isLocalPeer) {
39060
- const pricingPath = join76(nexusDir, "pricing.json");
39061
- if (existsSync56(pricingPath)) {
39060
+ const pricingPath = join77(nexusDir, "pricing.json");
39061
+ if (existsSync57(pricingPath)) {
39062
39062
  try {
39063
- const pricing = JSON.parse(readFileSync44(pricingPath, "utf8"));
39063
+ const pricing = JSON.parse(readFileSync45(pricingPath, "utf8"));
39064
39064
  return (pricing.models || []).map((m) => ({
39065
39065
  name: m.model || "unknown",
39066
39066
  size: m.parameterSize || "",
@@ -40724,13 +40724,321 @@ var init_tui_select = __esm({
40724
40724
  }
40725
40725
  });
40726
40726
 
40727
+ // packages/cli/dist/tui/personaplex.js
40728
+ var personaplex_exports = {};
40729
+ __export(personaplex_exports, {
40730
+ detectPersonaPlexCapability: () => detectPersonaPlexCapability,
40731
+ getPersonaPlexWSUrl: () => getPersonaPlexWSUrl,
40732
+ installPersonaPlex: () => installPersonaPlex,
40733
+ isPersonaPlexInstalled: () => isPersonaPlexInstalled,
40734
+ isPersonaPlexRunning: () => isPersonaPlexRunning,
40735
+ startPersonaPlexDaemon: () => startPersonaPlexDaemon,
40736
+ stopPersonaPlex: () => stopPersonaPlex
40737
+ });
40738
+ import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, mkdirSync as mkdirSync15 } from "node:fs";
40739
+ import { join as join54 } from "node:path";
40740
+ import { homedir as homedir13 } from "node:os";
40741
+ import { execSync as execSync27, spawn as spawn19 } from "node:child_process";
40742
+ function detectPersonaPlexCapability() {
40743
+ try {
40744
+ const nvsmi = execSync27("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits", {
40745
+ encoding: "utf8",
40746
+ timeout: 5e3,
40747
+ stdio: "pipe"
40748
+ }).trim();
40749
+ if (!nvsmi) {
40750
+ return { supported: false, reason: "No NVIDIA GPU detected", gpuName: "", vramGB: 0 };
40751
+ }
40752
+ const [gpuName, vramMB] = nvsmi.split("\n")[0].split(", ");
40753
+ const vramGB = parseInt(vramMB ?? "0", 10) / 1024;
40754
+ if (vramGB < 16) {
40755
+ return { supported: false, reason: `GPU has ${vramGB.toFixed(1)}GB VRAM (need \u226516GB)`, gpuName: gpuName ?? "", vramGB };
40756
+ }
40757
+ try {
40758
+ execSync27('python3 -c "import torch; assert torch.cuda.is_available()"', {
40759
+ timeout: 1e4,
40760
+ stdio: "pipe"
40761
+ });
40762
+ } catch {
40763
+ return { supported: false, reason: "PyTorch CUDA not available", gpuName: gpuName ?? "", vramGB };
40764
+ }
40765
+ return { supported: true, reason: "OK", gpuName: gpuName ?? "", vramGB };
40766
+ } catch {
40767
+ return { supported: false, reason: "nvidia-smi not found", gpuName: "", vramGB: 0 };
40768
+ }
40769
+ }
40770
+ function isPersonaPlexRunning() {
40771
+ if (!existsSync37(PID_FILE))
40772
+ return false;
40773
+ const pid = parseInt(readFileSync28(PID_FILE, "utf8").trim(), 10);
40774
+ if (isNaN(pid) || pid <= 0)
40775
+ return false;
40776
+ try {
40777
+ process.kill(pid, 0);
40778
+ return true;
40779
+ } catch {
40780
+ return false;
40781
+ }
40782
+ }
40783
+ function getPersonaPlexWSUrl() {
40784
+ if (!isPersonaPlexRunning())
40785
+ return null;
40786
+ if (!existsSync37(PORT_FILE))
40787
+ return null;
40788
+ const port = parseInt(readFileSync28(PORT_FILE, "utf8").trim(), 10);
40789
+ return isNaN(port) ? null : `ws://127.0.0.1:${port}`;
40790
+ }
40791
+ function isPersonaPlexInstalled() {
40792
+ return existsSync37(join54(PERSONAPLEX_DIR, "model_ready"));
40793
+ }
40794
+ async function installPersonaPlex(onInfo) {
40795
+ const log = onInfo ?? (() => {
40796
+ });
40797
+ mkdirSync15(PERSONAPLEX_DIR, { recursive: true });
40798
+ const venvDir = join54(PERSONAPLEX_DIR, "venv");
40799
+ if (!existsSync37(venvDir)) {
40800
+ log("Creating Python virtual environment...");
40801
+ try {
40802
+ execSync27(`python3 -m venv "${venvDir}"`, { timeout: 6e4, stdio: "pipe" });
40803
+ } catch (err) {
40804
+ log(`Failed to create venv: ${err instanceof Error ? err.message : String(err)}`);
40805
+ return false;
40806
+ }
40807
+ }
40808
+ const pip = process.platform === "win32" ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
40809
+ const python = process.platform === "win32" ? join54(venvDir, "Scripts", "python.exe") : join54(venvDir, "bin", "python3");
40810
+ log("Installing PersonaPlex dependencies (torch, transformers, websockets)...");
40811
+ try {
40812
+ execSync27(`"${pip}" install --quiet torch torchaudio transformers websockets soundfile huggingface_hub`, { timeout: 3e5, stdio: "pipe" });
40813
+ } catch (err) {
40814
+ log(`Dependency install failed: ${err instanceof Error ? err.message : String(err)}`);
40815
+ return false;
40816
+ }
40817
+ log("Downloading PersonaPlex-7B model (~14GB, this may take a while)...");
40818
+ try {
40819
+ execSync27(`"${python}" -c "from huggingface_hub import snapshot_download; snapshot_download('nvidia/personaplex-7b-v1', local_dir='${join54(PERSONAPLEX_DIR, "model").replace(/\\/g, "\\\\")}')"`, { timeout: 36e5, stdio: "pipe" });
40820
+ } catch (err) {
40821
+ log(`Model download failed: ${err instanceof Error ? err.message : String(err)}`);
40822
+ return false;
40823
+ }
40824
+ writeFileSync16(join54(PERSONAPLEX_DIR, "model_ready"), (/* @__PURE__ */ new Date()).toISOString());
40825
+ log("PersonaPlex installed successfully.");
40826
+ return true;
40827
+ }
40828
+ function writeDaemonScript() {
40829
+ const scriptPath2 = join54(PERSONAPLEX_DIR, "daemon.py");
40830
+ const modelDir2 = join54(PERSONAPLEX_DIR, "model");
40831
+ const script = `#!/usr/bin/env python3
40832
+ """PersonaPlex daemon \u2014 full-duplex voice WebSocket server."""
40833
+ import asyncio
40834
+ import json
40835
+ import os
40836
+ import signal
40837
+ import sys
40838
+ import numpy as np
40839
+
40840
+ # Write PID file
40841
+ pid_file = os.path.join(os.path.dirname(__file__), "daemon.pid")
40842
+ with open(pid_file, "w") as f:
40843
+ f.write(str(os.getpid()))
40844
+
40845
+ try:
40846
+ import torch
40847
+ import torchaudio
40848
+ from transformers import AutoModel, AutoProcessor
40849
+ import websockets
40850
+ import soundfile as sf
40851
+ except ImportError as e:
40852
+ print(f"Missing dependency: {e}", file=sys.stderr)
40853
+ sys.exit(1)
40854
+
40855
+ MODEL_DIR = ${JSON.stringify(modelDir2)}
40856
+ SAMPLE_RATE = 24000
40857
+ PORT = int(os.environ.get("PERSONAPLEX_PORT", "0")) # 0 = auto-assign
40858
+
40859
+ print("Loading PersonaPlex model...", file=sys.stderr)
40860
+ device = "cuda" if torch.cuda.is_available() else "cpu"
40861
+ dtype = torch.bfloat16 if device == "cuda" else torch.float32
40862
+
40863
+ try:
40864
+ model = AutoModel.from_pretrained(MODEL_DIR, trust_remote_code=True, torch_dtype=dtype)
40865
+ model = model.to(device)
40866
+ model.eval()
40867
+ processor = AutoProcessor.from_pretrained(MODEL_DIR, trust_remote_code=True)
40868
+ print(f"Model loaded on {device}", file=sys.stderr)
40869
+ except Exception as e:
40870
+ print(f"Model load failed: {e}", file=sys.stderr)
40871
+ sys.exit(1)
40872
+
40873
+ # Persona state
40874
+ persona_text = "You are a helpful voice assistant."
40875
+ voice_prompt = None # Audio conditioning tensor
40876
+
40877
+ async def handle_client(websocket, path):
40878
+ """Handle a single WebSocket client connection."""
40879
+ global persona_text, voice_prompt
40880
+ print(f"Client connected from {websocket.remote_address}", file=sys.stderr)
40881
+
40882
+ try:
40883
+ async for message in websocket:
40884
+ if isinstance(message, str):
40885
+ # JSON control message
40886
+ try:
40887
+ msg = json.loads(message)
40888
+ if msg.get("type") == "persona":
40889
+ persona_text = msg.get("text", persona_text)
40890
+ print(f"Persona updated: {persona_text[:60]}", file=sys.stderr)
40891
+ elif msg.get("type") == "voice_prompt":
40892
+ # Audio conditioning: base64 PCM \u2192 tensor
40893
+ import base64
40894
+ pcm_bytes = base64.b64decode(msg["audio"])
40895
+ audio = np.frombuffer(pcm_bytes, dtype=np.int16).astype(np.float32) / 32768.0
40896
+ voice_prompt = torch.tensor(audio, dtype=dtype, device=device).unsqueeze(0)
40897
+ print(f"Voice prompt set ({len(audio)} samples)", file=sys.stderr)
40898
+ elif msg.get("type") == "keepalive":
40899
+ await websocket.send(json.dumps({"type": "pong"}))
40900
+ except json.JSONDecodeError:
40901
+ pass
40902
+ else:
40903
+ # Binary audio data: PCM Int16 @ 24kHz
40904
+ pcm = np.frombuffer(message, dtype=np.int16).astype(np.float32) / 32768.0
40905
+ audio_tensor = torch.tensor(pcm, dtype=dtype, device=device).unsqueeze(0)
40906
+
40907
+ # Generate response
40908
+ with torch.no_grad():
40909
+ inputs = processor(
40910
+ audio=audio_tensor,
40911
+ text=persona_text,
40912
+ sampling_rate=SAMPLE_RATE,
40913
+ return_tensors="pt"
40914
+ ).to(device)
40915
+
40916
+ if voice_prompt is not None:
40917
+ inputs["voice_prompt"] = voice_prompt
40918
+
40919
+ outputs = model.generate(**inputs, max_new_tokens=512)
40920
+
40921
+ # Extract audio response
40922
+ if hasattr(outputs, "audio"):
40923
+ response_pcm = outputs.audio.cpu().numpy().flatten()
40924
+ else:
40925
+ response_pcm = outputs[0].cpu().numpy().flatten()
40926
+
40927
+ # Convert to Int16 and send
40928
+ response_int16 = (response_pcm * 32767).astype(np.int16)
40929
+ await websocket.send(response_int16.tobytes())
40930
+
40931
+ # Send text if available
40932
+ if hasattr(outputs, "text") and outputs.text:
40933
+ await websocket.send(json.dumps({
40934
+ "type": "transcript",
40935
+ "speaker": "agent",
40936
+ "text": outputs.text
40937
+ }))
40938
+
40939
+ except websockets.exceptions.ConnectionClosed:
40940
+ print("Client disconnected", file=sys.stderr)
40941
+
40942
+ async def main():
40943
+ port = PORT
40944
+ server = await websockets.serve(handle_client, "127.0.0.1", port)
40945
+ actual_port = server.sockets[0].getsockname()[1]
40946
+
40947
+ # Write port file
40948
+ port_file = os.path.join(os.path.dirname(__file__), "daemon.port")
40949
+ with open(port_file, "w") as f:
40950
+ f.write(str(actual_port))
40951
+
40952
+ print(f"PersonaPlex daemon listening on ws://127.0.0.1:{actual_port}", file=sys.stderr)
40953
+
40954
+ # Handle shutdown
40955
+ loop = asyncio.get_event_loop()
40956
+ stop = asyncio.Future()
40957
+ for sig in (signal.SIGINT, signal.SIGTERM):
40958
+ loop.add_signal_handler(sig, stop.set_result, None)
40959
+ await stop
40960
+ server.close()
40961
+ await server.wait_closed()
40962
+
40963
+ asyncio.run(main())
40964
+ `;
40965
+ writeFileSync16(scriptPath2, script, "utf8");
40966
+ return scriptPath2;
40967
+ }
40968
+ async function startPersonaPlexDaemon(onInfo) {
40969
+ const log = onInfo ?? (() => {
40970
+ });
40971
+ if (isPersonaPlexRunning()) {
40972
+ const url = getPersonaPlexWSUrl();
40973
+ if (url) {
40974
+ log(`PersonaPlex already running at ${url}`);
40975
+ return url;
40976
+ }
40977
+ }
40978
+ if (!isPersonaPlexInstalled()) {
40979
+ log("PersonaPlex not installed. Run /voice personaplex to set up.");
40980
+ return null;
40981
+ }
40982
+ mkdirSync15(PERSONAPLEX_DIR, { recursive: true });
40983
+ const scriptPath2 = writeDaemonScript();
40984
+ const venvPython2 = process.platform === "win32" ? join54(PERSONAPLEX_DIR, "venv", "Scripts", "python.exe") : join54(PERSONAPLEX_DIR, "venv", "bin", "python3");
40985
+ log("Starting PersonaPlex daemon...");
40986
+ const child = spawn19(venvPython2, [scriptPath2], {
40987
+ stdio: ["ignore", "pipe", "pipe"],
40988
+ detached: true,
40989
+ env: { ...process.env, PERSONAPLEX_PORT: "0" }
40990
+ });
40991
+ child.unref();
40992
+ const startTime = Date.now();
40993
+ const timeout = 6e4;
40994
+ while (Date.now() - startTime < timeout) {
40995
+ if (existsSync37(PORT_FILE)) {
40996
+ const port = parseInt(readFileSync28(PORT_FILE, "utf8").trim(), 10);
40997
+ if (!isNaN(port) && port > 0) {
40998
+ const url = `ws://127.0.0.1:${port}`;
40999
+ log(`PersonaPlex ready at ${url}`);
41000
+ return url;
41001
+ }
41002
+ }
41003
+ await new Promise((r) => setTimeout(r, 1e3));
41004
+ }
41005
+ log("PersonaPlex daemon failed to start within 60s.");
41006
+ return null;
41007
+ }
41008
+ function stopPersonaPlex() {
41009
+ if (!existsSync37(PID_FILE))
41010
+ return;
41011
+ const pid = parseInt(readFileSync28(PID_FILE, "utf8").trim(), 10);
41012
+ if (isNaN(pid) || pid <= 0)
41013
+ return;
41014
+ try {
41015
+ if (process.platform === "win32") {
41016
+ execSync27(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
41017
+ } else {
41018
+ process.kill(pid, "SIGTERM");
41019
+ }
41020
+ } catch {
41021
+ }
41022
+ }
41023
+ var PERSONAPLEX_DIR, PID_FILE, PORT_FILE, LOG_FILE;
41024
+ var init_personaplex = __esm({
41025
+ "packages/cli/dist/tui/personaplex.js"() {
41026
+ "use strict";
41027
+ init_render();
41028
+ PERSONAPLEX_DIR = join54(homedir13(), ".open-agents", "voice", "personaplex");
41029
+ PID_FILE = join54(PERSONAPLEX_DIR, "daemon.pid");
41030
+ PORT_FILE = join54(PERSONAPLEX_DIR, "daemon.port");
41031
+ LOG_FILE = join54(PERSONAPLEX_DIR, "daemon.log");
41032
+ }
41033
+ });
41034
+
40727
41035
  // packages/cli/dist/tui/setup.js
40728
41036
  import * as readline from "node:readline";
40729
- import { execSync as execSync27, spawn as spawn19, exec as exec2 } from "node:child_process";
41037
+ import { execSync as execSync28, spawn as spawn20, exec as exec2 } from "node:child_process";
40730
41038
  import { promisify as promisify6 } from "node:util";
40731
- import { existsSync as existsSync37, writeFileSync as writeFileSync16, readFileSync as readFileSync28, appendFileSync as appendFileSync2, mkdirSync as mkdirSync15 } from "node:fs";
40732
- import { join as join54 } from "node:path";
40733
- import { homedir as homedir13, platform as platform2 } from "node:os";
41039
+ import { existsSync as existsSync38, writeFileSync as writeFileSync17, readFileSync as readFileSync29, appendFileSync as appendFileSync2, mkdirSync as mkdirSync16 } from "node:fs";
41040
+ import { join as join55 } from "node:path";
41041
+ import { homedir as homedir14, platform as platform2 } from "node:os";
40734
41042
  async function checkToolSupport(modelName, backendUrl = "http://localhost:11434") {
40735
41043
  if (_toolSupportCache.has(modelName))
40736
41044
  return _toolSupportCache.get(modelName);
@@ -40761,7 +41069,7 @@ function detectSystemSpecs() {
40761
41069
  let gpuVramGB = 0;
40762
41070
  let gpuName = "";
40763
41071
  try {
40764
- const memInfo = execSync27("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
41072
+ const memInfo = execSync28("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
40765
41073
  encoding: "utf8",
40766
41074
  timeout: 5e3
40767
41075
  });
@@ -40781,7 +41089,7 @@ function detectSystemSpecs() {
40781
41089
  } catch {
40782
41090
  }
40783
41091
  try {
40784
- const nvidiaSmi = execSync27("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
41092
+ const nvidiaSmi = execSync28("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
40785
41093
  const lines = nvidiaSmi.trim().split("\n");
40786
41094
  if (lines.length > 0) {
40787
41095
  for (const line of lines) {
@@ -40952,7 +41260,7 @@ function ensureCurl() {
40952
41260
  for (const s of strategies) {
40953
41261
  if (hasCmd(s.check)) {
40954
41262
  try {
40955
- execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
41263
+ execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
40956
41264
  if (hasCmd("curl")) {
40957
41265
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
40958
41266
  `);
@@ -40966,7 +41274,7 @@ function ensureCurl() {
40966
41274
  }
40967
41275
  if (plat === "darwin") {
40968
41276
  try {
40969
- execSync27("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
41277
+ execSync28("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
40970
41278
  if (hasCmd("curl"))
40971
41279
  return true;
40972
41280
  } catch {
@@ -41001,7 +41309,7 @@ function installOllamaLinux() {
41001
41309
 
41002
41310
  `);
41003
41311
  try {
41004
- execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
41312
+ execSync28("curl -fsSL https://ollama.com/install.sh | sh", {
41005
41313
  stdio: "inherit",
41006
41314
  timeout: 3e5
41007
41315
  });
@@ -41029,10 +41337,10 @@ async function installOllamaMac(_rl) {
41029
41337
 
41030
41338
  `);
41031
41339
  try {
41032
- execSync27('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
41340
+ execSync28('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
41033
41341
  if (!hasCmd("brew")) {
41034
41342
  try {
41035
- const brewPrefix = existsSync37("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
41343
+ const brewPrefix = existsSync38("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
41036
41344
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
41037
41345
  } catch {
41038
41346
  }
@@ -41062,7 +41370,7 @@ async function installOllamaMac(_rl) {
41062
41370
 
41063
41371
  `);
41064
41372
  try {
41065
- execSync27("brew install ollama", {
41373
+ execSync28("brew install ollama", {
41066
41374
  stdio: "inherit",
41067
41375
  timeout: 3e5
41068
41376
  });
@@ -41089,7 +41397,7 @@ function installOllamaWindows() {
41089
41397
 
41090
41398
  `);
41091
41399
  try {
41092
- execSync27('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
41400
+ execSync28('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
41093
41401
  stdio: "inherit",
41094
41402
  timeout: 3e5
41095
41403
  });
@@ -41140,7 +41448,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
41140
41448
  process.stdout.write(` ${c2.cyan("\u25CF")} Starting ollama serve...
41141
41449
  `);
41142
41450
  try {
41143
- const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
41451
+ const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
41144
41452
  child.unref();
41145
41453
  } catch {
41146
41454
  process.stdout.write(` ${c2.yellow("\u26A0")} Could not start ollama serve.
@@ -41170,7 +41478,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
41170
41478
  }
41171
41479
  function pullModelWithAutoUpdate(tag) {
41172
41480
  try {
41173
- execSync27(`ollama pull ${tag}`, {
41481
+ execSync28(`ollama pull ${tag}`, {
41174
41482
  stdio: "inherit",
41175
41483
  timeout: 36e5
41176
41484
  // 1 hour max
@@ -41190,7 +41498,7 @@ function pullModelWithAutoUpdate(tag) {
41190
41498
 
41191
41499
  `);
41192
41500
  try {
41193
- execSync27("curl -fsSL https://ollama.com/install.sh | sh", {
41501
+ execSync28("curl -fsSL https://ollama.com/install.sh | sh", {
41194
41502
  stdio: "inherit",
41195
41503
  timeout: 3e5
41196
41504
  // 5 min max for install
@@ -41201,7 +41509,7 @@ function pullModelWithAutoUpdate(tag) {
41201
41509
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
41202
41510
 
41203
41511
  `);
41204
- execSync27(`ollama pull ${tag}`, {
41512
+ execSync28(`ollama pull ${tag}`, {
41205
41513
  stdio: "inherit",
41206
41514
  timeout: 36e5
41207
41515
  });
@@ -41303,7 +41611,7 @@ function ensurePython3() {
41303
41611
  if (plat === "darwin") {
41304
41612
  if (hasCmd("brew")) {
41305
41613
  try {
41306
- execSync27("brew install python3", { stdio: "inherit", timeout: 3e5 });
41614
+ execSync28("brew install python3", { stdio: "inherit", timeout: 3e5 });
41307
41615
  if (hasCmd("python3")) {
41308
41616
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
41309
41617
  `);
@@ -41316,7 +41624,7 @@ function ensurePython3() {
41316
41624
  for (const s of strategies) {
41317
41625
  if (hasCmd(s.check)) {
41318
41626
  try {
41319
- execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
41627
+ execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
41320
41628
  if (hasCmd("python3") || hasCmd("python")) {
41321
41629
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
41322
41630
  `);
@@ -41332,11 +41640,11 @@ function ensurePython3() {
41332
41640
  }
41333
41641
  function checkPythonVenv() {
41334
41642
  try {
41335
- execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
41643
+ execSync28("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
41336
41644
  return true;
41337
41645
  } catch {
41338
41646
  try {
41339
- execSync27("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
41647
+ execSync28("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
41340
41648
  return true;
41341
41649
  } catch {
41342
41650
  return false;
@@ -41355,7 +41663,7 @@ function ensurePythonVenv() {
41355
41663
  for (const s of strategies) {
41356
41664
  if (hasCmd(s.check)) {
41357
41665
  try {
41358
- execSync27(s.install, { stdio: "inherit", timeout: 12e4 });
41666
+ execSync28(s.install, { stdio: "inherit", timeout: 12e4 });
41359
41667
  if (checkPythonVenv()) {
41360
41668
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
41361
41669
  `);
@@ -41513,6 +41821,20 @@ async function doSetup(config, rl) {
41513
41821
  } else {
41514
41822
  process.stdout.write(` ${c2.dim(" GPU:")} No NVIDIA GPU detected (CPU inference)
41515
41823
  `);
41824
+ }
41825
+ let personaPlexCapable = false;
41826
+ try {
41827
+ const { detectPersonaPlexCapability: detectPersonaPlexCapability2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
41828
+ const ppCaps = detectPersonaPlexCapability2();
41829
+ personaPlexCapable = ppCaps.supported;
41830
+ if (ppCaps.supported) {
41831
+ process.stdout.write(` ${c2.green("\u2714")} PersonaPlex full-duplex voice: ${c2.bold("compatible")} (${ppCaps.gpuName}, ${ppCaps.vramGB.toFixed(0)}GB VRAM)
41832
+ `);
41833
+ process.stdout.write(` ${c2.dim("Enable with: /voice personaplex")}
41834
+
41835
+ `);
41836
+ }
41837
+ } catch {
41516
41838
  }
41517
41839
  const score = computeInferenceScore(specs);
41518
41840
  const bw = 30;
@@ -41602,7 +41924,7 @@ async function doSetup(config, rl) {
41602
41924
  ${c2.cyan("\u25CF")} Ollama is installed but not running. Starting automatically...
41603
41925
  `);
41604
41926
  try {
41605
- const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
41927
+ const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
41606
41928
  child.unref();
41607
41929
  await new Promise((resolve36) => setTimeout(resolve36, 3e3));
41608
41930
  try {
@@ -41630,7 +41952,7 @@ async function doSetup(config, rl) {
41630
41952
  ${c2.cyan("\u25CF")} Starting ollama serve...
41631
41953
  `);
41632
41954
  try {
41633
- const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
41955
+ const child = spawn20("ollama", ["serve"], { stdio: "ignore", detached: true });
41634
41956
  child.unref();
41635
41957
  await new Promise((resolve36) => setTimeout(resolve36, 3e3));
41636
41958
  try {
@@ -41763,12 +42085,12 @@ async function doSetup(config, rl) {
41763
42085
  `PARAMETER num_predict ${numPredict}`,
41764
42086
  `PARAMETER stop "<|endoftext|>"`
41765
42087
  ].join("\n");
41766
- const modelDir2 = join54(homedir13(), ".open-agents", "models");
41767
- mkdirSync15(modelDir2, { recursive: true });
41768
- const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
41769
- writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
42088
+ const modelDir2 = join55(homedir14(), ".open-agents", "models");
42089
+ mkdirSync16(modelDir2, { recursive: true });
42090
+ const modelfilePath = join55(modelDir2, `Modelfile.${customName}`);
42091
+ writeFileSync17(modelfilePath, modelfileContent + "\n", "utf8");
41770
42092
  process.stdout.write(` ${c2.dim("Creating model...")} `);
41771
- execSync27(`ollama create ${customName} -f ${modelfilePath}`, {
42093
+ execSync28(`ollama create ${customName} -f ${modelfilePath}`, {
41772
42094
  stdio: "pipe",
41773
42095
  timeout: 12e4
41774
42096
  });
@@ -41811,7 +42133,7 @@ async function isModelAvailable(config) {
41811
42133
  }
41812
42134
  function isFirstRun() {
41813
42135
  try {
41814
- return !existsSync37(join54(homedir13(), ".open-agents", "config.json"));
42136
+ return !existsSync38(join55(homedir14(), ".open-agents", "config.json"));
41815
42137
  } catch {
41816
42138
  return true;
41817
42139
  }
@@ -41819,7 +42141,7 @@ function isFirstRun() {
41819
42141
  function hasCmd(cmd) {
41820
42142
  try {
41821
42143
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
41822
- execSync27(whichCmd, { stdio: "pipe", timeout: 3e3 });
42144
+ execSync28(whichCmd, { stdio: "pipe", timeout: 3e3 });
41823
42145
  return true;
41824
42146
  } catch {
41825
42147
  return false;
@@ -41848,11 +42170,11 @@ function detectPkgManager() {
41848
42170
  return null;
41849
42171
  }
41850
42172
  function getVenvDir() {
41851
- return join54(homedir13(), ".open-agents", "venv");
42173
+ return join55(homedir14(), ".open-agents", "venv");
41852
42174
  }
41853
42175
  function hasVenvModule() {
41854
42176
  try {
41855
- execSync27("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
42177
+ execSync28("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
41856
42178
  return true;
41857
42179
  } catch {
41858
42180
  return false;
@@ -41861,9 +42183,9 @@ function hasVenvModule() {
41861
42183
  function ensureVenv(log) {
41862
42184
  const venvDir = getVenvDir();
41863
42185
  const isWin2 = process.platform === "win32";
41864
- const pipPath = isWin2 ? join54(venvDir, "Scripts", "pip.exe") : join54(venvDir, "bin", "pip");
42186
+ const pipPath = isWin2 ? join55(venvDir, "Scripts", "pip.exe") : join55(venvDir, "bin", "pip");
41865
42187
  const pythonCmd = isWin2 ? "python" : "python3";
41866
- if (existsSync37(pipPath))
42188
+ if (existsSync38(pipPath))
41867
42189
  return venvDir;
41868
42190
  log("Creating Python venv for vision deps...");
41869
42191
  if (!hasCmd(pythonCmd) && !hasCmd("python3")) {
@@ -41875,10 +42197,10 @@ function ensureVenv(log) {
41875
42197
  return null;
41876
42198
  }
41877
42199
  try {
41878
- mkdirSync15(join54(homedir13(), ".open-agents"), { recursive: true });
42200
+ mkdirSync16(join55(homedir14(), ".open-agents"), { recursive: true });
41879
42201
  const pyCmd = hasCmd(pythonCmd) ? pythonCmd : "python3";
41880
- execSync27(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
41881
- execSync27(`"${pipPath}" install --upgrade pip`, {
42202
+ execSync28(`${pyCmd} -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
42203
+ execSync28(`"${pipPath}" install --upgrade pip`, {
41882
42204
  stdio: "pipe",
41883
42205
  timeout: 6e4
41884
42206
  });
@@ -41891,7 +42213,7 @@ function ensureVenv(log) {
41891
42213
  }
41892
42214
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
41893
42215
  try {
41894
- execSync27(`sudo -n ${cmd}`, {
42216
+ execSync28(`sudo -n ${cmd}`, {
41895
42217
  stdio: "pipe",
41896
42218
  timeout: timeoutMs,
41897
42219
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -41904,7 +42226,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
41904
42226
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
41905
42227
  try {
41906
42228
  const escaped = cmd.replace(/'/g, "'\\''");
41907
- execSync27(`sudo -S bash -c '${escaped}'`, {
42229
+ execSync28(`sudo -S bash -c '${escaped}'`, {
41908
42230
  input: password + "\n",
41909
42231
  stdio: ["pipe", "pipe", "pipe"],
41910
42232
  timeout: timeoutMs,
@@ -42021,7 +42343,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
42021
42343
  ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
42022
42344
  } else {
42023
42345
  try {
42024
- execSync27(batchCmd, { stdio: "pipe", timeout: 18e4 });
42346
+ execSync28(batchCmd, { stdio: "pipe", timeout: 18e4 });
42025
42347
  ok = true;
42026
42348
  } catch {
42027
42349
  ok = false;
@@ -42058,7 +42380,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
42058
42380
  const venvCmds = {
42059
42381
  apt: () => {
42060
42382
  try {
42061
- const pyVer = execSync27(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
42383
+ const pyVer = execSync28(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
42062
42384
  return `apt-get install -y python3-venv python${pyVer}-venv`;
42063
42385
  } catch {
42064
42386
  return "apt-get install -y python3-venv";
@@ -42079,19 +42401,19 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
42079
42401
  }
42080
42402
  }
42081
42403
  const venvDir = getVenvDir();
42082
- const venvBin = join54(venvDir, "bin");
42083
- const venvMoondream = join54(venvBin, "moondream-station");
42404
+ const venvBin = join55(venvDir, "bin");
42405
+ const venvMoondream = join55(venvBin, "moondream-station");
42084
42406
  const venv = ensureVenv(log);
42085
- if (venv && !hasCmd("moondream-station") && !existsSync37(venvMoondream)) {
42086
- const venvPip2 = join54(venvBin, "pip");
42407
+ if (venv && !hasCmd("moondream-station") && !existsSync38(venvMoondream)) {
42408
+ const venvPip2 = join55(venvBin, "pip");
42087
42409
  log("Installing moondream-station in ~/.open-agents/venv...");
42088
42410
  try {
42089
- execSync27(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
42090
- if (existsSync37(venvMoondream)) {
42411
+ execSync28(`"${venvPip2}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
42412
+ if (existsSync38(venvMoondream)) {
42091
42413
  log("moondream-station installed successfully.");
42092
42414
  } else {
42093
42415
  try {
42094
- const check = execSync27(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
42416
+ const check = execSync28(`"${venvPip2}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
42095
42417
  if (check.includes("moondream")) {
42096
42418
  log("moondream-station package installed.");
42097
42419
  }
@@ -42104,11 +42426,11 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
42104
42426
  }
42105
42427
  }
42106
42428
  if (venv) {
42107
- const venvPython2 = join54(venvBin, "python");
42108
- const venvPip2 = join54(venvBin, "pip");
42429
+ const venvPython2 = join55(venvBin, "python");
42430
+ const venvPip2 = join55(venvBin, "pip");
42109
42431
  let ocrStackInstalled = false;
42110
42432
  try {
42111
- execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
42433
+ execSync28(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
42112
42434
  ocrStackInstalled = true;
42113
42435
  } catch {
42114
42436
  }
@@ -42116,9 +42438,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
42116
42438
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
42117
42439
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
42118
42440
  try {
42119
- execSync27(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
42441
+ execSync28(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
42120
42442
  try {
42121
- execSync27(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
42443
+ execSync28(`"${venvPython2}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
42122
42444
  log("OCR Python stack installed successfully.");
42123
42445
  } catch {
42124
42446
  log("OCR Python stack install completed but import verification failed.");
@@ -42152,9 +42474,9 @@ function ensureCloudflaredBackground(onInfo) {
42152
42474
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
42153
42475
  const cfArch = archMap[arch2] ?? "amd64";
42154
42476
  try {
42155
- execSync27(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir13()}/.local/bin" && mv /tmp/cloudflared "${homedir13()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
42156
- if (!process.env.PATH?.includes(`${homedir13()}/.local/bin`)) {
42157
- process.env.PATH = `${homedir13()}/.local/bin:${process.env.PATH}`;
42477
+ execSync28(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir14()}/.local/bin" && mv /tmp/cloudflared "${homedir14()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
42478
+ if (!process.env.PATH?.includes(`${homedir14()}/.local/bin`)) {
42479
+ process.env.PATH = `${homedir14()}/.local/bin:${process.env.PATH}`;
42158
42480
  }
42159
42481
  if (hasCmd("cloudflared")) {
42160
42482
  log("cloudflared installed.");
@@ -42163,7 +42485,7 @@ function ensureCloudflaredBackground(onInfo) {
42163
42485
  } catch {
42164
42486
  }
42165
42487
  try {
42166
- 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 });
42488
+ execSync28(`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 });
42167
42489
  if (hasCmd("cloudflared")) {
42168
42490
  log("cloudflared installed.");
42169
42491
  return true;
@@ -42172,7 +42494,7 @@ function ensureCloudflaredBackground(onInfo) {
42172
42494
  }
42173
42495
  } else if (os === "darwin") {
42174
42496
  try {
42175
- execSync27("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
42497
+ execSync28("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
42176
42498
  if (hasCmd("cloudflared")) {
42177
42499
  log("cloudflared installed via Homebrew.");
42178
42500
  return true;
@@ -42249,10 +42571,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
42249
42571
  `PARAMETER num_predict ${numPredict}`,
42250
42572
  `PARAMETER stop "<|endoftext|>"`
42251
42573
  ].join("\n");
42252
- const modelDir2 = join54(homedir13(), ".open-agents", "models");
42253
- mkdirSync15(modelDir2, { recursive: true });
42254
- const modelfilePath = join54(modelDir2, `Modelfile.${customName}`);
42255
- writeFileSync16(modelfilePath, modelfileContent + "\n", "utf8");
42574
+ const modelDir2 = join55(homedir14(), ".open-agents", "models");
42575
+ mkdirSync16(modelDir2, { recursive: true });
42576
+ const modelfilePath = join55(modelDir2, `Modelfile.${customName}`);
42577
+ writeFileSync17(modelfilePath, modelfileContent + "\n", "utf8");
42256
42578
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
42257
42579
  timeout: 12e4
42258
42580
  });
@@ -42314,7 +42636,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
42314
42636
  }
42315
42637
  async function ensureNeovim() {
42316
42638
  try {
42317
- const nvimPath = execSync27("which nvim 2>/dev/null || where nvim 2>nul", {
42639
+ const nvimPath = execSync28("which nvim 2>/dev/null || where nvim 2>nul", {
42318
42640
  encoding: "utf8",
42319
42641
  stdio: "pipe",
42320
42642
  timeout: 5e3
@@ -42326,24 +42648,24 @@ async function ensureNeovim() {
42326
42648
  const platform6 = process.platform;
42327
42649
  const arch2 = process.arch;
42328
42650
  if (platform6 === "linux") {
42329
- const binDir = join54(homedir13(), ".local", "bin");
42330
- const nvimDest = join54(binDir, "nvim");
42651
+ const binDir = join55(homedir14(), ".local", "bin");
42652
+ const nvimDest = join55(binDir, "nvim");
42331
42653
  try {
42332
- mkdirSync15(binDir, { recursive: true });
42654
+ mkdirSync16(binDir, { recursive: true });
42333
42655
  } catch {
42334
42656
  }
42335
42657
  const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
42336
42658
  const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
42337
42659
  console.log(` Downloading Neovim (${appImageName})...`);
42338
42660
  try {
42339
- execSync27(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
42340
- execSync27(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
42661
+ execSync28(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
42662
+ execSync28(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
42341
42663
  } catch (err) {
42342
42664
  console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
42343
42665
  return null;
42344
42666
  }
42345
42667
  try {
42346
- const ver = execSync27(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
42668
+ const ver = execSync28(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
42347
42669
  console.log(` Installed: ${ver}`);
42348
42670
  } catch {
42349
42671
  console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
@@ -42358,8 +42680,8 @@ async function ensureNeovim() {
42358
42680
  if (hasCmd("brew")) {
42359
42681
  console.log(" Installing Neovim via Homebrew...");
42360
42682
  try {
42361
- execSync27("brew install neovim", { stdio: "inherit", timeout: 12e4 });
42362
- const nvimPath = execSync27("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
42683
+ execSync28("brew install neovim", { stdio: "inherit", timeout: 12e4 });
42684
+ const nvimPath = execSync28("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
42363
42685
  return nvimPath || null;
42364
42686
  } catch {
42365
42687
  console.log(" brew install neovim failed.");
@@ -42373,7 +42695,7 @@ async function ensureNeovim() {
42373
42695
  if (hasCmd("choco")) {
42374
42696
  console.log(" Installing Neovim via Chocolatey...");
42375
42697
  try {
42376
- execSync27("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
42698
+ execSync28("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
42377
42699
  return "nvim";
42378
42700
  } catch {
42379
42701
  console.log(" choco install neovim failed.");
@@ -42382,7 +42704,7 @@ async function ensureNeovim() {
42382
42704
  if (hasCmd("winget")) {
42383
42705
  console.log(" Installing Neovim via winget...");
42384
42706
  try {
42385
- execSync27("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
42707
+ execSync28("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
42386
42708
  stdio: "inherit",
42387
42709
  timeout: 12e4
42388
42710
  });
@@ -42398,9 +42720,9 @@ async function ensureNeovim() {
42398
42720
  }
42399
42721
  function ensurePathInShellRc(binDir) {
42400
42722
  const shell = process.env.SHELL ?? "";
42401
- const rcFile = shell.includes("zsh") ? join54(homedir13(), ".zshrc") : join54(homedir13(), ".bashrc");
42723
+ const rcFile = shell.includes("zsh") ? join55(homedir14(), ".zshrc") : join55(homedir14(), ".bashrc");
42402
42724
  try {
42403
- const rcContent = existsSync37(rcFile) ? readFileSync28(rcFile, "utf8") : "";
42725
+ const rcContent = existsSync38(rcFile) ? readFileSync29(rcFile, "utf8") : "";
42404
42726
  if (rcContent.includes(binDir))
42405
42727
  return;
42406
42728
  const exportLine = `
@@ -42438,7 +42760,7 @@ var init_setup = __esm({
42438
42760
  });
42439
42761
 
42440
42762
  // packages/cli/dist/tui/drop-panel.js
42441
- import { existsSync as existsSync38 } from "node:fs";
42763
+ import { existsSync as existsSync39 } from "node:fs";
42442
42764
  import { extname as extname10, resolve as resolve29 } from "node:path";
42443
42765
  function ansi4(code, text) {
42444
42766
  return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
@@ -42553,7 +42875,7 @@ function showDropPanel(opts) {
42553
42875
  filePath = decodeURIComponent(filePath.slice(7));
42554
42876
  }
42555
42877
  filePath = resolve29(filePath);
42556
- if (!existsSync38(filePath)) {
42878
+ if (!existsSync39(filePath)) {
42557
42879
  errorMsg = `File not found: ${filePath}`;
42558
42880
  render();
42559
42881
  return;
@@ -42624,10 +42946,10 @@ var init_drop_panel = __esm({
42624
42946
  });
42625
42947
 
42626
42948
  // packages/cli/dist/tui/neovim-mode.js
42627
- import { existsSync as existsSync39, unlinkSync as unlinkSync8 } from "node:fs";
42949
+ import { existsSync as existsSync40, unlinkSync as unlinkSync8 } from "node:fs";
42628
42950
  import { tmpdir as tmpdir8 } from "node:os";
42629
- import { join as join55 } from "node:path";
42630
- import { execSync as execSync28 } from "node:child_process";
42951
+ import { join as join56 } from "node:path";
42952
+ import { execSync as execSync29 } from "node:child_process";
42631
42953
  function isNeovimActive() {
42632
42954
  return _state !== null && !_state.cleanedUp;
42633
42955
  }
@@ -42645,7 +42967,7 @@ async function startNeovimMode(opts) {
42645
42967
  }
42646
42968
  let nvimPath;
42647
42969
  try {
42648
- nvimPath = execSync28("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
42970
+ nvimPath = execSync29("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
42649
42971
  if (!nvimPath)
42650
42972
  throw new Error();
42651
42973
  } catch {
@@ -42674,9 +42996,9 @@ async function startNeovimMode(opts) {
42674
42996
  );
42675
42997
  } catch {
42676
42998
  }
42677
- const socketPath = join55(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
42999
+ const socketPath = join56(tmpdir8(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
42678
43000
  try {
42679
- if (existsSync39(socketPath))
43001
+ if (existsSync40(socketPath))
42680
43002
  unlinkSync8(socketPath);
42681
43003
  } catch {
42682
43004
  }
@@ -42903,13 +43225,13 @@ function resizeNeovim(cols, contentRows) {
42903
43225
  }
42904
43226
  async function connectRPC(state, neovimPkg, cols) {
42905
43227
  let attempts = 0;
42906
- while (!existsSync39(state.socketPath) && attempts < 30) {
43228
+ while (!existsSync40(state.socketPath) && attempts < 30) {
42907
43229
  await new Promise((r) => setTimeout(r, 200));
42908
43230
  attempts++;
42909
43231
  if (state.cleanedUp)
42910
43232
  return;
42911
43233
  }
42912
- if (!existsSync39(state.socketPath))
43234
+ if (!existsSync40(state.socketPath))
42913
43235
  return;
42914
43236
  const nvim = neovimPkg.attach({ socket: state.socketPath });
42915
43237
  state.nvim = nvim;
@@ -43046,7 +43368,7 @@ function doCleanup(state) {
43046
43368
  state.pty = null;
43047
43369
  }
43048
43370
  try {
43049
- if (existsSync39(state.socketPath))
43371
+ if (existsSync40(state.socketPath))
43050
43372
  unlinkSync8(state.socketPath);
43051
43373
  } catch {
43052
43374
  }
@@ -43481,8 +43803,8 @@ __export(sponsor_wizard_exports, {
43481
43803
  saveSponsorConfig: () => saveSponsorConfig,
43482
43804
  showSponsorDashboard: () => showSponsorDashboard
43483
43805
  });
43484
- import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync16 } from "node:fs";
43485
- import { join as join56 } from "node:path";
43806
+ import { existsSync as existsSync41, readFileSync as readFileSync30, writeFileSync as writeFileSync18, mkdirSync as mkdirSync17 } from "node:fs";
43807
+ import { join as join57 } from "node:path";
43486
43808
  function colorPreview(code) {
43487
43809
  return `\x1B[38;5;${code}m\u2588\u2588\u2588\u2588\x1B[0m (${code})`;
43488
43810
  }
@@ -43495,26 +43817,26 @@ function gradientPreview(start, end) {
43495
43817
  return s;
43496
43818
  }
43497
43819
  function sponsorDir(projectDir) {
43498
- return join56(projectDir, ".oa", "sponsor");
43820
+ return join57(projectDir, ".oa", "sponsor");
43499
43821
  }
43500
43822
  function configPath(projectDir) {
43501
- return join56(sponsorDir(projectDir), "config.json");
43823
+ return join57(sponsorDir(projectDir), "config.json");
43502
43824
  }
43503
43825
  function loadSponsorConfig(projectDir) {
43504
43826
  const p = configPath(projectDir);
43505
- if (!existsSync40(p))
43827
+ if (!existsSync41(p))
43506
43828
  return null;
43507
43829
  try {
43508
- return JSON.parse(readFileSync29(p, "utf8"));
43830
+ return JSON.parse(readFileSync30(p, "utf8"));
43509
43831
  } catch {
43510
43832
  return null;
43511
43833
  }
43512
43834
  }
43513
43835
  function saveSponsorConfig(projectDir, config) {
43514
43836
  const dir = sponsorDir(projectDir);
43515
- mkdirSync16(dir, { recursive: true });
43837
+ mkdirSync17(dir, { recursive: true });
43516
43838
  config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
43517
- writeFileSync17(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
43839
+ writeFileSync18(configPath(projectDir), JSON.stringify(config, null, 2), "utf8");
43518
43840
  }
43519
43841
  function defaultConfig() {
43520
43842
  return {
@@ -44217,10 +44539,10 @@ __export(voice_exports, {
44217
44539
  registerCustomOnnxModel: () => registerCustomOnnxModel,
44218
44540
  resetNarrationContext: () => resetNarrationContext
44219
44541
  });
44220
- import { existsSync as existsSync41, mkdirSync as mkdirSync17, writeFileSync as writeFileSync18, readFileSync as readFileSync30, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
44221
- import { join as join57, dirname as dirname18 } from "node:path";
44222
- import { homedir as homedir14, tmpdir as tmpdir9, platform as platform3 } from "node:os";
44223
- import { execSync as execSync29, spawn as nodeSpawn } from "node:child_process";
44542
+ import { existsSync as existsSync42, mkdirSync as mkdirSync18, writeFileSync as writeFileSync19, readFileSync as readFileSync31, unlinkSync as unlinkSync9, readdirSync as readdirSync11, renameSync, statSync as statSync13 } from "node:fs";
44543
+ import { join as join58, dirname as dirname18 } from "node:path";
44544
+ import { homedir as homedir15, tmpdir as tmpdir9, platform as platform3 } from "node:os";
44545
+ import { execSync as execSync30, spawn as nodeSpawn } from "node:child_process";
44224
44546
  import { createRequire } from "node:module";
44225
44547
  function sanitizeForTTS(text) {
44226
44548
  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();
@@ -44243,40 +44565,40 @@ function listVoiceModels() {
44243
44565
  }));
44244
44566
  }
44245
44567
  function voiceDir() {
44246
- return join57(homedir14(), ".open-agents", "voice");
44568
+ return join58(homedir15(), ".open-agents", "voice");
44247
44569
  }
44248
44570
  function modelsDir() {
44249
- return join57(voiceDir(), "models");
44571
+ return join58(voiceDir(), "models");
44250
44572
  }
44251
44573
  function modelDir(id) {
44252
- return join57(modelsDir(), id);
44574
+ return join58(modelsDir(), id);
44253
44575
  }
44254
44576
  function modelOnnxPath(id) {
44255
- return join57(modelDir(id), "model.onnx");
44577
+ return join58(modelDir(id), "model.onnx");
44256
44578
  }
44257
44579
  function modelConfigPath(id) {
44258
- return join57(modelDir(id), "config.json");
44580
+ return join58(modelDir(id), "config.json");
44259
44581
  }
44260
44582
  function luxttsVenvDir() {
44261
- return join57(voiceDir(), "luxtts-venv");
44583
+ return join58(voiceDir(), "luxtts-venv");
44262
44584
  }
44263
44585
  function luxttsVenvPy() {
44264
- return platform3() === "win32" ? join57(luxttsVenvDir(), "Scripts", "python.exe") : join57(luxttsVenvDir(), "bin", "python3");
44586
+ return platform3() === "win32" ? join58(luxttsVenvDir(), "Scripts", "python.exe") : join58(luxttsVenvDir(), "bin", "python3");
44265
44587
  }
44266
44588
  function luxttsRepoDir() {
44267
- return join57(voiceDir(), "LuxTTS");
44589
+ return join58(voiceDir(), "LuxTTS");
44268
44590
  }
44269
44591
  function luxttsCloneRefsDir() {
44270
- return join57(voiceDir(), "clone-refs");
44592
+ return join58(voiceDir(), "clone-refs");
44271
44593
  }
44272
44594
  function luxttsInferScript() {
44273
- return join57(voiceDir(), "luxtts-infer.py");
44595
+ return join58(voiceDir(), "luxtts-infer.py");
44274
44596
  }
44275
44597
  function writeDetectTorchScript(targetPath) {
44276
- if (existsSync41(targetPath))
44598
+ if (existsSync42(targetPath))
44277
44599
  return;
44278
44600
  try {
44279
- mkdirSync17(dirname18(targetPath), { recursive: true });
44601
+ mkdirSync18(dirname18(targetPath), { recursive: true });
44280
44602
  } catch {
44281
44603
  }
44282
44604
  const script = `#!/usr/bin/env python3
@@ -44349,7 +44671,7 @@ def main():
44349
44671
  if __name__ == "__main__": main()
44350
44672
  `;
44351
44673
  try {
44352
- writeFileSync18(targetPath, script, { mode: 493 });
44674
+ writeFileSync19(targetPath, script, { mode: 493 });
44353
44675
  } catch {
44354
44676
  }
44355
44677
  }
@@ -45159,8 +45481,8 @@ var init_voice = __esm({
45159
45481
  const refsDir = luxttsCloneRefsDir();
45160
45482
  const targets = ["glados", "overwatch"];
45161
45483
  for (const modelId of targets) {
45162
- const refFile = join57(refsDir, `${modelId}-ref.wav`);
45163
- if (existsSync41(refFile))
45484
+ const refFile = join58(refsDir, `${modelId}-ref.wav`);
45485
+ if (existsSync42(refFile))
45164
45486
  continue;
45165
45487
  try {
45166
45488
  await this.generateCloneRef(modelId);
@@ -45239,24 +45561,24 @@ var init_voice = __esm({
45239
45561
  }
45240
45562
  p = p.replace(/\\ /g, " ");
45241
45563
  if (p.startsWith("~/") || p === "~") {
45242
- p = join57(homedir14(), p.slice(1));
45564
+ p = join58(homedir15(), p.slice(1));
45243
45565
  }
45244
- if (!existsSync41(p)) {
45566
+ if (!existsSync42(p)) {
45245
45567
  return `File not found: ${p}
45246
45568
  (original input: ${audioPath})`;
45247
45569
  }
45248
45570
  audioPath = p;
45249
45571
  const refsDir = luxttsCloneRefsDir();
45250
- if (!existsSync41(refsDir))
45251
- mkdirSync17(refsDir, { recursive: true });
45572
+ if (!existsSync42(refsDir))
45573
+ mkdirSync18(refsDir, { recursive: true });
45252
45574
  const ext = audioPath.split(".").pop() || "wav";
45253
45575
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
45254
45576
  const ts = Date.now().toString(36);
45255
45577
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
45256
- const destPath = join57(refsDir, destFilename);
45578
+ const destPath = join58(refsDir, destFilename);
45257
45579
  try {
45258
- const data = readFileSync30(audioPath);
45259
- writeFileSync18(destPath, data);
45580
+ const data = readFileSync31(audioPath);
45581
+ writeFileSync19(destPath, data);
45260
45582
  } catch (err) {
45261
45583
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
45262
45584
  }
@@ -45296,9 +45618,9 @@ var init_voice = __esm({
45296
45618
  return `Failed to synthesize reference audio from ${source.label}.`;
45297
45619
  }
45298
45620
  const refsDir = luxttsCloneRefsDir();
45299
- if (!existsSync41(refsDir))
45300
- mkdirSync17(refsDir, { recursive: true });
45301
- const destPath = join57(refsDir, `${sourceModelId}-ref.wav`);
45621
+ if (!existsSync42(refsDir))
45622
+ mkdirSync18(refsDir, { recursive: true });
45623
+ const destPath = join58(refsDir, `${sourceModelId}-ref.wav`);
45302
45624
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
45303
45625
  this.writeWav(audioData, sampleRate, destPath);
45304
45626
  this.luxttsCloneRef = destPath;
@@ -45314,23 +45636,23 @@ var init_voice = __esm({
45314
45636
  // -------------------------------------------------------------------------
45315
45637
  /** Metadata file for friendly names of clone refs */
45316
45638
  static cloneMetaFile() {
45317
- return join57(luxttsCloneRefsDir(), "meta.json");
45639
+ return join58(luxttsCloneRefsDir(), "meta.json");
45318
45640
  }
45319
45641
  loadCloneMeta() {
45320
45642
  const p = _VoiceEngine.cloneMetaFile();
45321
- if (!existsSync41(p))
45643
+ if (!existsSync42(p))
45322
45644
  return {};
45323
45645
  try {
45324
- return JSON.parse(readFileSync30(p, "utf8"));
45646
+ return JSON.parse(readFileSync31(p, "utf8"));
45325
45647
  } catch {
45326
45648
  return {};
45327
45649
  }
45328
45650
  }
45329
45651
  saveCloneMeta(meta) {
45330
45652
  const dir = luxttsCloneRefsDir();
45331
- if (!existsSync41(dir))
45332
- mkdirSync17(dir, { recursive: true });
45333
- writeFileSync18(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
45653
+ if (!existsSync42(dir))
45654
+ mkdirSync18(dir, { recursive: true });
45655
+ writeFileSync19(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
45334
45656
  }
45335
45657
  /** Audio file extensions recognized as clone references */
45336
45658
  static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
@@ -45340,7 +45662,7 @@ var init_voice = __esm({
45340
45662
  */
45341
45663
  listCloneRefs() {
45342
45664
  const dir = luxttsCloneRefsDir();
45343
- if (!existsSync41(dir))
45665
+ if (!existsSync42(dir))
45344
45666
  return [];
45345
45667
  const meta = this.loadCloneMeta();
45346
45668
  const files = readdirSync11(dir).filter((f) => {
@@ -45348,7 +45670,7 @@ var init_voice = __esm({
45348
45670
  return _VoiceEngine.AUDIO_EXTS.has(ext);
45349
45671
  });
45350
45672
  return files.map((f) => {
45351
- const p = join57(dir, f);
45673
+ const p = join58(dir, f);
45352
45674
  let size = 0;
45353
45675
  try {
45354
45676
  size = statSync13(p).size;
@@ -45365,8 +45687,8 @@ var init_voice = __esm({
45365
45687
  }
45366
45688
  /** Delete a clone reference file by filename. Returns true if deleted. */
45367
45689
  deleteCloneRef(filename) {
45368
- const p = join57(luxttsCloneRefsDir(), filename);
45369
- if (!existsSync41(p))
45690
+ const p = join58(luxttsCloneRefsDir(), filename);
45691
+ if (!existsSync42(p))
45370
45692
  return false;
45371
45693
  try {
45372
45694
  unlinkSync9(p);
@@ -45390,8 +45712,8 @@ var init_voice = __esm({
45390
45712
  }
45391
45713
  /** Set the active clone reference by filename. */
45392
45714
  setActiveCloneRef(filename) {
45393
- const p = join57(luxttsCloneRefsDir(), filename);
45394
- if (!existsSync41(p))
45715
+ const p = join58(luxttsCloneRefsDir(), filename);
45716
+ if (!existsSync42(p))
45395
45717
  return `File not found: ${filename}`;
45396
45718
  this.luxttsCloneRef = p;
45397
45719
  return `Active clone voice set to: ${filename}`;
@@ -45716,7 +46038,7 @@ var init_voice = __esm({
45716
46038
  }
45717
46039
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
45718
46040
  }
45719
- const wavPath = join57(tmpdir9(), `oa-voice-${Date.now()}.wav`);
46041
+ const wavPath = join58(tmpdir9(), `oa-voice-${Date.now()}.wav`);
45720
46042
  this.writeStereoWav(stereo.left, stereo.right, sampleRate, wavPath);
45721
46043
  await this.playWav(wavPath);
45722
46044
  try {
@@ -45833,7 +46155,7 @@ var init_voice = __esm({
45833
46155
  buffer.writeInt16LE(rSample < 0 ? rSample * 32768 : rSample * 32767, pos);
45834
46156
  pos += 2;
45835
46157
  }
45836
- writeFileSync18(path, buffer);
46158
+ writeFileSync19(path, buffer);
45837
46159
  }
45838
46160
  // -------------------------------------------------------------------------
45839
46161
  // Phonemization
@@ -45911,7 +46233,7 @@ var init_voice = __esm({
45911
46233
  return buffer;
45912
46234
  }
45913
46235
  writeWav(samples, sampleRate, path) {
45914
- writeFileSync18(path, this.buildWavBuffer(samples, sampleRate));
46236
+ writeFileSync19(path, this.buildWavBuffer(samples, sampleRate));
45915
46237
  }
45916
46238
  // -------------------------------------------------------------------------
45917
46239
  // Audio playback (system default speakers)
@@ -45961,7 +46283,7 @@ var init_voice = __esm({
45961
46283
  }
45962
46284
  for (const player of ["paplay", "pw-play", "aplay"]) {
45963
46285
  try {
45964
- execSync29(`which ${player}`, { stdio: "pipe" });
46286
+ execSync30(`which ${player}`, { stdio: "pipe" });
45965
46287
  return [player, path];
45966
46288
  } catch {
45967
46289
  }
@@ -45990,7 +46312,7 @@ var init_voice = __esm({
45990
46312
  return this.python3Path;
45991
46313
  for (const bin of ["python3", "python"]) {
45992
46314
  try {
45993
- const path = execSync29(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
46315
+ const path = execSync30(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
45994
46316
  if (path) {
45995
46317
  this.python3Path = path;
45996
46318
  return path;
@@ -46056,7 +46378,7 @@ var init_voice = __esm({
46056
46378
  return false;
46057
46379
  }
46058
46380
  try {
46059
- execSync29(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
46381
+ execSync30(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
46060
46382
  this.mlxInstalled = true;
46061
46383
  return true;
46062
46384
  } catch {
@@ -46109,7 +46431,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46109
46431
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
46110
46432
  const mlxVoice = model.mlxVoice ?? "af_heart";
46111
46433
  const mlxLangCode = model.mlxLangCode ?? "a";
46112
- const wavPath = join57(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
46434
+ const wavPath = join58(tmpdir9(), `oa-mlx-${Date.now()}.wav`);
46113
46435
  const pyScript = [
46114
46436
  "import sys, json",
46115
46437
  "from mlx_audio.tts import generate as tts_gen",
@@ -46117,20 +46439,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46117
46439
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
46118
46440
  ].join("; ");
46119
46441
  try {
46120
- execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
46442
+ execSync30(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
46121
46443
  } catch (err) {
46122
46444
  try {
46123
46445
  const safeText = cleaned.replace(/'/g, "'\\''");
46124
- 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() });
46446
+ execSync30(`${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() });
46125
46447
  } catch (err2) {
46126
46448
  return;
46127
46449
  }
46128
46450
  }
46129
- if (!existsSync41(wavPath))
46451
+ if (!existsSync42(wavPath))
46130
46452
  return;
46131
46453
  if (volume !== 1) {
46132
46454
  try {
46133
- const wavData = readFileSync30(wavPath);
46455
+ const wavData = readFileSync31(wavPath);
46134
46456
  if (wavData.length > 44) {
46135
46457
  const header = wavData.subarray(0, 44);
46136
46458
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -46138,14 +46460,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46138
46460
  samples[i] = Math.round(samples[i] * volume);
46139
46461
  }
46140
46462
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
46141
- writeFileSync18(wavPath, scaled);
46463
+ writeFileSync19(wavPath, scaled);
46142
46464
  }
46143
46465
  } catch {
46144
46466
  }
46145
46467
  }
46146
46468
  if (this.onPCMOutput) {
46147
46469
  try {
46148
- const wavData = readFileSync30(wavPath);
46470
+ const wavData = readFileSync31(wavPath);
46149
46471
  if (wavData.length > 44) {
46150
46472
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
46151
46473
  const sampleRate = wavData.readUInt32LE(24);
@@ -46177,7 +46499,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46177
46499
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
46178
46500
  const mlxVoice = model.mlxVoice ?? "af_heart";
46179
46501
  const mlxLangCode = model.mlxLangCode ?? "a";
46180
- const wavPath = join57(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
46502
+ const wavPath = join58(tmpdir9(), `oa-mlx-buf-${Date.now()}.wav`);
46181
46503
  const pyScript = [
46182
46504
  "import sys, json",
46183
46505
  "from mlx_audio.tts import generate as tts_gen",
@@ -46185,19 +46507,19 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46185
46507
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
46186
46508
  ].join("; ");
46187
46509
  try {
46188
- execSync29(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
46510
+ execSync30(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
46189
46511
  } catch {
46190
46512
  try {
46191
46513
  const safeText = cleaned.replace(/'/g, "'\\''");
46192
- 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() });
46514
+ execSync30(`${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() });
46193
46515
  } catch {
46194
46516
  return null;
46195
46517
  }
46196
46518
  }
46197
- if (!existsSync41(wavPath))
46519
+ if (!existsSync42(wavPath))
46198
46520
  return null;
46199
46521
  try {
46200
- const data = readFileSync30(wavPath);
46522
+ const data = readFileSync31(wavPath);
46201
46523
  unlinkSync9(wavPath);
46202
46524
  return data;
46203
46525
  } catch {
@@ -46220,7 +46542,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46220
46542
  }
46221
46543
  const venvDir = luxttsVenvDir();
46222
46544
  const venvPy = luxttsVenvPy();
46223
- if (existsSync41(venvPy)) {
46545
+ if (existsSync42(venvPy)) {
46224
46546
  try {
46225
46547
  await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
46226
46548
  let hasCudaSys = false;
@@ -46234,7 +46556,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46234
46556
  if (torchCheck === "cpu") {
46235
46557
  renderWarning("GPU detected but PyTorch is CPU-only. Reinstalling with CUDA support in background...");
46236
46558
  try {
46237
- const detectScript = join57(voiceDir(), "detect-torch.py");
46559
+ const detectScript = join58(voiceDir(), "detect-torch.py");
46238
46560
  writeDetectTorchScript(detectScript);
46239
46561
  let pipArgs = `torch torchaudio --index-url https://download.pytorch.org/whl/cu124`;
46240
46562
  try {
@@ -46259,7 +46581,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46259
46581
  }
46260
46582
  }
46261
46583
  renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
46262
- if (!existsSync41(venvDir)) {
46584
+ if (!existsSync42(venvDir)) {
46263
46585
  renderInfo(" Creating Python virtual environment...");
46264
46586
  try {
46265
46587
  await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
@@ -46268,7 +46590,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46268
46590
  }
46269
46591
  }
46270
46592
  {
46271
- const detectScript = join57(voiceDir(), "detect-torch.py");
46593
+ const detectScript = join58(voiceDir(), "detect-torch.py");
46272
46594
  writeDetectTorchScript(detectScript);
46273
46595
  let pipArgsStr = "torch torchaudio";
46274
46596
  let torchDesc = "unknown platform";
@@ -46305,10 +46627,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46305
46627
  }
46306
46628
  }
46307
46629
  const repoDir = luxttsRepoDir();
46308
- if (!existsSync41(join57(repoDir, "zipvoice", "luxvoice.py"))) {
46630
+ if (!existsSync42(join58(repoDir, "zipvoice", "luxvoice.py"))) {
46309
46631
  renderInfo(" Cloning LuxTTS repository...");
46310
46632
  try {
46311
- if (existsSync41(repoDir)) {
46633
+ if (existsSync42(repoDir)) {
46312
46634
  const rmCmd = process.platform === "win32" ? `rmdir /s /q ${JSON.stringify(repoDir)}` : `rm -rf ${JSON.stringify(repoDir)}`;
46313
46635
  await this.asyncShell(rmCmd, 3e4);
46314
46636
  }
@@ -46387,7 +46709,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46387
46709
  renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
46388
46710
  }
46389
46711
  }
46390
- const isJetson = isArm && (existsSync41("/etc/nv_tegra_release") || existsSync41("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
46712
+ const isJetson = isArm && (existsSync42("/etc/nv_tegra_release") || existsSync42("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
46391
46713
  const installSteps = isArm ? [
46392
46714
  // ARM: install individually so we get clear error messages per package.
46393
46715
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
@@ -46457,14 +46779,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
46457
46779
  }
46458
46780
  /** Auto-detect an existing clone reference in the refs directory */
46459
46781
  autoDetectCloneRef() {
46460
- if (this.luxttsCloneRef && existsSync41(this.luxttsCloneRef))
46782
+ if (this.luxttsCloneRef && existsSync42(this.luxttsCloneRef))
46461
46783
  return;
46462
46784
  const refsDir = luxttsCloneRefsDir();
46463
- if (!existsSync41(refsDir))
46785
+ if (!existsSync42(refsDir))
46464
46786
  return;
46465
46787
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
46466
- const p = join57(refsDir, name);
46467
- if (existsSync41(p)) {
46788
+ const p = join58(refsDir, name);
46789
+ if (existsSync42(p)) {
46468
46790
  this.luxttsCloneRef = p;
46469
46791
  return;
46470
46792
  }
@@ -46564,15 +46886,15 @@ if __name__ == '__main__':
46564
46886
  main()
46565
46887
  `;
46566
46888
  const scriptPath2 = luxttsInferScript();
46567
- mkdirSync17(voiceDir(), { recursive: true });
46568
- writeFileSync18(scriptPath2, script);
46889
+ mkdirSync18(voiceDir(), { recursive: true });
46890
+ writeFileSync19(scriptPath2, script);
46569
46891
  }
46570
46892
  /** Ensure the LuxTTS daemon is running, spawn if needed */
46571
46893
  async ensureLuxttsDaemon() {
46572
46894
  if (this._luxttsDaemon && !this._luxttsDaemon.killed)
46573
46895
  return true;
46574
46896
  const venvPy = luxttsVenvPy();
46575
- if (!existsSync41(venvPy))
46897
+ if (!existsSync42(venvPy))
46576
46898
  return false;
46577
46899
  return new Promise((resolve36) => {
46578
46900
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
@@ -46656,7 +46978,7 @@ if __name__ == '__main__':
46656
46978
  * Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
46657
46979
  */
46658
46980
  async synthesizeLuxttsWav(text, speedFactor = 1) {
46659
- if (!this.luxttsCloneRef || !existsSync41(this.luxttsCloneRef))
46981
+ if (!this.luxttsCloneRef || !existsSync42(this.luxttsCloneRef))
46660
46982
  return null;
46661
46983
  const cleaned = text.replace(/\*/g, "").trim();
46662
46984
  if (!cleaned)
@@ -46664,7 +46986,7 @@ if __name__ == '__main__':
46664
46986
  const ready = await this.ensureLuxttsDaemon();
46665
46987
  if (!ready)
46666
46988
  return null;
46667
- const wavPath = join57(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
46989
+ const wavPath = join58(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
46668
46990
  try {
46669
46991
  await this.luxttsRequest({
46670
46992
  action: "synthesize",
@@ -46676,17 +46998,17 @@ if __name__ == '__main__':
46676
46998
  } catch {
46677
46999
  return null;
46678
47000
  }
46679
- return existsSync41(wavPath) ? wavPath : null;
47001
+ return existsSync42(wavPath) ? wavPath : null;
46680
47002
  }
46681
47003
  /**
46682
47004
  * Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
46683
47005
  * Cleans up the WAV file after playback.
46684
47006
  */
46685
47007
  async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
46686
- if (!existsSync41(wavPath))
47008
+ if (!existsSync42(wavPath))
46687
47009
  return;
46688
47010
  try {
46689
- const wavData = readFileSync30(wavPath);
47011
+ const wavData = readFileSync31(wavPath);
46690
47012
  if (wavData.length > 44) {
46691
47013
  const sampleRate = wavData.readUInt32LE(24);
46692
47014
  const samples = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
@@ -46701,13 +47023,13 @@ if __name__ == '__main__':
46701
47023
  }
46702
47024
  const header = wavData.subarray(0, 44);
46703
47025
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
46704
- writeFileSync18(wavPath, scaled);
47026
+ writeFileSync19(wavPath, scaled);
46705
47027
  }
46706
47028
  } catch {
46707
47029
  }
46708
47030
  if (pitchFactor !== 1) {
46709
47031
  try {
46710
- const wavData = readFileSync30(wavPath);
47032
+ const wavData = readFileSync31(wavPath);
46711
47033
  if (wavData.length > 44) {
46712
47034
  const int16 = new Int16Array(wavData.buffer, wavData.byteOffset + 44, (wavData.length - 44) / 2);
46713
47035
  const float32 = new Float32Array(int16.length);
@@ -46722,7 +47044,7 @@ if __name__ == '__main__':
46722
47044
  }
46723
47045
  if (this.onPCMOutput) {
46724
47046
  try {
46725
- const wavData = readFileSync30(wavPath);
47047
+ const wavData = readFileSync31(wavPath);
46726
47048
  if (wavData.length > 44) {
46727
47049
  const pcm = Buffer.from(wavData.buffer, wavData.byteOffset + 44, wavData.length - 44);
46728
47050
  const sampleRate = wavData.readUInt32LE(24);
@@ -46733,7 +47055,7 @@ if __name__ == '__main__':
46733
47055
  }
46734
47056
  if (stereoDelayMs > 0) {
46735
47057
  try {
46736
- const wavData = readFileSync30(wavPath);
47058
+ const wavData = readFileSync31(wavPath);
46737
47059
  if (wavData.length > 44) {
46738
47060
  const sampleRate = wavData.readUInt32LE(24);
46739
47061
  const numChannels = wavData.readUInt16LE(22);
@@ -46769,7 +47091,7 @@ if __name__ == '__main__':
46769
47091
  * Used for Telegram voice messages and WebSocket streaming.
46770
47092
  */
46771
47093
  async synthesizeLuxttsToBuffer(text) {
46772
- if (!this.luxttsCloneRef || !existsSync41(this.luxttsCloneRef))
47094
+ if (!this.luxttsCloneRef || !existsSync42(this.luxttsCloneRef))
46773
47095
  return null;
46774
47096
  const cleaned = text.replace(/\*/g, "").trim();
46775
47097
  if (!cleaned)
@@ -46777,7 +47099,7 @@ if __name__ == '__main__':
46777
47099
  const ready = await this.ensureLuxttsDaemon();
46778
47100
  if (!ready)
46779
47101
  return null;
46780
- const wavPath = join57(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
47102
+ const wavPath = join58(tmpdir9(), `oa-luxtts-buf-${Date.now()}.wav`);
46781
47103
  try {
46782
47104
  await this.luxttsRequest({
46783
47105
  action: "synthesize",
@@ -46789,10 +47111,10 @@ if __name__ == '__main__':
46789
47111
  } catch {
46790
47112
  return null;
46791
47113
  }
46792
- if (!existsSync41(wavPath))
47114
+ if (!existsSync42(wavPath))
46793
47115
  return null;
46794
47116
  try {
46795
- const data = readFileSync30(wavPath);
47117
+ const data = readFileSync31(wavPath);
46796
47118
  unlinkSync9(wavPath);
46797
47119
  return data;
46798
47120
  } catch {
@@ -46806,40 +47128,40 @@ if __name__ == '__main__':
46806
47128
  if (this.ort)
46807
47129
  return;
46808
47130
  const arch2 = process.arch;
46809
- mkdirSync17(voiceDir(), { recursive: true });
46810
- const pkgPath = join57(voiceDir(), "package.json");
47131
+ mkdirSync18(voiceDir(), { recursive: true });
47132
+ const pkgPath = join58(voiceDir(), "package.json");
46811
47133
  const expectedDeps = {
46812
47134
  "onnxruntime-node": "^1.21.0",
46813
47135
  "phonemizer": "^1.2.1"
46814
47136
  };
46815
- if (existsSync41(pkgPath)) {
47137
+ if (existsSync42(pkgPath)) {
46816
47138
  try {
46817
- const existing = JSON.parse(readFileSync30(pkgPath, "utf8"));
47139
+ const existing = JSON.parse(readFileSync31(pkgPath, "utf8"));
46818
47140
  if (!existing.dependencies?.["phonemizer"]) {
46819
47141
  existing.dependencies = { ...existing.dependencies, ...expectedDeps };
46820
- writeFileSync18(pkgPath, JSON.stringify(existing, null, 2));
47142
+ writeFileSync19(pkgPath, JSON.stringify(existing, null, 2));
46821
47143
  }
46822
47144
  } catch {
46823
47145
  }
46824
47146
  }
46825
- if (!existsSync41(pkgPath)) {
46826
- writeFileSync18(pkgPath, JSON.stringify({
47147
+ if (!existsSync42(pkgPath)) {
47148
+ writeFileSync19(pkgPath, JSON.stringify({
46827
47149
  name: "open-agents-voice",
46828
47150
  private: true,
46829
47151
  dependencies: expectedDeps
46830
47152
  }, null, 2));
46831
47153
  }
46832
- const voiceRequire = createRequire(join57(voiceDir(), "index.js"));
47154
+ const voiceRequire = createRequire(join58(voiceDir(), "index.js"));
46833
47155
  const probeOnnx = async () => {
46834
47156
  try {
46835
- const output = await this.asyncShell(`NODE_PATH="${join57(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
47157
+ const output = await this.asyncShell(`NODE_PATH="${join58(voiceDir(), "node_modules")}" node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, 15e3);
46836
47158
  return output.trim() === "OK";
46837
47159
  } catch {
46838
47160
  return false;
46839
47161
  }
46840
47162
  };
46841
- const onnxNodeModules = join57(voiceDir(), "node_modules", "onnxruntime-node");
46842
- const onnxInstalled = existsSync41(onnxNodeModules);
47163
+ const onnxNodeModules = join58(voiceDir(), "node_modules", "onnxruntime-node");
47164
+ const onnxInstalled = existsSync42(onnxNodeModules);
46843
47165
  if (onnxInstalled && !await probeOnnx()) {
46844
47166
  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.`);
46845
47167
  }
@@ -46889,18 +47211,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
46889
47211
  const dir = modelDir(id);
46890
47212
  const onnxPath = modelOnnxPath(id);
46891
47213
  const configPath2 = modelConfigPath(id);
46892
- if (existsSync41(onnxPath) && existsSync41(configPath2))
47214
+ if (existsSync42(onnxPath) && existsSync42(configPath2))
46893
47215
  return;
46894
- mkdirSync17(dir, { recursive: true });
46895
- if (!existsSync41(configPath2)) {
47216
+ mkdirSync18(dir, { recursive: true });
47217
+ if (!existsSync42(configPath2)) {
46896
47218
  renderInfo(`Downloading ${model.label} voice config...`);
46897
47219
  const configResp = await fetch(model.configUrl);
46898
47220
  if (!configResp.ok)
46899
47221
  throw new Error(`Failed to download config: HTTP ${configResp.status}`);
46900
47222
  const configText = await configResp.text();
46901
- writeFileSync18(configPath2, configText);
47223
+ writeFileSync19(configPath2, configText);
46902
47224
  }
46903
- if (!existsSync41(onnxPath)) {
47225
+ if (!existsSync42(onnxPath)) {
46904
47226
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
46905
47227
  const onnxResp = await fetch(model.onnxUrl);
46906
47228
  if (!onnxResp.ok)
@@ -46925,7 +47247,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
46925
47247
  }
46926
47248
  }
46927
47249
  const fullBuffer = Buffer.concat(chunks);
46928
- writeFileSync18(onnxPath, fullBuffer);
47250
+ writeFileSync19(onnxPath, fullBuffer);
46929
47251
  renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
46930
47252
  }
46931
47253
  }
@@ -46937,10 +47259,10 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
46937
47259
  throw new Error("ONNX runtime not loaded");
46938
47260
  const onnxPath = modelOnnxPath(this.modelId);
46939
47261
  const configPath2 = modelConfigPath(this.modelId);
46940
- if (!existsSync41(onnxPath) || !existsSync41(configPath2)) {
47262
+ if (!existsSync42(onnxPath) || !existsSync42(configPath2)) {
46941
47263
  throw new Error(`Model files not found for ${this.modelId}`);
46942
47264
  }
46943
- this.config = JSON.parse(readFileSync30(configPath2, "utf8"));
47265
+ this.config = JSON.parse(readFileSync31(configPath2, "utf8"));
46944
47266
  this.session = await this.ort.InferenceSession.create(onnxPath, {
46945
47267
  executionProviders: ["cpu"],
46946
47268
  graphOptimizationLevel: "all"
@@ -46967,8 +47289,8 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
46967
47289
  // packages/cli/dist/tui/commands.js
46968
47290
  import * as nodeOs from "node:os";
46969
47291
  import { execSync as nodeExecSync } from "node:child_process";
46970
- import { existsSync as existsSync42, readFileSync as readFileSync31, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
46971
- import { join as join58 } from "node:path";
47292
+ import { existsSync as existsSync43, readFileSync as readFileSync32, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync12, statSync as statSync14, rmSync } from "node:fs";
47293
+ import { join as join59 } from "node:path";
46972
47294
  function safeLog(text) {
46973
47295
  if (isNeovimActive()) {
46974
47296
  writeToNeovimOutput(text + "\n");
@@ -47387,9 +47709,9 @@ async function handleSlashCommand(input, ctx) {
47387
47709
  renderInfo("No wallet configured. Ask the agent to create one via the nexus tool.");
47388
47710
  }
47389
47711
  } else if (sub === "name") {
47390
- const { homedir: homedir20 } = __require("node:os");
47712
+ const { homedir: homedir21 } = __require("node:os");
47391
47713
  const { existsSync: ex, readFileSync: rf, writeFileSync: wf, mkdirSync: mkd } = __require("node:fs");
47392
- const namePath = __require("node:path").join(homedir20(), ".open-agents", "agent-name");
47714
+ const namePath = __require("node:path").join(homedir21(), ".open-agents", "agent-name");
47393
47715
  if (rest2) {
47394
47716
  const customName = rest2.replace(/[^a-zA-Z0-9_\-.\s]/g, "").trim().slice(0, 40);
47395
47717
  if (!customName) {
@@ -47662,22 +47984,22 @@ async function handleSlashCommand(input, ctx) {
47662
47984
  let content = "";
47663
47985
  let metadata = {};
47664
47986
  if (shareType === "tool") {
47665
- const toolDir = join58(ctx.repoRoot, ".oa", "tools");
47666
- const toolFile = join58(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
47667
- if (!existsSync42(toolFile)) {
47987
+ const toolDir = join59(ctx.repoRoot, ".oa", "tools");
47988
+ const toolFile = join59(toolDir, shareName.endsWith(".json") ? shareName : `${shareName}.json`);
47989
+ if (!existsSync43(toolFile)) {
47668
47990
  renderWarning(`Tool not found: ${toolFile}`);
47669
47991
  return "handled";
47670
47992
  }
47671
- content = readFileSync31(toolFile, "utf8");
47993
+ content = readFileSync32(toolFile, "utf8");
47672
47994
  metadata = { type: "tool", name: shareName };
47673
47995
  } else if (shareType === "skill") {
47674
- const skillDir = join58(ctx.repoRoot, ".oa", "skills", shareName);
47675
- const skillFile = join58(skillDir, "SKILL.md");
47676
- if (!existsSync42(skillFile)) {
47996
+ const skillDir = join59(ctx.repoRoot, ".oa", "skills", shareName);
47997
+ const skillFile = join59(skillDir, "SKILL.md");
47998
+ if (!existsSync43(skillFile)) {
47677
47999
  renderWarning(`Skill not found: ${skillFile}`);
47678
48000
  return "handled";
47679
48001
  }
47680
- content = readFileSync31(skillFile, "utf8");
48002
+ content = readFileSync32(skillFile, "utf8");
47681
48003
  metadata = { type: "skill", name: shareName };
47682
48004
  } else {
47683
48005
  renderWarning(`Unknown share type: ${shareType}. Use 'tool' or 'skill'.`);
@@ -47714,9 +48036,9 @@ async function handleSlashCommand(input, ctx) {
47714
48036
  try {
47715
48037
  const nexus = new NexusTool(ctx.repoRoot);
47716
48038
  await nexus.execute({ action: "ipfs_pin", cid: importCid, source: "import" });
47717
- const regFile = join58(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
47718
- if (existsSync42(regFile)) {
47719
- const reg = JSON.parse(readFileSync31(regFile, "utf8"));
48039
+ const regFile = join59(ctx.repoRoot, ".oa", "nexus", "ipfs", "cid-registry", "learning-cids.json");
48040
+ if (existsSync43(regFile)) {
48041
+ const reg = JSON.parse(readFileSync32(regFile, "utf8"));
47720
48042
  const pinned = Object.values(reg).some((e) => e.cid === importCid && e.pinned);
47721
48043
  if (pinned) {
47722
48044
  renderInfo(`CID ${importCid.slice(0, 20)}... pinned successfully.`);
@@ -47768,33 +48090,33 @@ async function handleSlashCommand(input, ctx) {
47768
48090
  lines.push(`
47769
48091
  ${c2.bold("IPFS / Helia Status")}
47770
48092
  `);
47771
- const ipfsDir = join58(ctx.repoRoot, ".oa", "ipfs");
47772
- const ipfsLocalDir = join58(ipfsDir, "local");
48093
+ const ipfsDir = join59(ctx.repoRoot, ".oa", "ipfs");
48094
+ const ipfsLocalDir = join59(ipfsDir, "local");
47773
48095
  let ipfsFiles = 0;
47774
48096
  let ipfsBytes = 0;
47775
48097
  let heliaBlocks = 0;
47776
48098
  let heliaBytes = 0;
47777
48099
  try {
47778
- if (existsSync42(ipfsLocalDir)) {
48100
+ if (existsSync43(ipfsLocalDir)) {
47779
48101
  const files = readdirSync12(ipfsLocalDir).filter((f) => f.endsWith(".json"));
47780
48102
  ipfsFiles = files.length;
47781
48103
  for (const f of files) {
47782
48104
  try {
47783
- ipfsBytes += statSync14(join58(ipfsLocalDir, f)).size;
48105
+ ipfsBytes += statSync14(join59(ipfsLocalDir, f)).size;
47784
48106
  } catch {
47785
48107
  }
47786
48108
  }
47787
48109
  }
47788
- const heliaBlockDir = join58(ipfsDir, "blocks");
47789
- if (existsSync42(heliaBlockDir)) {
48110
+ const heliaBlockDir = join59(ipfsDir, "blocks");
48111
+ if (existsSync43(heliaBlockDir)) {
47790
48112
  const walkDir = (dir) => {
47791
48113
  for (const entry of readdirSync12(dir, { withFileTypes: true })) {
47792
48114
  if (entry.isDirectory())
47793
- walkDir(join58(dir, entry.name));
48115
+ walkDir(join59(dir, entry.name));
47794
48116
  else {
47795
48117
  heliaBlocks++;
47796
48118
  try {
47797
- heliaBytes += statSync14(join58(dir, entry.name)).size;
48119
+ heliaBytes += statSync14(join59(dir, entry.name)).size;
47798
48120
  } catch {
47799
48121
  }
47800
48122
  }
@@ -47810,9 +48132,9 @@ async function handleSlashCommand(input, ctx) {
47810
48132
  lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
47811
48133
  lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
47812
48134
  try {
47813
- const statusFile = join58(ctx.repoRoot, ".oa", "nexus", "status.json");
47814
- if (existsSync42(statusFile)) {
47815
- const status = JSON.parse(readFileSync31(statusFile, "utf8"));
48135
+ const statusFile = join59(ctx.repoRoot, ".oa", "nexus", "status.json");
48136
+ if (existsSync43(statusFile)) {
48137
+ const status = JSON.parse(readFileSync32(statusFile, "utf8"));
47816
48138
  if (status.peerId) {
47817
48139
  lines.push(`
47818
48140
  ${c2.bold("Peer Info")}`);
@@ -47831,11 +48153,11 @@ async function handleSlashCommand(input, ctx) {
47831
48153
  ${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
47832
48154
  lines.push(`
47833
48155
  ${c2.bold("Identity Kernel")}`);
47834
- const idDir = join58(ctx.repoRoot, ".oa", "identity");
48156
+ const idDir = join59(ctx.repoRoot, ".oa", "identity");
47835
48157
  try {
47836
- const stateFile = join58(idDir, "self-state.json");
47837
- if (existsSync42(stateFile)) {
47838
- const state = JSON.parse(readFileSync31(stateFile, "utf8"));
48158
+ const stateFile = join59(idDir, "self-state.json");
48159
+ if (existsSync43(stateFile)) {
48160
+ const state = JSON.parse(readFileSync32(stateFile, "utf8"));
47839
48161
  lines.push(` Version: ${c2.bold("v" + (state.version ?? "?"))} Sessions: ${c2.bold(String(state.session_count ?? 0))}`);
47840
48162
  if (state.narrative_summary) {
47841
48163
  lines.push(` Narrative: ${c2.dim(state.narrative_summary.slice(0, 60))}${state.narrative_summary.length > 60 ? "..." : ""}`);
@@ -47844,9 +48166,9 @@ async function handleSlashCommand(input, ctx) {
47844
48166
  const traits = typeof state.personality_traits === "object" ? Object.entries(state.personality_traits).map(([k, v]) => `${k}:${v}`).join(", ") : String(state.personality_traits);
47845
48167
  lines.push(` Traits: ${c2.dim(traits.slice(0, 60))}`);
47846
48168
  }
47847
- const cidFile = join58(idDir, "cids.json");
47848
- if (existsSync42(cidFile)) {
47849
- const cids = JSON.parse(readFileSync31(cidFile, "utf8"));
48169
+ const cidFile = join59(idDir, "cids.json");
48170
+ if (existsSync43(cidFile)) {
48171
+ const cids = JSON.parse(readFileSync32(cidFile, "utf8"));
47850
48172
  const lastCid = Array.isArray(cids) ? cids[cids.length - 1] : cids.latest;
47851
48173
  if (lastCid)
47852
48174
  lines.push(` Last CID: ${c2.dim(String(lastCid).slice(0, 50))}`);
@@ -47859,9 +48181,9 @@ async function handleSlashCommand(input, ctx) {
47859
48181
  lines.push(`
47860
48182
  ${c2.bold("Memory Sentiment")}`);
47861
48183
  try {
47862
- const metaFile = join58(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
47863
- if (existsSync42(metaFile)) {
47864
- const store = JSON.parse(readFileSync31(metaFile, "utf8"));
48184
+ const metaFile = join59(ctx.repoRoot, ".oa", "memory", "metabolism", "store.json");
48185
+ if (existsSync43(metaFile)) {
48186
+ const store = JSON.parse(readFileSync32(metaFile, "utf8"));
47865
48187
  const active = store.filter((m) => m.type !== "quarantine");
47866
48188
  const recoveries = active.filter((m) => m.content?.startsWith("[recovery]")).length;
47867
48189
  const strategies = active.filter((m) => m.content?.startsWith("[strategy]")).length;
@@ -47879,8 +48201,8 @@ async function handleSlashCommand(input, ctx) {
47879
48201
  } catch {
47880
48202
  }
47881
48203
  try {
47882
- const dbPath = join58(ctx.repoRoot, ".oa", "memory", "structured.db");
47883
- if (existsSync42(dbPath)) {
48204
+ const dbPath = join59(ctx.repoRoot, ".oa", "memory", "structured.db");
48205
+ if (existsSync43(dbPath)) {
47884
48206
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
47885
48207
  const db = initDb2(dbPath);
47886
48208
  const memStore = new ProceduralMemoryStore2(db);
@@ -47901,8 +48223,8 @@ async function handleSlashCommand(input, ctx) {
47901
48223
  lines.push(`
47902
48224
  ${c2.bold("Storage Overview")}
47903
48225
  `);
47904
- const oaDir = join58(ctx.repoRoot, ".oa");
47905
- if (!existsSync42(oaDir)) {
48226
+ const oaDir = join59(ctx.repoRoot, ".oa");
48227
+ if (!existsSync43(oaDir)) {
47906
48228
  lines.push(` ${c2.dim("No .oa/ directory found.")}`);
47907
48229
  safeLog(lines.join("\n") + "\n");
47908
48230
  return "handled";
@@ -47912,7 +48234,7 @@ async function handleSlashCommand(input, ctx) {
47912
48234
  const walkStorage = (dir, category) => {
47913
48235
  try {
47914
48236
  for (const entry of readdirSync12(dir, { withFileTypes: true })) {
47915
- const full = join58(dir, entry.name);
48237
+ const full = join59(dir, entry.name);
47916
48238
  if (entry.isDirectory()) {
47917
48239
  const subCat = category || entry.name;
47918
48240
  walkStorage(full, subCat);
@@ -47948,10 +48270,10 @@ async function handleSlashCommand(input, ctx) {
47948
48270
  for (const entry of readdirSync12(dir, { withFileTypes: true })) {
47949
48271
  const name = entry.name.toLowerCase();
47950
48272
  if (sensitivePatterns.some((p) => name.includes(p))) {
47951
- sensitiveFound.push(join58(dir, entry.name).replace(oaDir + "/", ""));
48273
+ sensitiveFound.push(join59(dir, entry.name).replace(oaDir + "/", ""));
47952
48274
  }
47953
48275
  if (entry.isDirectory())
47954
- checkSensitive(join58(dir, entry.name));
48276
+ checkSensitive(join59(dir, entry.name));
47955
48277
  }
47956
48278
  } catch {
47957
48279
  }
@@ -47979,8 +48301,8 @@ async function handleSlashCommand(input, ctx) {
47979
48301
  renderInfo("Supported: .wav .mp3 .flac .ogg (audio\u2192transcribe) | .pdf .txt .md (text\u2192chunk)");
47980
48302
  return "handled";
47981
48303
  }
47982
- const resolvedPath = join58(ctx.repoRoot, filePath);
47983
- if (!existsSync42(resolvedPath)) {
48304
+ const resolvedPath = join59(ctx.repoRoot, filePath);
48305
+ if (!existsSync43(resolvedPath)) {
47984
48306
  renderWarning(`File not found: ${resolvedPath}`);
47985
48307
  return "handled";
47986
48308
  }
@@ -47996,9 +48318,9 @@ async function handleSlashCommand(input, ctx) {
47996
48318
  }
47997
48319
  try {
47998
48320
  const { initDb: initDb2, closeDb: cDb, ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
47999
- const dbDir = join58(ctx.repoRoot, ".oa", "memory");
48000
- mkdirSync18(dbDir, { recursive: true });
48001
- const db = initDb2(join58(dbDir, "structured.db"));
48321
+ const dbDir = join59(ctx.repoRoot, ".oa", "memory");
48322
+ mkdirSync19(dbDir, { recursive: true });
48323
+ const db = initDb2(join59(dbDir, "structured.db"));
48002
48324
  const memStore = new ProceduralMemoryStore2(db);
48003
48325
  if (isAudio) {
48004
48326
  renderInfo(`Transcribing: ${filePath}...`);
@@ -48039,7 +48361,7 @@ async function handleSlashCommand(input, ctx) {
48039
48361
  return "handled";
48040
48362
  }
48041
48363
  } else {
48042
- content = readFileSync31(resolvedPath, "utf8");
48364
+ content = readFileSync32(resolvedPath, "utf8");
48043
48365
  }
48044
48366
  if (!content.trim()) {
48045
48367
  renderWarning("No content extracted.");
@@ -48078,9 +48400,9 @@ async function handleSlashCommand(input, ctx) {
48078
48400
  }
48079
48401
  case "fortemi": {
48080
48402
  const fortemiSubCmd = (arg || "").trim().toLowerCase();
48081
- const fortemiDir = join58(ctx.repoRoot, "..", "fortemi-react");
48082
- const altFortemiDir = join58(nodeOs.homedir(), "fortemi-react");
48083
- const fDir = existsSync42(fortemiDir) ? fortemiDir : existsSync42(altFortemiDir) ? altFortemiDir : null;
48403
+ const fortemiDir = join59(ctx.repoRoot, "..", "fortemi-react");
48404
+ const altFortemiDir = join59(nodeOs.homedir(), "fortemi-react");
48405
+ const fDir = existsSync43(fortemiDir) ? fortemiDir : existsSync43(altFortemiDir) ? altFortemiDir : null;
48084
48406
  if (fortemiSubCmd === "start" || fortemiSubCmd === "") {
48085
48407
  if (!fDir) {
48086
48408
  renderWarning("fortemi-react not found adjacent or in home directory.");
@@ -48095,14 +48417,14 @@ async function handleSlashCommand(input, ctx) {
48095
48417
  // 24h
48096
48418
  nonce: Math.random().toString(36).slice(2, 10)
48097
48419
  };
48098
- const jwtFile = join58(ctx.repoRoot, ".oa", "fortemi-jwt.json");
48099
- mkdirSync18(join58(ctx.repoRoot, ".oa"), { recursive: true });
48100
- writeFileSync19(jwtFile, JSON.stringify(jwtPayload, null, 2));
48420
+ const jwtFile = join59(ctx.repoRoot, ".oa", "fortemi-jwt.json");
48421
+ mkdirSync19(join59(ctx.repoRoot, ".oa"), { recursive: true });
48422
+ writeFileSync20(jwtFile, JSON.stringify(jwtPayload, null, 2));
48101
48423
  renderInfo(`Launching fortemi-react from ${fDir}...`);
48102
48424
  try {
48103
- const { spawn: spawn22 } = __require("node:child_process");
48104
- const child = spawn22("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
48105
- cwd: join58(fDir, "apps", "standalone"),
48425
+ const { spawn: spawn23 } = __require("node:child_process");
48426
+ const child = spawn23("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
48427
+ cwd: join59(fDir, "apps", "standalone"),
48106
48428
  stdio: "ignore",
48107
48429
  detached: true,
48108
48430
  env: { ...process.env, OA_JWT: JSON.stringify(jwtPayload) }
@@ -48111,8 +48433,8 @@ async function handleSlashCommand(input, ctx) {
48111
48433
  renderInfo("Fortemi-React starting on http://localhost:3000");
48112
48434
  renderInfo(`JWT saved to ${jwtFile}`);
48113
48435
  renderInfo("Memory operations will proxy to fortemi when available.");
48114
- const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48115
- writeFileSync19(bridgeFile, JSON.stringify({
48436
+ const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48437
+ writeFileSync20(bridgeFile, JSON.stringify({
48116
48438
  url: "http://localhost:3000",
48117
48439
  pid: child.pid,
48118
48440
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -48124,12 +48446,12 @@ async function handleSlashCommand(input, ctx) {
48124
48446
  return "handled";
48125
48447
  }
48126
48448
  if (fortemiSubCmd === "status") {
48127
- const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48128
- if (!existsSync42(bridgeFile)) {
48449
+ const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48450
+ if (!existsSync43(bridgeFile)) {
48129
48451
  renderInfo("Fortemi bridge: not connected. Run /fortemi start");
48130
48452
  return "handled";
48131
48453
  }
48132
- const bridge = JSON.parse(readFileSync31(bridgeFile, "utf8"));
48454
+ const bridge = JSON.parse(readFileSync32(bridgeFile, "utf8"));
48133
48455
  let alive = false;
48134
48456
  try {
48135
48457
  process.kill(bridge.pid, 0);
@@ -48149,15 +48471,15 @@ async function handleSlashCommand(input, ctx) {
48149
48471
  lines.push(` Process: ${alive ? c2.green("running") : c2.yellow("not running")} (PID ${bridge.pid})`);
48150
48472
  lines.push(` HTTP: ${httpOk ? c2.green("connected") : c2.yellow("unreachable")}`);
48151
48473
  lines.push(` Started: ${bridge.startedAt}`);
48152
- lines.push(` JWT: ${existsSync42(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
48474
+ lines.push(` JWT: ${existsSync43(bridge.jwtFile) ? c2.green("valid") : c2.yellow("missing")}`);
48153
48475
  lines.push("");
48154
48476
  safeLog(lines.join("\n"));
48155
48477
  return "handled";
48156
48478
  }
48157
48479
  if (fortemiSubCmd === "stop") {
48158
- const bridgeFile = join58(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48159
- if (existsSync42(bridgeFile)) {
48160
- const bridge = JSON.parse(readFileSync31(bridgeFile, "utf8"));
48480
+ const bridgeFile = join59(ctx.repoRoot, ".oa", "fortemi-bridge.json");
48481
+ if (existsSync43(bridgeFile)) {
48482
+ const bridge = JSON.parse(readFileSync32(bridgeFile, "utf8"));
48161
48483
  try {
48162
48484
  process.kill(bridge.pid, "SIGTERM");
48163
48485
  } catch {
@@ -48214,6 +48536,37 @@ async function handleSlashCommand(input, ctx) {
48214
48536
  ctx.saveSettings(settings);
48215
48537
  };
48216
48538
  if (arg) {
48539
+ if (arg === "personaplex" || arg === "pp") {
48540
+ const { detectPersonaPlexCapability: detectPersonaPlexCapability2, isPersonaPlexInstalled: isPersonaPlexInstalled2, installPersonaPlex: installPersonaPlex2, startPersonaPlexDaemon: startPersonaPlexDaemon2, stopPersonaPlex: stopPersonaPlex2, isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
48541
+ const caps = detectPersonaPlexCapability2();
48542
+ if (!caps.supported) {
48543
+ renderWarning(`PersonaPlex not available: ${caps.reason}`);
48544
+ renderInfo("Requirements: NVIDIA GPU with \u226516GB VRAM (RTX 3090/4090/A100+), CUDA 12.1+, PyTorch");
48545
+ return "handled";
48546
+ }
48547
+ renderInfo(`GPU: ${caps.gpuName} (${caps.vramGB.toFixed(0)}GB VRAM) \u2014 PersonaPlex compatible \u2713`);
48548
+ if (!isPersonaPlexInstalled2()) {
48549
+ renderInfo("Installing PersonaPlex-7B (~14GB download)...");
48550
+ const ok = await installPersonaPlex2((msg2) => renderInfo(msg2));
48551
+ if (!ok) {
48552
+ renderError("PersonaPlex installation failed.");
48553
+ return "handled";
48554
+ }
48555
+ }
48556
+ if (isPersonaPlexRunning2()) {
48557
+ renderInfo("PersonaPlex daemon is running.");
48558
+ renderInfo("Use /call to start a full-duplex voice session.");
48559
+ } else {
48560
+ const url = await startPersonaPlexDaemon2((msg2) => renderInfo(msg2));
48561
+ if (url) {
48562
+ renderInfo(`PersonaPlex ready at ${url}`);
48563
+ renderInfo("Use /call to start a full-duplex voice session with PersonaPlex.");
48564
+ } else {
48565
+ renderError("PersonaPlex daemon failed to start.");
48566
+ }
48567
+ }
48568
+ return "handled";
48569
+ }
48217
48570
  if (arg === "enable" || arg === "on") {
48218
48571
  const msg2 = await ctx.voiceToggle();
48219
48572
  const isOn = msg2.toLowerCase().includes("enabled") || msg2.toLowerCase().includes("on");
@@ -48505,6 +48858,17 @@ async function handleSlashCommand(input, ctx) {
48505
48858
  renderWarning("Call mode not available in this context.");
48506
48859
  return "handled";
48507
48860
  }
48861
+ try {
48862
+ const { isPersonaPlexRunning: isPersonaPlexRunning2, getPersonaPlexWSUrl: getPersonaPlexWSUrl2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
48863
+ if (isPersonaPlexRunning2()) {
48864
+ const ppUrl = getPersonaPlexWSUrl2();
48865
+ if (ppUrl) {
48866
+ renderInfo(`PersonaPlex active \u2014 full-duplex mode (${ppUrl})`);
48867
+ renderInfo("257ms response latency, concurrent listen+speak");
48868
+ }
48869
+ }
48870
+ } catch {
48871
+ }
48508
48872
  if (arg === "stop" || arg === "off") {
48509
48873
  if (ctx.isCallActive?.()) {
48510
48874
  await ctx.callStop?.();
@@ -48738,10 +49102,10 @@ async function handleSlashCommand(input, ctx) {
48738
49102
  let sponsorName = (config.header.message || "").replace(/^\/+/, "").trim();
48739
49103
  if (!sponsorName || sponsorName.length < 2) {
48740
49104
  try {
48741
- const { homedir: homedir20 } = __require("os");
48742
- const namePath = __require("path").join(homedir20(), ".open-agents", "agent-name");
48743
- if (existsSync42(namePath))
48744
- sponsorName = readFileSync31(namePath, "utf8").trim();
49105
+ const { homedir: homedir21 } = __require("os");
49106
+ const namePath = __require("path").join(homedir21(), ".open-agents", "agent-name");
49107
+ if (existsSync43(namePath))
49108
+ sponsorName = readFileSync32(namePath, "utf8").trim();
48745
49109
  } catch {
48746
49110
  }
48747
49111
  if (!sponsorName)
@@ -49812,13 +50176,13 @@ async function showCohereDashboard(ctx) {
49812
50176
  } else if (idResult.key === "view") {
49813
50177
  await ik.execute({ operation: "hydrate" });
49814
50178
  } else if (idResult.key === "history") {
49815
- const snapDir = join58(ctx.repoRoot, ".oa", "identity", "snapshots");
49816
- if (existsSync42(snapDir)) {
50179
+ const snapDir = join59(ctx.repoRoot, ".oa", "identity", "snapshots");
50180
+ if (existsSync43(snapDir)) {
49817
50181
  const snaps = readdirSync12(snapDir).filter((f) => f.endsWith(".json")).sort().reverse();
49818
50182
  const snapItems = snaps.slice(0, 20).map((f) => ({
49819
50183
  key: f,
49820
50184
  label: f.replace(".json", ""),
49821
- detail: `${formatFileSize(statSync14(join58(snapDir, f)).size)}`
50185
+ detail: `${formatFileSize(statSync14(join59(snapDir, f)).size)}`
49822
50186
  }));
49823
50187
  if (snapItems.length > 0) {
49824
50188
  await tuiSelect({
@@ -50139,12 +50503,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
50139
50503
  continue;
50140
50504
  }
50141
50505
  const { basename: basename18, join: pathJoin } = await import("node:path");
50142
- const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync30, existsSync: exists } = await import("node:fs");
50143
- const { homedir: homedir20 } = await import("node:os");
50506
+ const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync31, existsSync: exists } = await import("node:fs");
50507
+ const { homedir: homedir21 } = await import("node:os");
50144
50508
  const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
50145
- const destDir = pathJoin(homedir20(), ".open-agents", "voice", "models", modelName);
50509
+ const destDir = pathJoin(homedir21(), ".open-agents", "voice", "models", modelName);
50146
50510
  if (!exists(destDir))
50147
- mkdirSync30(destDir, { recursive: true });
50511
+ mkdirSync31(destDir, { recursive: true });
50148
50512
  copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
50149
50513
  copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
50150
50514
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -50771,11 +51135,11 @@ async function handleSponsoredEndpoint(ctx, local) {
50771
51135
  }
50772
51136
  } catch {
50773
51137
  }
50774
- const sponsorDir2 = join58(ctx.repoRoot ?? process.cwd(), ".oa", "sponsor");
50775
- const knownFile = join58(sponsorDir2, "known-sponsors.json");
51138
+ const sponsorDir2 = join59(ctx.repoRoot ?? process.cwd(), ".oa", "sponsor");
51139
+ const knownFile = join59(sponsorDir2, "known-sponsors.json");
50776
51140
  try {
50777
- if (existsSync42(knownFile)) {
50778
- const saved = JSON.parse(readFileSync31(knownFile, "utf8"));
51141
+ if (existsSync43(knownFile)) {
51142
+ const saved = JSON.parse(readFileSync32(knownFile, "utf8"));
50779
51143
  for (const s of saved) {
50780
51144
  if (!sponsors.some((sp) => sp.url === s.url)) {
50781
51145
  sponsors.push({ ...s, source: "saved" });
@@ -50910,11 +51274,11 @@ async function handleSponsoredEndpoint(ctx, local) {
50910
51274
  }
50911
51275
  const saveKey = selected.url || selected.peerId || selected.name;
50912
51276
  try {
50913
- mkdirSync18(sponsorDir2, { recursive: true });
50914
- const existing = existsSync42(knownFile) ? JSON.parse(readFileSync31(knownFile, "utf8")) : [];
51277
+ mkdirSync19(sponsorDir2, { recursive: true });
51278
+ const existing = existsSync43(knownFile) ? JSON.parse(readFileSync32(knownFile, "utf8")) : [];
50915
51279
  const updated = existing.filter((s) => (s.url || s.peerId || s.name) !== saveKey);
50916
51280
  updated.push(selected);
50917
- writeFileSync19(knownFile, JSON.stringify(updated, null, 2), "utf8");
51281
+ writeFileSync20(knownFile, JSON.stringify(updated, null, 2), "utf8");
50918
51282
  } catch {
50919
51283
  }
50920
51284
  renderInfo(`Connected to sponsored endpoint: ${selected.name}`);
@@ -50983,11 +51347,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
50983
51347
  const models = await fetchModels(peerUrl, authKey);
50984
51348
  if (models.length > 0) {
50985
51349
  try {
50986
- const { writeFileSync: writeFileSync29, mkdirSync: mkdirSync30 } = await import("node:fs");
50987
- const { join: join76, dirname: dirname23 } = await import("node:path");
50988
- const cachePath = join76(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
50989
- mkdirSync30(dirname23(cachePath), { recursive: true });
50990
- writeFileSync29(cachePath, JSON.stringify({
51350
+ const { writeFileSync: writeFileSync30, mkdirSync: mkdirSync31 } = await import("node:fs");
51351
+ const { join: join77, dirname: dirname23 } = await import("node:path");
51352
+ const cachePath = join77(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
51353
+ mkdirSync31(dirname23(cachePath), { recursive: true });
51354
+ writeFileSync30(cachePath, JSON.stringify({
50991
51355
  peerId,
50992
51356
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
50993
51357
  models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
@@ -51036,7 +51400,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
51036
51400
  }
51037
51401
  }
51038
51402
  async function handleParallel(arg, ctx) {
51039
- const { execSync: execSync34 } = await import("node:child_process");
51403
+ const { execSync: execSync35 } = await import("node:child_process");
51040
51404
  const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
51041
51405
  const isRemote = ctx.config.backendType === "nexus";
51042
51406
  if (isRemote) {
@@ -51060,7 +51424,7 @@ async function handleParallel(arg, ctx) {
51060
51424
  }
51061
51425
  let systemdVal = "";
51062
51426
  try {
51063
- const out = execSync34("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
51427
+ const out = execSync35("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
51064
51428
  const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
51065
51429
  if (match)
51066
51430
  systemdVal = match[1];
@@ -51089,7 +51453,7 @@ async function handleParallel(arg, ctx) {
51089
51453
  }
51090
51454
  const isSystemd = (() => {
51091
51455
  try {
51092
- const out = execSync34("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
51456
+ const out = execSync35("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
51093
51457
  return out === "active" || out === "inactive";
51094
51458
  } catch {
51095
51459
  return false;
@@ -51103,10 +51467,10 @@ async function handleParallel(arg, ctx) {
51103
51467
  const overrideContent = `[Service]
51104
51468
  Environment="OLLAMA_NUM_PARALLEL=${n}"
51105
51469
  `;
51106
- execSync34(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
51107
- execSync34(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
51108
- execSync34("sudo systemctl daemon-reload", { stdio: "pipe" });
51109
- execSync34("sudo systemctl restart ollama.service", { stdio: "pipe" });
51470
+ execSync35(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
51471
+ execSync35(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
51472
+ execSync35("sudo systemctl daemon-reload", { stdio: "pipe" });
51473
+ execSync35("sudo systemctl restart ollama.service", { stdio: "pipe" });
51110
51474
  let ready = false;
51111
51475
  for (let i = 0; i < 30 && !ready; i++) {
51112
51476
  await new Promise((r) => setTimeout(r, 500));
@@ -51133,13 +51497,13 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
51133
51497
  renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
51134
51498
  try {
51135
51499
  try {
51136
- execSync34("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
51500
+ execSync35("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
51137
51501
  } catch {
51138
51502
  }
51139
51503
  await new Promise((r) => setTimeout(r, 1e3));
51140
51504
  process.env.OLLAMA_NUM_PARALLEL = String(n);
51141
- const { spawn: spawn22 } = await import("node:child_process");
51142
- const child = spawn22("ollama", ["serve"], {
51505
+ const { spawn: spawn23 } = await import("node:child_process");
51506
+ const child = spawn23("ollama", ["serve"], {
51143
51507
  stdio: "ignore",
51144
51508
  detached: true,
51145
51509
  env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
@@ -51186,17 +51550,17 @@ async function handleUpdate(subcommand, ctx) {
51186
51550
  try {
51187
51551
  const { createRequire: createRequire6 } = await import("node:module");
51188
51552
  const { fileURLToPath: fileURLToPath15 } = await import("node:url");
51189
- const { dirname: dirname23, join: join76 } = await import("node:path");
51190
- const { existsSync: existsSync56 } = await import("node:fs");
51553
+ const { dirname: dirname23, join: join77 } = await import("node:path");
51554
+ const { existsSync: existsSync57 } = await import("node:fs");
51191
51555
  const req = createRequire6(import.meta.url);
51192
51556
  const thisDir = dirname23(fileURLToPath15(import.meta.url));
51193
51557
  const candidates = [
51194
- join76(thisDir, "..", "package.json"),
51195
- join76(thisDir, "..", "..", "package.json"),
51196
- join76(thisDir, "..", "..", "..", "package.json")
51558
+ join77(thisDir, "..", "package.json"),
51559
+ join77(thisDir, "..", "..", "package.json"),
51560
+ join77(thisDir, "..", "..", "..", "package.json")
51197
51561
  ];
51198
51562
  for (const pkgPath of candidates) {
51199
- if (existsSync56(pkgPath)) {
51563
+ if (existsSync57(pkgPath)) {
51200
51564
  const pkg = req(pkgPath);
51201
51565
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
51202
51566
  currentVersion = pkg.version ?? "0.0.0";
@@ -51952,18 +52316,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
51952
52316
  const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
51953
52317
  let copied = false;
51954
52318
  try {
51955
- const { execSync: execSync34 } = __require("node:child_process");
52319
+ const { execSync: execSync35 } = __require("node:child_process");
51956
52320
  const platform6 = process.platform;
51957
52321
  if (platform6 === "darwin") {
51958
- execSync34("pbcopy", { input: cmd, timeout: 3e3 });
52322
+ execSync35("pbcopy", { input: cmd, timeout: 3e3 });
51959
52323
  copied = true;
51960
52324
  } else if (platform6 === "win32") {
51961
- execSync34("clip", { input: cmd, timeout: 3e3 });
52325
+ execSync35("clip", { input: cmd, timeout: 3e3 });
51962
52326
  copied = true;
51963
52327
  } else {
51964
52328
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
51965
52329
  try {
51966
- execSync34(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
52330
+ execSync35(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
51967
52331
  copied = true;
51968
52332
  break;
51969
52333
  } catch {
@@ -52050,10 +52414,10 @@ var init_commands = __esm({
52050
52414
  });
52051
52415
 
52052
52416
  // packages/cli/dist/tui/project-context.js
52053
- import { existsSync as existsSync43, readFileSync as readFileSync32, readdirSync as readdirSync13 } from "node:fs";
52054
- import { join as join59, basename as basename12 } from "node:path";
52055
- import { execSync as execSync30 } from "node:child_process";
52056
- import { homedir as homedir16, platform as platform4, release } from "node:os";
52417
+ import { existsSync as existsSync44, readFileSync as readFileSync33, readdirSync as readdirSync13 } from "node:fs";
52418
+ import { join as join60, basename as basename12 } from "node:path";
52419
+ import { execSync as execSync31 } from "node:child_process";
52420
+ import { homedir as homedir17, platform as platform4, release } from "node:os";
52057
52421
  function getModelTier(modelName) {
52058
52422
  const m = modelName.toLowerCase();
52059
52423
  const sizeMatch = m.match(/\b(\d+)b\b/);
@@ -52086,10 +52450,10 @@ function loadProjectMap(repoRoot) {
52086
52450
  if (!hasOaDirectory(repoRoot)) {
52087
52451
  initOaDirectory(repoRoot);
52088
52452
  }
52089
- const mapPath2 = join59(repoRoot, OA_DIR, "context", "project-map.md");
52090
- if (existsSync43(mapPath2)) {
52453
+ const mapPath2 = join60(repoRoot, OA_DIR, "context", "project-map.md");
52454
+ if (existsSync44(mapPath2)) {
52091
52455
  try {
52092
- const content = readFileSync32(mapPath2, "utf-8");
52456
+ const content = readFileSync33(mapPath2, "utf-8");
52093
52457
  return content;
52094
52458
  } catch {
52095
52459
  }
@@ -52098,19 +52462,19 @@ function loadProjectMap(repoRoot) {
52098
52462
  }
52099
52463
  function getGitInfo(repoRoot) {
52100
52464
  try {
52101
- execSync30("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
52465
+ execSync31("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
52102
52466
  } catch {
52103
52467
  return "";
52104
52468
  }
52105
52469
  const lines = [];
52106
52470
  try {
52107
- const branch = execSync30("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52471
+ const branch = execSync31("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52108
52472
  if (branch)
52109
52473
  lines.push(`Branch: ${branch}`);
52110
52474
  } catch {
52111
52475
  }
52112
52476
  try {
52113
- const status = execSync30("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52477
+ const status = execSync31("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52114
52478
  if (status) {
52115
52479
  const changed = status.split("\n").length;
52116
52480
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -52120,7 +52484,7 @@ function getGitInfo(repoRoot) {
52120
52484
  } catch {
52121
52485
  }
52122
52486
  try {
52123
- const log = execSync30("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52487
+ const log = execSync31("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
52124
52488
  if (log)
52125
52489
  lines.push(`Recent commits:
52126
52490
  ${log}`);
@@ -52130,31 +52494,31 @@ ${log}`);
52130
52494
  }
52131
52495
  function loadMemoryContext(repoRoot) {
52132
52496
  const sections = [];
52133
- const oaMemDir = join59(repoRoot, OA_DIR, "memory");
52497
+ const oaMemDir = join60(repoRoot, OA_DIR, "memory");
52134
52498
  const oaEntries = loadMemoryDir(oaMemDir, "project");
52135
52499
  if (oaEntries)
52136
52500
  sections.push(oaEntries);
52137
- const legacyMemDir = join59(repoRoot, ".open-agents", "memory");
52138
- if (legacyMemDir !== oaMemDir && existsSync43(legacyMemDir)) {
52501
+ const legacyMemDir = join60(repoRoot, ".open-agents", "memory");
52502
+ if (legacyMemDir !== oaMemDir && existsSync44(legacyMemDir)) {
52139
52503
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
52140
52504
  if (legacyEntries)
52141
52505
  sections.push(legacyEntries);
52142
52506
  }
52143
- const globalMemDir = join59(homedir16(), ".open-agents", "memory");
52507
+ const globalMemDir = join60(homedir17(), ".open-agents", "memory");
52144
52508
  const globalEntries = loadMemoryDir(globalMemDir, "global");
52145
52509
  if (globalEntries)
52146
52510
  sections.push(globalEntries);
52147
52511
  return sections.join("\n\n");
52148
52512
  }
52149
52513
  function loadMemoryDir(memDir, scope) {
52150
- if (!existsSync43(memDir))
52514
+ if (!existsSync44(memDir))
52151
52515
  return "";
52152
52516
  const lines = [];
52153
52517
  try {
52154
52518
  const files = readdirSync13(memDir).filter((f) => f.endsWith(".json"));
52155
52519
  for (const file of files.slice(0, 10)) {
52156
52520
  try {
52157
- const raw = readFileSync32(join59(memDir, file), "utf-8");
52521
+ const raw = readFileSync33(join60(memDir, file), "utf-8");
52158
52522
  const entries = JSON.parse(raw);
52159
52523
  const topic = basename12(file, ".json");
52160
52524
  const keys = Object.keys(entries);
@@ -53294,8 +53658,8 @@ __export(banner_exports, {
53294
53658
  saveBannerDesign: () => saveBannerDesign,
53295
53659
  setGridText: () => setGridText
53296
53660
  });
53297
- import { existsSync as existsSync44, readFileSync as readFileSync33, writeFileSync as writeFileSync20, mkdirSync as mkdirSync19 } from "node:fs";
53298
- import { join as join60 } from "node:path";
53661
+ import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20 } from "node:fs";
53662
+ import { join as join61 } from "node:path";
53299
53663
  function generateMnemonic(seed) {
53300
53664
  let h = 2166136261;
53301
53665
  for (let i = 0; i < seed.length; i++) {
@@ -53490,23 +53854,23 @@ function createSponsorBanner(sponsorName, tagline, primaryColor = 214, bgColor =
53490
53854
  };
53491
53855
  }
53492
53856
  function saveBannerDesign(workDir, design) {
53493
- const dir = join60(workDir, ".oa", "banners");
53494
- mkdirSync19(dir, { recursive: true });
53495
- writeFileSync20(join60(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
53857
+ const dir = join61(workDir, ".oa", "banners");
53858
+ mkdirSync20(dir, { recursive: true });
53859
+ writeFileSync21(join61(dir, `${design.id}.json`), JSON.stringify(design, null, 2), "utf8");
53496
53860
  }
53497
53861
  function loadBannerDesign(workDir, id) {
53498
- const file = join60(workDir, ".oa", "banners", `${id}.json`);
53499
- if (!existsSync44(file))
53862
+ const file = join61(workDir, ".oa", "banners", `${id}.json`);
53863
+ if (!existsSync45(file))
53500
53864
  return null;
53501
53865
  try {
53502
- return JSON.parse(readFileSync33(file, "utf8"));
53866
+ return JSON.parse(readFileSync34(file, "utf8"));
53503
53867
  } catch {
53504
53868
  return null;
53505
53869
  }
53506
53870
  }
53507
53871
  function listBannerDesigns(workDir) {
53508
- const dir = join60(workDir, ".oa", "banners");
53509
- if (!existsSync44(dir))
53872
+ const dir = join61(workDir, ".oa", "banners");
53873
+ if (!existsSync45(dir))
53510
53874
  return [];
53511
53875
  try {
53512
53876
  const { readdirSync: readdirSync23 } = __require("node:fs");
@@ -53864,22 +54228,22 @@ var init_banner = __esm({
53864
54228
  });
53865
54229
 
53866
54230
  // packages/cli/dist/tui/carousel-descriptors.js
53867
- import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync21, mkdirSync as mkdirSync20, readdirSync as readdirSync14 } from "node:fs";
53868
- import { join as join61, basename as basename13 } from "node:path";
54231
+ import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync21, readdirSync as readdirSync14 } from "node:fs";
54232
+ import { join as join62, basename as basename13 } from "node:path";
53869
54233
  function loadToolProfile(repoRoot) {
53870
- const filePath = join61(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
54234
+ const filePath = join62(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
53871
54235
  try {
53872
- if (!existsSync45(filePath))
54236
+ if (!existsSync46(filePath))
53873
54237
  return null;
53874
- return JSON.parse(readFileSync34(filePath, "utf-8"));
54238
+ return JSON.parse(readFileSync35(filePath, "utf-8"));
53875
54239
  } catch {
53876
54240
  return null;
53877
54241
  }
53878
54242
  }
53879
54243
  function saveToolProfile(repoRoot, profile) {
53880
- const contextDir = join61(repoRoot, OA_DIR, "context");
53881
- mkdirSync20(contextDir, { recursive: true });
53882
- writeFileSync21(join61(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
54244
+ const contextDir = join62(repoRoot, OA_DIR, "context");
54245
+ mkdirSync21(contextDir, { recursive: true });
54246
+ writeFileSync22(join62(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
53883
54247
  }
53884
54248
  function categorizeToolCall(toolName) {
53885
54249
  for (const cat of TOOL_CATEGORIES) {
@@ -53937,25 +54301,25 @@ function weightedColor(profile) {
53937
54301
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
53938
54302
  }
53939
54303
  function loadCachedDescriptors(repoRoot) {
53940
- const filePath = join61(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
54304
+ const filePath = join62(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
53941
54305
  try {
53942
- if (!existsSync45(filePath))
54306
+ if (!existsSync46(filePath))
53943
54307
  return null;
53944
- const cached = JSON.parse(readFileSync34(filePath, "utf-8"));
54308
+ const cached = JSON.parse(readFileSync35(filePath, "utf-8"));
53945
54309
  return cached.phrases.length > 0 ? cached.phrases : null;
53946
54310
  } catch {
53947
54311
  return null;
53948
54312
  }
53949
54313
  }
53950
54314
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
53951
- const contextDir = join61(repoRoot, OA_DIR, "context");
53952
- mkdirSync20(contextDir, { recursive: true });
54315
+ const contextDir = join62(repoRoot, OA_DIR, "context");
54316
+ mkdirSync21(contextDir, { recursive: true });
53953
54317
  const cached = {
53954
54318
  phrases,
53955
54319
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
53956
54320
  sourceHash
53957
54321
  };
53958
- writeFileSync21(join61(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
54322
+ writeFileSync22(join62(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
53959
54323
  }
53960
54324
  function generateDescriptors(repoRoot) {
53961
54325
  const profile = loadToolProfile(repoRoot);
@@ -54003,11 +54367,11 @@ function generateDescriptors(repoRoot) {
54003
54367
  return phrases;
54004
54368
  }
54005
54369
  function extractFromPackageJson(repoRoot, tags) {
54006
- const pkgPath = join61(repoRoot, "package.json");
54370
+ const pkgPath = join62(repoRoot, "package.json");
54007
54371
  try {
54008
- if (!existsSync45(pkgPath))
54372
+ if (!existsSync46(pkgPath))
54009
54373
  return;
54010
- const pkg = JSON.parse(readFileSync34(pkgPath, "utf-8"));
54374
+ const pkg = JSON.parse(readFileSync35(pkgPath, "utf-8"));
54011
54375
  if (pkg.name && typeof pkg.name === "string") {
54012
54376
  const parts = pkg.name.replace(/^@/, "").split("/");
54013
54377
  for (const p of parts)
@@ -54051,7 +54415,7 @@ function extractFromManifests(repoRoot, tags) {
54051
54415
  { file: ".github/workflows", tag: "ci/cd" }
54052
54416
  ];
54053
54417
  for (const check of manifestChecks) {
54054
- if (existsSync45(join61(repoRoot, check.file))) {
54418
+ if (existsSync46(join62(repoRoot, check.file))) {
54055
54419
  tags.push(check.tag);
54056
54420
  }
54057
54421
  }
@@ -54073,16 +54437,16 @@ function extractFromSessions(repoRoot, tags) {
54073
54437
  }
54074
54438
  }
54075
54439
  function extractFromMemory(repoRoot, tags) {
54076
- const memoryDir = join61(repoRoot, OA_DIR, "memory");
54440
+ const memoryDir = join62(repoRoot, OA_DIR, "memory");
54077
54441
  try {
54078
- if (!existsSync45(memoryDir))
54442
+ if (!existsSync46(memoryDir))
54079
54443
  return;
54080
54444
  const files = readdirSync14(memoryDir).filter((f) => f.endsWith(".json"));
54081
54445
  for (const file of files) {
54082
54446
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
54083
54447
  tags.push(topic);
54084
54448
  try {
54085
- const data = JSON.parse(readFileSync34(join61(memoryDir, file), "utf-8"));
54449
+ const data = JSON.parse(readFileSync35(join62(memoryDir, file), "utf-8"));
54086
54450
  if (data && typeof data === "object") {
54087
54451
  const keys = Object.keys(data).slice(0, 3);
54088
54452
  for (const key of keys) {
@@ -54753,13 +55117,13 @@ var init_stream_renderer = __esm({
54753
55117
  });
54754
55118
 
54755
55119
  // packages/cli/dist/tui/edit-history.js
54756
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync21 } from "node:fs";
54757
- import { join as join62 } from "node:path";
55120
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync22 } from "node:fs";
55121
+ import { join as join63 } from "node:path";
54758
55122
  function createEditHistoryLogger(repoRoot, sessionId) {
54759
- const historyDir = join62(repoRoot, ".oa", "history");
54760
- const logPath2 = join62(historyDir, "edits.jsonl");
55123
+ const historyDir = join63(repoRoot, ".oa", "history");
55124
+ const logPath2 = join63(historyDir, "edits.jsonl");
54761
55125
  try {
54762
- mkdirSync21(historyDir, { recursive: true });
55126
+ mkdirSync22(historyDir, { recursive: true });
54763
55127
  } catch {
54764
55128
  }
54765
55129
  function logToolCall(toolName, toolArgs, success) {
@@ -54868,17 +55232,17 @@ var init_edit_history = __esm({
54868
55232
  });
54869
55233
 
54870
55234
  // packages/cli/dist/tui/promptLoader.js
54871
- import { readFileSync as readFileSync35, existsSync as existsSync46 } from "node:fs";
54872
- import { join as join63, dirname as dirname19 } from "node:path";
55235
+ import { readFileSync as readFileSync36, existsSync as existsSync47 } from "node:fs";
55236
+ import { join as join64, dirname as dirname19 } from "node:path";
54873
55237
  import { fileURLToPath as fileURLToPath11 } from "node:url";
54874
55238
  function loadPrompt3(promptPath, vars) {
54875
55239
  let content = cache3.get(promptPath);
54876
55240
  if (content === void 0) {
54877
- const fullPath = join63(PROMPTS_DIR3, promptPath);
54878
- if (!existsSync46(fullPath)) {
55241
+ const fullPath = join64(PROMPTS_DIR3, promptPath);
55242
+ if (!existsSync47(fullPath)) {
54879
55243
  throw new Error(`Prompt file not found: ${fullPath}`);
54880
55244
  }
54881
- content = readFileSync35(fullPath, "utf-8");
55245
+ content = readFileSync36(fullPath, "utf-8");
54882
55246
  cache3.set(promptPath, content);
54883
55247
  }
54884
55248
  if (!vars)
@@ -54891,23 +55255,23 @@ var init_promptLoader3 = __esm({
54891
55255
  "use strict";
54892
55256
  __filename3 = fileURLToPath11(import.meta.url);
54893
55257
  __dirname6 = dirname19(__filename3);
54894
- devPath2 = join63(__dirname6, "..", "..", "prompts");
54895
- publishedPath2 = join63(__dirname6, "..", "prompts");
54896
- PROMPTS_DIR3 = existsSync46(devPath2) ? devPath2 : publishedPath2;
55258
+ devPath2 = join64(__dirname6, "..", "..", "prompts");
55259
+ publishedPath2 = join64(__dirname6, "..", "prompts");
55260
+ PROMPTS_DIR3 = existsSync47(devPath2) ? devPath2 : publishedPath2;
54897
55261
  cache3 = /* @__PURE__ */ new Map();
54898
55262
  }
54899
55263
  });
54900
55264
 
54901
55265
  // packages/cli/dist/tui/dream-engine.js
54902
- import { mkdirSync as mkdirSync22, writeFileSync as writeFileSync22, readFileSync as readFileSync36, existsSync as existsSync47, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
54903
- import { join as join64, basename as basename14 } from "node:path";
54904
- import { execSync as execSync31 } from "node:child_process";
55266
+ import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync23, readFileSync as readFileSync37, existsSync as existsSync48, cpSync, rmSync as rmSync2, readdirSync as readdirSync15 } from "node:fs";
55267
+ import { join as join65, basename as basename14 } from "node:path";
55268
+ import { execSync as execSync32 } from "node:child_process";
54905
55269
  function loadAutoresearchMemory(repoRoot) {
54906
- const memoryPath = join64(repoRoot, ".oa", "memory", "autoresearch.json");
54907
- if (!existsSync47(memoryPath))
55270
+ const memoryPath = join65(repoRoot, ".oa", "memory", "autoresearch.json");
55271
+ if (!existsSync48(memoryPath))
54908
55272
  return "";
54909
55273
  try {
54910
- const raw = readFileSync36(memoryPath, "utf-8");
55274
+ const raw = readFileSync37(memoryPath, "utf-8");
54911
55275
  const data = JSON.parse(raw);
54912
55276
  const sections = [];
54913
55277
  for (const key of AUTORESEARCH_MEMORY_KEYS) {
@@ -55097,14 +55461,14 @@ var init_dream_engine = __esm({
55097
55461
  const content = String(args["content"] ?? "");
55098
55462
  if (!rawPath)
55099
55463
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
55100
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join64(this.autoresearchDir, basename14(rawPath)) : join64(this.autoresearchDir, rawPath);
55464
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join65(this.autoresearchDir, basename14(rawPath)) : join65(this.autoresearchDir, rawPath);
55101
55465
  if (!targetPath.startsWith(this.autoresearchDir)) {
55102
55466
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
55103
55467
  }
55104
55468
  try {
55105
- const dir = join64(targetPath, "..");
55106
- mkdirSync22(dir, { recursive: true });
55107
- writeFileSync22(targetPath, content, "utf-8");
55469
+ const dir = join65(targetPath, "..");
55470
+ mkdirSync23(dir, { recursive: true });
55471
+ writeFileSync23(targetPath, content, "utf-8");
55108
55472
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
55109
55473
  } catch (err) {
55110
55474
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -55132,20 +55496,20 @@ var init_dream_engine = __esm({
55132
55496
  const rawPath = String(args["path"] ?? "");
55133
55497
  const oldStr = String(args["old_string"] ?? "");
55134
55498
  const newStr = String(args["new_string"] ?? "");
55135
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join64(this.autoresearchDir, basename14(rawPath)) : join64(this.autoresearchDir, rawPath);
55499
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join65(this.autoresearchDir, basename14(rawPath)) : join65(this.autoresearchDir, rawPath);
55136
55500
  if (!targetPath.startsWith(this.autoresearchDir)) {
55137
55501
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
55138
55502
  }
55139
55503
  try {
55140
- if (!existsSync47(targetPath)) {
55504
+ if (!existsSync48(targetPath)) {
55141
55505
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
55142
55506
  }
55143
- let content = readFileSync36(targetPath, "utf-8");
55507
+ let content = readFileSync37(targetPath, "utf-8");
55144
55508
  if (!content.includes(oldStr)) {
55145
55509
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
55146
55510
  }
55147
55511
  content = content.replace(oldStr, newStr);
55148
- writeFileSync22(targetPath, content, "utf-8");
55512
+ writeFileSync23(targetPath, content, "utf-8");
55149
55513
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
55150
55514
  } catch (err) {
55151
55515
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -55186,14 +55550,14 @@ var init_dream_engine = __esm({
55186
55550
  const content = String(args["content"] ?? "");
55187
55551
  if (!rawPath)
55188
55552
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
55189
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join64(this.dreamsDir, basename14(rawPath)) : join64(this.dreamsDir, rawPath);
55553
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join65(this.dreamsDir, basename14(rawPath)) : join65(this.dreamsDir, rawPath);
55190
55554
  if (!targetPath.startsWith(this.dreamsDir)) {
55191
55555
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
55192
55556
  }
55193
55557
  try {
55194
- const dir = join64(targetPath, "..");
55195
- mkdirSync22(dir, { recursive: true });
55196
- writeFileSync22(targetPath, content, "utf-8");
55558
+ const dir = join65(targetPath, "..");
55559
+ mkdirSync23(dir, { recursive: true });
55560
+ writeFileSync23(targetPath, content, "utf-8");
55197
55561
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
55198
55562
  } catch (err) {
55199
55563
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -55221,20 +55585,20 @@ var init_dream_engine = __esm({
55221
55585
  const rawPath = String(args["path"] ?? "");
55222
55586
  const oldStr = String(args["old_string"] ?? "");
55223
55587
  const newStr = String(args["new_string"] ?? "");
55224
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join64(this.dreamsDir, basename14(rawPath)) : join64(this.dreamsDir, rawPath);
55588
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join65(this.dreamsDir, basename14(rawPath)) : join65(this.dreamsDir, rawPath);
55225
55589
  if (!targetPath.startsWith(this.dreamsDir)) {
55226
55590
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
55227
55591
  }
55228
55592
  try {
55229
- if (!existsSync47(targetPath)) {
55593
+ if (!existsSync48(targetPath)) {
55230
55594
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
55231
55595
  }
55232
- let content = readFileSync36(targetPath, "utf-8");
55596
+ let content = readFileSync37(targetPath, "utf-8");
55233
55597
  if (!content.includes(oldStr)) {
55234
55598
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
55235
55599
  }
55236
55600
  content = content.replace(oldStr, newStr);
55237
- writeFileSync22(targetPath, content, "utf-8");
55601
+ writeFileSync23(targetPath, content, "utf-8");
55238
55602
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
55239
55603
  } catch (err) {
55240
55604
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -55265,7 +55629,7 @@ var init_dream_engine = __esm({
55265
55629
  }
55266
55630
  }
55267
55631
  try {
55268
- const output = execSync31(cmd, {
55632
+ const output = execSync32(cmd, {
55269
55633
  cwd: this.repoRoot,
55270
55634
  timeout: 3e4,
55271
55635
  encoding: "utf-8",
@@ -55288,7 +55652,7 @@ var init_dream_engine = __esm({
55288
55652
  constructor(config, repoRoot) {
55289
55653
  this.config = config;
55290
55654
  this.repoRoot = repoRoot;
55291
- this.dreamsDir = join64(repoRoot, ".oa", "dreams");
55655
+ this.dreamsDir = join65(repoRoot, ".oa", "dreams");
55292
55656
  this.state = {
55293
55657
  mode: "default",
55294
55658
  active: false,
@@ -55319,7 +55683,7 @@ var init_dream_engine = __esm({
55319
55683
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
55320
55684
  results: []
55321
55685
  };
55322
- mkdirSync22(this.dreamsDir, { recursive: true });
55686
+ mkdirSync23(this.dreamsDir, { recursive: true });
55323
55687
  this.saveDreamState();
55324
55688
  try {
55325
55689
  for (let cycle = 1; cycle <= totalCycles; cycle++) {
@@ -55372,8 +55736,8 @@ ${result.summary}`;
55372
55736
  if (mode !== "default" || cycle === totalCycles) {
55373
55737
  renderDreamContraction(cycle);
55374
55738
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
55375
- const summaryPath = join64(this.dreamsDir, `cycle-${cycle}-summary.md`);
55376
- writeFileSync22(summaryPath, cycleSummary, "utf-8");
55739
+ const summaryPath = join65(this.dreamsDir, `cycle-${cycle}-summary.md`);
55740
+ writeFileSync23(summaryPath, cycleSummary, "utf-8");
55377
55741
  }
55378
55742
  if (mode === "lucid" && !this.abortController.signal.aborted) {
55379
55743
  this.saveVersionCheckpoint(cycle);
@@ -55585,7 +55949,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
55585
55949
  }
55586
55950
  /** Build role-specific tool sets for swarm agents */
55587
55951
  buildSwarmTools(role, _workspace) {
55588
- const autoresearchDir = join64(this.repoRoot, ".oa", "autoresearch");
55952
+ const autoresearchDir = join65(this.repoRoot, ".oa", "autoresearch");
55589
55953
  const taskComplete = this.createSwarmTaskCompleteTool(role);
55590
55954
  switch (role) {
55591
55955
  case "researcher": {
@@ -55949,7 +56313,7 @@ INSTRUCTIONS:
55949
56313
  2. Summarize the key learnings and next steps
55950
56314
 
55951
56315
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
55952
- const reportPath = join64(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
56316
+ const reportPath = join65(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
55953
56317
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
55954
56318
 
55955
56319
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -55971,8 +56335,8 @@ ${summaryResult}
55971
56335
  *Generated by open-agents autoresearch swarm*
55972
56336
  `;
55973
56337
  try {
55974
- mkdirSync22(this.dreamsDir, { recursive: true });
55975
- writeFileSync22(reportPath, report, "utf-8");
56338
+ mkdirSync23(this.dreamsDir, { recursive: true });
56339
+ writeFileSync23(reportPath, report, "utf-8");
55976
56340
  } catch {
55977
56341
  }
55978
56342
  renderSwarmComplete(workspace);
@@ -56038,29 +56402,29 @@ ${summaryResult}
56038
56402
  }
56039
56403
  /** Save workspace backup for lucid mode */
56040
56404
  saveVersionCheckpoint(cycle) {
56041
- const checkpointDir = join64(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
56405
+ const checkpointDir = join65(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
56042
56406
  try {
56043
- mkdirSync22(checkpointDir, { recursive: true });
56407
+ mkdirSync23(checkpointDir, { recursive: true });
56044
56408
  try {
56045
- const gitStatus = execSync31("git status --porcelain", {
56409
+ const gitStatus = execSync32("git status --porcelain", {
56046
56410
  cwd: this.repoRoot,
56047
56411
  encoding: "utf-8",
56048
56412
  timeout: 1e4
56049
56413
  });
56050
- const gitDiff = execSync31("git diff", {
56414
+ const gitDiff = execSync32("git diff", {
56051
56415
  cwd: this.repoRoot,
56052
56416
  encoding: "utf-8",
56053
56417
  timeout: 1e4
56054
56418
  });
56055
- const gitHash = execSync31("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
56419
+ const gitHash = execSync32("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
56056
56420
  cwd: this.repoRoot,
56057
56421
  encoding: "utf-8",
56058
56422
  timeout: 5e3
56059
56423
  }).trim();
56060
- writeFileSync22(join64(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
56061
- writeFileSync22(join64(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
56062
- writeFileSync22(join64(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
56063
- writeFileSync22(join64(checkpointDir, "checkpoint.json"), JSON.stringify({
56424
+ writeFileSync23(join65(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
56425
+ writeFileSync23(join65(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
56426
+ writeFileSync23(join65(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
56427
+ writeFileSync23(join65(checkpointDir, "checkpoint.json"), JSON.stringify({
56064
56428
  cycle,
56065
56429
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
56066
56430
  gitHash,
@@ -56068,7 +56432,7 @@ ${summaryResult}
56068
56432
  }, null, 2), "utf-8");
56069
56433
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
56070
56434
  } catch {
56071
- writeFileSync22(join64(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
56435
+ writeFileSync23(join65(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
56072
56436
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
56073
56437
  }
56074
56438
  } catch (err) {
@@ -56126,14 +56490,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
56126
56490
  ---
56127
56491
  *Auto-generated by open-agents dream engine*
56128
56492
  `;
56129
- writeFileSync22(join64(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
56493
+ writeFileSync23(join65(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
56130
56494
  } catch {
56131
56495
  }
56132
56496
  }
56133
56497
  /** Save dream state for resume/inspection */
56134
56498
  saveDreamState() {
56135
56499
  try {
56136
- writeFileSync22(join64(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
56500
+ writeFileSync23(join65(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
56137
56501
  } catch {
56138
56502
  }
56139
56503
  }
@@ -56507,8 +56871,8 @@ var init_bless_engine = __esm({
56507
56871
  });
56508
56872
 
56509
56873
  // packages/cli/dist/tui/dmn-engine.js
56510
- import { existsSync as existsSync48, readFileSync as readFileSync37, writeFileSync as writeFileSync23, mkdirSync as mkdirSync23, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
56511
- import { join as join65, basename as basename15 } from "node:path";
56874
+ import { existsSync as existsSync49, readFileSync as readFileSync38, writeFileSync as writeFileSync24, mkdirSync as mkdirSync24, readdirSync as readdirSync16, unlinkSync as unlinkSync10 } from "node:fs";
56875
+ import { join as join66, basename as basename15 } from "node:path";
56512
56876
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
56513
56877
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
56514
56878
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -56628,9 +56992,9 @@ var init_dmn_engine = __esm({
56628
56992
  constructor(config, repoRoot) {
56629
56993
  this.config = config;
56630
56994
  this.repoRoot = repoRoot;
56631
- this.stateDir = join65(repoRoot, ".oa", "dmn");
56632
- this.historyDir = join65(repoRoot, ".oa", "dmn", "cycles");
56633
- mkdirSync23(this.historyDir, { recursive: true });
56995
+ this.stateDir = join66(repoRoot, ".oa", "dmn");
56996
+ this.historyDir = join66(repoRoot, ".oa", "dmn", "cycles");
56997
+ mkdirSync24(this.historyDir, { recursive: true });
56634
56998
  this.loadState();
56635
56999
  }
56636
57000
  get stats() {
@@ -57219,11 +57583,11 @@ OUTPUT: Call task_complete with JSON:
57219
57583
  async gatherMemoryTopics() {
57220
57584
  const topics = [];
57221
57585
  const dirs = [
57222
- join65(this.repoRoot, ".oa", "memory"),
57223
- join65(this.repoRoot, ".open-agents", "memory")
57586
+ join66(this.repoRoot, ".oa", "memory"),
57587
+ join66(this.repoRoot, ".open-agents", "memory")
57224
57588
  ];
57225
57589
  for (const dir of dirs) {
57226
- if (!existsSync48(dir))
57590
+ if (!existsSync49(dir))
57227
57591
  continue;
57228
57592
  try {
57229
57593
  const files = readdirSync16(dir).filter((f) => f.endsWith(".json"));
@@ -57239,29 +57603,29 @@ OUTPUT: Call task_complete with JSON:
57239
57603
  }
57240
57604
  // ── State persistence ─────────────────────────────────────────────────
57241
57605
  loadState() {
57242
- const path = join65(this.stateDir, "state.json");
57243
- if (existsSync48(path)) {
57606
+ const path = join66(this.stateDir, "state.json");
57607
+ if (existsSync49(path)) {
57244
57608
  try {
57245
- this.state = JSON.parse(readFileSync37(path, "utf-8"));
57609
+ this.state = JSON.parse(readFileSync38(path, "utf-8"));
57246
57610
  } catch {
57247
57611
  }
57248
57612
  }
57249
57613
  }
57250
57614
  saveState() {
57251
57615
  try {
57252
- writeFileSync23(join65(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
57616
+ writeFileSync24(join66(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
57253
57617
  } catch {
57254
57618
  }
57255
57619
  }
57256
57620
  saveCycleResult(result) {
57257
57621
  try {
57258
57622
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
57259
- writeFileSync23(join65(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
57623
+ writeFileSync24(join66(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
57260
57624
  const files = readdirSync16(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
57261
57625
  if (files.length > 50) {
57262
57626
  for (const old of files.slice(0, files.length - 50)) {
57263
57627
  try {
57264
- unlinkSync10(join65(this.historyDir, old));
57628
+ unlinkSync10(join66(this.historyDir, old));
57265
57629
  } catch {
57266
57630
  }
57267
57631
  }
@@ -57274,8 +57638,8 @@ OUTPUT: Call task_complete with JSON:
57274
57638
  });
57275
57639
 
57276
57640
  // packages/cli/dist/tui/snr-engine.js
57277
- import { existsSync as existsSync49, readdirSync as readdirSync17, readFileSync as readFileSync38 } from "node:fs";
57278
- import { join as join66, basename as basename16 } from "node:path";
57641
+ import { existsSync as existsSync50, readdirSync as readdirSync17, readFileSync as readFileSync39 } from "node:fs";
57642
+ import { join as join67, basename as basename16 } from "node:path";
57279
57643
  function computeDPrime(signalScores, noiseScores) {
57280
57644
  if (signalScores.length === 0 || noiseScores.length === 0)
57281
57645
  return 0;
@@ -57515,11 +57879,11 @@ Call task_complete with the JSON array when done.`, onEvent)
57515
57879
  loadMemoryEntries(topics) {
57516
57880
  const entries = [];
57517
57881
  const dirs = [
57518
- join66(this.repoRoot, ".oa", "memory"),
57519
- join66(this.repoRoot, ".open-agents", "memory")
57882
+ join67(this.repoRoot, ".oa", "memory"),
57883
+ join67(this.repoRoot, ".open-agents", "memory")
57520
57884
  ];
57521
57885
  for (const dir of dirs) {
57522
- if (!existsSync49(dir))
57886
+ if (!existsSync50(dir))
57523
57887
  continue;
57524
57888
  try {
57525
57889
  const files = readdirSync17(dir).filter((f) => f.endsWith(".json"));
@@ -57528,7 +57892,7 @@ Call task_complete with the JSON array when done.`, onEvent)
57528
57892
  if (topics.length > 0 && !topics.includes(topic))
57529
57893
  continue;
57530
57894
  try {
57531
- const data = JSON.parse(readFileSync38(join66(dir, f), "utf-8"));
57895
+ const data = JSON.parse(readFileSync39(join67(dir, f), "utf-8"));
57532
57896
  for (const [key, val] of Object.entries(data)) {
57533
57897
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
57534
57898
  entries.push({ topic, key, value });
@@ -58095,8 +58459,8 @@ var init_tool_policy = __esm({
58095
58459
  });
58096
58460
 
58097
58461
  // packages/cli/dist/tui/telegram-bridge.js
58098
- import { mkdirSync as mkdirSync24, existsSync as existsSync50, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
58099
- import { join as join67, resolve as resolve30 } from "node:path";
58462
+ import { mkdirSync as mkdirSync25, existsSync as existsSync51, unlinkSync as unlinkSync11, readdirSync as readdirSync18, statSync as statSync15 } from "node:fs";
58463
+ import { join as join68, resolve as resolve30 } from "node:path";
58100
58464
  import { writeFile as writeFileAsync } from "node:fs/promises";
58101
58465
  function convertMarkdownToTelegramHTML(md) {
58102
58466
  let html = md;
@@ -58424,7 +58788,7 @@ with summary "no_reply" to silently skip without responding.
58424
58788
  this.polling = true;
58425
58789
  this.abortController = new AbortController();
58426
58790
  try {
58427
- mkdirSync24(this.mediaCacheDir, { recursive: true });
58791
+ mkdirSync25(this.mediaCacheDir, { recursive: true });
58428
58792
  } catch {
58429
58793
  }
58430
58794
  this.mediaCacheCleanupTimer = setInterval(() => this.cleanupMediaCache(), 5 * 60 * 1e3);
@@ -58861,7 +59225,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
58861
59225
  return null;
58862
59226
  const buffer = Buffer.from(await res.arrayBuffer());
58863
59227
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
58864
- const localPath = join67(this.mediaCacheDir, fileName);
59228
+ const localPath = join68(this.mediaCacheDir, fileName);
58865
59229
  await writeFileAsync(localPath, buffer);
58866
59230
  return localPath;
58867
59231
  } catch {
@@ -59877,7 +60241,7 @@ __export(text_selection_exports, {
59877
60241
  stripAnsi: () => stripAnsi3,
59878
60242
  visibleLength: () => visibleLength
59879
60243
  });
59880
- import { execSync as execSync32 } from "node:child_process";
60244
+ import { execSync as execSync33 } from "node:child_process";
59881
60245
  function stripAnsi3(s) {
59882
60246
  return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
59883
60247
  }
@@ -59888,16 +60252,16 @@ function copyText(text) {
59888
60252
  try {
59889
60253
  const platform6 = process.platform;
59890
60254
  if (platform6 === "darwin") {
59891
- execSync32("pbcopy", { input: text, timeout: 3e3 });
60255
+ execSync33("pbcopy", { input: text, timeout: 3e3 });
59892
60256
  return true;
59893
60257
  }
59894
60258
  if (platform6 === "win32") {
59895
- execSync32("clip", { input: text, timeout: 3e3 });
60259
+ execSync33("clip", { input: text, timeout: 3e3 });
59896
60260
  return true;
59897
60261
  }
59898
60262
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
59899
60263
  try {
59900
- execSync32(tool, { input: text, timeout: 3e3 });
60264
+ execSync33(tool, { input: text, timeout: 3e3 });
59901
60265
  return true;
59902
60266
  } catch {
59903
60267
  continue;
@@ -59906,10 +60270,10 @@ function copyText(text) {
59906
60270
  if (!_clipboardAutoInstallAttempted) {
59907
60271
  _clipboardAutoInstallAttempted = true;
59908
60272
  try {
59909
- execSync32("which apt-get", { timeout: 2e3, stdio: "pipe" });
60273
+ execSync33("which apt-get", { timeout: 2e3, stdio: "pipe" });
59910
60274
  try {
59911
- execSync32("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
59912
- execSync32("xclip -selection clipboard", { input: text, timeout: 3e3 });
60275
+ execSync33("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
60276
+ execSync33("xclip -selection clipboard", { input: text, timeout: 3e3 });
59913
60277
  return true;
59914
60278
  } catch {
59915
60279
  }
@@ -60217,7 +60581,7 @@ var init_text_selection = __esm({
60217
60581
  });
60218
60582
 
60219
60583
  // packages/cli/dist/tui/status-bar.js
60220
- import { readFileSync as readFileSync39 } from "node:fs";
60584
+ import { readFileSync as readFileSync40 } from "node:fs";
60221
60585
  function setTerminalTitle(task, version) {
60222
60586
  if (!process.stdout.isTTY)
60223
60587
  return;
@@ -60914,7 +61278,7 @@ var init_status_bar = __esm({
60914
61278
  if (nexusDir) {
60915
61279
  try {
60916
61280
  const metricsPath = nexusDir + "/remote-metrics.json";
60917
- const raw = readFileSync39(metricsPath, "utf8");
61281
+ const raw = readFileSync40(metricsPath, "utf8");
60918
61282
  const cached = JSON.parse(raw);
60919
61283
  if (cached && cached.ts && Date.now() - cached.ts < 6e4) {
60920
61284
  const m = cached.data;
@@ -63207,24 +63571,24 @@ var init_direct_input = __esm({
63207
63571
  });
63208
63572
 
63209
63573
  // packages/cli/dist/api/profiles.js
63210
- import { existsSync as existsSync51, readFileSync as readFileSync40, writeFileSync as writeFileSync24, mkdirSync as mkdirSync25, readdirSync as readdirSync19, unlinkSync as unlinkSync12 } from "node:fs";
63211
- import { join as join68 } from "node:path";
63212
- import { homedir as homedir17 } from "node:os";
63574
+ import { existsSync as existsSync52, readFileSync as readFileSync41, writeFileSync as writeFileSync25, mkdirSync as mkdirSync26, readdirSync as readdirSync19, unlinkSync as unlinkSync12 } from "node:fs";
63575
+ import { join as join69 } from "node:path";
63576
+ import { homedir as homedir18 } from "node:os";
63213
63577
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes15, scryptSync as scryptSync3, createHash as createHash5 } from "node:crypto";
63214
63578
  function globalProfileDir() {
63215
- return join68(homedir17(), ".open-agents", "profiles");
63579
+ return join69(homedir18(), ".open-agents", "profiles");
63216
63580
  }
63217
63581
  function projectProfileDir(projectDir) {
63218
- return join68(projectDir || process.cwd(), ".oa", "profiles");
63582
+ return join69(projectDir || process.cwd(), ".oa", "profiles");
63219
63583
  }
63220
63584
  function listProfiles(projectDir) {
63221
63585
  const result = [];
63222
63586
  const seen = /* @__PURE__ */ new Set();
63223
63587
  const projDir = projectProfileDir(projectDir);
63224
- if (existsSync51(projDir)) {
63588
+ if (existsSync52(projDir)) {
63225
63589
  for (const f of readdirSync19(projDir).filter((f2) => f2.endsWith(".json"))) {
63226
63590
  try {
63227
- const raw = JSON.parse(readFileSync40(join68(projDir, f), "utf8"));
63591
+ const raw = JSON.parse(readFileSync41(join69(projDir, f), "utf8"));
63228
63592
  const name = f.replace(".json", "");
63229
63593
  seen.add(name);
63230
63594
  result.push({
@@ -63238,13 +63602,13 @@ function listProfiles(projectDir) {
63238
63602
  }
63239
63603
  }
63240
63604
  const globDir = globalProfileDir();
63241
- if (existsSync51(globDir)) {
63605
+ if (existsSync52(globDir)) {
63242
63606
  for (const f of readdirSync19(globDir).filter((f2) => f2.endsWith(".json"))) {
63243
63607
  const name = f.replace(".json", "");
63244
63608
  if (seen.has(name))
63245
63609
  continue;
63246
63610
  try {
63247
- const raw = JSON.parse(readFileSync40(join68(globDir, f), "utf8"));
63611
+ const raw = JSON.parse(readFileSync41(join69(globDir, f), "utf8"));
63248
63612
  result.push({
63249
63613
  name,
63250
63614
  description: raw.description || "",
@@ -63259,12 +63623,12 @@ function listProfiles(projectDir) {
63259
63623
  }
63260
63624
  function loadProfile(name, password, projectDir) {
63261
63625
  const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
63262
- const projPath = join68(projectProfileDir(projectDir), `${sanitized}.json`);
63263
- const globPath = join68(globalProfileDir(), `${sanitized}.json`);
63264
- const filePath = existsSync51(projPath) ? projPath : existsSync51(globPath) ? globPath : null;
63626
+ const projPath = join69(projectProfileDir(projectDir), `${sanitized}.json`);
63627
+ const globPath = join69(globalProfileDir(), `${sanitized}.json`);
63628
+ const filePath = existsSync52(projPath) ? projPath : existsSync52(globPath) ? globPath : null;
63265
63629
  if (!filePath)
63266
63630
  return null;
63267
- const raw = JSON.parse(readFileSync40(filePath, "utf8"));
63631
+ const raw = JSON.parse(readFileSync41(filePath, "utf8"));
63268
63632
  if (raw.encrypted === true) {
63269
63633
  if (!password)
63270
63634
  return null;
@@ -63274,23 +63638,23 @@ function loadProfile(name, password, projectDir) {
63274
63638
  }
63275
63639
  function saveProfile(profile, password, scope = "global", projectDir) {
63276
63640
  const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
63277
- mkdirSync25(dir, { recursive: true });
63641
+ mkdirSync26(dir, { recursive: true });
63278
63642
  const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
63279
- const filePath = join68(dir, `${sanitized}.json`);
63643
+ const filePath = join69(dir, `${sanitized}.json`);
63280
63644
  profile.modified = (/* @__PURE__ */ new Date()).toISOString();
63281
63645
  if (password) {
63282
63646
  const encrypted = encryptProfile(profile, password);
63283
- writeFileSync24(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
63647
+ writeFileSync25(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
63284
63648
  } else {
63285
63649
  profile.encrypted = false;
63286
- writeFileSync24(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
63650
+ writeFileSync25(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
63287
63651
  }
63288
63652
  }
63289
63653
  function deleteProfile(name, scope = "global", projectDir) {
63290
63654
  const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "");
63291
63655
  const dir = scope === "project" ? projectProfileDir(projectDir) : globalProfileDir();
63292
- const filePath = join68(dir, `${sanitized}.json`);
63293
- if (existsSync51(filePath)) {
63656
+ const filePath = join69(dir, `${sanitized}.json`);
63657
+ if (existsSync52(filePath)) {
63294
63658
  unlinkSync12(filePath);
63295
63659
  return true;
63296
63660
  }
@@ -63383,22 +63747,22 @@ import * as http from "node:http";
63383
63747
  import * as https from "node:https";
63384
63748
  import { createRequire as createRequire3 } from "node:module";
63385
63749
  import { fileURLToPath as fileURLToPath12 } from "node:url";
63386
- import { dirname as dirname20, join as join69, resolve as resolve31 } from "node:path";
63387
- import { spawn as spawn20 } from "node:child_process";
63388
- import { mkdirSync as mkdirSync26, writeFileSync as writeFileSync25, readFileSync as readFileSync41, readdirSync as readdirSync20, existsSync as existsSync52 } from "node:fs";
63750
+ import { dirname as dirname20, join as join70, resolve as resolve31 } from "node:path";
63751
+ import { spawn as spawn21 } from "node:child_process";
63752
+ import { mkdirSync as mkdirSync27, writeFileSync as writeFileSync26, readFileSync as readFileSync42, readdirSync as readdirSync20, existsSync as existsSync53 } from "node:fs";
63389
63753
  import { randomBytes as randomBytes16 } from "node:crypto";
63390
63754
  function getVersion3() {
63391
63755
  try {
63392
63756
  const require2 = createRequire3(import.meta.url);
63393
63757
  const thisDir = dirname20(fileURLToPath12(import.meta.url));
63394
63758
  const candidates = [
63395
- join69(thisDir, "..", "package.json"),
63396
- join69(thisDir, "..", "..", "package.json"),
63397
- join69(thisDir, "..", "..", "..", "package.json")
63759
+ join70(thisDir, "..", "package.json"),
63760
+ join70(thisDir, "..", "..", "package.json"),
63761
+ join70(thisDir, "..", "..", "..", "package.json")
63398
63762
  ];
63399
63763
  for (const pkgPath of candidates) {
63400
63764
  try {
63401
- if (!existsSync52(pkgPath))
63765
+ if (!existsSync53(pkgPath))
63402
63766
  continue;
63403
63767
  const pkg = require2(pkgPath);
63404
63768
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
@@ -63693,29 +64057,29 @@ function ollamaStream(ollamaUrl, path, method, body, onData, onEnd, onError) {
63693
64057
  }
63694
64058
  function jobsDir() {
63695
64059
  const root = resolve31(process.cwd());
63696
- const dir = join69(root, ".oa", "jobs");
63697
- mkdirSync26(dir, { recursive: true });
64060
+ const dir = join70(root, ".oa", "jobs");
64061
+ mkdirSync27(dir, { recursive: true });
63698
64062
  return dir;
63699
64063
  }
63700
64064
  function loadJob(id) {
63701
- const file = join69(jobsDir(), `${id}.json`);
63702
- if (!existsSync52(file))
64065
+ const file = join70(jobsDir(), `${id}.json`);
64066
+ if (!existsSync53(file))
63703
64067
  return null;
63704
64068
  try {
63705
- return JSON.parse(readFileSync41(file, "utf-8"));
64069
+ return JSON.parse(readFileSync42(file, "utf-8"));
63706
64070
  } catch {
63707
64071
  return null;
63708
64072
  }
63709
64073
  }
63710
64074
  function listJobs() {
63711
64075
  const dir = jobsDir();
63712
- if (!existsSync52(dir))
64076
+ if (!existsSync53(dir))
63713
64077
  return [];
63714
64078
  const files = readdirSync20(dir).filter((f) => f.endsWith(".json")).sort();
63715
64079
  const jobs = [];
63716
64080
  for (const file of files) {
63717
64081
  try {
63718
- jobs.push(JSON.parse(readFileSync41(join69(dir, file), "utf-8")));
64082
+ jobs.push(JSON.parse(readFileSync42(join70(dir, file), "utf-8")));
63719
64083
  } catch {
63720
64084
  }
63721
64085
  }
@@ -64108,8 +64472,8 @@ async function handleV1Run(req, res) {
64108
64472
  if (workingDir) {
64109
64473
  cwd4 = resolve31(workingDir);
64110
64474
  } else if (isolate) {
64111
- const wsDir = join69(dir, "..", "workspaces", id);
64112
- mkdirSync26(wsDir, { recursive: true });
64475
+ const wsDir = join70(dir, "..", "workspaces", id);
64476
+ mkdirSync27(wsDir, { recursive: true });
64113
64477
  cwd4 = wsDir;
64114
64478
  } else {
64115
64479
  cwd4 = resolve31(process.cwd());
@@ -64173,7 +64537,7 @@ async function handleV1Run(req, res) {
64173
64537
  }
64174
64538
  }
64175
64539
  }
64176
- const child = spawn20("node", [oaBin, ...args], {
64540
+ const child = spawn21("node", [oaBin, ...args], {
64177
64541
  cwd: cwd4,
64178
64542
  env: runEnv,
64179
64543
  stdio: ["ignore", "pipe", "pipe"],
@@ -64181,7 +64545,7 @@ async function handleV1Run(req, res) {
64181
64545
  });
64182
64546
  child.unref();
64183
64547
  job.pid = child.pid ?? 0;
64184
- writeFileSync25(join69(dir, `${id}.json`), JSON.stringify(job, null, 2));
64548
+ writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
64185
64549
  runningProcesses.set(id, child);
64186
64550
  if (streamMode) {
64187
64551
  res.writeHead(200, {
@@ -64211,7 +64575,7 @@ async function handleV1Run(req, res) {
64211
64575
  job.status = code === 0 ? "completed" : "failed";
64212
64576
  job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
64213
64577
  try {
64214
- writeFileSync25(join69(dir, `${id}.json`), JSON.stringify(job, null, 2));
64578
+ writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
64215
64579
  } catch {
64216
64580
  }
64217
64581
  runningProcesses.delete(id);
@@ -64242,7 +64606,7 @@ async function handleV1Run(req, res) {
64242
64606
  job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
64243
64607
  }
64244
64608
  try {
64245
- writeFileSync25(join69(dir, `${id}.json`), JSON.stringify(job, null, 2));
64609
+ writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
64246
64610
  } catch {
64247
64611
  }
64248
64612
  runningProcesses.delete(id);
@@ -64283,7 +64647,7 @@ function handleV1RunsDelete(res, id) {
64283
64647
  job.error = "Aborted via API";
64284
64648
  const dir = jobsDir();
64285
64649
  try {
64286
- writeFileSync25(join69(dir, `${id}.json`), JSON.stringify(job, null, 2));
64650
+ writeFileSync26(join70(dir, `${id}.json`), JSON.stringify(job, null, 2));
64287
64651
  } catch {
64288
64652
  }
64289
64653
  runningProcesses.delete(id);
@@ -64395,7 +64759,7 @@ async function handlePostCommand(res, cmd) {
64395
64759
  return;
64396
64760
  }
64397
64761
  try {
64398
- const child = spawn20("node", [oaBin, "run", `/${cmd}`, "--json"], {
64762
+ const child = spawn21("node", [oaBin, "run", `/${cmd}`, "--json"], {
64399
64763
  env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
64400
64764
  stdio: ["ignore", "pipe", "pipe"],
64401
64765
  timeout: 3e4
@@ -64808,13 +65172,13 @@ var init_serve = __esm({
64808
65172
 
64809
65173
  // packages/cli/dist/tui/interactive.js
64810
65174
  import { cwd } from "node:process";
64811
- import { resolve as resolve32, join as join70, dirname as dirname21, extname as extname11 } from "node:path";
65175
+ import { resolve as resolve32, join as join71, dirname as dirname21, extname as extname11 } from "node:path";
64812
65176
  import { createRequire as createRequire4 } from "node:module";
64813
65177
  import { fileURLToPath as fileURLToPath13 } from "node:url";
64814
- import { readFileSync as readFileSync42, writeFileSync as writeFileSync26, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync21, mkdirSync as mkdirSync27 } from "node:fs";
64815
- import { existsSync as existsSync53 } from "node:fs";
64816
- import { execSync as execSync33 } from "node:child_process";
64817
- import { homedir as homedir18 } from "node:os";
65178
+ import { readFileSync as readFileSync43, writeFileSync as writeFileSync27, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync21, mkdirSync as mkdirSync28 } from "node:fs";
65179
+ import { existsSync as existsSync54 } from "node:fs";
65180
+ import { execSync as execSync34 } from "node:child_process";
65181
+ import { homedir as homedir19 } from "node:os";
64818
65182
  function formatTimeAgo(date) {
64819
65183
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
64820
65184
  if (seconds < 60)
@@ -64833,12 +65197,12 @@ function getVersion4() {
64833
65197
  const require2 = createRequire4(import.meta.url);
64834
65198
  const thisDir = dirname21(fileURLToPath13(import.meta.url));
64835
65199
  const candidates = [
64836
- join70(thisDir, "..", "package.json"),
64837
- join70(thisDir, "..", "..", "package.json"),
64838
- join70(thisDir, "..", "..", "..", "package.json")
65200
+ join71(thisDir, "..", "package.json"),
65201
+ join71(thisDir, "..", "..", "package.json"),
65202
+ join71(thisDir, "..", "..", "..", "package.json")
64839
65203
  ];
64840
65204
  for (const pkgPath of candidates) {
64841
- if (existsSync53(pkgPath)) {
65205
+ if (existsSync54(pkgPath)) {
64842
65206
  const pkg = require2(pkgPath);
64843
65207
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
64844
65208
  return pkg.version ?? "0.0.0";
@@ -65074,15 +65438,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
65074
65438
  function gatherMemorySnippets(root) {
65075
65439
  const snippets = [];
65076
65440
  const dirs = [
65077
- join70(root, ".oa", "memory"),
65078
- join70(root, ".open-agents", "memory")
65441
+ join71(root, ".oa", "memory"),
65442
+ join71(root, ".open-agents", "memory")
65079
65443
  ];
65080
65444
  for (const dir of dirs) {
65081
- if (!existsSync53(dir))
65445
+ if (!existsSync54(dir))
65082
65446
  continue;
65083
65447
  try {
65084
65448
  for (const f of readdirSync21(dir).filter((f2) => f2.endsWith(".json"))) {
65085
- const data = JSON.parse(readFileSync42(join70(dir, f), "utf-8"));
65449
+ const data = JSON.parse(readFileSync43(join71(dir, f), "utf-8"));
65086
65450
  for (const val of Object.values(data)) {
65087
65451
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
65088
65452
  if (v.length > 10)
@@ -65239,9 +65603,9 @@ ${metabolismMemories}
65239
65603
  } catch {
65240
65604
  }
65241
65605
  try {
65242
- const archeFile = join70(repoRoot, ".oa", "arche", "variants.json");
65243
- if (existsSync53(archeFile)) {
65244
- const variants = JSON.parse(readFileSync42(archeFile, "utf8"));
65606
+ const archeFile = join71(repoRoot, ".oa", "arche", "variants.json");
65607
+ if (existsSync54(archeFile)) {
65608
+ const variants = JSON.parse(readFileSync43(archeFile, "utf8"));
65245
65609
  if (variants.length > 0) {
65246
65610
  let filtered = variants;
65247
65611
  if (taskType) {
@@ -65410,9 +65774,9 @@ RULES:
65410
65774
  const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
65411
65775
  let identityInjection = "";
65412
65776
  try {
65413
- const ikStateFile = join70(repoRoot, ".oa", "identity", "self-state.json");
65414
- if (existsSync53(ikStateFile)) {
65415
- const selfState = JSON.parse(readFileSync42(ikStateFile, "utf8"));
65777
+ const ikStateFile = join71(repoRoot, ".oa", "identity", "self-state.json");
65778
+ if (existsSync54(ikStateFile)) {
65779
+ const selfState = JSON.parse(readFileSync43(ikStateFile, "utf8"));
65416
65780
  const lines = [
65417
65781
  `[Identity State v${selfState.version}]`,
65418
65782
  `Self: ${selfState.narrative_summary}`,
@@ -66055,13 +66419,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
66055
66419
  });
66056
66420
  }
66057
66421
  try {
66058
- const ikDir = join70(repoRoot, ".oa", "identity");
66059
- const ikFile = join70(ikDir, "self-state.json");
66422
+ const ikDir = join71(repoRoot, ".oa", "identity");
66423
+ const ikFile = join71(ikDir, "self-state.json");
66060
66424
  let ikState;
66061
- if (existsSync53(ikFile)) {
66062
- ikState = JSON.parse(readFileSync42(ikFile, "utf8"));
66425
+ if (existsSync54(ikFile)) {
66426
+ ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
66063
66427
  } else {
66064
- mkdirSync27(ikDir, { recursive: true });
66428
+ mkdirSync28(ikDir, { recursive: true });
66065
66429
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
66066
66430
  ikState = {
66067
66431
  self_id: `oa-${machineId}`,
@@ -66087,7 +66451,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
66087
66451
  }
66088
66452
  ikState.session_count = (ikState.session_count || 0) + 1;
66089
66453
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
66090
- writeFileSync26(ikFile, JSON.stringify(ikState, null, 2));
66454
+ writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
66091
66455
  } catch (ikErr) {
66092
66456
  try {
66093
66457
  console.error("[IK-OBSERVE]", ikErr);
@@ -66102,14 +66466,14 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
66102
66466
  } else {
66103
66467
  renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
66104
66468
  try {
66105
- const ikFile = join70(repoRoot, ".oa", "identity", "self-state.json");
66106
- if (existsSync53(ikFile)) {
66107
- const ikState = JSON.parse(readFileSync42(ikFile, "utf8"));
66469
+ const ikFile = join71(repoRoot, ".oa", "identity", "self-state.json");
66470
+ if (existsSync54(ikFile)) {
66471
+ const ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
66108
66472
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
66109
66473
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
66110
66474
  ikState.session_count = (ikState.session_count || 0) + 1;
66111
66475
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
66112
- writeFileSync26(ikFile, JSON.stringify(ikState, null, 2));
66476
+ writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
66113
66477
  }
66114
66478
  } catch {
66115
66479
  }
@@ -66206,10 +66570,10 @@ async function startInteractive(config, repoPath) {
66206
66570
  process.stdin.pause();
66207
66571
  }
66208
66572
  try {
66209
- const oaDir = join70(repoRoot, ".oa");
66210
- const nexusPidFile = join70(oaDir, "nexus", "daemon.pid");
66211
- if (existsSync53(nexusPidFile)) {
66212
- const pid = parseInt(readFileSync42(nexusPidFile, "utf8").trim(), 10);
66573
+ const oaDir = join71(repoRoot, ".oa");
66574
+ const nexusPidFile = join71(oaDir, "nexus", "daemon.pid");
66575
+ if (existsSync54(nexusPidFile)) {
66576
+ const pid = parseInt(readFileSync43(nexusPidFile, "utf8").trim(), 10);
66213
66577
  if (pid > 0) {
66214
66578
  try {
66215
66579
  process.kill(pid, 0);
@@ -66518,7 +66882,7 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
66518
66882
  let p2pGateway = null;
66519
66883
  let peerMesh = null;
66520
66884
  let inferenceRouter = null;
66521
- const secretVault = new SecretVault(join70(repoRoot, ".oa", "vault.enc"));
66885
+ const secretVault = new SecretVault(join71(repoRoot, ".oa", "vault.enc"));
66522
66886
  let adminSessionKey = null;
66523
66887
  const callSubAgents = /* @__PURE__ */ new Map();
66524
66888
  const streamRenderer = new StreamRenderer();
@@ -66741,13 +67105,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
66741
67105
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
66742
67106
  return [hits, line];
66743
67107
  }
66744
- const HISTORY_DIR = join70(homedir18(), ".open-agents");
66745
- const HISTORY_FILE = join70(HISTORY_DIR, "repl-history");
67108
+ const HISTORY_DIR = join71(homedir19(), ".open-agents");
67109
+ const HISTORY_FILE = join71(HISTORY_DIR, "repl-history");
66746
67110
  const MAX_HISTORY_LINES = 500;
66747
67111
  let savedHistory = [];
66748
67112
  try {
66749
- if (existsSync53(HISTORY_FILE)) {
66750
- const raw = readFileSync42(HISTORY_FILE, "utf8").trim();
67113
+ if (existsSync54(HISTORY_FILE)) {
67114
+ const raw = readFileSync43(HISTORY_FILE, "utf8").trim();
66751
67115
  if (raw)
66752
67116
  savedHistory = raw.split("\n").reverse();
66753
67117
  }
@@ -66850,12 +67214,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
66850
67214
  if (!line.trim())
66851
67215
  return;
66852
67216
  try {
66853
- mkdirSync27(HISTORY_DIR, { recursive: true });
67217
+ mkdirSync28(HISTORY_DIR, { recursive: true });
66854
67218
  appendFileSync4(HISTORY_FILE, line + "\n", "utf8");
66855
67219
  if (Math.random() < 0.02) {
66856
- const all = readFileSync42(HISTORY_FILE, "utf8").trim().split("\n");
67220
+ const all = readFileSync43(HISTORY_FILE, "utf8").trim().split("\n");
66857
67221
  if (all.length > MAX_HISTORY_LINES) {
66858
- writeFileSync26(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
67222
+ writeFileSync27(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
66859
67223
  }
66860
67224
  }
66861
67225
  } catch {
@@ -67039,7 +67403,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
67039
67403
  } catch {
67040
67404
  }
67041
67405
  try {
67042
- const oaDir = join70(repoRoot, ".oa");
67406
+ const oaDir = join71(repoRoot, ".oa");
67043
67407
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
67044
67408
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
67045
67409
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -67071,7 +67435,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
67071
67435
  } catch {
67072
67436
  }
67073
67437
  try {
67074
- const oaDir = join70(repoRoot, ".oa");
67438
+ const oaDir = join71(repoRoot, ".oa");
67075
67439
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
67076
67440
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
67077
67441
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -67112,11 +67476,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
67112
67476
  }
67113
67477
  try {
67114
67478
  const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
67115
- const globalNamePath = join70(_hd(), ".open-agents", "agent-name");
67479
+ const globalNamePath = join71(_hd(), ".open-agents", "agent-name");
67116
67480
  let agName = "";
67117
67481
  try {
67118
- if (existsSync53(globalNamePath))
67119
- agName = readFileSync42(globalNamePath, "utf8").trim();
67482
+ if (existsSync54(globalNamePath))
67483
+ agName = readFileSync43(globalNamePath, "utf8").trim();
67120
67484
  } catch {
67121
67485
  }
67122
67486
  if (!agName) {
@@ -68081,7 +68445,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68081
68445
  kind,
68082
68446
  targetUrl,
68083
68447
  authKey,
68084
- stateDir: join70(repoRoot, ".oa"),
68448
+ stateDir: join71(repoRoot, ".oa"),
68085
68449
  passthrough: passthrough ?? false,
68086
68450
  loadbalance: loadbalance ?? false,
68087
68451
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -68129,7 +68493,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68129
68493
  await tunnelGateway.stop();
68130
68494
  tunnelGateway = null;
68131
68495
  }
68132
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join70(repoRoot, ".oa") });
68496
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join71(repoRoot, ".oa") });
68133
68497
  newTunnel.on("stats", (stats) => {
68134
68498
  statusBar.setExposeStatus({
68135
68499
  status: stats.status,
@@ -68401,15 +68765,15 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68401
68765
  writeContent(() => renderInfo(`Killed ${bgKilled} background task(s).`));
68402
68766
  }
68403
68767
  try {
68404
- const nexusDir = join70(repoRoot, OA_DIR, "nexus");
68405
- const pidFile = join70(nexusDir, "daemon.pid");
68406
- if (existsSync53(pidFile)) {
68407
- const pid = parseInt(readFileSync42(pidFile, "utf8").trim(), 10);
68768
+ const nexusDir = join71(repoRoot, OA_DIR, "nexus");
68769
+ const pidFile = join71(nexusDir, "daemon.pid");
68770
+ if (existsSync54(pidFile)) {
68771
+ const pid = parseInt(readFileSync43(pidFile, "utf8").trim(), 10);
68408
68772
  if (pid > 0) {
68409
68773
  try {
68410
68774
  if (process.platform === "win32") {
68411
68775
  try {
68412
- execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
68776
+ execSync34(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
68413
68777
  } catch {
68414
68778
  }
68415
68779
  } else {
@@ -68426,17 +68790,17 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68426
68790
  } catch {
68427
68791
  }
68428
68792
  try {
68429
- const voiceDir2 = join70(homedir18(), ".open-agents", "voice");
68793
+ const voiceDir2 = join71(homedir19(), ".open-agents", "voice");
68430
68794
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
68431
68795
  for (const pf of voicePidFiles) {
68432
- const pidPath = join70(voiceDir2, pf);
68433
- if (existsSync53(pidPath)) {
68796
+ const pidPath = join71(voiceDir2, pf);
68797
+ if (existsSync54(pidPath)) {
68434
68798
  try {
68435
- const pid = parseInt(readFileSync42(pidPath, "utf8").trim(), 10);
68799
+ const pid = parseInt(readFileSync43(pidPath, "utf8").trim(), 10);
68436
68800
  if (pid > 0) {
68437
68801
  if (process.platform === "win32") {
68438
68802
  try {
68439
- execSync33(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
68803
+ execSync34(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
68440
68804
  } catch {
68441
68805
  }
68442
68806
  } else {
@@ -68453,11 +68817,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68453
68817
  } catch {
68454
68818
  }
68455
68819
  try {
68456
- execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
68820
+ execSync34(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
68457
68821
  } catch {
68458
68822
  }
68459
- const oaPath = join70(repoRoot, OA_DIR);
68460
- if (existsSync53(oaPath)) {
68823
+ const oaPath = join71(repoRoot, OA_DIR);
68824
+ if (existsSync54(oaPath)) {
68461
68825
  let deleted = false;
68462
68826
  for (let attempt = 0; attempt < 3; attempt++) {
68463
68827
  try {
@@ -68467,14 +68831,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
68467
68831
  } catch (err) {
68468
68832
  if (attempt < 2) {
68469
68833
  try {
68470
- execSync33(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
68834
+ execSync34(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
68471
68835
  } catch {
68472
68836
  }
68473
68837
  } else {
68474
68838
  writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
68475
68839
  if (process.platform === "win32") {
68476
68840
  try {
68477
- execSync33(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
68841
+ execSync34(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
68478
68842
  deleted = true;
68479
68843
  } catch {
68480
68844
  }
@@ -68867,8 +69231,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
68867
69231
  }
68868
69232
  }
68869
69233
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
68870
- const isImage = isImagePath(cleanPath) && existsSync53(resolve32(repoRoot, cleanPath));
68871
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync53(resolve32(repoRoot, cleanPath));
69234
+ const isImage = isImagePath(cleanPath) && existsSync54(resolve32(repoRoot, cleanPath));
69235
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync54(resolve32(repoRoot, cleanPath));
68872
69236
  if (activeTask) {
68873
69237
  if (activeTask.runner.isPaused) {
68874
69238
  activeTask.runner.resume();
@@ -68877,7 +69241,7 @@ Execute this skill now. Follow the behavioral guidance above.`;
68877
69241
  if (isImage) {
68878
69242
  try {
68879
69243
  const imgPath = resolve32(repoRoot, cleanPath);
68880
- const imgBuffer = readFileSync42(imgPath);
69244
+ const imgBuffer = readFileSync43(imgPath);
68881
69245
  const base64 = imgBuffer.toString("base64");
68882
69246
  const ext = extname11(cleanPath).toLowerCase();
68883
69247
  const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
@@ -69405,13 +69769,13 @@ async function runWithTUI(task, config, repoPath) {
69405
69769
  const handle = startTask(task, config, repoRoot);
69406
69770
  await handle.promise;
69407
69771
  try {
69408
- const ikDir = join70(repoRoot, ".oa", "identity");
69409
- const ikFile = join70(ikDir, "self-state.json");
69772
+ const ikDir = join71(repoRoot, ".oa", "identity");
69773
+ const ikFile = join71(ikDir, "self-state.json");
69410
69774
  let ikState;
69411
- if (existsSync53(ikFile)) {
69412
- ikState = JSON.parse(readFileSync42(ikFile, "utf8"));
69775
+ if (existsSync54(ikFile)) {
69776
+ ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
69413
69777
  } else {
69414
- mkdirSync27(ikDir, { recursive: true });
69778
+ mkdirSync28(ikDir, { recursive: true });
69415
69779
  ikState = {
69416
69780
  self_id: `oa-${Date.now().toString(36)}`,
69417
69781
  version: 1,
@@ -69433,7 +69797,7 @@ async function runWithTUI(task, config, repoPath) {
69433
69797
  ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
69434
69798
  ikState.session_count = (ikState.session_count || 0) + 1;
69435
69799
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
69436
- writeFileSync26(ikFile, JSON.stringify(ikState, null, 2));
69800
+ writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
69437
69801
  } catch (ikErr) {
69438
69802
  }
69439
69803
  try {
@@ -69442,12 +69806,12 @@ async function runWithTUI(task, config, repoPath) {
69442
69806
  ec.archiveVariantSync(`Task: ${task.slice(0, 200)}`, "success \u2014 completed", ["general"]);
69443
69807
  } catch {
69444
69808
  try {
69445
- const archeDir = join70(repoRoot, ".oa", "arche");
69446
- const archeFile = join70(archeDir, "variants.json");
69809
+ const archeDir = join71(repoRoot, ".oa", "arche");
69810
+ const archeFile = join71(archeDir, "variants.json");
69447
69811
  let variants = [];
69448
69812
  try {
69449
- if (existsSync53(archeFile))
69450
- variants = JSON.parse(readFileSync42(archeFile, "utf8"));
69813
+ if (existsSync54(archeFile))
69814
+ variants = JSON.parse(readFileSync43(archeFile, "utf8"));
69451
69815
  } catch {
69452
69816
  }
69453
69817
  variants.push({
@@ -69462,15 +69826,15 @@ async function runWithTUI(task, config, repoPath) {
69462
69826
  });
69463
69827
  if (variants.length > 50)
69464
69828
  variants = variants.slice(-50);
69465
- mkdirSync27(archeDir, { recursive: true });
69466
- writeFileSync26(archeFile, JSON.stringify(variants, null, 2));
69829
+ mkdirSync28(archeDir, { recursive: true });
69830
+ writeFileSync27(archeFile, JSON.stringify(variants, null, 2));
69467
69831
  } catch {
69468
69832
  }
69469
69833
  }
69470
69834
  try {
69471
- const metaFile = join70(repoRoot, ".oa", "memory", "metabolism", "store.json");
69472
- if (existsSync53(metaFile)) {
69473
- const store = JSON.parse(readFileSync42(metaFile, "utf8"));
69835
+ const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
69836
+ if (existsSync54(metaFile)) {
69837
+ const store = JSON.parse(readFileSync43(metaFile, "utf8"));
69474
69838
  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);
69475
69839
  let updated = false;
69476
69840
  for (const item of surfaced) {
@@ -69481,7 +69845,7 @@ async function runWithTUI(task, config, repoPath) {
69481
69845
  updated = true;
69482
69846
  }
69483
69847
  if (updated) {
69484
- writeFileSync26(metaFile, JSON.stringify(store, null, 2));
69848
+ writeFileSync27(metaFile, JSON.stringify(store, null, 2));
69485
69849
  }
69486
69850
  }
69487
69851
  } catch {
@@ -69534,9 +69898,9 @@ Rules:
69534
69898
  try {
69535
69899
  const { initDb: initDb2 } = __require("@open-agents/memory");
69536
69900
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
69537
- const dbDir = join70(repoRoot, ".oa", "memory");
69538
- mkdirSync27(dbDir, { recursive: true });
69539
- const db = initDb2(join70(dbDir, "structured.db"));
69901
+ const dbDir = join71(repoRoot, ".oa", "memory");
69902
+ mkdirSync28(dbDir, { recursive: true });
69903
+ const db = initDb2(join71(dbDir, "structured.db"));
69540
69904
  const memStore = new ProceduralMemoryStore2(db);
69541
69905
  memStore.createWithEmbedding({
69542
69906
  content: content.slice(0, 600),
@@ -69551,12 +69915,12 @@ Rules:
69551
69915
  db.close();
69552
69916
  } catch {
69553
69917
  }
69554
- const metaDir = join70(repoRoot, ".oa", "memory", "metabolism");
69555
- const storeFile = join70(metaDir, "store.json");
69918
+ const metaDir = join71(repoRoot, ".oa", "memory", "metabolism");
69919
+ const storeFile = join71(metaDir, "store.json");
69556
69920
  let store = [];
69557
69921
  try {
69558
- if (existsSync53(storeFile))
69559
- store = JSON.parse(readFileSync42(storeFile, "utf8"));
69922
+ if (existsSync54(storeFile))
69923
+ store = JSON.parse(readFileSync43(storeFile, "utf8"));
69560
69924
  } catch {
69561
69925
  }
69562
69926
  store.push({
@@ -69572,26 +69936,26 @@ Rules:
69572
69936
  });
69573
69937
  if (store.length > 100)
69574
69938
  store = store.slice(-100);
69575
- mkdirSync27(metaDir, { recursive: true });
69576
- writeFileSync26(storeFile, JSON.stringify(store, null, 2));
69939
+ mkdirSync28(metaDir, { recursive: true });
69940
+ writeFileSync27(storeFile, JSON.stringify(store, null, 2));
69577
69941
  }
69578
69942
  }
69579
69943
  } catch {
69580
69944
  }
69581
69945
  try {
69582
- const cohereSettingsFile = join70(repoRoot, ".oa", "settings.json");
69946
+ const cohereSettingsFile = join71(repoRoot, ".oa", "settings.json");
69583
69947
  let cohereActive = false;
69584
69948
  try {
69585
- if (existsSync53(cohereSettingsFile)) {
69586
- const settings = JSON.parse(readFileSync42(cohereSettingsFile, "utf8"));
69949
+ if (existsSync54(cohereSettingsFile)) {
69950
+ const settings = JSON.parse(readFileSync43(cohereSettingsFile, "utf8"));
69587
69951
  cohereActive = settings.cohere === true;
69588
69952
  }
69589
69953
  } catch {
69590
69954
  }
69591
69955
  if (cohereActive) {
69592
- const metaFile = join70(repoRoot, ".oa", "memory", "metabolism", "store.json");
69593
- if (existsSync53(metaFile)) {
69594
- const store = JSON.parse(readFileSync42(metaFile, "utf8"));
69956
+ const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
69957
+ if (existsSync54(metaFile)) {
69958
+ const store = JSON.parse(readFileSync43(metaFile, "utf8"));
69595
69959
  const latest = store.filter((m) => m.sourceTrace === "trajectory-extraction" || m.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
69596
69960
  if (latest && latest.scores?.confidence >= 0.6) {
69597
69961
  try {
@@ -69616,18 +69980,18 @@ Rules:
69616
69980
  }
69617
69981
  } catch (err) {
69618
69982
  try {
69619
- const ikFile = join70(repoRoot, ".oa", "identity", "self-state.json");
69620
- if (existsSync53(ikFile)) {
69621
- const ikState = JSON.parse(readFileSync42(ikFile, "utf8"));
69983
+ const ikFile = join71(repoRoot, ".oa", "identity", "self-state.json");
69984
+ if (existsSync54(ikFile)) {
69985
+ const ikState = JSON.parse(readFileSync43(ikFile, "utf8"));
69622
69986
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
69623
69987
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
69624
69988
  ikState.session_count = (ikState.session_count || 0) + 1;
69625
69989
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
69626
- writeFileSync26(ikFile, JSON.stringify(ikState, null, 2));
69990
+ writeFileSync27(ikFile, JSON.stringify(ikState, null, 2));
69627
69991
  }
69628
- const metaFile = join70(repoRoot, ".oa", "memory", "metabolism", "store.json");
69629
- if (existsSync53(metaFile)) {
69630
- const store = JSON.parse(readFileSync42(metaFile, "utf8"));
69992
+ const metaFile = join71(repoRoot, ".oa", "memory", "metabolism", "store.json");
69993
+ if (existsSync54(metaFile)) {
69994
+ const store = JSON.parse(readFileSync43(metaFile, "utf8"));
69631
69995
  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);
69632
69996
  for (const item of surfaced) {
69633
69997
  item.accessCount = (item.accessCount || 0) + 1;
@@ -69635,15 +69999,15 @@ Rules:
69635
69999
  item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
69636
70000
  item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
69637
70001
  }
69638
- writeFileSync26(metaFile, JSON.stringify(store, null, 2));
70002
+ writeFileSync27(metaFile, JSON.stringify(store, null, 2));
69639
70003
  }
69640
70004
  try {
69641
- const archeDir = join70(repoRoot, ".oa", "arche");
69642
- const archeFile = join70(archeDir, "variants.json");
70005
+ const archeDir = join71(repoRoot, ".oa", "arche");
70006
+ const archeFile = join71(archeDir, "variants.json");
69643
70007
  let variants = [];
69644
70008
  try {
69645
- if (existsSync53(archeFile))
69646
- variants = JSON.parse(readFileSync42(archeFile, "utf8"));
70009
+ if (existsSync54(archeFile))
70010
+ variants = JSON.parse(readFileSync43(archeFile, "utf8"));
69647
70011
  } catch {
69648
70012
  }
69649
70013
  variants.push({
@@ -69658,8 +70022,8 @@ Rules:
69658
70022
  });
69659
70023
  if (variants.length > 50)
69660
70024
  variants = variants.slice(-50);
69661
- mkdirSync27(archeDir, { recursive: true });
69662
- writeFileSync26(archeFile, JSON.stringify(variants, null, 2));
70025
+ mkdirSync28(archeDir, { recursive: true });
70026
+ writeFileSync27(archeFile, JSON.stringify(variants, null, 2));
69663
70027
  } catch {
69664
70028
  }
69665
70029
  } catch {
@@ -69725,14 +70089,14 @@ __export(run_exports, {
69725
70089
  statusCommand: () => statusCommand
69726
70090
  });
69727
70091
  import { resolve as resolve33 } from "node:path";
69728
- import { spawn as spawn21 } from "node:child_process";
69729
- import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync27, readFileSync as readFileSync43, readdirSync as readdirSync22, existsSync as existsSync54 } from "node:fs";
70092
+ import { spawn as spawn22 } from "node:child_process";
70093
+ import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync28, readFileSync as readFileSync44, readdirSync as readdirSync22, existsSync as existsSync55 } from "node:fs";
69730
70094
  import { randomBytes as randomBytes17 } from "node:crypto";
69731
- import { join as join71 } from "node:path";
70095
+ import { join as join72 } from "node:path";
69732
70096
  function jobsDir2(repoPath) {
69733
70097
  const root = resolve33(repoPath ?? process.cwd());
69734
- const dir = join71(root, ".oa", "jobs");
69735
- mkdirSync28(dir, { recursive: true });
70098
+ const dir = join72(root, ".oa", "jobs");
70099
+ mkdirSync29(dir, { recursive: true });
69736
70100
  return dir;
69737
70101
  }
69738
70102
  async function runCommand(opts, config) {
@@ -69809,7 +70173,7 @@ async function runBackground(task, config, opts) {
69809
70173
  const args = [task, "--json"];
69810
70174
  if (config.model)
69811
70175
  args.push("--model", config.model);
69812
- const child = spawn21("node", [oaBin, ...args], {
70176
+ const child = spawn22("node", [oaBin, ...args], {
69813
70177
  cwd: repoRoot,
69814
70178
  env: { ...process.env, OA_JOB_ID: id },
69815
70179
  stdio: ["ignore", "pipe", "pipe"],
@@ -69817,7 +70181,7 @@ async function runBackground(task, config, opts) {
69817
70181
  });
69818
70182
  child.unref();
69819
70183
  job.pid = child.pid ?? 0;
69820
- writeFileSync27(join71(dir, `${id}.json`), JSON.stringify(job, null, 2));
70184
+ writeFileSync28(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
69821
70185
  let output = "";
69822
70186
  child.stdout?.on("data", (chunk) => {
69823
70187
  output += chunk.toString();
@@ -69833,7 +70197,7 @@ async function runBackground(task, config, opts) {
69833
70197
  job.summary = result.summary;
69834
70198
  job.durationMs = result.durationMs;
69835
70199
  job.error = result.error;
69836
- writeFileSync27(join71(dir, `${id}.json`), JSON.stringify(job, null, 2));
70200
+ writeFileSync28(join72(dir, `${id}.json`), JSON.stringify(job, null, 2));
69837
70201
  } catch {
69838
70202
  }
69839
70203
  });
@@ -69849,13 +70213,13 @@ async function runBackground(task, config, opts) {
69849
70213
  }
69850
70214
  function statusCommand(jobId, repoPath) {
69851
70215
  const dir = jobsDir2(repoPath);
69852
- const file = join71(dir, `${jobId}.json`);
69853
- if (!existsSync54(file)) {
70216
+ const file = join72(dir, `${jobId}.json`);
70217
+ if (!existsSync55(file)) {
69854
70218
  console.error(`Job not found: ${jobId}`);
69855
70219
  console.log(`Available jobs: oa jobs`);
69856
70220
  process.exit(1);
69857
70221
  }
69858
- const job = JSON.parse(readFileSync43(file, "utf-8"));
70222
+ const job = JSON.parse(readFileSync44(file, "utf-8"));
69859
70223
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
69860
70224
  const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
69861
70225
  console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
@@ -69878,7 +70242,7 @@ function jobsCommand(repoPath) {
69878
70242
  console.log("Jobs:");
69879
70243
  for (const file of files) {
69880
70244
  try {
69881
- const job = JSON.parse(readFileSync43(join71(dir, file), "utf-8"));
70245
+ const job = JSON.parse(readFileSync44(join72(dir, file), "utf-8"));
69882
70246
  const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
69883
70247
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
69884
70248
  console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
@@ -69898,7 +70262,7 @@ import { glob } from "glob";
69898
70262
  import ignore from "ignore";
69899
70263
  import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
69900
70264
  import { createHash as createHash6 } from "node:crypto";
69901
- import { join as join72, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
70265
+ import { join as join73, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
69902
70266
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
69903
70267
  var init_codebase_indexer = __esm({
69904
70268
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -69942,7 +70306,7 @@ var init_codebase_indexer = __esm({
69942
70306
  const ig = ignore.default();
69943
70307
  if (this.config.respectGitignore) {
69944
70308
  try {
69945
- const gitignoreContent = await readFile23(join72(this.config.rootDir, ".gitignore"), "utf-8");
70309
+ const gitignoreContent = await readFile23(join73(this.config.rootDir, ".gitignore"), "utf-8");
69946
70310
  ig.add(gitignoreContent);
69947
70311
  } catch {
69948
70312
  }
@@ -69957,7 +70321,7 @@ var init_codebase_indexer = __esm({
69957
70321
  for (const relativePath of files) {
69958
70322
  if (ig.ignores(relativePath))
69959
70323
  continue;
69960
- const fullPath = join72(this.config.rootDir, relativePath);
70324
+ const fullPath = join73(this.config.rootDir, relativePath);
69961
70325
  try {
69962
70326
  const fileStat = await stat4(fullPath);
69963
70327
  if (fileStat.size > this.config.maxFileSize)
@@ -70003,7 +70367,7 @@ var init_codebase_indexer = __esm({
70003
70367
  if (!child) {
70004
70368
  child = {
70005
70369
  name: part,
70006
- path: join72(current.path, part),
70370
+ path: join73(current.path, part),
70007
70371
  type: "directory",
70008
70372
  children: []
70009
70373
  };
@@ -70086,13 +70450,13 @@ __export(index_repo_exports, {
70086
70450
  indexRepoCommand: () => indexRepoCommand
70087
70451
  });
70088
70452
  import { resolve as resolve34 } from "node:path";
70089
- import { existsSync as existsSync55, statSync as statSync16 } from "node:fs";
70453
+ import { existsSync as existsSync56, statSync as statSync16 } from "node:fs";
70090
70454
  import { cwd as cwd2 } from "node:process";
70091
70455
  async function indexRepoCommand(opts, _config) {
70092
70456
  const repoRoot = resolve34(opts.repoPath ?? cwd2());
70093
70457
  printHeader("Index Repository");
70094
70458
  printInfo(`Indexing: ${repoRoot}`);
70095
- if (!existsSync55(repoRoot)) {
70459
+ if (!existsSync56(repoRoot)) {
70096
70460
  printError(`Path does not exist: ${repoRoot}`);
70097
70461
  process.exit(1);
70098
70462
  }
@@ -70344,8 +70708,8 @@ var config_exports2 = {};
70344
70708
  __export(config_exports2, {
70345
70709
  configCommand: () => configCommand
70346
70710
  });
70347
- import { join as join73, resolve as resolve35 } from "node:path";
70348
- import { homedir as homedir19 } from "node:os";
70711
+ import { join as join74, resolve as resolve35 } from "node:path";
70712
+ import { homedir as homedir20 } from "node:os";
70349
70713
  import { cwd as cwd3 } from "node:process";
70350
70714
  function redactIfSensitive(key, value) {
70351
70715
  if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
@@ -70427,7 +70791,7 @@ function handleShow(opts, config) {
70427
70791
  }
70428
70792
  }
70429
70793
  printSection("Config File");
70430
- printInfo(`~/.open-agents/config.json (${join73(homedir19(), ".open-agents", "config.json")})`);
70794
+ printInfo(`~/.open-agents/config.json (${join74(homedir20(), ".open-agents", "config.json")})`);
70431
70795
  printSection("Priority Chain");
70432
70796
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
70433
70797
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -70466,7 +70830,7 @@ function handleSet(opts, _config) {
70466
70830
  const coerced = coerceForSettings(key, value);
70467
70831
  saveProjectSettings(repoRoot, { [key]: coerced });
70468
70832
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
70469
- printInfo(`Saved to ${join73(repoRoot, ".oa", "settings.json")}`);
70833
+ printInfo(`Saved to ${join74(repoRoot, ".oa", "settings.json")}`);
70470
70834
  printInfo("This override applies only when running in this workspace.");
70471
70835
  } catch (err) {
70472
70836
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -70609,8 +70973,8 @@ __export(eval_exports, {
70609
70973
  evalCommand: () => evalCommand
70610
70974
  });
70611
70975
  import { tmpdir as tmpdir10 } from "node:os";
70612
- import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync28 } from "node:fs";
70613
- import { join as join74 } from "node:path";
70976
+ import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync29 } from "node:fs";
70977
+ import { join as join75 } from "node:path";
70614
70978
  async function evalCommand(opts, config) {
70615
70979
  const suiteName = opts.suite ?? "basic";
70616
70980
  const suite = SUITES[suiteName];
@@ -70735,9 +71099,9 @@ async function evalCommand(opts, config) {
70735
71099
  process.exit(failed > 0 ? 1 : 0);
70736
71100
  }
70737
71101
  function createTempEvalRepo() {
70738
- const dir = join74(tmpdir10(), `open-agents-eval-${Date.now()}`);
70739
- mkdirSync29(dir, { recursive: true });
70740
- writeFileSync28(join74(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
71102
+ const dir = join75(tmpdir10(), `open-agents-eval-${Date.now()}`);
71103
+ mkdirSync30(dir, { recursive: true });
71104
+ writeFileSync29(join75(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
70741
71105
  return dir;
70742
71106
  }
70743
71107
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -70797,7 +71161,7 @@ init_updater();
70797
71161
  import { parseArgs as nodeParseArgs2 } from "node:util";
70798
71162
  import { createRequire as createRequire5 } from "node:module";
70799
71163
  import { fileURLToPath as fileURLToPath14 } from "node:url";
70800
- import { dirname as dirname22, join as join75 } from "node:path";
71164
+ import { dirname as dirname22, join as join76 } from "node:path";
70801
71165
 
70802
71166
  // packages/cli/dist/cli.js
70803
71167
  import { createInterface } from "node:readline";
@@ -70904,7 +71268,7 @@ init_output();
70904
71268
  function getVersion5() {
70905
71269
  try {
70906
71270
  const require2 = createRequire5(import.meta.url);
70907
- const pkgPath = join75(dirname22(fileURLToPath14(import.meta.url)), "..", "package.json");
71271
+ const pkgPath = join76(dirname22(fileURLToPath14(import.meta.url)), "..", "package.json");
70908
71272
  const pkg = require2(pkgPath);
70909
71273
  return pkg.version;
70910
71274
  } catch {
@@ -71179,12 +71543,12 @@ function crashLog(label, err) {
71179
71543
  const logLine = `[${timestamp}] ${label}: ${msg}
71180
71544
  `;
71181
71545
  try {
71182
- const { appendFileSync: appendFileSync5, mkdirSync: mkdirSync30 } = __require("node:fs");
71183
- const { join: join76 } = __require("node:path");
71184
- const { homedir: homedir20 } = __require("node:os");
71185
- const logDir = join76(homedir20(), ".open-agents");
71186
- mkdirSync30(logDir, { recursive: true });
71187
- appendFileSync5(join76(logDir, "crash.log"), logLine);
71546
+ const { appendFileSync: appendFileSync5, mkdirSync: mkdirSync31 } = __require("node:fs");
71547
+ const { join: join77 } = __require("node:path");
71548
+ const { homedir: homedir21 } = __require("node:os");
71549
+ const logDir = join77(homedir21(), ".open-agents");
71550
+ mkdirSync31(logDir, { recursive: true });
71551
+ appendFileSync5(join77(logDir, "crash.log"), logLine);
71188
71552
  } catch {
71189
71553
  }
71190
71554
  try {