open-agents-ai 0.151.0 → 0.153.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +345 -184
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18541,9 +18541,9 @@ function getVersion(binary) {
18541
18541
  }
18542
18542
  }
18543
18543
  function installOpencode() {
18544
- const platform5 = process.platform;
18544
+ const platform6 = process.platform;
18545
18545
  try {
18546
- if (platform5 === "win32") {
18546
+ if (platform6 === "win32") {
18547
18547
  execSync19('powershell -Command "irm https://opencode.ai/install | iex"', {
18548
18548
  stdio: "pipe",
18549
18549
  timeout: 12e4
@@ -18815,9 +18815,9 @@ function getVersion2(binary) {
18815
18815
  }
18816
18816
  }
18817
18817
  function installDroid() {
18818
- const platform5 = process.platform;
18818
+ const platform6 = process.platform;
18819
18819
  try {
18820
- if (platform5 === "win32") {
18820
+ if (platform6 === "win32") {
18821
18821
  execSync20('powershell -Command "irm https://app.factory.ai/cli/windows | iex"', {
18822
18822
  stdio: "pipe",
18823
18823
  timeout: 12e4
@@ -20529,8 +20529,8 @@ import { execSync as execSync22 } from "node:child_process";
20529
20529
  function getSystemStatus() {
20530
20530
  const lines = ["# System Health\n"];
20531
20531
  try {
20532
- const uptime = execSync22("uptime", { encoding: "utf-8", timeout: 3e3 }).trim();
20533
- const loadMatch = uptime.match(/load average:\s*([\d.]+),\s*([\d.]+),\s*([\d.]+)/);
20532
+ const uptime2 = execSync22("uptime", { encoding: "utf-8", timeout: 3e3 }).trim();
20533
+ const loadMatch = uptime2.match(/load average:\s*([\d.]+),\s*([\d.]+),\s*([\d.]+)/);
20534
20534
  if (loadMatch) {
20535
20535
  lines.push(`CPU Load: ${loadMatch[1]} (1m) ${loadMatch[2]} (5m) ${loadMatch[3]} (15m)`);
20536
20536
  }
@@ -20678,6 +20678,147 @@ var init_process_health = __esm({
20678
20678
  }
20679
20679
  });
20680
20680
 
20681
+ // packages/execution/dist/tools/environment-snapshot.js
20682
+ import { execSync as execSync23 } from "node:child_process";
20683
+ import { cpus, totalmem, freemem, hostname as hostname2, platform, arch, uptime } from "node:os";
20684
+ import { statfsSync } from "node:fs";
20685
+ function collectSnapshot(workingDir) {
20686
+ const now = /* @__PURE__ */ new Date();
20687
+ const cpuInfo = cpus();
20688
+ const totalRAM = totalmem();
20689
+ const freeRAM = freemem();
20690
+ let load1 = 0, load5 = 0, load15 = 0;
20691
+ try {
20692
+ const loadavg4 = __require("node:os").loadavg();
20693
+ load1 = loadavg4[0];
20694
+ load5 = loadavg4[1];
20695
+ load15 = loadavg4[2];
20696
+ } catch {
20697
+ }
20698
+ let gpu = void 0;
20699
+ try {
20700
+ const nvOut = execSync23("nvidia-smi --query-gpu=name,memory.total,memory.used,temperature.gpu --format=csv,noheader,nounits", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split(",").map((s) => s.trim());
20701
+ if (nvOut.length >= 3) {
20702
+ gpu = {
20703
+ name: nvOut[0],
20704
+ vramTotalMB: parseInt(nvOut[1], 10),
20705
+ vramUsedMB: parseInt(nvOut[2], 10),
20706
+ vramUsedPercent: Math.round(parseInt(nvOut[2], 10) / parseInt(nvOut[1], 10) * 100),
20707
+ tempC: nvOut[3] ? parseInt(nvOut[3], 10) : void 0
20708
+ };
20709
+ }
20710
+ } catch {
20711
+ }
20712
+ let battery = void 0;
20713
+ try {
20714
+ if (platform() === "linux") {
20715
+ const cap = execSync23("cat /sys/class/power_supply/BAT0/capacity 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
20716
+ const status = execSync23("cat /sys/class/power_supply/BAT0/status 2>/dev/null", { encoding: "utf-8", timeout: 1e3 }).trim();
20717
+ if (cap)
20718
+ battery = { percent: parseInt(cap, 10), charging: status === "Charging" || status === "Full" };
20719
+ } else if (platform() === "darwin") {
20720
+ const pmOut = execSync23("pmset -g batt", { encoding: "utf-8", timeout: 2e3 });
20721
+ const match = pmOut.match(/(\d+)%;\s*(charging|discharging|charged)/i);
20722
+ if (match)
20723
+ battery = { percent: parseInt(match[1], 10), charging: match[2].toLowerCase() !== "discharging" };
20724
+ }
20725
+ } catch {
20726
+ }
20727
+ let disk = { availableGB: 0, totalGB: 0, usedPercent: 0 };
20728
+ try {
20729
+ const stats = statfsSync(workingDir || "/");
20730
+ const totalBytes = stats.blocks * stats.bsize;
20731
+ const availBytes = stats.bavail * stats.bsize;
20732
+ disk = {
20733
+ totalGB: Math.round(totalBytes / 1024 ** 3),
20734
+ availableGB: Math.round(availBytes / 1024 ** 3),
20735
+ usedPercent: Math.round((1 - availBytes / totalBytes) * 100)
20736
+ };
20737
+ } catch {
20738
+ }
20739
+ let processInfo = { total: 0, nodeCount: 0, oaSpawned: 0, topCpu: [] };
20740
+ try {
20741
+ const psLines = execSync23("ps -eo pid,%cpu,args --sort=-%cpu --no-headers 2>/dev/null | head -50", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n");
20742
+ const total = parseInt(execSync23("ps aux | wc -l", { encoding: "utf-8", timeout: 2e3 }).trim(), 10);
20743
+ let nodeCount = 0;
20744
+ let oaSpawned = 0;
20745
+ const topCpu = [];
20746
+ const oaPattern = /open-agents|nexus-daemon|vitest|esbuild.*service|python3 -u -i|start-moondream|live-whisper/;
20747
+ for (const line of psLines) {
20748
+ const parts = line.trim().split(/\s+/);
20749
+ if (parts.length < 3)
20750
+ continue;
20751
+ const pid = parseInt(parts[0], 10);
20752
+ const cpu = parseFloat(parts[1]);
20753
+ const cmd = parts.slice(2).join(" ");
20754
+ if (/node\b/.test(cmd))
20755
+ nodeCount++;
20756
+ if (oaPattern.test(cmd))
20757
+ oaSpawned++;
20758
+ if (cpu > 1 && topCpu.length < 5) {
20759
+ topCpu.push({ pid, cpu, cmd: cmd.slice(0, 60) });
20760
+ }
20761
+ }
20762
+ processInfo = { total, nodeCount, oaSpawned, topCpu };
20763
+ } catch {
20764
+ }
20765
+ let uptimeStr = "";
20766
+ const secs = uptime();
20767
+ const days = Math.floor(secs / 86400);
20768
+ const hours = Math.floor(secs % 86400 / 3600);
20769
+ uptimeStr = days > 0 ? `${days}d ${hours}h` : `${hours}h ${Math.floor(secs % 3600 / 60)}m`;
20770
+ return {
20771
+ timestamp: now.toISOString(),
20772
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
20773
+ uptime: uptimeStr,
20774
+ cpu: {
20775
+ model: cpuInfo[0]?.model?.replace(/\s+/g, " ").trim() ?? "unknown",
20776
+ cores: cpuInfo.length,
20777
+ load1m: Math.round(load1 * 100) / 100,
20778
+ load5m: Math.round(load5 * 100) / 100,
20779
+ load15m: Math.round(load15 * 100) / 100
20780
+ },
20781
+ ram: {
20782
+ totalGB: Math.round(totalRAM / 1024 ** 3),
20783
+ availableGB: Math.round(freeRAM / 1024 ** 3),
20784
+ usedPercent: Math.round((1 - freeRAM / totalRAM) * 100)
20785
+ },
20786
+ gpu,
20787
+ battery,
20788
+ disk,
20789
+ network: { hostname: hostname2(), platform: platform(), arch: arch() },
20790
+ processes: processInfo
20791
+ };
20792
+ }
20793
+ function formatSnapshotForContext(snap) {
20794
+ const lines = [];
20795
+ lines.push(`<environment>`);
20796
+ lines.push(`Time: ${snap.timestamp.replace("T", " ").replace(/\.\d+Z$/, "Z")} (${snap.timezone})`);
20797
+ lines.push(`System: ${snap.network.platform}/${snap.network.arch} | ${snap.cpu.cores} cores | ${snap.cpu.model.slice(0, 40)}`);
20798
+ lines.push(`CPU Load: ${snap.cpu.load1m} (1m) ${snap.cpu.load5m} (5m) \u2014 ${snap.cpu.load1m > snap.cpu.cores * 0.8 ? "HIGH" : "normal"}`);
20799
+ lines.push(`RAM: ${snap.ram.availableGB}GB free / ${snap.ram.totalGB}GB (${snap.ram.usedPercent}% used)`);
20800
+ if (snap.gpu) {
20801
+ lines.push(`GPU: ${snap.gpu.name} | ${snap.gpu.vramUsedMB}MB / ${snap.gpu.vramTotalMB}MB VRAM (${snap.gpu.vramUsedPercent}%)${snap.gpu.tempC ? ` ${snap.gpu.tempC}\xB0C` : ""}`);
20802
+ }
20803
+ if (snap.battery) {
20804
+ const icon = snap.battery.charging ? "\u26A1" : snap.battery.percent < 20 ? "\u{1FAAB}" : "\u{1F50B}";
20805
+ lines.push(`Battery: ${icon} ${snap.battery.percent}% ${snap.battery.charging ? "(charging)" : "(discharging)"}`);
20806
+ }
20807
+ lines.push(`Disk: ${snap.disk.availableGB}GB free / ${snap.disk.totalGB}GB (${snap.disk.usedPercent}% used)`);
20808
+ lines.push(`Processes: ${snap.processes.total} total | ${snap.processes.nodeCount} node | ${snap.processes.oaSpawned} OA-spawned`);
20809
+ lines.push(`Uptime: ${snap.uptime}`);
20810
+ if (snap.processes.topCpu.length > 0) {
20811
+ lines.push(`Top CPU: ${snap.processes.topCpu.map((p) => `${p.cmd.slice(0, 25)}(${p.cpu}%)`).join(", ")}`);
20812
+ }
20813
+ lines.push(`</environment>`);
20814
+ return lines.join("\n");
20815
+ }
20816
+ var init_environment_snapshot = __esm({
20817
+ "packages/execution/dist/tools/environment-snapshot.js"() {
20818
+ "use strict";
20819
+ }
20820
+ });
20821
+
20681
20822
  // packages/execution/dist/tools/fortemi-bridge.js
20682
20823
  import { existsSync as existsSync27, readFileSync as readFileSync20 } from "node:fs";
20683
20824
  import { join as join41 } from "node:path";
@@ -21508,6 +21649,7 @@ __export(dist_exports, {
21508
21649
  checkDesktopDeps: () => checkDesktopDeps,
21509
21650
  clearExploreNotes: () => clearExploreNotes,
21510
21651
  clearWorkingNotes: () => clearWorkingNotes,
21652
+ collectSnapshot: () => collectSnapshot,
21511
21653
  createFortemiBridgeTools: () => createFortemiBridgeTools,
21512
21654
  createWorktree: () => createWorktree,
21513
21655
  detectSearchProvider: () => detectSearchProvider,
@@ -21515,6 +21657,7 @@ __export(dist_exports, {
21515
21657
  ensureAllDesktopDeps: () => ensureAllDesktopDeps,
21516
21658
  ensureCommand: () => ensureCommand,
21517
21659
  ensureDepsForGroup: () => ensureDepsForGroup,
21660
+ formatSnapshotForContext: () => formatSnapshotForContext,
21518
21661
  getActiveAttentionItems: () => getActiveAttentionItems,
21519
21662
  getDueReminders: () => getDueReminders,
21520
21663
  getExploreNotes: () => getExploreNotes,
@@ -21614,6 +21757,7 @@ var init_dist2 = __esm({
21614
21757
  init_change_log();
21615
21758
  init_repo_map();
21616
21759
  init_process_health();
21760
+ init_environment_snapshot();
21617
21761
  init_nexus();
21618
21762
  init_fortemi_bridge();
21619
21763
  init_system_deps();
@@ -24973,6 +25117,15 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
24973
25117
  } else {
24974
25118
  compacted = await this.compactMessages(messages);
24975
25119
  }
25120
+ if (this.options.environmentProvider) {
25121
+ try {
25122
+ const envStr = this.options.environmentProvider();
25123
+ if (envStr) {
25124
+ compacted.push({ role: "system", content: envStr });
25125
+ }
25126
+ } catch {
25127
+ }
25128
+ }
24976
25129
  const { maxOutputTokens: effectiveMaxTokens } = this.contextLimits();
24977
25130
  const chatRequest = {
24978
25131
  messages: compacted,
@@ -28423,7 +28576,7 @@ __export(listen_exports, {
28423
28576
  isVideoPath: () => isVideoPath,
28424
28577
  waitForTranscribeCli: () => waitForTranscribeCli
28425
28578
  });
28426
- import { spawn as spawn15, execSync as execSync23 } from "node:child_process";
28579
+ import { spawn as spawn15, execSync as execSync24 } from "node:child_process";
28427
28580
  import { existsSync as existsSync31, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readdirSync as readdirSync7 } from "node:fs";
28428
28581
  import { join as join46, dirname as dirname14 } from "node:path";
28429
28582
  import { homedir as homedir10 } from "node:os";
@@ -28442,10 +28595,10 @@ function isTranscribablePath(path) {
28442
28595
  return isAudioPath(path) || isVideoPath(path);
28443
28596
  }
28444
28597
  function findMicCaptureCommand() {
28445
- const platform5 = process.platform;
28446
- if (platform5 === "linux") {
28598
+ const platform6 = process.platform;
28599
+ if (platform6 === "linux") {
28447
28600
  try {
28448
- execSync23("which arecord", { stdio: "pipe" });
28601
+ execSync24("which arecord", { stdio: "pipe" });
28449
28602
  return {
28450
28603
  cmd: "arecord",
28451
28604
  args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
@@ -28453,9 +28606,9 @@ function findMicCaptureCommand() {
28453
28606
  } catch {
28454
28607
  }
28455
28608
  }
28456
- if (platform5 === "darwin") {
28609
+ if (platform6 === "darwin") {
28457
28610
  try {
28458
- execSync23("which sox", { stdio: "pipe" });
28611
+ execSync24("which sox", { stdio: "pipe" });
28459
28612
  return {
28460
28613
  cmd: "sox",
28461
28614
  args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
@@ -28464,8 +28617,8 @@ function findMicCaptureCommand() {
28464
28617
  }
28465
28618
  }
28466
28619
  try {
28467
- execSync23("which ffmpeg", { stdio: "pipe" });
28468
- if (platform5 === "linux") {
28620
+ execSync24("which ffmpeg", { stdio: "pipe" });
28621
+ if (platform6 === "linux") {
28469
28622
  return {
28470
28623
  cmd: "ffmpeg",
28471
28624
  args: [
@@ -28484,7 +28637,7 @@ function findMicCaptureCommand() {
28484
28637
  "pipe:1"
28485
28638
  ]
28486
28639
  };
28487
- } else if (platform5 === "darwin") {
28640
+ } else if (platform6 === "darwin") {
28488
28641
  return {
28489
28642
  cmd: "ffmpeg",
28490
28643
  args: [
@@ -28523,7 +28676,7 @@ function findLiveWhisperScript() {
28523
28676
  return p;
28524
28677
  }
28525
28678
  try {
28526
- const globalRoot = execSync23("npm root -g", {
28679
+ const globalRoot = execSync24("npm root -g", {
28527
28680
  encoding: "utf-8",
28528
28681
  timeout: 5e3,
28529
28682
  stdio: ["pipe", "pipe", "pipe"]
@@ -28556,7 +28709,7 @@ function ensureTranscribeCliBackground() {
28556
28709
  return;
28557
28710
  _bgInstallPromise = (async () => {
28558
28711
  try {
28559
- const globalRoot = execSync23("npm root -g", {
28712
+ const globalRoot = execSync24("npm root -g", {
28560
28713
  encoding: "utf-8",
28561
28714
  timeout: 5e3,
28562
28715
  stdio: ["pipe", "pipe", "pipe"]
@@ -28762,7 +28915,7 @@ var init_listen = __esm({
28762
28915
  }
28763
28916
  if (!this.transcribeCliAvailable) {
28764
28917
  try {
28765
- execSync23("which transcribe-cli", { stdio: "pipe" });
28918
+ execSync24("which transcribe-cli", { stdio: "pipe" });
28766
28919
  this.transcribeCliAvailable = true;
28767
28920
  } catch {
28768
28921
  this.transcribeCliAvailable = false;
@@ -28779,7 +28932,7 @@ var init_listen = __esm({
28779
28932
  } catch {
28780
28933
  }
28781
28934
  try {
28782
- const globalRoot = execSync23("npm root -g", {
28935
+ const globalRoot = execSync24("npm root -g", {
28783
28936
  encoding: "utf-8",
28784
28937
  timeout: 5e3,
28785
28938
  stdio: ["pipe", "pipe", "pipe"]
@@ -28829,7 +28982,7 @@ var init_listen = __esm({
28829
28982
  }
28830
28983
  if (!tc) {
28831
28984
  try {
28832
- execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
28985
+ execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
28833
28986
  this.transcribeCliAvailable = null;
28834
28987
  tc = await this.loadTranscribeCli();
28835
28988
  } catch {
@@ -29012,7 +29165,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29012
29165
  }
29013
29166
  if (!tc) {
29014
29167
  try {
29015
- execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29168
+ execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29016
29169
  this.transcribeCliAvailable = null;
29017
29170
  tc = await this.loadTranscribeCli();
29018
29171
  } catch {
@@ -29066,7 +29219,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
29066
29219
  }
29067
29220
  if (!tc) {
29068
29221
  try {
29069
- execSync23("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29222
+ execSync24("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
29070
29223
  this.transcribeCliAvailable = null;
29071
29224
  tc = await this.loadTranscribeCli();
29072
29225
  } catch {
@@ -33573,7 +33726,7 @@ var init_render = __esm({
33573
33726
 
33574
33727
  // packages/cli/dist/tui/voice-session.js
33575
33728
  import { createServer as createServer2 } from "node:http";
33576
- import { spawn as spawn16, execSync as execSync24 } from "node:child_process";
33729
+ import { spawn as spawn16, execSync as execSync25 } from "node:child_process";
33577
33730
  import { EventEmitter as EventEmitter2 } from "node:events";
33578
33731
  function generateFrontendHTML() {
33579
33732
  return `<!DOCTYPE html>
@@ -34305,7 +34458,7 @@ import { spawn as spawn17, exec } from "node:child_process";
34305
34458
  import { EventEmitter as EventEmitter3 } from "node:events";
34306
34459
  import { randomBytes as randomBytes11 } from "node:crypto";
34307
34460
  import { URL as URL2 } from "node:url";
34308
- import { loadavg, cpus, totalmem, freemem } from "node:os";
34461
+ import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
34309
34462
  import { existsSync as existsSync32, readFileSync as readFileSync23, writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, mkdirSync as mkdirSync11, readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
34310
34463
  import { join as join47 } from "node:path";
34311
34464
  function cleanForwardHeaders(raw, targetHost) {
@@ -34397,9 +34550,9 @@ function parseRateLimitHeaders(headers) {
34397
34550
  }
34398
34551
  async function collectSystemMetricsAsync() {
34399
34552
  const [l1, l5, l15] = loadavg();
34400
- const cores = cpus().length;
34401
- const totalMem = totalmem();
34402
- const freeMem = freemem();
34553
+ const cores = cpus2().length;
34554
+ const totalMem = totalmem2();
34555
+ const freeMem = freemem2();
34403
34556
  const usedMem = totalMem - freeMem;
34404
34557
  const gpu = {
34405
34558
  available: false,
@@ -36942,7 +37095,7 @@ ${activitySummary}
36942
37095
  });
36943
37096
 
36944
37097
  // packages/cli/dist/tui/model-picker.js
36945
- import { totalmem as totalmem2 } from "node:os";
37098
+ import { totalmem as totalmem3 } from "node:os";
36946
37099
  function isImageGenModel(name, family) {
36947
37100
  return IMAGE_GEN_PATTERNS.some((p) => p.test(name) || family && p.test(family));
36948
37101
  }
@@ -36991,15 +37144,15 @@ async function fetchOllamaModels(baseUrl) {
36991
37144
  }
36992
37145
  if (show.model_info) {
36993
37146
  const info = show.model_info;
36994
- const arch = info["general.architecture"];
37147
+ const arch2 = info["general.architecture"];
36995
37148
  const paramCount = info["general.parameter_count"];
36996
37149
  const fileSizeGB = result[i].sizeBytes > 0 ? result[i].sizeBytes / 1024 ** 3 : paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
36997
- if (arch) {
36998
- const archMax = info[`${arch}.context_length`];
36999
- const nLayers = info[`${arch}.block_count`];
37000
- const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
37001
- const keyDim = info[`${arch}.attention.key_length`];
37002
- const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
37150
+ if (arch2) {
37151
+ const archMax = info[`${arch2}.context_length`];
37152
+ const nLayers = info[`${arch2}.block_count`];
37153
+ const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
37154
+ const keyDim = info[`${arch2}.attention.key_length`];
37155
+ const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
37003
37156
  if (archMax && nLayers && nKVHeads && keyDim && valDim) {
37004
37157
  const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
37005
37158
  result[i].contextLength = estimateRealisticContext(kvBytesPerToken, archMax, fileSizeGB);
@@ -37302,15 +37455,15 @@ async function queryModelContextSize(baseUrl, modelName) {
37302
37455
  }
37303
37456
  if (data.model_info) {
37304
37457
  const info = data.model_info;
37305
- const arch = info["general.architecture"];
37458
+ const arch2 = info["general.architecture"];
37306
37459
  const paramCount = info["general.parameter_count"];
37307
37460
  const modelSizeGB2 = paramCount ? paramCount * 0.6 / 1024 ** 3 : 4;
37308
- if (arch) {
37309
- const archMax = info[`${arch}.context_length`];
37310
- const nLayers = info[`${arch}.block_count`];
37311
- const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
37312
- const keyDim = info[`${arch}.attention.key_length`];
37313
- const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
37461
+ if (arch2) {
37462
+ const archMax = info[`${arch2}.context_length`];
37463
+ const nLayers = info[`${arch2}.block_count`];
37464
+ const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
37465
+ const keyDim = info[`${arch2}.attention.key_length`];
37466
+ const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
37314
37467
  if (archMax && nLayers && nKVHeads && keyDim && valDim) {
37315
37468
  const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
37316
37469
  return estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2);
@@ -37327,7 +37480,7 @@ async function queryModelContextSize(baseUrl, modelName) {
37327
37480
  }
37328
37481
  }
37329
37482
  function estimateRealisticContext(kvBytesPerToken, archMax, modelSizeGB2) {
37330
- const totalMemGB = totalmem2() / 1024 ** 3;
37483
+ const totalMemGB = totalmem3() / 1024 ** 3;
37331
37484
  const usableBytes = totalMemGB * 0.7 * 1024 ** 3;
37332
37485
  const maxTokens = Math.floor(usableBytes / kvBytesPerToken);
37333
37486
  let numCtx = Math.max(2048, Math.floor(maxTokens / 1024) * 1024);
@@ -38203,18 +38356,18 @@ var init_oa_directory = __esm({
38203
38356
 
38204
38357
  // packages/cli/dist/tui/setup.js
38205
38358
  import * as readline from "node:readline";
38206
- import { execSync as execSync25, spawn as spawn18, exec as exec2 } from "node:child_process";
38359
+ import { execSync as execSync26, spawn as spawn18, exec as exec2 } from "node:child_process";
38207
38360
  import { promisify as promisify6 } from "node:util";
38208
38361
  import { existsSync as existsSync36, writeFileSync as writeFileSync15, readFileSync as readFileSync27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync14 } from "node:fs";
38209
38362
  import { join as join52 } from "node:path";
38210
- import { homedir as homedir12, platform } from "node:os";
38363
+ import { homedir as homedir12, platform as platform2 } from "node:os";
38211
38364
  function detectSystemSpecs() {
38212
38365
  let totalRamGB = 0;
38213
38366
  let availableRamGB = 0;
38214
38367
  let gpuVramGB = 0;
38215
38368
  let gpuName = "";
38216
38369
  try {
38217
- const memInfo = execSync25("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
38370
+ const memInfo = execSync26("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
38218
38371
  encoding: "utf8",
38219
38372
  timeout: 5e3
38220
38373
  });
@@ -38234,7 +38387,7 @@ function detectSystemSpecs() {
38234
38387
  } catch {
38235
38388
  }
38236
38389
  try {
38237
- const nvidiaSmi = execSync25("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
38390
+ const nvidiaSmi = execSync26("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
38238
38391
  const lines = nvidiaSmi.trim().split("\n");
38239
38392
  if (lines.length > 0) {
38240
38393
  for (const line of lines) {
@@ -38394,7 +38547,7 @@ function askSecret(rl, question) {
38394
38547
  function ensureCurl() {
38395
38548
  if (hasCmd("curl"))
38396
38549
  return true;
38397
- const plat = platform();
38550
+ const plat = platform2();
38398
38551
  if (plat === "win32") {
38399
38552
  process.stdout.write(` ${c2.yellow("\u26A0")} curl not found on Windows \u2014 install it manually.
38400
38553
  `);
@@ -38413,7 +38566,7 @@ function ensureCurl() {
38413
38566
  for (const s of strategies) {
38414
38567
  if (hasCmd(s.check)) {
38415
38568
  try {
38416
- execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
38569
+ execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
38417
38570
  if (hasCmd("curl")) {
38418
38571
  process.stdout.write(` ${c2.green("\u2714")} curl installed via ${s.label}.
38419
38572
  `);
@@ -38427,7 +38580,7 @@ function ensureCurl() {
38427
38580
  }
38428
38581
  if (plat === "darwin") {
38429
38582
  try {
38430
- execSync25("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
38583
+ execSync26("xcode-select --install", { stdio: "inherit", timeout: 3e5 });
38431
38584
  if (hasCmd("curl"))
38432
38585
  return true;
38433
38586
  } catch {
@@ -38438,7 +38591,7 @@ function ensureCurl() {
38438
38591
  return false;
38439
38592
  }
38440
38593
  async function autoInstallOllama(rl) {
38441
- const plat = platform();
38594
+ const plat = platform2();
38442
38595
  if (plat !== "win32" && !ensureCurl()) {
38443
38596
  return false;
38444
38597
  }
@@ -38462,7 +38615,7 @@ function installOllamaLinux() {
38462
38615
 
38463
38616
  `);
38464
38617
  try {
38465
- execSync25("curl -fsSL https://ollama.com/install.sh | sh", {
38618
+ execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
38466
38619
  stdio: "inherit",
38467
38620
  timeout: 3e5
38468
38621
  });
@@ -38490,7 +38643,7 @@ async function installOllamaMac(_rl) {
38490
38643
 
38491
38644
  `);
38492
38645
  try {
38493
- execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
38646
+ execSync26('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
38494
38647
  if (!hasCmd("brew")) {
38495
38648
  try {
38496
38649
  const brewPrefix = existsSync36("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
@@ -38523,7 +38676,7 @@ async function installOllamaMac(_rl) {
38523
38676
 
38524
38677
  `);
38525
38678
  try {
38526
- execSync25("brew install ollama", {
38679
+ execSync26("brew install ollama", {
38527
38680
  stdio: "inherit",
38528
38681
  timeout: 3e5
38529
38682
  });
@@ -38550,7 +38703,7 @@ function installOllamaWindows() {
38550
38703
 
38551
38704
  `);
38552
38705
  try {
38553
- execSync25('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
38706
+ execSync26('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
38554
38707
  stdio: "inherit",
38555
38708
  timeout: 3e5
38556
38709
  });
@@ -38631,7 +38784,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
38631
38784
  }
38632
38785
  function pullModelWithAutoUpdate(tag) {
38633
38786
  try {
38634
- execSync25(`ollama pull ${tag}`, {
38787
+ execSync26(`ollama pull ${tag}`, {
38635
38788
  stdio: "inherit",
38636
38789
  timeout: 36e5
38637
38790
  // 1 hour max
@@ -38651,7 +38804,7 @@ function pullModelWithAutoUpdate(tag) {
38651
38804
 
38652
38805
  `);
38653
38806
  try {
38654
- execSync25("curl -fsSL https://ollama.com/install.sh | sh", {
38807
+ execSync26("curl -fsSL https://ollama.com/install.sh | sh", {
38655
38808
  stdio: "inherit",
38656
38809
  timeout: 3e5
38657
38810
  // 5 min max for install
@@ -38662,7 +38815,7 @@ function pullModelWithAutoUpdate(tag) {
38662
38815
  process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
38663
38816
 
38664
38817
  `);
38665
- execSync25(`ollama pull ${tag}`, {
38818
+ execSync26(`ollama pull ${tag}`, {
38666
38819
  stdio: "inherit",
38667
38820
  timeout: 36e5
38668
38821
  });
@@ -38746,7 +38899,7 @@ function renderScoreBar(score, width = 20) {
38746
38899
  function ensurePython3() {
38747
38900
  process.stdout.write(` ${c2.cyan("\u25CF")} Installing Python3...
38748
38901
  `);
38749
- const plat = platform();
38902
+ const plat = platform2();
38750
38903
  if (plat === "win32") {
38751
38904
  process.stdout.write(` ${c2.dim("Download Python from https://python.org/downloads/")}
38752
38905
 
@@ -38764,7 +38917,7 @@ function ensurePython3() {
38764
38917
  if (plat === "darwin") {
38765
38918
  if (hasCmd("brew")) {
38766
38919
  try {
38767
- execSync25("brew install python3", { stdio: "inherit", timeout: 3e5 });
38920
+ execSync26("brew install python3", { stdio: "inherit", timeout: 3e5 });
38768
38921
  if (hasCmd("python3")) {
38769
38922
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via Homebrew.
38770
38923
  `);
@@ -38777,7 +38930,7 @@ function ensurePython3() {
38777
38930
  for (const s of strategies) {
38778
38931
  if (hasCmd(s.check)) {
38779
38932
  try {
38780
- execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
38933
+ execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
38781
38934
  if (hasCmd("python3") || hasCmd("python")) {
38782
38935
  process.stdout.write(` ${c2.green("\u2714")} Python3 installed via ${s.label}.
38783
38936
  `);
@@ -38793,11 +38946,11 @@ function ensurePython3() {
38793
38946
  }
38794
38947
  function checkPythonVenv() {
38795
38948
  try {
38796
- execSync25("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
38949
+ execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
38797
38950
  return true;
38798
38951
  } catch {
38799
38952
  try {
38800
- execSync25("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
38953
+ execSync26("python -m venv --help", { stdio: "pipe", timeout: 5e3 });
38801
38954
  return true;
38802
38955
  } catch {
38803
38956
  return false;
@@ -38816,7 +38969,7 @@ function ensurePythonVenv() {
38816
38969
  for (const s of strategies) {
38817
38970
  if (hasCmd(s.check)) {
38818
38971
  try {
38819
- execSync25(s.install, { stdio: "inherit", timeout: 12e4 });
38972
+ execSync26(s.install, { stdio: "inherit", timeout: 12e4 });
38820
38973
  if (checkPythonVenv()) {
38821
38974
  process.stdout.write(` ${c2.green("\u2714")} python3-venv installed via ${s.label}.
38822
38975
  `);
@@ -39252,7 +39405,7 @@ async function doSetup(config, rl) {
39252
39405
  const modelfilePath = join52(modelDir2, `Modelfile.${customName}`);
39253
39406
  writeFileSync15(modelfilePath, modelfileContent + "\n", "utf8");
39254
39407
  process.stdout.write(` ${c2.dim("Creating model...")} `);
39255
- execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
39408
+ execSync26(`ollama create ${customName} -f ${modelfilePath}`, {
39256
39409
  stdio: "pipe",
39257
39410
  timeout: 12e4
39258
39411
  });
@@ -39303,7 +39456,7 @@ function isFirstRun() {
39303
39456
  function hasCmd(cmd) {
39304
39457
  try {
39305
39458
  const whichCmd = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
39306
- execSync25(whichCmd, { stdio: "pipe", timeout: 3e3 });
39459
+ execSync26(whichCmd, { stdio: "pipe", timeout: 3e3 });
39307
39460
  return true;
39308
39461
  } catch {
39309
39462
  return false;
@@ -39336,7 +39489,7 @@ function getVenvDir() {
39336
39489
  }
39337
39490
  function hasVenvModule() {
39338
39491
  try {
39339
- execSync25("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39492
+ execSync26("python3 -m venv --help", { stdio: "pipe", timeout: 5e3 });
39340
39493
  return true;
39341
39494
  } catch {
39342
39495
  return false;
@@ -39358,8 +39511,8 @@ function ensureVenv(log) {
39358
39511
  }
39359
39512
  try {
39360
39513
  mkdirSync14(join52(homedir12(), ".open-agents"), { recursive: true });
39361
- execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
39362
- execSync25(`"${join52(venvDir, "bin", "pip")}" install --upgrade pip`, {
39514
+ execSync26(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
39515
+ execSync26(`"${join52(venvDir, "bin", "pip")}" install --upgrade pip`, {
39363
39516
  stdio: "pipe",
39364
39517
  timeout: 6e4
39365
39518
  });
@@ -39372,7 +39525,7 @@ function ensureVenv(log) {
39372
39525
  }
39373
39526
  function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39374
39527
  try {
39375
- execSync25(`sudo -n ${cmd}`, {
39528
+ execSync26(`sudo -n ${cmd}`, {
39376
39529
  stdio: "pipe",
39377
39530
  timeout: timeoutMs,
39378
39531
  env: { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
@@ -39385,7 +39538,7 @@ function trySudoPasswordless(cmd, timeoutMs = 12e4) {
39385
39538
  function runWithSudo(cmd, password, timeoutMs = 12e4) {
39386
39539
  try {
39387
39540
  const escaped = cmd.replace(/'/g, "'\\''");
39388
- execSync25(`sudo -S bash -c '${escaped}'`, {
39541
+ execSync26(`sudo -S bash -c '${escaped}'`, {
39389
39542
  input: password + "\n",
39390
39543
  stdio: ["pipe", "pipe", "pipe"],
39391
39544
  timeout: timeoutMs,
@@ -39492,7 +39645,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
39492
39645
  ok = await sudoInstall(batchCmd, getPassword, log, cachedPasswordRef, 18e4);
39493
39646
  } else {
39494
39647
  try {
39495
- execSync25(batchCmd, { stdio: "pipe", timeout: 18e4 });
39648
+ execSync26(batchCmd, { stdio: "pipe", timeout: 18e4 });
39496
39649
  ok = true;
39497
39650
  } catch {
39498
39651
  ok = false;
@@ -39529,7 +39682,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
39529
39682
  const venvCmds = {
39530
39683
  apt: () => {
39531
39684
  try {
39532
- const pyVer = execSync25(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
39685
+ const pyVer = execSync26(`python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).trim();
39533
39686
  return `apt-get install -y python3-venv python${pyVer}-venv`;
39534
39687
  } catch {
39535
39688
  return "apt-get install -y python3-venv";
@@ -39557,12 +39710,12 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
39557
39710
  const venvPip = join52(venvBin, "pip");
39558
39711
  log("Installing moondream-station in ~/.open-agents/venv...");
39559
39712
  try {
39560
- execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
39713
+ execSync26(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
39561
39714
  if (existsSync36(venvMoondream)) {
39562
39715
  log("moondream-station installed successfully.");
39563
39716
  } else {
39564
39717
  try {
39565
- const check = execSync25(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
39718
+ const check = execSync26(`"${venvPip}" show moondream-station`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 });
39566
39719
  if (check.includes("moondream")) {
39567
39720
  log("moondream-station package installed.");
39568
39721
  }
@@ -39579,7 +39732,7 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
39579
39732
  const venvPip2 = join52(venvBin, "pip");
39580
39733
  let ocrStackInstalled = false;
39581
39734
  try {
39582
- execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
39735
+ execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
39583
39736
  ocrStackInstalled = true;
39584
39737
  } catch {
39585
39738
  }
@@ -39587,9 +39740,9 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
39587
39740
  const ocrPackages = "pytesseract Pillow opencv-python-headless numpy";
39588
39741
  log("Installing OCR Python stack (pytesseract, OpenCV, Pillow, numpy)...");
39589
39742
  try {
39590
- execSync25(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
39743
+ execSync26(`"${venvPip2}" install ${ocrPackages}`, { stdio: "pipe", timeout: 3e5 });
39591
39744
  try {
39592
- execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
39745
+ execSync26(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
39593
39746
  log("OCR Python stack installed successfully.");
39594
39747
  } catch {
39595
39748
  log("OCR Python stack install completed but import verification failed.");
@@ -39613,17 +39766,17 @@ function ensureCloudflaredBackground(onInfo) {
39613
39766
  });
39614
39767
  log("Installing cloudflared for live voice sessions...");
39615
39768
  _cloudflaredInstallPromise = (async () => {
39616
- const arch = process.arch;
39617
- const os = platform();
39769
+ const arch2 = process.arch;
39770
+ const os = platform2();
39618
39771
  if (os !== "win32" && !ensureCurl()) {
39619
39772
  log("curl not available \u2014 cannot install cloudflared.");
39620
39773
  return false;
39621
39774
  }
39622
39775
  if (os === "linux") {
39623
39776
  const archMap = { x64: "amd64", arm64: "arm64", arm: "arm" };
39624
- const cfArch = archMap[arch] ?? "amd64";
39777
+ const cfArch = archMap[arch2] ?? "amd64";
39625
39778
  try {
39626
- execSync25(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
39779
+ execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && mkdir -p "${homedir12()}/.local/bin" && mv /tmp/cloudflared "${homedir12()}/.local/bin/cloudflared"`, { stdio: "pipe", timeout: 6e4 });
39627
39780
  if (!process.env.PATH?.includes(`${homedir12()}/.local/bin`)) {
39628
39781
  process.env.PATH = `${homedir12()}/.local/bin:${process.env.PATH}`;
39629
39782
  }
@@ -39634,7 +39787,7 @@ function ensureCloudflaredBackground(onInfo) {
39634
39787
  } catch {
39635
39788
  }
39636
39789
  try {
39637
- execSync25(`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 });
39790
+ execSync26(`curl -fsSL "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${cfArch}" -o /tmp/cloudflared && chmod +x /tmp/cloudflared && sudo mv /tmp/cloudflared /usr/local/bin/cloudflared 2>/dev/null`, { stdio: "pipe", timeout: 6e4 });
39638
39791
  if (hasCmd("cloudflared")) {
39639
39792
  log("cloudflared installed.");
39640
39793
  return true;
@@ -39643,7 +39796,7 @@ function ensureCloudflaredBackground(onInfo) {
39643
39796
  }
39644
39797
  } else if (os === "darwin") {
39645
39798
  try {
39646
- execSync25("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
39799
+ execSync26("brew install cloudflared", { stdio: "pipe", timeout: 12e4 });
39647
39800
  if (hasCmd("cloudflared")) {
39648
39801
  log("cloudflared installed via Homebrew.");
39649
39802
  return true;
@@ -39692,14 +39845,14 @@ async function queryModelKVInfo(backendUrl, modelName) {
39692
39845
  if (!data.model_info)
39693
39846
  return null;
39694
39847
  const info = data.model_info;
39695
- const arch = info["general.architecture"];
39696
- if (!arch)
39848
+ const arch2 = info["general.architecture"];
39849
+ if (!arch2)
39697
39850
  return null;
39698
- const nLayers = info[`${arch}.block_count`];
39699
- const nKVHeads = info[`${arch}.attention.head_count_kv`] ?? info[`${arch}.attention.head_count`];
39700
- const keyDim = info[`${arch}.attention.key_length`];
39701
- const valDim = info[`${arch}.attention.value_length`] ?? keyDim;
39702
- const archMax = info[`${arch}.context_length`];
39851
+ const nLayers = info[`${arch2}.block_count`];
39852
+ const nKVHeads = info[`${arch2}.attention.head_count_kv`] ?? info[`${arch2}.attention.head_count`];
39853
+ const keyDim = info[`${arch2}.attention.key_length`];
39854
+ const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
39855
+ const archMax = info[`${arch2}.context_length`];
39703
39856
  if (!nLayers || !nKVHeads || !keyDim || !valDim || !archMax)
39704
39857
  return null;
39705
39858
  const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
@@ -39785,7 +39938,7 @@ async function ensureExpandedContext(modelName, backendUrl) {
39785
39938
  }
39786
39939
  async function ensureNeovim() {
39787
39940
  try {
39788
- const nvimPath = execSync25("which nvim 2>/dev/null || where nvim 2>nul", {
39941
+ const nvimPath = execSync26("which nvim 2>/dev/null || where nvim 2>nul", {
39789
39942
  encoding: "utf8",
39790
39943
  stdio: "pipe",
39791
39944
  timeout: 5e3
@@ -39794,27 +39947,27 @@ async function ensureNeovim() {
39794
39947
  return nvimPath;
39795
39948
  } catch {
39796
39949
  }
39797
- const platform5 = process.platform;
39798
- const arch = process.arch;
39799
- if (platform5 === "linux") {
39950
+ const platform6 = process.platform;
39951
+ const arch2 = process.arch;
39952
+ if (platform6 === "linux") {
39800
39953
  const binDir = join52(homedir12(), ".local", "bin");
39801
39954
  const nvimDest = join52(binDir, "nvim");
39802
39955
  try {
39803
39956
  mkdirSync14(binDir, { recursive: true });
39804
39957
  } catch {
39805
39958
  }
39806
- const appImageName = arch === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
39959
+ const appImageName = arch2 === "arm64" ? "nvim-linux-arm64.appimage" : "nvim-linux-x86_64.appimage";
39807
39960
  const url = `https://github.com/neovim/neovim/releases/latest/download/${appImageName}`;
39808
39961
  console.log(` Downloading Neovim (${appImageName})...`);
39809
39962
  try {
39810
- execSync25(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
39811
- execSync25(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
39963
+ execSync26(`curl -fsSL "${url}" -o "${nvimDest}"`, { stdio: "pipe", timeout: 6e4 });
39964
+ execSync26(`chmod +x "${nvimDest}"`, { stdio: "pipe", timeout: 3e3 });
39812
39965
  } catch (err) {
39813
39966
  console.log(` Failed to download Neovim: ${err instanceof Error ? err.message : String(err)}`);
39814
39967
  return null;
39815
39968
  }
39816
39969
  try {
39817
- const ver = execSync25(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
39970
+ const ver = execSync26(`"${nvimDest}" --version`, { encoding: "utf8", stdio: "pipe", timeout: 5e3 }).split("\n")[0];
39818
39971
  console.log(` Installed: ${ver}`);
39819
39972
  } catch {
39820
39973
  console.log(" Warning: nvim binary downloaded but may not work (missing FUSE? Try: nvim --appimage-extract)");
@@ -39825,12 +39978,12 @@ async function ensureNeovim() {
39825
39978
  ensurePathInShellRc(binDir);
39826
39979
  return nvimDest;
39827
39980
  }
39828
- if (platform5 === "darwin") {
39981
+ if (platform6 === "darwin") {
39829
39982
  if (hasCmd("brew")) {
39830
39983
  console.log(" Installing Neovim via Homebrew...");
39831
39984
  try {
39832
- execSync25("brew install neovim", { stdio: "inherit", timeout: 12e4 });
39833
- const nvimPath = execSync25("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
39985
+ execSync26("brew install neovim", { stdio: "inherit", timeout: 12e4 });
39986
+ const nvimPath = execSync26("which nvim", { encoding: "utf8", stdio: "pipe", timeout: 3e3 }).trim();
39834
39987
  return nvimPath || null;
39835
39988
  } catch {
39836
39989
  console.log(" brew install neovim failed.");
@@ -39840,11 +39993,11 @@ async function ensureNeovim() {
39840
39993
  console.log(" Homebrew not found. Install Neovim: brew install neovim");
39841
39994
  return null;
39842
39995
  }
39843
- if (platform5 === "win32") {
39996
+ if (platform6 === "win32") {
39844
39997
  if (hasCmd("choco")) {
39845
39998
  console.log(" Installing Neovim via Chocolatey...");
39846
39999
  try {
39847
- execSync25("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
40000
+ execSync26("choco install neovim -y", { stdio: "inherit", timeout: 12e4 });
39848
40001
  return "nvim";
39849
40002
  } catch {
39850
40003
  console.log(" choco install neovim failed.");
@@ -39853,7 +40006,7 @@ async function ensureNeovim() {
39853
40006
  if (hasCmd("winget")) {
39854
40007
  console.log(" Installing Neovim via winget...");
39855
40008
  try {
39856
- execSync25("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
40009
+ execSync26("winget install Neovim.Neovim --accept-source-agreements --accept-package-agreements", {
39857
40010
  stdio: "inherit",
39858
40011
  timeout: 12e4
39859
40012
  });
@@ -40775,7 +40928,7 @@ var init_drop_panel = __esm({
40775
40928
  import { existsSync as existsSync38, unlinkSync as unlinkSync7 } from "node:fs";
40776
40929
  import { tmpdir as tmpdir8 } from "node:os";
40777
40930
  import { join as join53 } from "node:path";
40778
- import { execSync as execSync26 } from "node:child_process";
40931
+ import { execSync as execSync27 } from "node:child_process";
40779
40932
  function isNeovimActive() {
40780
40933
  return _state !== null && !_state.cleanedUp;
40781
40934
  }
@@ -40793,7 +40946,7 @@ async function startNeovimMode(opts) {
40793
40946
  }
40794
40947
  let nvimPath;
40795
40948
  try {
40796
- nvimPath = execSync26("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
40949
+ nvimPath = execSync27("which nvim 2>/dev/null", { encoding: "utf8" }).trim();
40797
40950
  if (!nvimPath)
40798
40951
  throw new Error();
40799
40952
  } catch {
@@ -41253,8 +41406,8 @@ __export(voice_exports, {
41253
41406
  });
41254
41407
  import { existsSync as existsSync39, mkdirSync as mkdirSync15, writeFileSync as writeFileSync16, readFileSync as readFileSync28, unlinkSync as unlinkSync8, readdirSync as readdirSync10, renameSync, statSync as statSync13 } from "node:fs";
41255
41408
  import { join as join54, dirname as dirname18 } from "node:path";
41256
- import { homedir as homedir13, tmpdir as tmpdir9, platform as platform2 } from "node:os";
41257
- import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
41409
+ import { homedir as homedir13, tmpdir as tmpdir9, platform as platform3 } from "node:os";
41410
+ import { execSync as execSync28, spawn as nodeSpawn } from "node:child_process";
41258
41411
  import { createRequire } from "node:module";
41259
41412
  function sanitizeForTTS(text) {
41260
41413
  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();
@@ -41295,7 +41448,7 @@ function luxttsVenvDir() {
41295
41448
  return join54(voiceDir(), "luxtts-venv");
41296
41449
  }
41297
41450
  function luxttsVenvPy() {
41298
- return platform2() === "win32" ? join54(luxttsVenvDir(), "Scripts", "python.exe") : join54(luxttsVenvDir(), "bin", "python3");
41451
+ return platform3() === "win32" ? join54(luxttsVenvDir(), "Scripts", "python.exe") : join54(luxttsVenvDir(), "bin", "python3");
41299
41452
  }
41300
41453
  function luxttsRepoDir() {
41301
41454
  return join54(voiceDir(), "LuxTTS");
@@ -42983,7 +43136,7 @@ var init_voice = __esm({
42983
43136
  });
42984
43137
  }
42985
43138
  getPlayCommand(path) {
42986
- const os = platform2();
43139
+ const os = platform3();
42987
43140
  if (os === "darwin")
42988
43141
  return ["afplay", path];
42989
43142
  if (os === "win32") {
@@ -42995,7 +43148,7 @@ var init_voice = __esm({
42995
43148
  }
42996
43149
  for (const player of ["paplay", "pw-play", "aplay"]) {
42997
43150
  try {
42998
- execSync27(`which ${player}`, { stdio: "pipe" });
43151
+ execSync28(`which ${player}`, { stdio: "pipe" });
42999
43152
  return [player, path];
43000
43153
  } catch {
43001
43154
  }
@@ -43016,7 +43169,7 @@ var init_voice = __esm({
43016
43169
  // -------------------------------------------------------------------------
43017
43170
  /** Check if we're on macOS Apple Silicon */
43018
43171
  isMlxCapable() {
43019
- return platform2() === "darwin" && process.arch === "arm64";
43172
+ return platform3() === "darwin" && process.arch === "arm64";
43020
43173
  }
43021
43174
  /** Resolve python3 binary path (cached after first call) */
43022
43175
  findPython3() {
@@ -43024,7 +43177,7 @@ var init_voice = __esm({
43024
43177
  return this.python3Path;
43025
43178
  for (const bin of ["python3", "python"]) {
43026
43179
  try {
43027
- const path = execSync27(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43180
+ const path = execSync28(`which ${bin}`, { stdio: "pipe", timeout: 5e3 }).toString().trim();
43028
43181
  if (path) {
43029
43182
  this.python3Path = path;
43030
43183
  return path;
@@ -43090,7 +43243,7 @@ var init_voice = __esm({
43090
43243
  return false;
43091
43244
  }
43092
43245
  try {
43093
- execSync27(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43246
+ execSync28(`${py} -c "import mlx_audio"`, { stdio: "pipe", timeout: 1e4 });
43094
43247
  this.mlxInstalled = true;
43095
43248
  return true;
43096
43249
  } catch {
@@ -43151,11 +43304,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43151
43304
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43152
43305
  ].join("; ");
43153
43306
  try {
43154
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43307
+ execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43155
43308
  } catch (err) {
43156
43309
  try {
43157
43310
  const safeText = cleaned.replace(/'/g, "'\\''");
43158
- execSync27(`${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() });
43311
+ execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43159
43312
  } catch (err2) {
43160
43313
  return;
43161
43314
  }
@@ -43219,11 +43372,11 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43219
43372
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
43220
43373
  ].join("; ");
43221
43374
  try {
43222
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43375
+ execSync28(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43223
43376
  } catch {
43224
43377
  try {
43225
43378
  const safeText = cleaned.replace(/'/g, "'\\''");
43226
- execSync27(`${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() });
43379
+ execSync28(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir9() });
43227
43380
  } catch {
43228
43381
  return null;
43229
43382
  }
@@ -43317,8 +43470,8 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
43317
43470
  pipArgsStr = "torch torchaudio --index-url https://download.pytorch.org/whl/cu124";
43318
43471
  torchDesc = "CUDA (fallback)";
43319
43472
  } catch {
43320
- const arch = process.arch;
43321
- if (arch === "arm64" || arch === "arm") {
43473
+ const arch2 = process.arch;
43474
+ if (arch2 === "arm64" || arch2 === "arm") {
43322
43475
  pipArgsStr = "torch torchaudio";
43323
43476
  torchDesc = "ARM CPU (generic PyPI)";
43324
43477
  } else {
@@ -43790,7 +43943,7 @@ if __name__ == '__main__':
43790
43943
  async ensureRuntime() {
43791
43944
  if (this.ort)
43792
43945
  return;
43793
- const arch = process.arch;
43946
+ const arch2 = process.arch;
43794
43947
  mkdirSync15(voiceDir(), { recursive: true });
43795
43948
  const pkgPath = join54(voiceDir(), "package.json");
43796
43949
  const expectedDeps = {
@@ -43826,7 +43979,7 @@ if __name__ == '__main__':
43826
43979
  const onnxNodeModules = join54(voiceDir(), "node_modules", "onnxruntime-node");
43827
43980
  const onnxInstalled = existsSync39(onnxNodeModules);
43828
43981
  if (onnxInstalled && !await probeOnnx()) {
43829
- throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). 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.`);
43982
+ 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.`);
43830
43983
  }
43831
43984
  try {
43832
43985
  this.ort = voiceRequire("onnxruntime-node");
@@ -43835,12 +43988,12 @@ if __name__ == '__main__':
43835
43988
  try {
43836
43989
  await this.asyncShell(`cd "${voiceDir()}" && npm install --no-audit --no-fund`, 12e4);
43837
43990
  } catch (err) {
43838
- const archHint = arch !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch}.` : "";
43991
+ const archHint = arch2 !== "x64" ? ` onnxruntime-node may not have prebuilt binaries for ${process.platform}-${arch2}.` : "";
43839
43992
  throw new Error(`Failed to install voice dependencies.${archHint} Try manually: cd ${voiceDir()} && npm install
43840
43993
  Error: ${err instanceof Error ? err.message : String(err)}`);
43841
43994
  }
43842
43995
  if (!await probeOnnx()) {
43843
- throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). 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.`);
43996
+ 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.`);
43844
43997
  }
43845
43998
  try {
43846
43999
  this.ort = voiceRequire("onnxruntime-node");
@@ -43858,7 +44011,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
43858
44011
  const phonemizerMod = voiceRequire("phonemizer");
43859
44012
  this.phonemizeFn = phonemizerMod.phonemize ?? phonemizerMod.default?.phonemize ?? phonemizerMod;
43860
44013
  } catch (err) {
43861
- const archHint = arch !== "x64" ? ` phonemizer WASM may not support ${process.platform}-${arch}.` : "";
44014
+ const archHint = arch2 !== "x64" ? ` phonemizer WASM may not support ${process.platform}-${arch2}.` : "";
43862
44015
  throw new Error(`Failed to install phonemizer.${archHint} Try manually: cd ${voiceDir()} && npm install
43863
44016
  Error: ${err instanceof Error ? err.message : String(err)}`);
43864
44017
  }
@@ -47311,7 +47464,7 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
47311
47464
  }
47312
47465
  }
47313
47466
  async function handleParallel(arg, ctx) {
47314
- const { execSync: execSync32 } = await import("node:child_process");
47467
+ const { execSync: execSync33 } = await import("node:child_process");
47315
47468
  const baseUrl = ctx.config.backendUrl || "http://localhost:11434";
47316
47469
  const isRemote = ctx.config.backendType === "nexus";
47317
47470
  if (isRemote) {
@@ -47335,7 +47488,7 @@ async function handleParallel(arg, ctx) {
47335
47488
  }
47336
47489
  let systemdVal = "";
47337
47490
  try {
47338
- const out = execSync32("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
47491
+ const out = execSync33("systemctl show ollama.service -p Environment 2>/dev/null || true", { encoding: "utf8" });
47339
47492
  const match = out.match(/OLLAMA_NUM_PARALLEL=(\d+)/);
47340
47493
  if (match)
47341
47494
  systemdVal = match[1];
@@ -47364,7 +47517,7 @@ async function handleParallel(arg, ctx) {
47364
47517
  }
47365
47518
  const isSystemd = (() => {
47366
47519
  try {
47367
- const out = execSync32("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
47520
+ const out = execSync33("systemctl is-active ollama.service 2>/dev/null", { encoding: "utf8" }).trim();
47368
47521
  return out === "active" || out === "inactive";
47369
47522
  } catch {
47370
47523
  return false;
@@ -47378,10 +47531,10 @@ async function handleParallel(arg, ctx) {
47378
47531
  const overrideContent = `[Service]
47379
47532
  Environment="OLLAMA_NUM_PARALLEL=${n}"
47380
47533
  `;
47381
- execSync32(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
47382
- execSync32(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
47383
- execSync32("sudo systemctl daemon-reload", { stdio: "pipe" });
47384
- execSync32("sudo systemctl restart ollama.service", { stdio: "pipe" });
47534
+ execSync33(`sudo mkdir -p ${overrideDir}`, { stdio: "pipe" });
47535
+ execSync33(`echo '${overrideContent}' | sudo tee ${overrideFile} > /dev/null`, { stdio: "pipe" });
47536
+ execSync33("sudo systemctl daemon-reload", { stdio: "pipe" });
47537
+ execSync33("sudo systemctl restart ollama.service", { stdio: "pipe" });
47385
47538
  let ready = false;
47386
47539
  for (let i = 0; i < 30 && !ready; i++) {
47387
47540
  await new Promise((r) => setTimeout(r, 500));
@@ -47408,7 +47561,7 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
47408
47561
  renderInfo(`Setting OLLAMA_NUM_PARALLEL=${n}...`);
47409
47562
  try {
47410
47563
  try {
47411
- execSync32("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
47564
+ execSync33("pkill -f 'ollama serve' 2>/dev/null || true", { stdio: "pipe" });
47412
47565
  } catch {
47413
47566
  }
47414
47567
  await new Promise((r) => setTimeout(r, 1e3));
@@ -47957,15 +48110,15 @@ function fmtUptime(ms) {
47957
48110
  return `${Math.floor(sec / 3600)}h ${Math.floor(sec % 3600 / 60)}m`;
47958
48111
  }
47959
48112
  function getLocalSystemMetrics() {
47960
- const cpus4 = nodeOs.cpus();
48113
+ const cpus5 = nodeOs.cpus();
47961
48114
  const loads = nodeOs.loadavg();
47962
48115
  const totalMem = nodeOs.totalmem();
47963
48116
  const freeMem = nodeOs.freemem();
47964
48117
  const usedMem = totalMem - freeMem;
47965
48118
  const result = {
47966
- cpuModel: cpus4[0]?.model?.trim() ?? "unknown",
47967
- cpuCores: cpus4.length,
47968
- cpuUtil: Math.min(100, Math.round(loads[0] / cpus4.length * 100)),
48119
+ cpuModel: cpus5[0]?.model?.trim() ?? "unknown",
48120
+ cpuCores: cpus5.length,
48121
+ cpuUtil: Math.min(100, Math.round(loads[0] / cpus5.length * 100)),
47969
48122
  memTotalGB: Math.round(totalMem / (1024 * 1024 * 1024) * 10) / 10,
47970
48123
  memUsedGB: Math.round(usedMem / (1024 * 1024 * 1024) * 10) / 10,
47971
48124
  memUtil: Math.round(usedMem / totalMem * 100),
@@ -48059,12 +48212,12 @@ async function showExposeDashboard(gateway, rl, ctx) {
48059
48212
  const now = Date.now();
48060
48213
  const w = cols();
48061
48214
  const h = rows();
48062
- const uptime = s ? fmtUptime(now - (s.startedAt || now)) : "0s";
48215
+ const uptime2 = s ? fmtUptime(now - (s.startedAt || now)) : "0s";
48063
48216
  const lines = [];
48064
48217
  const statusDot = !s ? c2.dim("\u25CF") : s.status === "active" ? c2.green("\u25CF") : s.status === "error" ? c2.red("\u25CF") : c2.yellow("\u25CF");
48065
48218
  const statusLabel = s?.status || "unknown";
48066
48219
  lines.push("");
48067
- lines.push(` ${c2.bold("Expose Dashboard")} ${statusDot} ${statusLabel} ${c2.dim("uptime")} ${uptime} ${c2.dim((/* @__PURE__ */ new Date()).toLocaleTimeString())}`);
48220
+ lines.push(` ${c2.bold("Expose Dashboard")} ${statusDot} ${statusLabel} ${c2.dim("uptime")} ${uptime2} ${c2.dim((/* @__PURE__ */ new Date()).toLocaleTimeString())}`);
48068
48221
  const isTunnel = !!gateway.tunnelUrl;
48069
48222
  const isP2P = !!gateway.peerId;
48070
48223
  const endpointId = isTunnel ? gateway.tunnelUrl : isP2P ? gateway.peerId : null;
@@ -48210,18 +48363,18 @@ async function showExposeDashboard(gateway, rl, ctx) {
48210
48363
  const cmd = `/endpoint ${id} --auth ${gateway.authKey ?? ""}`;
48211
48364
  let copied = false;
48212
48365
  try {
48213
- const { execSync: execSync32 } = __require("node:child_process");
48214
- const platform5 = process.platform;
48215
- if (platform5 === "darwin") {
48216
- execSync32("pbcopy", { input: cmd, timeout: 3e3 });
48366
+ const { execSync: execSync33 } = __require("node:child_process");
48367
+ const platform6 = process.platform;
48368
+ if (platform6 === "darwin") {
48369
+ execSync33("pbcopy", { input: cmd, timeout: 3e3 });
48217
48370
  copied = true;
48218
- } else if (platform5 === "win32") {
48219
- execSync32("clip", { input: cmd, timeout: 3e3 });
48371
+ } else if (platform6 === "win32") {
48372
+ execSync33("clip", { input: cmd, timeout: 3e3 });
48220
48373
  copied = true;
48221
48374
  } else {
48222
48375
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
48223
48376
  try {
48224
- execSync32(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
48377
+ execSync33(tool, { input: cmd, timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] });
48225
48378
  copied = true;
48226
48379
  break;
48227
48380
  } catch {
@@ -48310,8 +48463,8 @@ var init_commands = __esm({
48310
48463
  // packages/cli/dist/tui/project-context.js
48311
48464
  import { existsSync as existsSync41, readFileSync as readFileSync30, readdirSync as readdirSync12 } from "node:fs";
48312
48465
  import { join as join56, basename as basename11 } from "node:path";
48313
- import { execSync as execSync28 } from "node:child_process";
48314
- import { homedir as homedir15, platform as platform3, release } from "node:os";
48466
+ import { execSync as execSync29 } from "node:child_process";
48467
+ import { homedir as homedir15, platform as platform4, release } from "node:os";
48315
48468
  function getModelTier(modelName) {
48316
48469
  const m = modelName.toLowerCase();
48317
48470
  const sizeMatch = m.match(/\b(\d+)b\b/);
@@ -48356,19 +48509,19 @@ function loadProjectMap(repoRoot) {
48356
48509
  }
48357
48510
  function getGitInfo(repoRoot) {
48358
48511
  try {
48359
- execSync28("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
48512
+ execSync29("git rev-parse --is-inside-work-tree", { cwd: repoRoot, stdio: "pipe" });
48360
48513
  } catch {
48361
48514
  return "";
48362
48515
  }
48363
48516
  const lines = [];
48364
48517
  try {
48365
- const branch = execSync28("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48518
+ const branch = execSync29("git branch --show-current", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48366
48519
  if (branch)
48367
48520
  lines.push(`Branch: ${branch}`);
48368
48521
  } catch {
48369
48522
  }
48370
48523
  try {
48371
- const status = execSync28("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48524
+ const status = execSync29("git status --porcelain", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48372
48525
  if (status) {
48373
48526
  const changed = status.split("\n").length;
48374
48527
  lines.push(`Working tree: ${changed} changed file(s)`);
@@ -48378,7 +48531,7 @@ function getGitInfo(repoRoot) {
48378
48531
  } catch {
48379
48532
  }
48380
48533
  try {
48381
- const log = execSync28("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48534
+ const log = execSync29("git log --oneline -5 --no-decorate", { cwd: repoRoot, encoding: "utf-8", stdio: "pipe" }).trim();
48382
48535
  if (log)
48383
48536
  lines.push(`Recent commits:
48384
48537
  ${log}`);
@@ -48453,7 +48606,7 @@ function getEnvironment(repoRoot) {
48453
48606
  const lines = [
48454
48607
  `Working directory: ${repoRoot}`,
48455
48608
  `Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
48456
- `Platform: ${platform3()} ${release()}`,
48609
+ `Platform: ${platform4()} ${release()}`,
48457
48610
  `Node: ${process.version}`
48458
48611
  ];
48459
48612
  return lines.join("\n");
@@ -49536,8 +49689,8 @@ function generateMnemonic(seed) {
49536
49689
  }
49537
49690
  function getNodeMnemonic() {
49538
49691
  try {
49539
- const { hostname: hostname2, userInfo: userInfo2 } = __require("node:os");
49540
- return generateMnemonic(`${hostname2()}:${userInfo2().username}`);
49692
+ const { hostname: hostname3, userInfo: userInfo2 } = __require("node:os");
49693
+ return generateMnemonic(`${hostname3()}:${userInfo2().username}`);
49541
49694
  } catch {
49542
49695
  return generateMnemonic("unknown-node");
49543
49696
  }
@@ -50930,7 +51083,7 @@ var init_promptLoader3 = __esm({
50930
51083
  // packages/cli/dist/tui/dream-engine.js
50931
51084
  import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync19, readFileSync as readFileSync33, existsSync as existsSync44, cpSync, rmSync as rmSync2, readdirSync as readdirSync14 } from "node:fs";
50932
51085
  import { join as join60, basename as basename13 } from "node:path";
50933
- import { execSync as execSync29 } from "node:child_process";
51086
+ import { execSync as execSync30 } from "node:child_process";
50934
51087
  function loadAutoresearchMemory(repoRoot) {
50935
51088
  const memoryPath = join60(repoRoot, ".oa", "memory", "autoresearch.json");
50936
51089
  if (!existsSync44(memoryPath))
@@ -51294,7 +51447,7 @@ var init_dream_engine = __esm({
51294
51447
  }
51295
51448
  }
51296
51449
  try {
51297
- const output = execSync29(cmd, {
51450
+ const output = execSync30(cmd, {
51298
51451
  cwd: this.repoRoot,
51299
51452
  timeout: 3e4,
51300
51453
  encoding: "utf-8",
@@ -52071,17 +52224,17 @@ ${summaryResult}
52071
52224
  try {
52072
52225
  mkdirSync19(checkpointDir, { recursive: true });
52073
52226
  try {
52074
- const gitStatus = execSync29("git status --porcelain", {
52227
+ const gitStatus = execSync30("git status --porcelain", {
52075
52228
  cwd: this.repoRoot,
52076
52229
  encoding: "utf-8",
52077
52230
  timeout: 1e4
52078
52231
  });
52079
- const gitDiff = execSync29("git diff", {
52232
+ const gitDiff = execSync30("git diff", {
52080
52233
  cwd: this.repoRoot,
52081
52234
  encoding: "utf-8",
52082
52235
  timeout: 1e4
52083
52236
  });
52084
- const gitHash = execSync29("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
52237
+ const gitHash = execSync30("git rev-parse HEAD 2>/dev/null || echo 'no-git'", {
52085
52238
  cwd: this.repoRoot,
52086
52239
  encoding: "utf-8",
52087
52240
  timeout: 5e3
@@ -55595,7 +55748,7 @@ var init_braille_spinner = __esm({
55595
55748
  });
55596
55749
 
55597
55750
  // packages/cli/dist/tui/system-metrics.js
55598
- import { loadavg as loadavg3, cpus as cpus3, totalmem as totalmem4, freemem as freemem3, platform as platform4 } from "node:os";
55751
+ import { loadavg as loadavg3, cpus as cpus4, totalmem as totalmem5, freemem as freemem4, platform as platform5 } from "node:os";
55599
55752
  import { exec as exec3 } from "node:child_process";
55600
55753
  import { readFile as readFile22 } from "node:fs/promises";
55601
55754
  function formatRate(bytesPerSec) {
@@ -55629,7 +55782,7 @@ async function readProcNetDev() {
55629
55782
  }
55630
55783
  async function collectNetworkMetrics() {
55631
55784
  const now = Date.now();
55632
- const plat = platform4();
55785
+ const plat = platform5();
55633
55786
  if (plat === "linux") {
55634
55787
  const snap = await readProcNetDev();
55635
55788
  if (!snap)
@@ -55727,10 +55880,10 @@ function getInstantSnapshot() {
55727
55880
  }
55728
55881
  function collectCpuRam() {
55729
55882
  const [l1] = loadavg3();
55730
- const cores = cpus3().length;
55731
- const cpuModel = cpus3()[0]?.model ?? "";
55732
- const totalMem = totalmem4();
55733
- const usedMem = totalMem - freemem3();
55883
+ const cores = cpus4().length;
55884
+ const cpuModel = cpus4()[0]?.model ?? "";
55885
+ const totalMem = totalmem5();
55886
+ const usedMem = totalMem - freemem4();
55734
55887
  return {
55735
55888
  cpuUtil: Math.min(100, Math.round(l1 / cores * 100)),
55736
55889
  cpuCores: cores,
@@ -55891,7 +56044,7 @@ __export(text_selection_exports, {
55891
56044
  stripAnsi: () => stripAnsi3,
55892
56045
  visibleLength: () => visibleLength
55893
56046
  });
55894
- import { execSync as execSync30 } from "node:child_process";
56047
+ import { execSync as execSync31 } from "node:child_process";
55895
56048
  function stripAnsi3(s) {
55896
56049
  return s.replace(/\x1B\[[0-9;]*[A-Za-z]|\x1B\].*?(?:\x07|\x1B\\)/g, "");
55897
56050
  }
@@ -55900,18 +56053,18 @@ function visibleLength(s) {
55900
56053
  }
55901
56054
  function copyText(text) {
55902
56055
  try {
55903
- const platform5 = process.platform;
55904
- if (platform5 === "darwin") {
55905
- execSync30("pbcopy", { input: text, timeout: 3e3 });
56056
+ const platform6 = process.platform;
56057
+ if (platform6 === "darwin") {
56058
+ execSync31("pbcopy", { input: text, timeout: 3e3 });
55906
56059
  return true;
55907
56060
  }
55908
- if (platform5 === "win32") {
55909
- execSync30("clip", { input: text, timeout: 3e3 });
56061
+ if (platform6 === "win32") {
56062
+ execSync31("clip", { input: text, timeout: 3e3 });
55910
56063
  return true;
55911
56064
  }
55912
56065
  for (const tool of ["xclip -selection clipboard", "xsel --clipboard --input", "wl-copy"]) {
55913
56066
  try {
55914
- execSync30(tool, { input: text, timeout: 3e3 });
56067
+ execSync31(tool, { input: text, timeout: 3e3 });
55915
56068
  return true;
55916
56069
  } catch {
55917
56070
  continue;
@@ -55920,10 +56073,10 @@ function copyText(text) {
55920
56073
  if (!_clipboardAutoInstallAttempted) {
55921
56074
  _clipboardAutoInstallAttempted = true;
55922
56075
  try {
55923
- execSync30("which apt-get", { timeout: 2e3, stdio: "pipe" });
56076
+ execSync31("which apt-get", { timeout: 2e3, stdio: "pipe" });
55924
56077
  try {
55925
- execSync30("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
55926
- execSync30("xclip -selection clipboard", { input: text, timeout: 3e3 });
56078
+ execSync31("sudo -n apt-get install -y xclip 2>/dev/null", { timeout: 15e3, stdio: "pipe" });
56079
+ execSync31("xclip -selection clipboard", { input: text, timeout: 3e3 });
55927
56080
  return true;
55928
56081
  } catch {
55929
56082
  }
@@ -58364,7 +58517,7 @@ import { createRequire as createRequire2 } from "node:module";
58364
58517
  import { fileURLToPath as fileURLToPath12 } from "node:url";
58365
58518
  import { readFileSync as readFileSync37, writeFileSync as writeFileSync21, appendFileSync as appendFileSync4, rmSync as rmSync3, readdirSync as readdirSync18, mkdirSync as mkdirSync22 } from "node:fs";
58366
58519
  import { existsSync as existsSync48 } from "node:fs";
58367
- import { execSync as execSync31 } from "node:child_process";
58520
+ import { execSync as execSync32 } from "node:child_process";
58368
58521
  import { homedir as homedir16 } from "node:os";
58369
58522
  function formatTimeAgo(date) {
58370
58523
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -58746,6 +58899,13 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
58746
58899
  const modelTier = getModelTier(config.model);
58747
58900
  const projectCtx = buildProjectContext(repoRoot, taskStores?.contextStores);
58748
58901
  let dynamicContext = formatContextForPrompt(projectCtx, modelTier);
58902
+ const environmentProvider = () => {
58903
+ try {
58904
+ return formatSnapshotForContext(collectSnapshot(repoRoot));
58905
+ } catch {
58906
+ return "";
58907
+ }
58908
+ };
58749
58909
  try {
58750
58910
  const { MemoryMetabolismTool: MemoryMetabolismTool2 } = __require("@open-agents/execution");
58751
58911
  const mm = new MemoryMetabolismTool2(repoRoot);
@@ -58940,7 +59100,8 @@ ${lines.join("\n")}
58940
59100
  contextWindowSize: contextWindowSize ?? 0,
58941
59101
  personality: personality ? getPreset(personality) : void 0,
58942
59102
  personalityName: personality ?? void 0,
58943
- identityInjection
59103
+ identityInjection,
59104
+ environmentProvider
58944
59105
  });
58945
59106
  runner.setWorkingDirectory(repoRoot);
58946
59107
  const tools = buildTools(repoRoot, config, contextWindowSize);
@@ -61637,7 +61798,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
61637
61798
  try {
61638
61799
  if (process.platform === "win32") {
61639
61800
  try {
61640
- execSync31(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
61801
+ execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
61641
61802
  } catch {
61642
61803
  }
61643
61804
  } else {
@@ -61664,7 +61825,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
61664
61825
  if (pid > 0) {
61665
61826
  if (process.platform === "win32") {
61666
61827
  try {
61667
- execSync31(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
61828
+ execSync32(`taskkill /F /PID ${pid}`, { timeout: 5e3, stdio: "ignore" });
61668
61829
  } catch {
61669
61830
  }
61670
61831
  } else {
@@ -61681,7 +61842,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
61681
61842
  } catch {
61682
61843
  }
61683
61844
  try {
61684
- execSync31(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
61845
+ execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
61685
61846
  } catch {
61686
61847
  }
61687
61848
  const oaPath = join64(repoRoot, OA_DIR);
@@ -61695,14 +61856,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
61695
61856
  } catch (err) {
61696
61857
  if (attempt < 2) {
61697
61858
  try {
61698
- execSync31(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
61859
+ execSync32(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.3", { timeout: 3e3, stdio: "ignore" });
61699
61860
  } catch {
61700
61861
  }
61701
61862
  } else {
61702
61863
  writeContent(() => renderWarning(`Could not fully remove ${OA_DIR}/: ${err instanceof Error ? err.message : String(err)}`));
61703
61864
  if (process.platform === "win32") {
61704
61865
  try {
61705
- execSync31(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
61866
+ execSync32(`rd /s /q "${oaPath}"`, { timeout: 1e4, stdio: "ignore" });
61706
61867
  deleted = true;
61707
61868
  } catch {
61708
61869
  }