omnius 1.0.24 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -74631,12 +74631,12 @@ var require_x509_cjs = __commonJS({
74631
74631
  var require_crypto = __commonJS({
74632
74632
  "../node_modules/acme-client/src/crypto/index.js"(exports) {
74633
74633
  var net5 = __require("net");
74634
- var { promisify: promisify6 } = __require("util");
74634
+ var { promisify: promisify7 } = __require("util");
74635
74635
  var crypto14 = __require("crypto");
74636
74636
  var asn1js4 = require_build2();
74637
74637
  var x5093 = require_x509_cjs();
74638
- var randomInt2 = promisify6(crypto14.randomInt);
74639
- var generateKeyPair2 = promisify6(crypto14.generateKeyPair);
74638
+ var randomInt2 = promisify7(crypto14.randomInt);
74639
+ var generateKeyPair2 = promisify7(crypto14.generateKeyPair);
74640
74640
  x5093.cryptoProvider.set(crypto14.webcrypto);
74641
74641
  var subjectAltNameOID = "2.5.29.17";
74642
74642
  var alpnAcmeIdentifierOID = "1.3.6.1.5.5.7.1.31";
@@ -109481,9 +109481,9 @@ var require_lib = __commonJS({
109481
109481
  var require_forge2 = __commonJS({
109482
109482
  "../node_modules/acme-client/src/crypto/forge.js"(exports) {
109483
109483
  var net5 = __require("net");
109484
- var { promisify: promisify6 } = __require("util");
109484
+ var { promisify: promisify7 } = __require("util");
109485
109485
  var forge = require_lib();
109486
- var generateKeyPair2 = promisify6(forge.pki.rsa.generateKeyPair);
109486
+ var generateKeyPair2 = promisify7(forge.pki.rsa.generateKeyPair);
109487
109487
  function forgeObjectFromPem(input) {
109488
109488
  const msg = forge.pem.decode(input)[0];
109489
109489
  let result;
@@ -126709,7 +126709,7 @@ var require_mock_interceptor = __commonJS({
126709
126709
  var require_mock_client = __commonJS({
126710
126710
  "../node_modules/undici/lib/mock/mock-client.js"(exports, module) {
126711
126711
  "use strict";
126712
- var { promisify: promisify6 } = __require("node:util");
126712
+ var { promisify: promisify7 } = __require("node:util");
126713
126713
  var Client2 = require_client2();
126714
126714
  var { buildMockDispatch } = require_mock_utils();
126715
126715
  var {
@@ -126757,7 +126757,7 @@ var require_mock_client = __commonJS({
126757
126757
  this[kDispatches] = [];
126758
126758
  }
126759
126759
  async [kClose]() {
126760
- await promisify6(this[kOriginalClose])();
126760
+ await promisify7(this[kOriginalClose])();
126761
126761
  this[kConnected] = 0;
126762
126762
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
126763
126763
  }
@@ -126970,7 +126970,7 @@ var require_mock_call_history = __commonJS({
126970
126970
  var require_mock_pool = __commonJS({
126971
126971
  "../node_modules/undici/lib/mock/mock-pool.js"(exports, module) {
126972
126972
  "use strict";
126973
- var { promisify: promisify6 } = __require("node:util");
126973
+ var { promisify: promisify7 } = __require("node:util");
126974
126974
  var Pool = require_pool();
126975
126975
  var { buildMockDispatch } = require_mock_utils();
126976
126976
  var {
@@ -127018,7 +127018,7 @@ var require_mock_pool = __commonJS({
127018
127018
  this[kDispatches] = [];
127019
127019
  }
127020
127020
  async [kClose]() {
127021
- await promisify6(this[kOriginalClose])();
127021
+ await promisify7(this[kOriginalClose])();
127022
127022
  this[kConnected] = 0;
127023
127023
  this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
127024
127024
  }
@@ -515039,14 +515039,17 @@ function collectSnapshot(workingDir) {
515039
515039
  }
515040
515040
  } catch {
515041
515041
  }
515042
- let disk = { availableGB: 0, totalGB: 0, usedPercent: 0 };
515042
+ let disk = { path: workingDir || "/", availableGB: 0, usedGB: 0, totalGB: 0, usedPercent: 0 };
515043
515043
  try {
515044
515044
  const stats = statfsSync(workingDir || "/");
515045
515045
  const totalBytes = stats.blocks * stats.bsize;
515046
515046
  const availBytes = stats.bavail * stats.bsize;
515047
+ const usedBytes = totalBytes - availBytes;
515047
515048
  disk = {
515049
+ path: workingDir || "/",
515048
515050
  totalGB: Math.round(totalBytes / 1024 ** 3),
515049
515051
  availableGB: Math.round(availBytes / 1024 ** 3),
515052
+ usedGB: Math.round(usedBytes / 1024 ** 3),
515050
515053
  usedPercent: Math.round((1 - availBytes / totalBytes) * 100)
515051
515054
  };
515052
515055
  } catch {
@@ -515119,7 +515122,7 @@ function formatSnapshotForContext(snap) {
515119
515122
  const icon = snap.battery.charging ? "⚡" : snap.battery.percent < 20 ? "đŸĒĢ" : "🔋";
515120
515123
  lines.push(`Battery: ${icon} ${snap.battery.percent}% ${snap.battery.charging ? "(charging)" : "(discharging)"}`);
515121
515124
  }
515122
- lines.push(`Disk: ${snap.disk.availableGB}GB free / ${snap.disk.totalGB}GB (${snap.disk.usedPercent}% used)`);
515125
+ lines.push(`Disk: disk_available_gb=${snap.disk.availableGB} disk_used_gb=${snap.disk.usedGB} disk_total_gb=${snap.disk.totalGB} disk_used_pct=${snap.disk.usedPercent} path=${snap.disk.path}`);
515123
515126
  lines.push(`Processes: ${snap.processes.total} total | ${snap.processes.nodeCount} node | ${snap.processes.omniusSpawned} Omnius-spawned`);
515124
515127
  lines.push(`Uptime: ${snap.uptime}`);
515125
515128
  if (snap.processes.topCpu.length > 0) {
@@ -518049,9 +518052,9 @@ var init_verifierRunner = __esm({
518049
518052
  async executeTests(patch, repoRoot) {
518050
518053
  if (patch.testsToRun.length === 0)
518051
518054
  return "(no tests specified)";
518052
- const { execFile: execFile6 } = await import("node:child_process");
518053
- const { promisify: promisify6 } = await import("node:util");
518054
- const execFileAsync4 = promisify6(execFile6);
518055
+ const { execFile: execFile7 } = await import("node:child_process");
518056
+ const { promisify: promisify7 } = await import("node:util");
518057
+ const execFileAsync5 = promisify7(execFile7);
518055
518058
  const outputs = [];
518056
518059
  const workDir = this.options.workingDir || repoRoot;
518057
518060
  for (const cmd of patch.testsToRun.slice(0, 3)) {
@@ -518060,7 +518063,7 @@ var init_verifierRunner = __esm({
518060
518063
  const [bin, ...args] = parts;
518061
518064
  if (!bin)
518062
518065
  continue;
518063
- const { stdout, stderr } = await execFileAsync4(bin, args, {
518066
+ const { stdout, stderr } = await execFileAsync5(bin, args, {
518064
518067
  cwd: workDir,
518065
518068
  timeout: 6e4,
518066
518069
  maxBuffer: 1024 * 1024
@@ -556518,7 +556521,7 @@ import { EventEmitter as EventEmitter6 } from "node:events";
556518
556521
  import { randomBytes as randomBytes18 } from "node:crypto";
556519
556522
  import { URL as URL2 } from "node:url";
556520
556523
  import { loadavg, cpus as cpus2, totalmem as totalmem3, freemem as freemem3 } from "node:os";
556521
- import { existsSync as existsSync80, readFileSync as readFileSync63, writeFileSync as writeFileSync42, unlinkSync as unlinkSync13, mkdirSync as mkdirSync45, readdirSync as readdirSync25, statSync as statSync28 } from "node:fs";
556524
+ import { existsSync as existsSync80, readFileSync as readFileSync63, writeFileSync as writeFileSync42, unlinkSync as unlinkSync13, mkdirSync as mkdirSync45, readdirSync as readdirSync25, statSync as statSync28, statfsSync as statfsSync2 } from "node:fs";
556522
556525
  import { join as join96 } from "node:path";
556523
556526
  function cleanForwardHeaders(raw, targetHost) {
556524
556527
  const out = {};
@@ -556608,6 +556611,27 @@ async function collectSystemMetricsAsync() {
556608
556611
  const totalMem = totalmem3();
556609
556612
  const freeMem = freemem3();
556610
556613
  const usedMem = totalMem - freeMem;
556614
+ let disk = {
556615
+ path: process.cwd(),
556616
+ totalGB: 0,
556617
+ freeGB: 0,
556618
+ usedGB: 0,
556619
+ utilization: -1
556620
+ };
556621
+ try {
556622
+ const fs10 = statfsSync2(process.cwd());
556623
+ const totalBytes = fs10.blocks * fs10.bsize;
556624
+ const freeBytes = fs10.bavail * fs10.bsize;
556625
+ const usedBytes = totalBytes - freeBytes;
556626
+ disk = {
556627
+ path: process.cwd(),
556628
+ totalGB: Math.round(totalBytes / 1024 ** 3 * 10) / 10,
556629
+ freeGB: Math.round(freeBytes / 1024 ** 3 * 10) / 10,
556630
+ usedGB: Math.round(usedBytes / 1024 ** 3 * 10) / 10,
556631
+ utilization: totalBytes > 0 ? Math.round(usedBytes / totalBytes * 100) : -1
556632
+ };
556633
+ } catch {
556634
+ }
556611
556635
  const gpu = {
556612
556636
  available: false,
556613
556637
  name: "",
@@ -556650,6 +556674,7 @@ async function collectSystemMetricsAsync() {
556650
556674
  usedGB: Math.round(usedMem / 1024 ** 3 * 10) / 10,
556651
556675
  utilization: Math.round(usedMem / totalMem * 100)
556652
556676
  },
556677
+ disk,
556653
556678
  gpu,
556654
556679
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
556655
556680
  };
@@ -561458,6 +561483,60 @@ var init_braille_spinner = __esm({
561458
561483
  }
561459
561484
  });
561460
561485
 
561486
+ // packages/cli/src/tui/disk-monitor.ts
561487
+ import { execFile as execFile5 } from "node:child_process";
561488
+ import { promisify as promisify5 } from "node:util";
561489
+ function unavailableDiskMetrics(path11 = process.cwd()) {
561490
+ return {
561491
+ path: path11,
561492
+ mount: "",
561493
+ totalGB: 0,
561494
+ usedGB: 0,
561495
+ freeGB: 0,
561496
+ util: -1
561497
+ };
561498
+ }
561499
+ async function collectDiskMetrics(path11 = process.cwd()) {
561500
+ if (process.platform === "win32") return unavailableDiskMetrics(path11);
561501
+ try {
561502
+ const { stdout } = await execFileAsync4("df", ["-Pk", path11], {
561503
+ encoding: "utf8",
561504
+ timeout: 3e3,
561505
+ maxBuffer: 128 * 1024
561506
+ });
561507
+ const lines = stdout.trim().split("\n").filter(Boolean);
561508
+ const line = lines[lines.length - 1];
561509
+ if (!line) return unavailableDiskMetrics(path11);
561510
+ const parts = line.trim().split(/\s+/);
561511
+ if (parts.length < 6) return unavailableDiskMetrics(path11);
561512
+ const totalKB = Number(parts[1] ?? 0);
561513
+ const usedKB = Number(parts[2] ?? 0);
561514
+ const freeKB = Number(parts[3] ?? 0);
561515
+ if (!Number.isFinite(totalKB) || totalKB <= 0) return unavailableDiskMetrics(path11);
561516
+ const totalGB = totalKB / (1024 * 1024);
561517
+ const usedGB = usedKB / (1024 * 1024);
561518
+ const freeGB = freeKB / (1024 * 1024);
561519
+ const util2 = Math.max(0, Math.min(100, Math.round(usedKB / totalKB * 100)));
561520
+ return {
561521
+ path: path11,
561522
+ mount: parts.slice(5).join(" "),
561523
+ totalGB: Math.round(totalGB * 10) / 10,
561524
+ usedGB: Math.round(usedGB * 10) / 10,
561525
+ freeGB: Math.round(freeGB * 10) / 10,
561526
+ util: util2
561527
+ };
561528
+ } catch {
561529
+ return unavailableDiskMetrics(path11);
561530
+ }
561531
+ }
561532
+ var execFileAsync4;
561533
+ var init_disk_monitor = __esm({
561534
+ "packages/cli/src/tui/disk-monitor.ts"() {
561535
+ "use strict";
561536
+ execFileAsync4 = promisify5(execFile5);
561537
+ }
561538
+ });
561539
+
561461
561540
  // packages/cli/src/tui/system-metrics.ts
561462
561541
  var system_metrics_exports = {};
561463
561542
  __export(system_metrics_exports, {
@@ -561575,6 +561654,7 @@ async function collectGpuMetrics() {
561575
561654
  }
561576
561655
  function getInstantSnapshot() {
561577
561656
  const cr = collectCpuRam();
561657
+ const disk = unavailableDiskMetrics();
561578
561658
  return {
561579
561659
  source: "local",
561580
561660
  hardware: {
@@ -561588,7 +561668,12 @@ function getInstantSnapshot() {
561588
561668
  vramTotalMB: 0,
561589
561669
  memUtil: cr.memUtil,
561590
561670
  memUsedGB: cr.memUsedGB,
561591
- memTotalGB: cr.memTotalGB
561671
+ memTotalGB: cr.memTotalGB,
561672
+ diskUtil: disk.util,
561673
+ diskUsedGB: disk.usedGB,
561674
+ diskTotalGB: disk.totalGB,
561675
+ diskFreeGB: disk.freeGB,
561676
+ diskPath: disk.path
561592
561677
  },
561593
561678
  network: { rxBytesPerSec: 0, txBytesPerSec: 0 }
561594
561679
  };
@@ -561635,8 +561720,9 @@ function collectCpuRam() {
561635
561720
  }
561636
561721
  async function collectLocalMetrics() {
561637
561722
  const cpuRam = collectCpuRam();
561638
- const [gpu, network] = await Promise.all([
561723
+ const [gpu, disk, network] = await Promise.all([
561639
561724
  collectGpuMetrics(),
561725
+ collectDiskMetrics(),
561640
561726
  collectNetworkMetrics()
561641
561727
  ]);
561642
561728
  return {
@@ -561652,7 +561738,12 @@ async function collectLocalMetrics() {
561652
561738
  vramTotalMB: gpu.vramTotalMB,
561653
561739
  memUtil: cpuRam.memUtil,
561654
561740
  memUsedGB: cpuRam.memUsedGB,
561655
- memTotalGB: cpuRam.memTotalGB
561741
+ memTotalGB: cpuRam.memTotalGB,
561742
+ diskUtil: disk.util,
561743
+ diskUsedGB: disk.usedGB,
561744
+ diskTotalGB: disk.totalGB,
561745
+ diskFreeGB: disk.freeGB,
561746
+ diskPath: disk.path
561656
561747
  },
561657
561748
  network
561658
561749
  };
@@ -561661,6 +561752,7 @@ var _lastNetSnapshot, _nvidiaSmiAvailable, _cpuPrevSnapshot, SystemMetricsCollec
561661
561752
  var init_system_metrics = __esm({
561662
561753
  "packages/cli/src/tui/system-metrics.ts"() {
561663
561754
  "use strict";
561755
+ init_disk_monitor();
561664
561756
  _lastNetSnapshot = null;
561665
561757
  _nvidiaSmiAvailable = null;
561666
561758
  _cpuPrevSnapshot = null;
@@ -561721,7 +561813,12 @@ var init_system_metrics = __esm({
561721
561813
  vramTotalMB: hw.vramTotalMB ?? 0,
561722
561814
  memUtil: hw.memUtil ?? -1,
561723
561815
  memUsedGB: hw.memUsedGB ?? 0,
561724
- memTotalGB: hw.memTotalGB ?? 0
561816
+ memTotalGB: hw.memTotalGB ?? 0,
561817
+ diskUtil: hw.diskUtil ?? -1,
561818
+ diskUsedGB: hw.diskUsedGB ?? 0,
561819
+ diskTotalGB: hw.diskTotalGB ?? 0,
561820
+ diskFreeGB: hw.diskFreeGB ?? 0,
561821
+ diskPath: hw.diskPath ?? ""
561725
561822
  };
561726
561823
  this._latest = {
561727
561824
  source: "remote",
@@ -563781,7 +563878,12 @@ var init_status_bar = __esm({
563781
563878
  vramTotalMB: metrics2.vramTotalMB ?? 0,
563782
563879
  memUtil: metrics2.memUtil,
563783
563880
  memTotalGB: metrics2.memTotalGB ?? 0,
563784
- memUsedGB: metrics2.memUsedGB ?? 0
563881
+ memUsedGB: metrics2.memUsedGB ?? 0,
563882
+ diskUtil: metrics2.diskUtil ?? -1,
563883
+ diskUsedGB: metrics2.diskUsedGB ?? 0,
563884
+ diskTotalGB: metrics2.diskTotalGB ?? 0,
563885
+ diskFreeGB: metrics2.diskFreeGB ?? 0,
563886
+ diskPath: metrics2.diskPath ?? ""
563785
563887
  });
563786
563888
  }
563787
563889
  /** Clear remote metrics and switch back to local collection */
@@ -563839,7 +563941,12 @@ var init_status_bar = __esm({
563839
563941
  gpuUtil: data.gpu?.available ? data.gpu.utilization ?? 0 : -1,
563840
563942
  gpuName: data.gpu?.name ?? "",
563841
563943
  vramUtil: data.gpu?.available ? data.gpu.vramUtilization ?? 0 : -1,
563842
- memUtil: data.memory?.utilization ?? 0
563944
+ memUtil: data.memory?.utilization ?? 0,
563945
+ diskUtil: data.disk?.utilization ?? -1,
563946
+ diskUsedGB: data.disk?.usedGB ?? 0,
563947
+ diskTotalGB: data.disk?.totalGB ?? 0,
563948
+ diskFreeGB: data.disk?.freeGB ?? 0,
563949
+ diskPath: data.disk?.path ?? ""
563843
563950
  });
563844
563951
  }
563845
563952
  } catch {
@@ -563938,7 +564045,12 @@ var init_status_bar = __esm({
563938
564045
  vramTotalMB: m2.gpu?.vramTotalMB ?? 0,
563939
564046
  memUtil: m2.memory?.utilization ?? 0,
563940
564047
  memTotalGB: m2.memory?.totalGB ?? 0,
563941
- memUsedGB: m2.memory?.usedGB ?? 0
564048
+ memUsedGB: m2.memory?.usedGB ?? 0,
564049
+ diskUtil: m2.disk?.utilization ?? -1,
564050
+ diskTotalGB: m2.disk?.totalGB ?? 0,
564051
+ diskUsedGB: m2.disk?.usedGB ?? 0,
564052
+ diskFreeGB: m2.disk?.freeGB ?? 0,
564053
+ diskPath: m2.disk?.path ?? ""
563942
564054
  });
563943
564055
  return;
563944
564056
  }
@@ -565407,6 +565519,14 @@ ${CONTENT_BG_SEQ}`);
565407
565519
  hwExpW += 5 + `${rm3.memUtil}%`.length + memDetail.length;
565408
565520
  hwCompW += 5 + `${rm3.memUtil}%`.length;
565409
565521
  }
565522
+ if (rm3.diskUtil >= 0) {
565523
+ const diskColor = rm3.diskUtil > 90 ? c3.red : rm3.diskUtil > 75 ? c3.yellow : c3.green;
565524
+ const diskDetail = rm3.diskTotalGB > 0 ? ` (${rm3.diskFreeGB.toFixed(rm3.diskFreeGB < 10 ? 1 : 0)}GB free)` : "";
565525
+ hwExpStr += ` Disk ${diskColor(rm3.diskUtil + "%")}${c3.dim(diskDetail)}`;
565526
+ hwCompStr += ` Disk ${diskColor(rm3.diskUtil + "%")}`;
565527
+ hwExpW += 6 + `${rm3.diskUtil}%`.length + diskDetail.length;
565528
+ hwCompW += 6 + `${rm3.diskUtil}%`.length;
565529
+ }
565410
565530
  if (rm3.gpuUtil >= 0) {
565411
565531
  const gpuColor = rm3.gpuUtil > 80 ? c3.red : rm3.gpuUtil > 50 ? c3.yellow : c3.green;
565412
565532
  const gpuNameShort = rm3.gpuName ? ` (${rm3.gpuName.slice(0, 20)})` : "";
@@ -567849,7 +567969,7 @@ __export(setup_exports, {
567849
567969
  });
567850
567970
  import * as readline from "node:readline";
567851
567971
  import { execSync as execSync50, spawn as spawn25, exec as exec4 } from "node:child_process";
567852
- import { promisify as promisify5 } from "node:util";
567972
+ import { promisify as promisify6 } from "node:util";
567853
567973
  import { existsSync as existsSync86, writeFileSync as writeFileSync46, readFileSync as readFileSync70, appendFileSync as appendFileSync4, mkdirSync as mkdirSync49 } from "node:fs";
567854
567974
  import { join as join103 } from "node:path";
567855
567975
  import { homedir as homedir30, platform as platform4 } from "node:os";
@@ -570231,7 +570351,7 @@ var init_setup = __esm({
570231
570351
  init_config();
570232
570352
  init_dist();
570233
570353
  init_tui_select();
570234
- execAsync2 = promisify5(exec4);
570354
+ execAsync2 = promisify6(exec4);
570235
570355
  OMNIUS_FIRST_RUN_BANNER = [
570236
570356
  " ░▒▓██████▓▒░░▒▓██████████████▓▒░░▒▓███████▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ ",
570237
570357
  "░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ",
@@ -579756,6 +579876,7 @@ import {
579756
579876
  writeFileSync as writeFileSync50,
579757
579877
  mkdirSync as mkdirSync53,
579758
579878
  readdirSync as readdirSync30,
579879
+ lstatSync,
579759
579880
  statSync as statSync34,
579760
579881
  rmSync as rmSync3,
579761
579882
  appendFileSync as appendFileSync5
@@ -586370,8 +586491,9 @@ function renderImagePresetDetail(prefix, text) {
586370
586491
  renderInfo(`${prefix}${first2}`);
586371
586492
  for (const line of rest) renderInfo(`${" ".repeat(prefix.length)}${line}`);
586372
586493
  }
586373
- function renderImageModelList() {
586494
+ async function renderImageModelList(ctx3) {
586374
586495
  const specs = detectSystemSpecs();
586496
+ const ollamaSizes = ctx3 ? await fetchOllamaModelSizes(ctx3).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
586375
586497
  const hardware = `${specs.totalRamGB.toFixed(0)}GB RAM` + (specs.gpuVramGB > 0 ? ` + ${specs.gpuVramGB.toFixed(0)}GB VRAM (${specs.gpuName || "NVIDIA GPU"})` : " + no NVIDIA VRAM detected");
586376
586498
  renderInfo(`Image models for this hardware: ${hardware}`);
586377
586499
  renderInfo("Fit legend: 85+ excellent, 60+ comfortable, 40+ offload/quantized, below 40 heavy/cloud.");
@@ -586389,7 +586511,9 @@ function renderImageModelList() {
586389
586511
  for (const preset of presets) {
586390
586512
  const fit2 = rateImagePresetForHardware(preset, specs);
586391
586513
  const primary = category === "Primary hyper-realistic baseline" ? c3.cyan(" ★") : "";
586392
- renderInfo(`${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${primary}`);
586514
+ const disk = ctx3 ? imageModelDiskStats(ctx3, preset, ollamaSizes) : { downloaded: false, bytes: 0, paths: [] };
586515
+ const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
586516
+ renderInfo(`${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${primary}${diskInfo}`);
586393
586517
  renderInfo(` id: ${preset.id}`);
586394
586518
  renderInfo(` type: ${preset.backend} ¡ ${preset.sizeClass ?? "unknown size"} ¡ ${fit2.label}`);
586395
586519
  renderImagePresetDetail(" quality: ", preset.quality ?? preset.note);
@@ -586412,6 +586536,32 @@ function cacheCandidatePaths(root, model) {
586412
586536
  join110(root, "cache", "huggingface", "hub", slug)
586413
586537
  ];
586414
586538
  }
586539
+ function directorySizeBytes2(path11, seen = /* @__PURE__ */ new Set()) {
586540
+ try {
586541
+ const stat5 = lstatSync(path11);
586542
+ if (stat5.isSymbolicLink()) return 0;
586543
+ if (stat5.isFile()) return stat5.size;
586544
+ if (!stat5.isDirectory()) return 0;
586545
+ const realKey = `${stat5.dev}:${stat5.ino}`;
586546
+ if (seen.has(realKey)) return 0;
586547
+ seen.add(realKey);
586548
+ let total = 0;
586549
+ for (const entry of readdirSync30(path11)) {
586550
+ total += directorySizeBytes2(join110(path11, entry), seen);
586551
+ }
586552
+ return total;
586553
+ } catch {
586554
+ return 0;
586555
+ }
586556
+ }
586557
+ function cachedModelDiskStats(root, model) {
586558
+ const paths = cacheCandidatePaths(root, model).filter((path11) => existsSync96(path11));
586559
+ const bytes = paths.reduce((sum, path11) => sum + directorySizeBytes2(path11), 0);
586560
+ return { downloaded: paths.length > 0, bytes, paths };
586561
+ }
586562
+ function downloadedModelSuffix(stats) {
586563
+ return stats.downloaded ? ` ¡ downloaded ${formatFileSize(stats.bytes)}` : "";
586564
+ }
586415
586565
  function removeCachedModelPaths(root, model) {
586416
586566
  const removed = [];
586417
586567
  for (const path11 of cacheCandidatePaths(root, model)) {
@@ -586424,6 +586574,37 @@ function removeCachedModelPaths(root, model) {
586424
586574
  function ollamaApiBase(ctx3) {
586425
586575
  return String(ctx3.config.backendUrl || "http://localhost:11434").replace(/\/v1\/?$/, "").replace(/\/$/, "");
586426
586576
  }
586577
+ async function fetchOllamaModelSizes(ctx3) {
586578
+ const sizes = /* @__PURE__ */ new Map();
586579
+ const resp = await fetch(`${ollamaApiBase(ctx3)}/api/tags`, {
586580
+ signal: AbortSignal.timeout(5e3)
586581
+ });
586582
+ if (!resp.ok) return sizes;
586583
+ const data = await resp.json().catch(() => null);
586584
+ for (const entry of data?.models ?? []) {
586585
+ const size = Number(entry.size ?? 0);
586586
+ if (!Number.isFinite(size) || size <= 0) continue;
586587
+ for (const raw of [entry.name, entry.model]) {
586588
+ if (!raw) continue;
586589
+ sizes.set(raw, size);
586590
+ sizes.set(raw.replace(/:latest$/, ""), size);
586591
+ }
586592
+ }
586593
+ return sizes;
586594
+ }
586595
+ function ollamaModelDiskStats(model, sizes) {
586596
+ const bytes = sizes.get(model) ?? sizes.get(`${model}:latest`) ?? sizes.get(model.replace(/:latest$/, "")) ?? 0;
586597
+ return { downloaded: bytes > 0, bytes, paths: [] };
586598
+ }
586599
+ function imageModelDiskStats(ctx3, preset, ollamaSizes) {
586600
+ if (preset.backend === "ollama") return ollamaModelDiskStats(preset.id, ollamaSizes);
586601
+ if (preset.backend === "diffusers") return cachedModelDiskStats(imageGenerationDir(ctx3.repoRoot), preset.id);
586602
+ return { downloaded: false, bytes: 0, paths: [] };
586603
+ }
586604
+ function audioModelDiskStats(ctx3, preset) {
586605
+ if (preset.backend === "project") return { downloaded: false, bytes: 0, paths: [] };
586606
+ return cachedModelDiskStats(audioGenerationDir(ctx3.repoRoot), preset.id);
586607
+ }
586427
586608
  async function deleteOllamaWeights(ctx3, model) {
586428
586609
  const resp = await fetch(`${ollamaApiBase(ctx3)}/api/delete`, {
586429
586610
  method: "DELETE",
@@ -586453,19 +586634,23 @@ async function deleteImageModelWeights(ctx3, preset) {
586453
586634
  async function showImageModelsMenu(ctx3, hasLocal) {
586454
586635
  const settings = resolveSettings(ctx3.repoRoot);
586455
586636
  const specs = detectSystemSpecs();
586637
+ const ollamaSizes = await fetchOllamaModelSizes(ctx3).catch(() => /* @__PURE__ */ new Map());
586638
+ const buildModelItem = (preset) => {
586639
+ const fit2 = rateImagePresetForHardware(preset, specs);
586640
+ const disk = imageModelDiskStats(ctx3, preset, ollamaSizes);
586641
+ const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
586642
+ return {
586643
+ key: `model:${preset.id}`,
586644
+ label: `${downloaded}${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
586645
+ detail: `${fit2.score}/100 ${fit2.label} ¡ ${preset.category ?? preset.backend} ¡ ${preset.sizeClass ?? preset.id}${downloadedModelSuffix(disk)}`
586646
+ };
586647
+ };
586456
586648
  const items = [
586457
586649
  { key: "setup:ollama", label: "Setup Ollama", detail: "Pull x/z-image-turbo or x/flux2-klein" },
586458
586650
  { key: "setup:diffusers", label: "Setup Diffusers", detail: "Auto-installs SDXL Turbo under .omnius/image-gen/.venv" },
586459
586651
  { key: "setup:sdcpp", label: "Setup stable-diffusion.cpp", detail: "CPU/GGUF/checkpoint route" },
586460
586652
  { key: "hdr:models", label: selectColors.dim("─── Models ───") },
586461
- ...IMAGE_GENERATION_MODEL_PRESETS.map((preset) => {
586462
- const fit2 = rateImagePresetForHardware(preset, specs);
586463
- return {
586464
- key: `model:${preset.id}`,
586465
- label: `${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
586466
- detail: `${fit2.score}/100 ${fit2.label} ¡ ${preset.category ?? preset.backend} ¡ ${preset.sizeClass ?? preset.id}`
586467
- };
586468
- })
586653
+ ...IMAGE_GENERATION_MODEL_PRESETS.map(buildModelItem)
586469
586654
  ];
586470
586655
  const result = await tuiSelect({
586471
586656
  items,
@@ -586491,6 +586676,11 @@ async function showImageModelsMenu(ctx3, hasLocal) {
586491
586676
  }
586492
586677
  deleteImageModelWeights(ctx3, preset).then((messages2) => {
586493
586678
  for (const message2 of messages2) renderInfo(message2);
586679
+ if (preset.backend === "ollama") {
586680
+ ollamaSizes.delete(preset.id);
586681
+ ollamaSizes.delete(`${preset.id}:latest`);
586682
+ }
586683
+ Object.assign(item, buildModelItem(preset));
586494
586684
  done(false);
586495
586685
  }).catch((err) => {
586496
586686
  renderError(`Image weight delete failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -586548,7 +586738,7 @@ async function handleImageCommand(ctx3, arg, hasLocal) {
586548
586738
  return "handled";
586549
586739
  }
586550
586740
  if (parsed.subcommand === "models" || parsed.subcommand === "list") {
586551
- renderImageModelList();
586741
+ await renderImageModelList(ctx3);
586552
586742
  return "handled";
586553
586743
  }
586554
586744
  if (parsed.subcommand === "setup") {
@@ -586683,7 +586873,7 @@ function rateAudioPresetForHardware(preset, specs) {
586683
586873
  function audioFitIcon(score) {
586684
586874
  return imageFitIcon(score);
586685
586875
  }
586686
- function renderAudioModelList(kind) {
586876
+ async function renderAudioModelList(ctx3, kind) {
586687
586877
  const specs = detectSystemSpecs();
586688
586878
  const title = kind === "music" ? "Music" : "Sound";
586689
586879
  const hardware = `${specs.totalRamGB.toFixed(0)}GB RAM` + (specs.gpuVramGB > 0 ? ` + ${specs.gpuVramGB.toFixed(0)}GB VRAM (${specs.gpuName || "NVIDIA GPU"})` : " + no NVIDIA VRAM detected");
@@ -586706,7 +586896,9 @@ function renderAudioModelList(kind) {
586706
586896
  renderInfo(c3.bold(category));
586707
586897
  for (const preset of presets) {
586708
586898
  const fit2 = rateAudioPresetForHardware(preset, specs);
586709
- renderInfo(`${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}`);
586899
+ const disk = audioModelDiskStats(ctx3, preset);
586900
+ const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
586901
+ renderInfo(`${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`);
586710
586902
  renderInfo(` id: ${preset.id}`);
586711
586903
  renderInfo(` type: ${preset.backend} ¡ ${preset.sizeClass} ¡ ${fit2.label}`);
586712
586904
  renderImagePresetDetail(" quality: ", preset.quality);
@@ -586728,6 +586920,16 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
586728
586920
  const specs = detectSystemSpecs();
586729
586921
  const activeModel = activeAudioModel(settings, kind);
586730
586922
  const title = kind === "music" ? "Music Generation" : "Sound Generation";
586923
+ const buildModelItem = (preset) => {
586924
+ const fit2 = rateAudioPresetForHardware(preset, specs);
586925
+ const disk = audioModelDiskStats(ctx3, preset);
586926
+ const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
586927
+ return {
586928
+ key: `model:${preset.id}`,
586929
+ label: `${downloaded}${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
586930
+ detail: `${fit2.label} ¡ ${preset.category} ¡ ${preset.sizeClass}${downloadedModelSuffix(disk)}`
586931
+ };
586932
+ };
586731
586933
  const setupItems = kind === "music" ? [
586732
586934
  { key: "setup:transformers", label: "Setup Transformers", detail: "Default MusicGen path; avoids AudioCraft/PyAV headers" },
586733
586935
  { key: "setup:audiocraft", label: "Setup AudioCraft", detail: "Optional MusicGen/AudioGen upstream runtime" },
@@ -586742,14 +586944,7 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
586742
586944
  const items = [
586743
586945
  ...setupItems,
586744
586946
  { key: "hdr:models", label: selectColors.dim("─── Models ───") },
586745
- ...AUDIO_GENERATION_MODEL_PRESETS.filter((preset) => preset.kind === kind).map((preset) => {
586746
- const fit2 = rateAudioPresetForHardware(preset, specs);
586747
- return {
586748
- key: `model:${preset.id}`,
586749
- label: `${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
586750
- detail: `${fit2.label} ¡ ${preset.category} ¡ ${preset.sizeClass}`
586751
- };
586752
- })
586947
+ ...AUDIO_GENERATION_MODEL_PRESETS.filter((preset) => preset.kind === kind).map(buildModelItem)
586753
586948
  ];
586754
586949
  const result = await tuiSelect({
586755
586950
  items,
@@ -586775,6 +586970,7 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
586775
586970
  }
586776
586971
  deleteAudioModelWeights(ctx3, preset).then((messages2) => {
586777
586972
  for (const message2 of messages2) renderInfo(message2);
586973
+ Object.assign(item, buildModelItem(preset));
586778
586974
  done(false);
586779
586975
  }).catch((err) => {
586780
586976
  renderError(`${kind} weight delete failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -586835,7 +587031,7 @@ async function handleAudioGenerationCommand(ctx3, arg, hasLocal, kind) {
586835
587031
  return "handled";
586836
587032
  }
586837
587033
  if (parsed.subcommand === "models" || parsed.subcommand === "list") {
586838
- renderAudioModelList(kind);
587034
+ await renderAudioModelList(ctx3, kind);
586839
587035
  return "handled";
586840
587036
  }
586841
587037
  if (parsed.subcommand === "setup") {
@@ -587355,7 +587551,9 @@ async function showModelPicker(ctx3, local = false) {
587355
587551
  function formatFileSize(bytes) {
587356
587552
  if (bytes < 1024) return `${bytes}B`;
587357
587553
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}KB`;
587358
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
587554
+ if (bytes < 1024 ** 3) return `${(bytes / 1024 ** 2).toFixed(1)}MB`;
587555
+ if (bytes < 1024 ** 4) return `${(bytes / 1024 ** 3).toFixed(1)}GB`;
587556
+ return `${(bytes / 1024 ** 4).toFixed(1)}TB`;
587359
587557
  }
587360
587558
  async function handleVoiceMenu(ctx3, save2, hasLocal) {
587361
587559
  const modeLabels = {
@@ -597926,7 +598124,7 @@ var init_vision_ingress = __esm({
597926
598124
  });
597927
598125
 
597928
598126
  // packages/cli/src/tui/telegram-bridge.ts
597929
- import { mkdirSync as mkdirSync60, existsSync as existsSync106, unlinkSync as unlinkSync21, readdirSync as readdirSync36, statSync as statSync36, readFileSync as readFileSync87, writeFileSync as writeFileSync57 } from "node:fs";
598127
+ import { mkdirSync as mkdirSync60, existsSync as existsSync106, unlinkSync as unlinkSync21, readdirSync as readdirSync36, statSync as statSync36, statfsSync as statfsSync3, readFileSync as readFileSync87, writeFileSync as writeFileSync57 } from "node:fs";
597930
598128
  import { join as join121, resolve as resolve39, basename as basename23, relative as relative13, isAbsolute as isAbsolute7, extname as extname15 } from "node:path";
597931
598129
  import { writeFile as writeFileAsync } from "node:fs/promises";
597932
598130
  import { createHash as createHash19, randomInt } from "node:crypto";
@@ -598194,12 +598392,28 @@ function buildTelegramRuntimeContext(now = /* @__PURE__ */ new Date(), repoRoot)
598194
598392
  timeZoneName: "short"
598195
598393
  }).format(now);
598196
598394
  const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || process.env["TZ"] || "system";
598395
+ let diskLine = "";
598396
+ if (repoRoot) {
598397
+ try {
598398
+ const stats = statfsSync3(repoRoot);
598399
+ const totalBytes = stats.blocks * stats.bsize;
598400
+ const freeBytes = stats.bavail * stats.bsize;
598401
+ const usedBytes = totalBytes - freeBytes;
598402
+ const totalGB = Math.round(totalBytes / 1024 ** 3);
598403
+ const freeGB = Math.round(freeBytes / 1024 ** 3);
598404
+ const usedGB = Math.round(usedBytes / 1024 ** 3);
598405
+ const usedPct = totalBytes > 0 ? Math.round(usedBytes / totalBytes * 100) : 0;
598406
+ diskLine = `Disk: disk_available_gb=${freeGB} disk_used_gb=${usedGB} disk_total_gb=${totalGB} disk_used_pct=${usedPct} path=${repoRoot}`;
598407
+ } catch {
598408
+ }
598409
+ }
598197
598410
  return [
598198
598411
  `Current date: ${date}`,
598199
598412
  `Current time: ${time}`,
598200
598413
  `Current ISO timestamp: ${now.toISOString()}`,
598201
598414
  `Timezone: ${timezone}`,
598202
- repoRoot ? `Working directory: ${repoRoot}` : ""
598415
+ repoRoot ? `Working directory: ${repoRoot}` : "",
598416
+ diskLine
598203
598417
  ].filter(Boolean).join("\n");
598204
598418
  }
598205
598419
  function telegramSessionIdFromKey(sessionKey) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.24",
9
+ "version": "1.0.25",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",