omnius 1.0.618 → 1.0.620

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
@@ -204044,7 +204044,7 @@ var require_snapshot_recorder = __commonJS({
204044
204044
  "../node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
204045
204045
  "use strict";
204046
204046
  var { writeFile: writeFile27, readFile: readFile27, mkdir: mkdir24 } = __require("node:fs/promises");
204047
- var { dirname: dirname67, resolve: resolve88 } = __require("node:path");
204047
+ var { dirname: dirname68, resolve: resolve88 } = __require("node:path");
204048
204048
  var { setTimeout: setTimeout3, clearTimeout: clearTimeout3 } = __require("node:timers");
204049
204049
  var { InvalidArgumentError, UndiciError } = require_errors2();
204050
204050
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -204275,7 +204275,7 @@ var require_snapshot_recorder = __commonJS({
204275
204275
  throw new InvalidArgumentError("Snapshot path is required");
204276
204276
  }
204277
204277
  const resolvedPath = resolve88(path16);
204278
- await mkdir24(dirname67(resolvedPath), { recursive: true });
204278
+ await mkdir24(dirname68(resolvedPath), { recursive: true });
204279
204279
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
204280
204280
  hash: hash2,
204281
204281
  snapshot
@@ -317937,15 +317937,15 @@ var init_ls = __esm({
317937
317937
  });
317938
317938
 
317939
317939
  // ../node_modules/@helia/unixfs/dist/src/commands/mkdir.js
317940
- async function mkdir6(parentCid, dirname67, blockstore, options2 = {}) {
317941
- if (dirname67.includes("/")) {
317940
+ async function mkdir6(parentCid, dirname68, blockstore, options2 = {}) {
317941
+ if (dirname68.includes("/")) {
317942
317942
  throw new InvalidParametersError4("Path must not have slashes");
317943
317943
  }
317944
317944
  const entry = await exporter2(parentCid, blockstore, options2);
317945
317945
  if (entry.type !== "directory") {
317946
317946
  throw new NotADirectoryError(`${parentCid.toString()} was not a UnixFS directory`);
317947
317947
  }
317948
- log16("creating %s", dirname67);
317948
+ log16("creating %s", dirname68);
317949
317949
  const metadata = new UnixFS({
317950
317950
  type: "directory",
317951
317951
  mode: options2.mode,
@@ -317961,9 +317961,9 @@ async function mkdir6(parentCid, dirname67, blockstore, options2 = {}) {
317961
317961
  await blockstore.put(emptyDirCid, buf);
317962
317962
  const [directory, pblink] = await Promise.all([
317963
317963
  cidToDirectory(parentCid, blockstore, options2),
317964
- cidToPBLink(emptyDirCid, dirname67, blockstore, options2)
317964
+ cidToPBLink(emptyDirCid, dirname68, blockstore, options2)
317965
317965
  ]);
317966
- log16("adding empty dir called %s to %c", dirname67, parentCid);
317966
+ log16("adding empty dir called %s to %c", dirname68, parentCid);
317967
317967
  const result = await addLink(directory, pblink, blockstore, {
317968
317968
  ...options2,
317969
317969
  allowOverwriting: options2.force
@@ -318462,8 +318462,8 @@ var init_unixfs2 = __esm({
318462
318462
  async *ls(cid, options2 = {}) {
318463
318463
  yield* ls(cid, this.components.blockstore, options2);
318464
318464
  }
318465
- async mkdir(cid, dirname67, options2 = {}) {
318466
- return mkdir6(cid, dirname67, this.components.blockstore, options2);
318465
+ async mkdir(cid, dirname68, options2 = {}) {
318466
+ return mkdir6(cid, dirname68, this.components.blockstore, options2);
318467
318467
  }
318468
318468
  async rm(cid, path16, options2 = {}) {
318469
318469
  return rm3(cid, path16, this.components.blockstore, options2);
@@ -566258,7 +566258,7 @@ var require_path_browserify = __commonJS({
566258
566258
  _makeLong: function _makeLong(path16) {
566259
566259
  return path16;
566260
566260
  },
566261
- dirname: function dirname67(path16) {
566261
+ dirname: function dirname68(path16) {
566262
566262
  assertPath(path16);
566263
566263
  if (path16.length === 0) return ".";
566264
566264
  var code8 = path16.charCodeAt(0);
@@ -602245,9 +602245,9 @@ function whisperModel(engineId, id2, label) {
602245
602245
  languages: ["multilingual"],
602246
602246
  capabilities: whisperCapabilities,
602247
602247
  resources: {
602248
- cpuSupported: engineId === "transcribe-cli",
602248
+ cpuSupported: false,
602249
602249
  architectures: ["x64", "arm64"],
602250
- notes: engineId === "transcribe-cli" ? ["Managed transcribe-cli runtime; implementation may use faster-whisper or ONNX."] : ["CUDA is required by Omnius unless an explicit local override is configured."]
602250
+ notes: ["CUDA is required by Omnius unless an explicit local override is configured."]
602251
602251
  }
602252
602252
  };
602253
602253
  }
@@ -602300,7 +602300,7 @@ var init_registry2 = __esm({
602300
602300
  VIBEVOICE_ASR_SOURCE_REVISION = "94da20d98b2fa7688e9cbfaf7692ddb4954f7600";
602301
602301
  VIBEVOICE_ASR_QWEN_TOKENIZER_REVISION = "d149729398750b98c0af14eb82c78cfe92750796";
602302
602302
  VIBEVOICE_ASR_WEIGHTS_BYTES = 17348198410;
602303
- NEMOTRON_DISABLED_REASON = "Nemotron is catalogued but its legacy self-installing worker is disabled until it is migrated to the managed fail-closed runtime.";
602303
+ NEMOTRON_DISABLED_REASON = "Nemotron is unavailable because its managed CUDA runtime could not be activated.";
602304
602304
  whisperCapabilities = Object.freeze({
602305
602305
  file: true,
602306
602306
  pcmStream: true,
@@ -602325,15 +602325,6 @@ var init_registry2 = __esm({
602325
602325
  setupMode: "managed",
602326
602326
  models: whisperModels("openai-whisper")
602327
602327
  },
602328
- {
602329
- id: "transcribe-cli",
602330
- label: "transcribe-cli",
602331
- detail: "Managed faster-whisper/ONNX bridge for live and file transcription",
602332
- provider: "transcribe-cli",
602333
- runtime: "node",
602334
- setupMode: "managed",
602335
- models: whisperModels("transcribe-cli")
602336
- },
602337
602328
  {
602338
602329
  id: "nemotron-streaming",
602339
602330
  label: "NVIDIA Nemotron Speech Streaming",
@@ -602341,8 +602332,6 @@ var init_registry2 = __esm({
602341
602332
  provider: "NVIDIA",
602342
602333
  runtime: "python",
602343
602334
  setupMode: "managed",
602344
- availability: "disabled",
602345
- unavailableReason: NEMOTRON_DISABLED_REASON,
602346
602335
  models: [
602347
602336
  {
602348
602337
  id: "nemotron-speech-streaming-en-0.6b",
@@ -602423,8 +602412,10 @@ var init_registry2 = __esm({
602423
602412
  ENGINE_ALIASES = {
602424
602413
  whisper: "openai-whisper",
602425
602414
  openai_whisper: "openai-whisper",
602426
- faster_whisper: "transcribe-cli",
602427
- transcribe_cli: "transcribe-cli",
602415
+ transcribe_cli: "openai-whisper",
602416
+ transcribe_cli_runtime: "openai-whisper",
602417
+ "transcribe-cli": "openai-whisper",
602418
+ faster_whisper: "openai-whisper",
602428
602419
  nemotron: "nemotron-streaming",
602429
602420
  vibevoice: "vibevoice-transformers",
602430
602421
  vibevoice_asr: "vibevoice-transformers"
@@ -633848,8 +633839,8 @@ var init_adversaryStream = __esm({
633848
633839
  return;
633849
633840
  try {
633850
633841
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120, existsSync: existsSync184 } = __require("node:fs");
633851
- const { dirname: dirname67 } = __require("node:path");
633852
- const dir = dirname67(this.persistPath);
633842
+ const { dirname: dirname68 } = __require("node:path");
633843
+ const dir = dirname68(this.persistPath);
633853
633844
  if (!existsSync184(dir))
633854
633845
  mkdirSync120(dir, { recursive: true });
633855
633846
  writeFileSync104(this.persistPath, JSON.stringify({ ledger: this.ledger }, null, 2));
@@ -682403,16 +682394,64 @@ var init_image_ascii_preview = __esm({
682403
682394
  var py_embed_exports = {};
682404
682395
  __export(py_embed_exports, {
682405
682396
  ensureEmbedDeps: () => ensureEmbedDeps,
682397
+ ensureManagedAsrModel: () => ensureManagedAsrModel,
682398
+ getManagedAsrReadiness: () => getManagedAsrReadiness,
682406
682399
  getVenvPython: () => getVenvPython,
682407
682400
  runEmbedAudio: () => runEmbedAudio,
682408
682401
  runEmbedImage: () => runEmbedImage,
682409
682402
  runEmbedText: () => runEmbedText,
682410
- runTranscribeFile: () => runTranscribeFile
682403
+ runTranscribeFile: () => runTranscribeFile,
682404
+ transcribeManagedNemotronFile: () => transcribeManagedNemotronFile
682411
682405
  });
682412
682406
  import { spawnSync as spawnSync9 } from "node:child_process";
682413
682407
  import { existsSync as existsSync122, mkdirSync as mkdirSync74, readFileSync as readFileSync99, writeFileSync as writeFileSync64 } from "node:fs";
682414
- import { join as join134 } from "node:path";
682408
+ import { dirname as dirname46, join as join134 } from "node:path";
682415
682409
  import { homedir as homedir41 } from "node:os";
682410
+ import { fileURLToPath as fileURLToPath21 } from "node:url";
682411
+ function managedAsrStateFile(engineId) {
682412
+ return join134(MANAGED_ASR_ROOT, engineId, "models.json");
682413
+ }
682414
+ function managedAsrModelDir(engineId) {
682415
+ return join134(MANAGED_ASR_MODEL_ROOT, engineId);
682416
+ }
682417
+ function readManagedAsrState(engineId) {
682418
+ try {
682419
+ return JSON.parse(readFileSync99(managedAsrStateFile(engineId), "utf8"));
682420
+ } catch {
682421
+ return {};
682422
+ }
682423
+ }
682424
+ function persistManagedAsrReadiness(readiness) {
682425
+ const root = join134(MANAGED_ASR_ROOT, readiness.engineId);
682426
+ mkdirSync74(root, { recursive: true });
682427
+ const state2 = readManagedAsrState(readiness.engineId);
682428
+ state2.models ??= {};
682429
+ state2.models[readiness.modelId] = {
682430
+ installed: readiness.installed,
682431
+ weightsReady: readiness.weightsReady,
682432
+ device: readiness.device,
682433
+ lastError: readiness.lastError,
682434
+ pulledAt: readiness.pulledAt
682435
+ };
682436
+ writeFileSync64(managedAsrStateFile(readiness.engineId), `${JSON.stringify(state2, null, 2)}
682437
+ `, "utf8");
682438
+ }
682439
+ function assertManagedAsrModel(engineId, modelId) {
682440
+ if (engineId === "openai-whisper" && WHISPER_MODEL_IDS2.has(modelId)) return;
682441
+ if (engineId === "nemotron-streaming" && modelId === NEMOTRON_MODEL_ID) return;
682442
+ throw new Error(`No managed CUDA runtime is registered for ASR model ${engineId}/${modelId}`);
682443
+ }
682444
+ function parseWorkerEvents(output2) {
682445
+ const events = [];
682446
+ for (const line of output2.split(/\r?\n/)) {
682447
+ try {
682448
+ const value2 = JSON.parse(line);
682449
+ if (value2 && typeof value2 === "object") events.push(value2);
682450
+ } catch {
682451
+ }
682452
+ }
682453
+ return events;
682454
+ }
682416
682455
  function getVenvDir() {
682417
682456
  return join134(homedir41(), ".omnius", "venv");
682418
682457
  }
@@ -682781,6 +682820,126 @@ ${log22.slice(-2e3)}` };
682781
682820
  }
682782
682821
  return { ok: ok3, log: log22 };
682783
682822
  }
682823
+ function getManagedAsrReadiness(engineId, modelId) {
682824
+ assertManagedAsrModel(engineId, modelId);
682825
+ const saved = readManagedAsrState(engineId).models?.[modelId];
682826
+ return {
682827
+ engineId,
682828
+ modelId,
682829
+ installed: Boolean(saved?.installed && existsSync122(getVenvPython())),
682830
+ weightsReady: Boolean(saved?.weightsReady),
682831
+ active: false,
682832
+ device: saved?.device,
682833
+ lastError: saved?.lastError,
682834
+ pulledAt: saved?.pulledAt
682835
+ };
682836
+ }
682837
+ function ensureManagedAsrModel(input) {
682838
+ const engineId = input.engineId.trim().toLowerCase();
682839
+ const modelId = input.modelId.trim().toLowerCase();
682840
+ assertManagedAsrModel(engineId, modelId);
682841
+ const deps = ensureEmbedDeps();
682842
+ if (!deps.ok) throw new Error(`ASR dependency setup failed: ${deps.log.slice(-2400)}`);
682843
+ const modelDir2 = managedAsrModelDir(engineId);
682844
+ mkdirSync74(modelDir2, { recursive: true });
682845
+ const env2 = {
682846
+ ...process.env,
682847
+ OMNIUS_ASR_MODEL_DIR: modelDir2,
682848
+ ...input.device ? { OMNIUS_ASR_CUDA_DEVICE: input.device } : {}
682849
+ };
682850
+ let device = "";
682851
+ let failure = "";
682852
+ if (engineId === "openai-whisper") {
682853
+ const code8 = [
682854
+ "import json, os, sys",
682855
+ "import torch, whisper",
682856
+ "allow_cpu=os.environ.get('OMNIUS_ASR_ALLOW_CPU','').strip().lower() in ('1','true','yes','on')",
682857
+ "if torch.cuda.is_available() and torch.cuda.device_count() > 0:",
682858
+ " index=int(os.environ.get('OMNIUS_ASR_CUDA_DEVICE','0') or '0')",
682859
+ " if index < 0 or index >= torch.cuda.device_count(): raise RuntimeError(f'CUDA device {index} is outside the visible device range')",
682860
+ " torch.cuda.set_device(index); device=f'cuda:{index}'",
682861
+ "elif allow_cpu: device='cpu'",
682862
+ `else: raise RuntimeError(f'CUDA-only ASR is enabled but torch cannot use CUDA (torch.version.cuda={getattr(torch.version, \\"cuda\\", None)}, device_count={torch.cuda.device_count()})')`,
682863
+ "model=whisper.load_model(sys.argv[1], device=device, download_root=sys.argv[2])",
682864
+ "print(json.dumps({'ok': True, 'device': device, 'cuda': device.startswith('cuda'), 'model': sys.argv[1]}))"
682865
+ ].join("\n");
682866
+ const pulled = spawnSync9(getVenvPython(), ["-c", code8, modelId, modelDir2], {
682867
+ encoding: "utf8",
682868
+ timeout: 12e5,
682869
+ env: env2
682870
+ });
682871
+ const events = parseWorkerEvents(`${pulled.stdout || ""}`);
682872
+ const ready = events.find((event) => event["ok"] === true);
682873
+ device = typeof ready?.["device"] === "string" ? ready["device"] : "";
682874
+ failure = `${pulled.stderr || ""}`.trim() || (pulled.error ? String(pulled.error) : "");
682875
+ if (pulled.status !== 0 || !ready || !device) {
682876
+ const message2 = failure || `Whisper model pull exited with status ${pulled.status ?? "unknown"}`;
682877
+ const readiness2 = { engineId, modelId, installed: true, weightsReady: false, active: false, lastError: message2 };
682878
+ persistManagedAsrReadiness(readiness2);
682879
+ throw new Error(message2);
682880
+ }
682881
+ } else {
682882
+ const script = locateScript("live-nemotron.py");
682883
+ const pulled = spawnSync9(getVenvPython(), [script, "--model", modelId, "--setup"], {
682884
+ encoding: "utf8",
682885
+ timeout: 12e5,
682886
+ env: env2
682887
+ });
682888
+ const events = parseWorkerEvents(`${pulled.stdout || ""}`);
682889
+ const ready = events.find((event) => event["type"] === "ready");
682890
+ const error = events.find((event) => event["type"] === "error");
682891
+ device = typeof ready?.["device"] === "string" ? ready["device"] : "";
682892
+ failure = String(error?.["message"] ?? (`${pulled.stderr || ""}`.trim() || pulled.error || ""));
682893
+ if (pulled.status !== 0 || !ready || !device) {
682894
+ const message2 = failure || `Nemotron model pull exited with status ${pulled.status ?? "unknown"}`;
682895
+ const readiness2 = { engineId, modelId, installed: true, weightsReady: false, active: false, lastError: message2 };
682896
+ persistManagedAsrReadiness(readiness2);
682897
+ throw new Error(message2);
682898
+ }
682899
+ }
682900
+ const readiness = {
682901
+ engineId,
682902
+ modelId,
682903
+ installed: true,
682904
+ weightsReady: true,
682905
+ active: false,
682906
+ device,
682907
+ pulledAt: (/* @__PURE__ */ new Date()).toISOString()
682908
+ };
682909
+ persistManagedAsrReadiness(readiness);
682910
+ return readiness;
682911
+ }
682912
+ function transcribeManagedNemotronFile(input) {
682913
+ const modelId = input.modelId.trim().toLowerCase();
682914
+ const existing = getManagedAsrReadiness("nemotron-streaming", modelId);
682915
+ if (!existing.weightsReady) ensureManagedAsrModel({ engineId: "nemotron-streaming", modelId, device: input.device });
682916
+ const result = spawnSync9(
682917
+ getVenvPython(),
682918
+ [locateScript("live-nemotron.py"), "--model", modelId, "--file", input.path],
682919
+ {
682920
+ encoding: "utf8",
682921
+ timeout: 12e5,
682922
+ env: {
682923
+ ...process.env,
682924
+ OMNIUS_ASR_MODEL_DIR: managedAsrModelDir("nemotron-streaming"),
682925
+ ...input.device ? { OMNIUS_ASR_CUDA_DEVICE: input.device } : {}
682926
+ }
682927
+ }
682928
+ );
682929
+ const events = parseWorkerEvents(`${result.stdout || ""}`);
682930
+ const transcript = [...events].reverse().find((event) => event["type"] === "transcript");
682931
+ const ready = events.find((event) => event["type"] === "ready");
682932
+ const error = events.find((event) => event["type"] === "error");
682933
+ if (result.status !== 0 || !transcript) {
682934
+ throw new Error(String(error?.["message"] ?? (`${result.stderr || ""}`.trim() || result.error || "Nemotron file transcription failed")));
682935
+ }
682936
+ return {
682937
+ text: String(transcript["text"] ?? ""),
682938
+ duration: Number.isFinite(Number(transcript["audioSeconds"])) ? Number(transcript["audioSeconds"]) : null,
682939
+ device: typeof ready?.["device"] === "string" ? ready["device"] : existing.device,
682940
+ warnings: []
682941
+ };
682942
+ }
682784
682943
  function runEmbedImage(input) {
682785
682944
  const py = getVenvPython();
682786
682945
  const script = locateScript("embed-image.py");
@@ -682827,20 +682986,23 @@ function runTranscribeFile(input) {
682827
682986
  }
682828
682987
  function locateScript(name10) {
682829
682988
  const candidates = [
682989
+ join134(MODULE_DIR, "..", "scripts", name10),
682830
682990
  join134(process.cwd(), "dist", "scripts", name10),
682831
682991
  join134(process.cwd(), name10),
682832
682992
  join134(process.cwd(), "scripts", name10)
682833
682993
  ];
682834
682994
  for (const c9 of candidates) if (existsSync122(c9)) return c9;
682835
682995
  const fallback = join134(process.cwd(), name10);
682836
- try {
682837
- writeFileSync64(fallback, 'print("missing script")\n');
682838
- } catch {
682839
- }
682840
682996
  return fallback;
682841
682997
  }
682998
+ var MODULE_DIR, MANAGED_ASR_ROOT, MANAGED_ASR_MODEL_ROOT, WHISPER_MODEL_IDS2, NEMOTRON_MODEL_ID;
682842
682999
  var init_py_embed = __esm({
682843
683000
  "packages/cli/src/api/py-embed.ts"() {
683001
+ MODULE_DIR = dirname46(fileURLToPath21(import.meta.url));
683002
+ MANAGED_ASR_ROOT = join134(homedir41(), ".omnius", "runtimes", "asr");
683003
+ MANAGED_ASR_MODEL_ROOT = join134(homedir41(), ".omnius", "models", "asr");
683004
+ WHISPER_MODEL_IDS2 = /* @__PURE__ */ new Set(["tiny", "base", "small", "medium", "large-v3"]);
683005
+ NEMOTRON_MODEL_ID = "nemotron-speech-streaming-en-0.6b";
682844
683006
  }
682845
683007
  });
682846
683008
 
@@ -682866,9 +683028,9 @@ import {
682866
683028
  writeFileSync as writeFileSync65,
682867
683029
  readdirSync as readdirSync37
682868
683030
  } from "node:fs";
682869
- import { join as join135, dirname as dirname46 } from "node:path";
683031
+ import { join as join135, dirname as dirname47 } from "node:path";
682870
683032
  import { homedir as homedir42 } from "node:os";
682871
- import { fileURLToPath as fileURLToPath21 } from "node:url";
683033
+ import { fileURLToPath as fileURLToPath22 } from "node:url";
682872
683034
  import { EventEmitter as EventEmitter6 } from "node:events";
682873
683035
  import { createInterface as createInterface3 } from "node:readline";
682874
683036
  function isAudioPath(path16) {
@@ -683121,7 +683283,7 @@ async function findMicCaptureCommand() {
683121
683283
  return null;
683122
683284
  }
683123
683285
  async function findTranscribeFileScript() {
683124
- const thisDir = dirname46(fileURLToPath21(import.meta.url));
683286
+ const thisDir = dirname47(fileURLToPath22(import.meta.url));
683125
683287
  const candidates = [
683126
683288
  join135(thisDir, "../../../../packages/execution/scripts/transcribe-file.py"),
683127
683289
  join135(thisDir, "../../../packages/execution/scripts/transcribe-file.py"),
@@ -683206,15 +683368,15 @@ async function transcribeFileViaWhisper(filePath, model) {
683206
683368
  }
683207
683369
  });
683208
683370
  }
683209
- async function findLiveWhisperScript() {
683210
- const thisDir = dirname46(fileURLToPath21(import.meta.url));
683371
+ async function findLiveAsrScript(scriptName) {
683372
+ const thisDir = dirname47(fileURLToPath22(import.meta.url));
683211
683373
  const candidates = [
683212
- join135(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
683213
- join135(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
683214
- join135(thisDir, "../../execution/scripts/live-whisper.py"),
683374
+ join135(thisDir, "../../../../packages/execution/scripts", scriptName),
683375
+ join135(thisDir, "../../../packages/execution/scripts", scriptName),
683376
+ join135(thisDir, "../../execution/scripts", scriptName),
683215
683377
  // npm install layout — scripts bundled alongside dist
683216
- join135(thisDir, "../scripts/live-whisper.py"),
683217
- join135(thisDir, "../../scripts/live-whisper.py")
683378
+ join135(thisDir, "../scripts", scriptName),
683379
+ join135(thisDir, "../../scripts", scriptName)
683218
683380
  ];
683219
683381
  for (const p2 of candidates) {
683220
683382
  if (existsSync123(p2)) return p2;
@@ -683222,8 +683384,8 @@ async function findLiveWhisperScript() {
683222
683384
  try {
683223
683385
  const globalRoot = (await execFileText5("npm", ["root", "-g"], { timeout: 5e3 })).trim();
683224
683386
  const candidates2 = [
683225
- join135(globalRoot, "omnius", "dist", "scripts", "live-whisper.py"),
683226
- join135(globalRoot, "omnius", "scripts", "live-whisper.py")
683387
+ join135(globalRoot, "omnius", "dist", "scripts", scriptName),
683388
+ join135(globalRoot, "omnius", "scripts", scriptName)
683227
683389
  ];
683228
683390
  for (const p2 of candidates2) {
683229
683391
  if (existsSync123(p2)) return p2;
@@ -683242,7 +683404,7 @@ async function findLiveWhisperScript() {
683242
683404
  "omnius",
683243
683405
  "dist",
683244
683406
  "scripts",
683245
- "live-whisper.py"
683407
+ scriptName
683246
683408
  );
683247
683409
  if (existsSync123(p2)) return p2;
683248
683410
  }
@@ -683251,6 +683413,12 @@ async function findLiveWhisperScript() {
683251
683413
  }
683252
683414
  return null;
683253
683415
  }
683416
+ async function findLiveWhisperScript() {
683417
+ return findLiveAsrScript("live-whisper.py");
683418
+ }
683419
+ async function findLiveNemotronScript() {
683420
+ return findLiveAsrScript("live-nemotron.py");
683421
+ }
683254
683422
  function defaultConsensusModel(primaryModel) {
683255
683423
  const model = primaryModel.trim().toLowerCase();
683256
683424
  if (model === "tiny") return "base";
@@ -683472,18 +683640,21 @@ var init_listen = __esm({
683472
683640
  196
683473
683641
  ];
683474
683642
  WhisperFallbackTranscriber = class extends EventEmitter6 {
683475
- constructor(model, scriptPath2) {
683643
+ constructor(model, scriptPath2, engineId = "openai-whisper") {
683476
683644
  super();
683477
683645
  this.model = model;
683478
683646
  this.scriptPath = scriptPath2;
683647
+ this.engineId = engineId;
683479
683648
  }
683480
683649
  model;
683481
683650
  scriptPath;
683651
+ engineId;
683482
683652
  process = null;
683483
683653
  _ready = false;
683484
683654
  registeredBrokerName = null;
683485
683655
  lastVadSpeech = null;
683486
683656
  lastVisibleVadAt = 0;
683657
+ stderrTail = "";
683487
683658
  get ready() {
683488
683659
  return this._ready;
683489
683660
  }
@@ -683510,30 +683681,32 @@ var init_listen = __esm({
683510
683681
  }
683511
683682
  updateListenLiveState({
683512
683683
  phase: "loading-model",
683513
- backend: "openai-whisper",
683684
+ backend: this.engineId,
683514
683685
  model: this.model,
683515
- lastStatus: `loading whisper ${this.model} model...`
683686
+ lastStatus: `loading ${this.engineId} ${this.model} model...`
683516
683687
  });
683517
683688
  const consensusModel = resolveAsrConsensusModel(this.model);
683518
683689
  const consensusThreshold = String(process.env["OMNIUS_ASR_CONSENSUS_THRESHOLD"] ?? "0.45");
683519
683690
  const silenceMs = String(process.env["OMNIUS_ASR_SILENCE_MS"] ?? "3000");
683691
+ const workerArgs = this.engineId === "nemotron-streaming" ? [this.scriptPath, "--model", this.model] : [
683692
+ this.scriptPath,
683693
+ "--model",
683694
+ this.model,
683695
+ "--chunk-seconds",
683696
+ "3",
683697
+ "--window-seconds",
683698
+ "10",
683699
+ "--consensus-model",
683700
+ consensusModel,
683701
+ "--consensus-threshold",
683702
+ consensusThreshold,
683703
+ "--silence-ms",
683704
+ silenceMs
683705
+ ];
683706
+ this.stderrTail = "";
683520
683707
  this.process = spawn33(
683521
683708
  pyPath,
683522
- [
683523
- this.scriptPath,
683524
- "--model",
683525
- this.model,
683526
- "--chunk-seconds",
683527
- "3",
683528
- "--window-seconds",
683529
- "10",
683530
- "--consensus-model",
683531
- consensusModel,
683532
- "--consensus-threshold",
683533
- consensusThreshold,
683534
- "--silence-ms",
683535
- silenceMs
683536
- ],
683709
+ workerArgs,
683537
683710
  {
683538
683711
  stdio: ["pipe", "pipe", "pipe"],
683539
683712
  env: { ...process.env }
@@ -683559,7 +683732,7 @@ var init_listen = __esm({
683559
683732
  case "ready":
683560
683733
  this._ready = true;
683561
683734
  clearTimeout(timeout2);
683562
- updateListenLiveState({ phase: "ready", lastStatus: "whisper model loaded" });
683735
+ updateListenLiveState({ phase: "ready", lastStatus: `${this.engineId} model loaded` });
683563
683736
  this.registerBrokerModel(evt);
683564
683737
  this.emit("ready");
683565
683738
  resolve88();
@@ -683589,7 +683762,7 @@ var init_listen = __esm({
683589
683762
  const speech = evt.speech === true;
683590
683763
  const now2 = Date.now();
683591
683764
  if (process.env["OMNIUS_ASR_VERBOSE_VAD"] === "1" && (speech !== this.lastVadSpeech || now2 - this.lastVisibleVadAt > 1e4)) {
683592
- this.emit("status", `Whisper VAD: ${speech ? "speech" : "silence"}`);
683765
+ this.emit("status", `${this.engineId} VAD: ${speech ? "speech" : "silence"}`);
683593
683766
  this.lastVisibleVadAt = now2;
683594
683767
  }
683595
683768
  this.lastVadSpeech = speech;
@@ -683614,7 +683787,11 @@ var init_listen = __esm({
683614
683787
  });
683615
683788
  this.process.stderr?.on("data", (data) => {
683616
683789
  const text2 = data.toString().trim();
683617
- if (text2) this.emit("status", text2);
683790
+ if (text2) {
683791
+ this.stderrTail = `${this.stderrTail}
683792
+ ${text2}`.slice(-2e3);
683793
+ this.emit("status", text2);
683794
+ }
683618
683795
  });
683619
683796
  onChildError(this.process, (err) => {
683620
683797
  clearTimeout(timeout2);
@@ -683625,7 +683802,9 @@ var init_listen = __esm({
683625
683802
  if (!this._ready) {
683626
683803
  clearTimeout(timeout2);
683627
683804
  reject(
683628
- new Error(`Whisper worker exited with code ${code8} before ready`)
683805
+ new Error(
683806
+ `${this.engineId} worker exited with code ${code8} before ready` + (this.stderrTail ? `: ${this.stderrTail.trim()}` : "")
683807
+ )
683629
683808
  );
683630
683809
  }
683631
683810
  });
@@ -683656,11 +683835,11 @@ var init_listen = __esm({
683656
683835
  const gpuIndexMatch = device.match(/^cuda:(\d+)/);
683657
683836
  const gpuIndex = gpuIndexMatch ? Number(gpuIndexMatch[1]) : null;
683658
683837
  const consensus = typeof evt["consensusModel"] === "string" && String(evt["consensusModel"]).trim() ? String(evt["consensusModel"]).trim() : "";
683659
- const name10 = `whisper:${this.model}${consensus ? `+${consensus}` : ""}`;
683838
+ const name10 = `${this.engineId}:${this.model}${consensus ? `+${consensus}` : ""}`;
683660
683839
  const vramMB = Math.max(0, Math.round(Number(evt["vramUsedMB"] ?? 0)));
683661
683840
  try {
683662
683841
  getModelBroker().registerLoaded({
683663
- key: `whisper-cli:${name10}`,
683842
+ key: `asr-worker:${name10}`,
683664
683843
  name: name10,
683665
683844
  domain: "asr",
683666
683845
  host: "whisper-cli",
@@ -683707,7 +683886,7 @@ var init_listen = __esm({
683707
683886
  // Medium by default (EGG lineage): with utterance-chunked capture the
683708
683887
  // per-utterance compute fits, and accuracy jumps over base.
683709
683888
  model: config?.model ?? "medium",
683710
- engineId: config?.engineId ?? "openai-whisper",
683889
+ engineId: normalizeAsrEngineId(config?.engineId ?? "openai-whisper"),
683711
683890
  modelId: config?.modelId ?? config?.model ?? "medium",
683712
683891
  mode: config?.mode ?? "confirm",
683713
683892
  silenceTimeoutMs: config?.silenceTimeoutMs ?? 3e3
@@ -683794,6 +683973,14 @@ var init_listen = __esm({
683794
683973
  }
683795
683974
  const unavailableReason = getAsrEngineUnavailableReason(selection.engineId);
683796
683975
  if (unavailableReason) throw new Error(unavailableReason);
683976
+ if (options2.setup && (selection.engineId === "openai-whisper" || selection.engineId === "nemotron-streaming")) {
683977
+ const managed = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
683978
+ managed.ensureManagedAsrModel({
683979
+ engineId: selection.engineId,
683980
+ modelId: selection.modelId,
683981
+ device: options2.device
683982
+ });
683983
+ }
683797
683984
  const whisperModel2 = selection.modelId;
683798
683985
  if (wasActive) await this.stop();
683799
683986
  if (previous.engineId === "vibevoice-transformers") await stopVibeVoiceAsr();
@@ -683939,7 +684126,7 @@ var init_listen = __esm({
683939
684126
  const req3 = createRequire12(import.meta.url);
683940
684127
  const loaded = req3("transcribe-cli");
683941
684128
  try {
683942
- transcribeCliPackageDirs.add(dirname46(req3.resolve("transcribe-cli/package.json")));
684129
+ transcribeCliPackageDirs.add(dirname47(req3.resolve("transcribe-cli/package.json")));
683943
684130
  } catch {
683944
684131
  }
683945
684132
  return loaded;
@@ -683986,9 +684173,7 @@ var init_listen = __esm({
683986
684173
  if (this.config.engineId === "vibevoice-transformers") {
683987
684174
  return "VibeVoice ASR does not support incremental PCM streaming. Use file/completed-utterance transcription or select Whisper.";
683988
684175
  }
683989
- if (this.config.engineId === "nemotron-streaming") {
683990
- return "Nemotron live activation is unavailable until its managed CUDA runtime passes the hardware gate.";
683991
- }
684176
+ const isNemotron = this.config.engineId === "nemotron-streaming";
683992
684177
  this.micWaterfall = [];
683993
684178
  updateListenLiveState({
683994
684179
  phase: "bootstrapping",
@@ -684005,17 +684190,17 @@ var init_listen = __esm({
684005
684190
  updateListenLiveState({ phase: "error", lastStatus: "no mic capture tool (arecord/sox/ffmpeg)" });
684006
684191
  return "No microphone capture tool found. Install arecord (Linux), sox (macOS), or ffmpeg.";
684007
684192
  }
684008
- const consensusEnabled = asrConsensusEnabled(this.config.model);
684009
- const useTranscribeCli = this.config.engineId === "transcribe-cli" || liveAsrUseTranscribeCli() && !consensusEnabled;
684193
+ const consensusEnabled = !isNemotron && asrConsensusEnabled(this.config.model);
684194
+ const useTranscribeCli = !isNemotron && liveAsrUseTranscribeCli() && !consensusEnabled;
684010
684195
  const preferWhisperFallback = !useTranscribeCli;
684011
684196
  if (preferWhisperFallback) {
684012
684197
  this.emit(
684013
684198
  "info",
684014
- consensusEnabled ? "ASR consensus enabled — using live-whisper.py with CUDA-only Whisper guard." : "Using live-whisper.py with CUDA-only Whisper guard."
684199
+ consensusEnabled ? "ASR consensus enabled — using live-whisper.py with CUDA-only Whisper guard." : isNemotron ? "Using managed Nemotron worker with CUDA-only guard." : "Using live-whisper.py with CUDA-only Whisper guard."
684015
684200
  );
684016
684201
  updateListenLiveState({
684017
- backend: "openai-whisper",
684018
- lastStatus: consensusEnabled ? "starting consensus Whisper backend..." : "starting CUDA Whisper backend..."
684202
+ backend: this.config.engineId,
684203
+ lastStatus: consensusEnabled ? "starting consensus Whisper backend..." : isNemotron ? "starting CUDA Nemotron backend..." : "starting CUDA Whisper backend..."
684019
684204
  });
684020
684205
  }
684021
684206
  let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
@@ -684043,7 +684228,7 @@ var init_listen = __esm({
684043
684228
  let tcUpToDate = false;
684044
684229
  try {
684045
684230
  const tcPkgPath = join135(
684046
- dirname46(__require.resolve?.("transcribe-cli/package.json") || ""),
684231
+ dirname47(__require.resolve?.("transcribe-cli/package.json") || ""),
684047
684232
  "package.json"
684048
684233
  );
684049
684234
  if (existsSync123(tcPkgPath)) {
@@ -684141,15 +684326,16 @@ var init_listen = __esm({
684141
684326
  }
684142
684327
  }
684143
684328
  if (!this.liveTranscriber) {
684144
- const scriptPath2 = await findLiveWhisperScript();
684329
+ const scriptPath2 = isNemotron ? await findLiveNemotronScript() : await findLiveWhisperScript();
684145
684330
  if (!scriptPath2) {
684146
684331
  const hint = transcribeCliError ? ` transcribe-cli error: ${transcribeCliError}` : "";
684147
- return `No transcription backend available.${hint} live-whisper.py not found.`;
684332
+ return `No transcription backend available.${hint} ${isNemotron ? "live-nemotron.py" : "live-whisper.py"} not found.`;
684148
684333
  }
684149
684334
  try {
684150
684335
  const fallback = new WhisperFallbackTranscriber(
684151
684336
  this.config.model,
684152
- scriptPath2
684337
+ scriptPath2,
684338
+ isNemotron ? "nemotron-streaming" : "openai-whisper"
684153
684339
  );
684154
684340
  usedFallback = true;
684155
684341
  fallback.on("status", (msg) => {
@@ -684188,7 +684374,7 @@ transcribe-cli error: ${transcribeCliError}` : "";
684188
684374
  this.emit("started");
684189
684375
  this.emit("recording", true);
684190
684376
  const modeDesc = this.config.mode === "auto" ? `auto (${this.config.silenceTimeoutMs / 1e3}s timeout)` : "confirm (press Enter to submit)";
684191
- const backend = usedFallback ? "openai-whisper" : "transcribe-cli";
684377
+ const backend = usedFallback ? this.config.engineId : "transcribe-cli";
684192
684378
  updateListenLiveState({
684193
684379
  phase: "listening",
684194
684380
  backend,
@@ -684299,6 +684485,18 @@ transcribe-cli error: ${transcribeCliError}` : "";
684299
684485
  * Caller is responsible for calling .stop() when done.
684300
684486
  */
684301
684487
  async createCallTranscriber() {
684488
+ if (this.config.engineId === "vibevoice-transformers") return null;
684489
+ if (this.config.engineId === "nemotron-streaming") {
684490
+ const scriptPath3 = await findLiveNemotronScript();
684491
+ if (!scriptPath3) return null;
684492
+ try {
684493
+ const fallback = new WhisperFallbackTranscriber(this.config.model, scriptPath3, "nemotron-streaming");
684494
+ await fallback.start();
684495
+ return fallback;
684496
+ } catch {
684497
+ return null;
684498
+ }
684499
+ }
684302
684500
  const requireConsensus = asrConsensusEnabled(this.config.model);
684303
684501
  const useTranscribeCli = liveAsrUseTranscribeCli() && !requireConsensus;
684304
684502
  let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
@@ -684391,15 +684589,36 @@ transcribe-cli error: ${transcribeCliError}` : "";
684391
684589
  };
684392
684590
  }
684393
684591
  if (this.config.engineId === "nemotron-streaming") {
684394
- throw new Error("Nemotron file transcription is disabled until its managed runtime passes the hardware gate");
684592
+ const managed = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
684593
+ const result = managed.transcribeManagedNemotronFile({
684594
+ path: filePath,
684595
+ modelId: this.config.modelId,
684596
+ device: options2.device
684597
+ });
684598
+ if (outputDir2) {
684599
+ const { basename: basename47 } = await import("node:path");
684600
+ const transcriptDir = join135(outputDir2, ".omnius", "transcripts");
684601
+ mkdirSync75(transcriptDir, { recursive: true });
684602
+ writeFileSync65(join135(transcriptDir, `${basename47(filePath)}.txt`), result.text, "utf-8");
684603
+ }
684604
+ return {
684605
+ text: result.text,
684606
+ duration: result.duration,
684607
+ speakers: [],
684608
+ engineId: "nemotron-streaming",
684609
+ modelId: this.config.modelId,
684610
+ warnings: result.warnings,
684611
+ segments: []
684612
+ };
684395
684613
  }
684396
- let tc = this.config.engineId === "transcribe-cli" ? await this.loadTranscribeCli() : null;
684397
- if (this.config.engineId === "transcribe-cli" && !tc && _bgInstallPromise) {
684614
+ const useTranscribeCli = liveAsrUseTranscribeCli();
684615
+ let tc = useTranscribeCli ? await this.loadTranscribeCli() : null;
684616
+ if (useTranscribeCli && !tc && _bgInstallPromise) {
684398
684617
  await _bgInstallPromise;
684399
684618
  this.transcribeCliAvailable = null;
684400
684619
  tc = await this.loadTranscribeCli();
684401
684620
  }
684402
- if (this.config.engineId === "transcribe-cli" && !tc) {
684621
+ if (useTranscribeCli && !tc) {
684403
684622
  try {
684404
684623
  await ensureManagedTranscribeCliNode();
684405
684624
  this.transcribeCliAvailable = null;
@@ -703296,7 +703515,7 @@ var init_types3 = __esm({
703296
703515
  // packages/cli/src/tui/p2p/secret-vault.ts
703297
703516
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes23, scryptSync as scryptSync2, createHash as createHash55 } from "node:crypto";
703298
703517
  import { readFileSync as readFileSync106, writeFileSync as writeFileSync69, existsSync as existsSync130, mkdirSync as mkdirSync80 } from "node:fs";
703299
- import { dirname as dirname47 } from "node:path";
703518
+ import { dirname as dirname48 } from "node:path";
703300
703519
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
703301
703520
  var init_secret_vault = __esm({
703302
703521
  "packages/cli/src/tui/p2p/secret-vault.ts"() {
@@ -703502,7 +703721,7 @@ var init_secret_vault = __esm({
703502
703721
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
703503
703722
  const tag = cipher.getAuthTag();
703504
703723
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
703505
- const dir = dirname47(this.storePath);
703724
+ const dir = dirname48(this.storePath);
703506
703725
  if (!existsSync130(dir)) mkdirSync80(dir, { recursive: true });
703507
703726
  writeFileSync69(this.storePath, blob, { mode: 384 });
703508
703727
  }
@@ -705177,7 +705396,7 @@ __export(omnius_directory_exports, {
705177
705396
  writeTaskHandoff: () => writeTaskHandoff2
705178
705397
  });
705179
705398
  import { appendFileSync as appendFileSync15, cpSync as cpSync2, existsSync as existsSync132, mkdirSync as mkdirSync82, readFileSync as readFileSync108, writeFileSync as writeFileSync71, readdirSync as readdirSync41, statSync as statSync52, unlinkSync as unlinkSync28, openSync as openSync9, closeSync as closeSync9, renameSync as renameSync19, watch as fsWatch3 } from "node:fs";
705180
- import { join as join143, relative as relative18, basename as basename27, dirname as dirname48, resolve as resolve67 } from "node:path";
705399
+ import { join as join143, relative as relative18, basename as basename27, dirname as dirname49, resolve as resolve67 } from "node:path";
705181
705400
  import { homedir as homedir45 } from "node:os";
705182
705401
  import { createHash as createHash58 } from "node:crypto";
705183
705402
  function isGitRoot(dir) {
@@ -705242,7 +705461,7 @@ function ensureOmniusIgnored(repoRoot) {
705242
705461
  if (!gitRoot) return;
705243
705462
  const gitignorePath = findNearestExistingGitignore(repoRoot, gitRoot);
705244
705463
  if (!gitignorePath) return;
705245
- const gitignoreDir = dirname48(gitignorePath);
705464
+ const gitignoreDir = dirname49(gitignorePath);
705246
705465
  const relDir = relative18(gitignoreDir || ".", repoRoot).replace(/\\/g, "/");
705247
705466
  const ignorePattern = relDir && relDir !== "." ? `${relDir}/.omnius/` : ".omnius/";
705248
705467
  const content = readFileSync108(gitignorePath, "utf-8");
@@ -705825,7 +706044,7 @@ function pruneContextLedger(ledgerPath) {
705825
706044
  const lines = readFileSync108(ledgerPath, "utf-8").split(/\r?\n/).filter((line) => line.trim().length > 0);
705826
706045
  if (lines.length <= MAX_CONTEXT_LEDGER_LINES) return;
705827
706046
  const kept = lines.slice(-MAX_CONTEXT_LEDGER_LINES);
705828
- const archiveDir = join143(dirname48(ledgerPath), "archive");
706047
+ const archiveDir = join143(dirname49(ledgerPath), "archive");
705829
706048
  mkdirSync82(archiveDir, { recursive: true });
705830
706049
  const archivePath = join143(
705831
706050
  archiveDir,
@@ -707573,8 +707792,8 @@ var init_render2 = __esm({
707573
707792
 
707574
707793
  // packages/prompts/dist/promptLoader.js
707575
707794
  import { readFileSync as readFileSync111, existsSync as existsSync135 } from "node:fs";
707576
- import { join as join145, dirname as dirname49 } from "node:path";
707577
- import { fileURLToPath as fileURLToPath22 } from "node:url";
707795
+ import { join as join145, dirname as dirname50 } from "node:path";
707796
+ import { fileURLToPath as fileURLToPath23 } from "node:url";
707578
707797
  function resolvePromptsDir(baseDir, promptPath = "code.md") {
707579
707798
  const devPath2 = join145(baseDir, "..", "templates");
707580
707799
  const publishedPath2 = join145(baseDir, "..", "prompts", "templates");
@@ -707602,8 +707821,8 @@ var __filename4, __dirname5, PROMPTS_DIR2, cache6;
707602
707821
  var init_promptLoader2 = __esm({
707603
707822
  "packages/prompts/dist/promptLoader.js"() {
707604
707823
  "use strict";
707605
- __filename4 = fileURLToPath22(import.meta.url);
707606
- __dirname5 = dirname49(__filename4);
707824
+ __filename4 = fileURLToPath23(import.meta.url);
707825
+ __dirname5 = dirname50(__filename4);
707607
707826
  PROMPTS_DIR2 = resolvePromptsDir(__dirname5);
707608
707827
  cache6 = /* @__PURE__ */ new Map();
707609
707828
  }
@@ -707717,8 +707936,8 @@ var init_task_templates = __esm({
707717
707936
  });
707718
707937
 
707719
707938
  // packages/prompts/dist/index.js
707720
- import { join as join146, dirname as dirname50 } from "node:path";
707721
- import { fileURLToPath as fileURLToPath23 } from "node:url";
707939
+ import { join as join146, dirname as dirname51 } from "node:path";
707940
+ import { fileURLToPath as fileURLToPath24 } from "node:url";
707722
707941
  var _dir, _packageRoot;
707723
707942
  var init_dist9 = __esm({
707724
707943
  "packages/prompts/dist/index.js"() {
@@ -707727,7 +707946,7 @@ var init_dist9 = __esm({
707727
707946
  init_render2();
707728
707947
  init_task_templates();
707729
707948
  init_render2();
707730
- _dir = dirname50(fileURLToPath23(import.meta.url));
707949
+ _dir = dirname51(fileURLToPath24(import.meta.url));
707731
707950
  _packageRoot = join146(_dir, "..");
707732
707951
  }
707733
707952
  });
@@ -709125,7 +709344,7 @@ var init_braille_spinner = __esm({
709125
709344
 
709126
709345
  // packages/cli/src/tui/project-context.ts
709127
709346
  import { existsSync as existsSync137, readFileSync as readFileSync113, readdirSync as readdirSync42, mkdirSync as mkdirSync84, statSync as statSync54, writeFileSync as writeFileSync73 } from "node:fs";
709128
- import { dirname as dirname51, join as join148, basename as basename29, resolve as resolve69 } from "node:path";
709347
+ import { dirname as dirname52, join as join148, basename as basename29, resolve as resolve69 } from "node:path";
709129
709348
  import { homedir as homedir48 } from "node:os";
709130
709349
  function projectContextUrlSpanAt(text2, index) {
709131
709350
  PROJECT_CONTEXT_URL_RE.lastIndex = 0;
@@ -709199,7 +709418,7 @@ function findGitDir(repoRoot) {
709199
709418
  }
709200
709419
  return gitPath;
709201
709420
  }
709202
- const parent = dirname51(dir);
709421
+ const parent = dirname52(dir);
709203
709422
  if (parent === dir) return null;
709204
709423
  dir = parent;
709205
709424
  }
@@ -710850,7 +711069,7 @@ __export(status_bar_exports, {
710850
711069
  stripSubAgentPrefix: () => stripSubAgentPrefix,
710851
711070
  unlockFooterRedraws: () => unlockFooterRedraws
710852
711071
  });
710853
- import { basename as basename30, dirname as dirname52 } from "node:path";
711072
+ import { basename as basename30, dirname as dirname53 } from "node:path";
710854
711073
  import { readFile as readFileAsync } from "node:fs/promises";
710855
711074
  function headerButtonGlyphFg() {
710856
711075
  const a2 = tuiAccent();
@@ -715153,7 +715372,7 @@ ${CONTENT_BG_SEQ}`);
715153
715372
  if (limit <= 6) return value2.slice(-limit);
715154
715373
  const marker = "...";
715155
715374
  const leaf = basename30(value2);
715156
- const parentLeaf = basename30(dirname52(value2));
715375
+ const parentLeaf = basename30(dirname53(value2));
715157
715376
  const suffix = parentLeaf && parentLeaf !== "." && parentLeaf !== leaf ? `${parentLeaf}/${leaf}` : leaf;
715158
715377
  if (suffix.length + marker.length + 1 <= limit) {
715159
715378
  return `${marker}/${suffix}`;
@@ -717314,10 +717533,10 @@ __export(personaplex_exports, {
717314
717533
  stopPersonaPlex: () => stopPersonaPlex
717315
717534
  });
717316
717535
  import { existsSync as existsSync138, writeFileSync as writeFileSync74, readFileSync as readFileSync114, mkdirSync as mkdirSync85, copyFileSync as copyFileSync5, readdirSync as readdirSync43, statSync as statSync55 } from "node:fs";
717317
- import { join as join149, dirname as dirname53 } from "node:path";
717536
+ import { join as join149, dirname as dirname54 } from "node:path";
717318
717537
  import { homedir as homedir49 } from "node:os";
717319
717538
  import { spawn as spawn37 } from "node:child_process";
717320
- import { fileURLToPath as fileURLToPath24 } from "node:url";
717539
+ import { fileURLToPath as fileURLToPath25 } from "node:url";
717321
717540
  function personaplexPythonEnv(extra = {}) {
717322
717541
  const env2 = { ...process.env, ...extra };
717323
717542
  applyMediaCudaDeviceFilterToEnv(env2, "voice");
@@ -718124,7 +718343,7 @@ function getShippedVoicesDir() {
718124
718343
  // repo root
718125
718344
  ];
718126
718345
  try {
718127
- const modDir = dirname53(fileURLToPath24(import.meta.url));
718346
+ const modDir = dirname54(fileURLToPath25(import.meta.url));
718128
718347
  candidates.push(join149(modDir, "..", "voices", "personaplex"));
718129
718348
  candidates.push(join149(modDir, "..", "..", "..", "voices", "personaplex"));
718130
718349
  candidates.push(join149(modDir, "..", "..", "..", "..", "voices", "personaplex"));
@@ -719507,7 +719726,7 @@ async function runOptionalDepsSetup(rl) {
719507
719726
  };
719508
719727
  process.stdout.write(` ${c3.bold("Optional dependencies")}
719509
719728
  `);
719510
- process.stdout.write(` ${c3.dim("These add features (vision/OCR, voice tunnel, live transcription). You can install them now or later via the in-TUI commands.")}
719729
+ process.stdout.write(` ${c3.dim("These add features (vision/OCR, voice tunnel). You can install them now or later via the in-TUI commands.")}
719511
719730
 
719512
719731
  `);
719513
719732
  const askVision = await ask(rl, ` ${c3.bold("Install vision / OCR deps?")} (Y/n) `);
@@ -719554,31 +719773,6 @@ async function runOptionalDepsSetup(rl) {
719554
719773
  } else {
719555
719774
  process.stdout.write(` ${c3.dim("Skipped cloudflared.")}
719556
719775
 
719557
- `);
719558
- }
719559
- const askTranscribe = await ask(rl, ` ${c3.bold("Install transcribe-cli for live transcription?")} (Y/n) `);
719560
- if (askTranscribe.toLowerCase() !== "n") {
719561
- process.stdout.write(` ${c3.cyan("●")} Installing managed transcribe-cli runtime...
719562
- `);
719563
- try {
719564
- const ok3 = await ensureTranscribeCliBackground();
719565
- if (ok3) {
719566
- process.stdout.write(` ${c3.green("✔")} Transcribe-CLI installed.
719567
-
719568
- `);
719569
- } else {
719570
- process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install did not complete — live transcription will be unavailable.
719571
-
719572
- `);
719573
- }
719574
- } catch (err) {
719575
- process.stdout.write(` ${c3.cyan("⚠")} transcribe-cli install hit an error: ${err instanceof Error ? err.message : String(err)}
719576
-
719577
- `);
719578
- }
719579
- } else {
719580
- process.stdout.write(` ${c3.dim("Skipped transcribe-cli.")}
719581
-
719582
719776
  `);
719583
719777
  }
719584
719778
  }
@@ -721206,7 +721400,6 @@ var init_setup = __esm({
721206
721400
  init_config();
721207
721401
  init_dist6();
721208
721402
  init_tui_select();
721209
- init_listen();
721210
721403
  init_ollama_gpu_policy();
721211
721404
  execAsync2 = promisify8(exec5);
721212
721405
  OMNIUS_FIRST_RUN_BANNER = [
@@ -725729,7 +725922,7 @@ import {
725729
725922
  renameSync as renameSync20,
725730
725923
  unlinkSync as unlinkSync31
725731
725924
  } from "node:fs";
725732
- import { dirname as dirname54, join as join155 } from "node:path";
725925
+ import { dirname as dirname55, join as join155 } from "node:path";
725733
725926
  import { homedir as homedir52 } from "node:os";
725734
725927
  import { randomBytes as randomBytes26 } from "node:crypto";
725735
725928
  function configHome() {
@@ -725745,7 +725938,7 @@ function bootstrapApiKeyFile() {
725745
725938
  return fromEnv || join155(configHome(), "api.key");
725746
725939
  }
725747
725940
  function ensureDirFor(file) {
725748
- const dir = dirname54(file);
725941
+ const dir = dirname55(file);
725749
725942
  if (!existsSync146(dir)) mkdirSync87(dir, { recursive: true });
725750
725943
  }
725751
725944
  function atomicWritePrivateFile(file, content) {
@@ -728710,10 +728903,10 @@ import {
728710
728903
  statSync as statSync59,
728711
728904
  writeFileSync as writeFileSync80
728712
728905
  } from "node:fs";
728713
- import { dirname as dirname55, join as join160, resolve as resolve72 } from "node:path";
728906
+ import { dirname as dirname56, join as join160, resolve as resolve72 } from "node:path";
728714
728907
  import { platform as platform8 } from "node:os";
728715
728908
  import { spawn as spawn39, spawnSync as spawnSync10 } from "node:child_process";
728716
- import { fileURLToPath as fileURLToPath25 } from "node:url";
728909
+ import { fileURLToPath as fileURLToPath26 } from "node:url";
728717
728910
  function normalizeVoiceboxModelId(value2) {
728718
728911
  const normalized3 = String(value2 || "").trim().toLowerCase().replace(/-/g, "_");
728719
728912
  return MODEL_ALIASES[normalized3] ?? normalized3;
@@ -728848,7 +729041,7 @@ async function runCommand(command, args, options2 = {}) {
728848
729041
  });
728849
729042
  }
728850
729043
  function packageAssetPath(...segments) {
728851
- const moduleDir = dirname55(fileURLToPath25(import.meta.url));
729044
+ const moduleDir = dirname56(fileURLToPath26(import.meta.url));
728852
729045
  const candidates = [
728853
729046
  join160(moduleDir, "..", "assets", ...segments),
728854
729047
  join160(moduleDir, "..", "..", "assets", ...segments)
@@ -729218,7 +729411,7 @@ function writeProfileMap(value2) {
729218
729411
  if (Buffer.byteLength(serialized) > PROFILE_MAP_MAX_BYTES) {
729219
729412
  throw new Error("Voicebox profile map exceeded its bounded storage limit");
729220
729413
  }
729221
- mkdirSync91(dirname55(profileMapPath()), { recursive: true });
729414
+ mkdirSync91(dirname56(profileMapPath()), { recursive: true });
729222
729415
  const temporary = `${profileMapPath()}.tmp-${process.pid}-${Date.now()}`;
729223
729416
  writeFileSync80(temporary, serialized, { mode: 384 });
729224
729417
  renameSync21(temporary, profileMapPath());
@@ -729606,13 +729799,13 @@ import {
729606
729799
  copyFileSync as copyFileSync6,
729607
729800
  rmSync as rmSync13
729608
729801
  } from "node:fs";
729609
- import { basename as basename32, join as join161, dirname as dirname56, resolve as resolve73 } from "node:path";
729802
+ import { basename as basename32, join as join161, dirname as dirname57, resolve as resolve73 } from "node:path";
729610
729803
  import { homedir as homedir55, tmpdir as tmpdir24, platform as platform9 } from "node:os";
729611
729804
  import {
729612
729805
  spawn as nodeSpawn
729613
729806
  } from "node:child_process";
729614
729807
  import { createRequire as createRequire8 } from "node:module";
729615
- import { fileURLToPath as fileURLToPath26 } from "node:url";
729808
+ import { fileURLToPath as fileURLToPath27 } from "node:url";
729616
729809
  function voicePythonEnv(extra = {}) {
729617
729810
  const { TRANSFORMERS_CACHE: _deprecatedCache, ...baseEnv } = process.env;
729618
729811
  const { TRANSFORMERS_CACHE: _extraDeprecatedCache, ...safeExtra } = extra;
@@ -729712,7 +729905,7 @@ function luxttsInferScript2() {
729712
729905
  return join161(voiceDir2(), "luxtts-infer.py");
729713
729906
  }
729714
729907
  function resolveBundledVoiceAsset(relativePath2) {
729715
- const moduleDir = dirname56(fileURLToPath26(import.meta.url));
729908
+ const moduleDir = dirname57(fileURLToPath27(import.meta.url));
729716
729909
  const candidates = [
729717
729910
  // npm bundle: publish/dist/index.js -> publish/assets
729718
729911
  join161(moduleDir, "..", "assets", relativePath2),
@@ -729813,7 +730006,7 @@ function consolidateVoiceDirs2() {
729813
730006
  const c9 = join161(dir, ".omnius", "voice");
729814
730007
  if (existsSync152(c9) && c9 !== globalVoice) candidates.add(c9);
729815
730008
  prev = dir;
729816
- dir = dirname56(dir);
730009
+ dir = dirname57(dir);
729817
730010
  }
729818
730011
  for (const root of COMMON_PROJECT_ROOTS) {
729819
730012
  const rootDir2 = join161(homedir55(), root);
@@ -730008,7 +730201,7 @@ function insertTagAfterOpeningClause(text2, tag) {
730008
730201
  function writeDetectTorchScript(targetPath) {
730009
730202
  if (existsSync152(targetPath)) return;
730010
730203
  try {
730011
- mkdirSync92(dirname56(targetPath), { recursive: true });
730204
+ mkdirSync92(dirname57(targetPath), { recursive: true });
730012
730205
  } catch {
730013
730206
  }
730014
730207
  const script = `#!/usr/bin/env python3
@@ -734566,7 +734759,7 @@ import {
734566
734759
  appendFileSync as appendFileSync17,
734567
734760
  writeSync as writeSync5
734568
734761
  } from "node:fs";
734569
- import { basename as basename33, dirname as dirname57, relative as relative20, join as join162 } from "node:path";
734762
+ import { basename as basename33, dirname as dirname58, relative as relative20, join as join162 } from "node:path";
734570
734763
  function omniusPinnedDependencyVersion(name10) {
734571
734764
  const spec = OMNIUS_PINNED_DEPENDENCY_SPECS[name10];
734572
734765
  if (!spec) return null;
@@ -748404,7 +748597,7 @@ async function collectSponsorMediaStream(args) {
748404
748597
  }
748405
748598
  const safeName3 = basename33(artifact.filename).replace(/[^\w.-]/g, "_") || `artifact${defaultExtensionForMime(artifact.mime)}`;
748406
748599
  const outputPath3 = join162(args.outputRoot, safeName3);
748407
- mkdirSync93(dirname57(outputPath3), { recursive: true });
748600
+ mkdirSync93(dirname58(outputPath3), { recursive: true });
748408
748601
  writeFileSync82(outputPath3, bytes2);
748409
748602
  return { ok: true, path: outputPath3, metadata };
748410
748603
  }
@@ -748905,14 +749098,14 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
748905
749098
  if (models.length > 0) {
748906
749099
  try {
748907
749100
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120 } = await import("node:fs");
748908
- const { join: join197, dirname: dirname67 } = await import("node:path");
749101
+ const { join: join197, dirname: dirname68 } = await import("node:path");
748909
749102
  const cachePath2 = join197(
748910
749103
  ctx3.repoRoot || process.cwd(),
748911
749104
  ".omnius",
748912
749105
  "nexus",
748913
749106
  "peer-models-cache.json"
748914
749107
  );
748915
- mkdirSync120(dirname67(cachePath2), { recursive: true });
749108
+ mkdirSync120(dirname68(cachePath2), { recursive: true });
748916
749109
  writeFileSync104(
748917
749110
  cachePath2,
748918
749111
  JSON.stringify(
@@ -748988,14 +749181,14 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local, advertisedModels
748988
749181
  );
748989
749182
  try {
748990
749183
  const { writeFileSync: writeFileSync104, mkdirSync: mkdirSync120 } = await import("node:fs");
748991
- const { join: join197, dirname: dirname67 } = await import("node:path");
749184
+ const { join: join197, dirname: dirname68 } = await import("node:path");
748992
749185
  const cachePath2 = join197(
748993
749186
  ctx3.repoRoot || process.cwd(),
748994
749187
  ".omnius",
748995
749188
  "nexus",
748996
749189
  "peer-models-cache.json"
748997
749190
  );
748998
- mkdirSync120(dirname67(cachePath2), { recursive: true });
749191
+ mkdirSync120(dirname68(cachePath2), { recursive: true });
748999
749192
  writeFileSync104(
749000
749193
  cachePath2,
749001
749194
  JSON.stringify(
@@ -750021,11 +750214,11 @@ async function handleUpdate(subcommand, ctx3) {
750021
750214
  let currentVersion = "0.0.0";
750022
750215
  try {
750023
750216
  const { createRequire: createRequire12 } = await import("node:module");
750024
- const { fileURLToPath: fileURLToPath32 } = await import("node:url");
750025
- const { dirname: dirname67, join: join197 } = await import("node:path");
750217
+ const { fileURLToPath: fileURLToPath33 } = await import("node:url");
750218
+ const { dirname: dirname68, join: join197 } = await import("node:path");
750026
750219
  const { existsSync: existsSync184 } = await import("node:fs");
750027
750220
  const req3 = createRequire12(import.meta.url);
750028
- const thisDir = dirname67(fileURLToPath32(import.meta.url));
750221
+ const thisDir = dirname68(fileURLToPath33(import.meta.url));
750029
750222
  const candidates = [
750030
750223
  join197(thisDir, "..", "package.json"),
750031
750224
  join197(thisDir, "..", "..", "package.json"),
@@ -751178,9 +751371,7 @@ async function handleUpdate(subcommand, ctx3) {
751178
751371
  } else {
751179
751372
  installOverlay.setStatus("cloudflared ready");
751180
751373
  }
751181
- installOverlay.setStatus("Checking managed transcribe-cli runtime...");
751182
- await ensureTranscribeCliBackground().catch(() => false);
751183
- installOverlay.setStatus("cloudflared/transcribe checks complete");
751374
+ installOverlay.setStatus("Cloudflared checks complete");
751184
751375
  }
751185
751376
  if (!primaryUpdated) {
751186
751377
  installOverlay.stop("Done — no restart needed");
@@ -751740,7 +751931,6 @@ var init_commands = __esm({
751740
751931
  init_typed_node_events();
751741
751932
  init_platforms();
751742
751933
  init_workspace_explorer();
751743
- init_listen();
751744
751934
  init_dist6();
751745
751935
  init_tui_select();
751746
751936
  init_usage_bars();
@@ -751784,10 +751974,10 @@ var init_commands = __esm({
751784
751974
  }
751785
751975
  try {
751786
751976
  const { createRequire: createRequire12 } = await import("node:module");
751787
- const { fileURLToPath: fileURLToPath32 } = await import("node:url");
751977
+ const { fileURLToPath: fileURLToPath33 } = await import("node:url");
751788
751978
  const { dirname: pathDirname, join: pathJoin } = await import("node:path");
751789
751979
  const localRequire = createRequire12(import.meta.url);
751790
- const here = pathDirname(fileURLToPath32(import.meta.url));
751980
+ const here = pathDirname(fileURLToPath33(import.meta.url));
751791
751981
  let version5 = "?";
751792
751982
  for (const up of ["..", "../..", "../../.."]) {
751793
751983
  try {
@@ -757468,8 +757658,8 @@ Call task_complete with the JSON array when done.`,
757468
757658
 
757469
757659
  // packages/cli/src/tui/promptLoader.ts
757470
757660
  import { readFileSync as readFileSync132, existsSync as existsSync161 } from "node:fs";
757471
- import { join as join170, dirname as dirname59 } from "node:path";
757472
- import { fileURLToPath as fileURLToPath27 } from "node:url";
757661
+ import { join as join170, dirname as dirname60 } from "node:path";
757662
+ import { fileURLToPath as fileURLToPath28 } from "node:url";
757473
757663
  function loadPrompt3(promptPath, vars) {
757474
757664
  let content = cache7.get(promptPath);
757475
757665
  if (content === void 0) {
@@ -757486,8 +757676,8 @@ function loadPrompt3(promptPath, vars) {
757486
757676
  var __filename5, __dirname6, devPath, publishedPath, PROMPTS_DIR3, cache7;
757487
757677
  var init_promptLoader3 = __esm({
757488
757678
  "packages/cli/src/tui/promptLoader.ts"() {
757489
- __filename5 = fileURLToPath27(import.meta.url);
757490
- __dirname6 = dirname59(__filename5);
757679
+ __filename5 = fileURLToPath28(import.meta.url);
757680
+ __dirname6 = dirname60(__filename5);
757491
757681
  devPath = join170(__dirname6, "..", "..", "prompts");
757492
757682
  publishedPath = join170(__dirname6, "..", "prompts");
757493
757683
  PROMPTS_DIR3 = existsSync161(devPath) ? devPath : publishedPath;
@@ -762703,7 +762893,7 @@ import {
762703
762893
  import { mkdir as mkdir23 } from "node:fs/promises";
762704
762894
  import {
762705
762895
  basename as basename41,
762706
- dirname as dirname60,
762896
+ dirname as dirname61,
762707
762897
  extname as extname21,
762708
762898
  isAbsolute as isAbsolute16,
762709
762899
  join as join174,
@@ -762924,7 +763114,7 @@ function scopedTool(base3, root, mode) {
762924
763114
  guarded.path.rel
762925
763115
  );
762926
763116
  if (!materialized.ok) return denied(materialized.error);
762927
- mkdirSync102(dirname60(guarded.path.abs), { recursive: true });
763117
+ mkdirSync102(dirname61(guarded.path.abs), { recursive: true });
762928
763118
  writeFileSync90(guarded.path.abs, readFileSync135(materialized.path));
762929
763119
  materialized.cleanup?.();
762930
763120
  restoredEditPath = guarded.path.abs;
@@ -763443,7 +763633,7 @@ var init_telegram_creative_tools = __esm({
763443
763633
  stage: "setup",
763444
763634
  message: "Preparing scoped TTS audio file"
763445
763635
  });
763446
- await mkdir23(dirname60(guarded.path.abs), { recursive: true });
763636
+ await mkdir23(dirname61(guarded.path.abs), { recursive: true });
763447
763637
  const tts = new TtsGenerateTool();
763448
763638
  this.emitProgress(start2, {
763449
763639
  stage: "load",
@@ -766872,7 +767062,7 @@ import {
766872
767062
  } from "node:fs";
766873
767063
  import {
766874
767064
  join as join177,
766875
- dirname as dirname61,
767065
+ dirname as dirname62,
766876
767066
  resolve as resolve79,
766877
767067
  basename as basename43,
766878
767068
  relative as relative22,
@@ -771215,7 +771405,7 @@ ${message2}`)
771215
771405
  appendTelegramIntakeJournal(sessionKey, entry) {
771216
771406
  const write2 = async () => {
771217
771407
  const path16 = this.telegramIntakePath(sessionKey);
771218
- await mkdirAsync(dirname61(path16), { recursive: true });
771408
+ await mkdirAsync(dirname62(path16), { recursive: true });
771219
771409
  await appendFileAsync(path16, `${JSON.stringify(entry)}
771220
771410
  `, "utf8");
771221
771411
  };
@@ -786963,15 +787153,14 @@ function getDaemonListenEngine() {
786963
787153
  const settings = loadGlobalSettings();
786964
787154
  const modelId = settings.asrModel?.trim() || "medium";
786965
787155
  const whisperModels2 = /* @__PURE__ */ new Set(["tiny", "base", "small", "medium", "large-v3"]);
787156
+ const persistedEngine = settings.asrEngine?.trim() ?? "openai-whisper";
787157
+ const engineId = normalizeAsrEngineId(persistedEngine);
786966
787158
  _listenEngine = getListenEngine({
786967
- engineId: settings.asrEngine?.trim() || "openai-whisper",
787159
+ engineId,
786968
787160
  modelId,
786969
787161
  ...whisperModels2.has(modelId) ? { model: modelId } : {}
786970
787162
  });
786971
787163
  }
786972
- if (_listenEngine.currentEngine === "transcribe-cli" && !_daemonAsrBootstrap) {
786973
- _daemonAsrBootstrap = ensureTranscribeCliBackground().catch(() => false);
786974
- }
786975
787164
  return _listenEngine;
786976
787165
  }
786977
787166
  function getVoiceBus() {
@@ -787219,7 +787408,7 @@ function _resetForTests() {
787219
787408
  _shutdownTimer = null;
787220
787409
  }
787221
787410
  }
787222
- var _voiceEngine, _listenEngine, _voiceChatSession, _bus, _state3, _loadedAt, _lastError, _clients2, _ttsSpeaking, _shutdownTimer, _daemonAsrBootstrap, _runtimeLoadPromise, IDLE_SHUTDOWN_MS, _wired;
787411
+ var _voiceEngine, _listenEngine, _voiceChatSession, _bus, _state3, _loadedAt, _lastError, _clients2, _ttsSpeaking, _shutdownTimer, _runtimeLoadPromise, IDLE_SHUTDOWN_MS, _wired;
787223
787412
  var init_voice_runtime = __esm({
787224
787413
  "packages/cli/src/api/voice-runtime.ts"() {
787225
787414
  init_voice();
@@ -787237,7 +787426,6 @@ var init_voice_runtime = __esm({
787237
787426
  _clients2 = /* @__PURE__ */ new Map();
787238
787427
  _ttsSpeaking = false;
787239
787428
  _shutdownTimer = null;
787240
- _daemonAsrBootstrap = null;
787241
787429
  _runtimeLoadPromise = null;
787242
787430
  IDLE_SHUTDOWN_MS = 6e4;
787243
787431
  _wired = false;
@@ -788687,7 +788875,7 @@ var init_audit_log = __esm({
788687
788875
  // packages/cli/src/api/disk-task-output.ts
788688
788876
  import { open } from "node:fs/promises";
788689
788877
  import { existsSync as existsSync171, mkdirSync as mkdirSync108, statSync as statSync66 } from "node:fs";
788690
- import { dirname as dirname62 } from "node:path";
788878
+ import { dirname as dirname63 } from "node:path";
788691
788879
  import * as fsConstants from "node:constants";
788692
788880
  var O_NOFOLLOW2, O_APPEND2, O_CREAT2, O_WRONLY2, OPEN_FLAGS_WRITE, OPEN_MODE, DiskTaskOutput;
788693
788881
  var init_disk_task_output = __esm({
@@ -788705,7 +788893,7 @@ var init_disk_task_output = __esm({
788705
788893
  fileSize = 0;
788706
788894
  constructor(outputPath3) {
788707
788895
  this.path = outputPath3;
788708
- mkdirSync108(dirname62(outputPath3), { recursive: true });
788896
+ mkdirSync108(dirname63(outputPath3), { recursive: true });
788709
788897
  }
788710
788898
  /** Queue content for async append. Non-blocking. */
788711
788899
  append(chunk) {
@@ -808764,7 +808952,7 @@ function getOpenApiSpec() {
808764
808952
  patch: {
808765
808953
  summary: "Persist and activate an exact ASR selection",
808766
808954
  tags: ["ASR"],
808767
- description: "Body: {engineId, modelId?, setup?, device?}. Selection is validated against the registry. VibeVoice activation is CUDA-only and fail-closed; setup=true installs the pinned runtime and exact weights before activation. Hardware evidence uses nvidia-smi on discrete Linux and NVIDIA's documented tegrastats plus a CUDA Torch property probe on Jetson/L4T.",
808955
+ description: "Body: {engineId, modelId?, setup?, device?}. Selection is validated against the registry. setup=true pulls the exact managed model and verifies CUDA placement before activation. Hardware evidence uses nvidia-smi on discrete Linux and NVIDIA's documented tegrastats plus a CUDA Torch property probe on Jetson/L4T.",
808768
808956
  responses: { 200: { description: "Exact selection activated" }, 400: { description: "Unknown engine or model" }, 409: { description: "Runtime unavailable or not installed" }, 500: { description: "Setup, hardware preflight, or activation failed" } }
808769
808957
  }
808770
808958
  },
@@ -808773,11 +808961,29 @@ function getOpenApiSpec() {
808773
808961
  post: {
808774
808962
  summary: "Install a managed ASR runtime and its pinned weights",
808775
808963
  tags: ["ASR"],
808776
- description: "Currently implemented for vibevoice-transformers. The exact microsoft/VibeVoice-ASR revision and tokenizer snapshot are stored under the unified Omnius ASR model/runtime directories; model weights are never bundled into npm.",
808964
+ description: "Body: {modelId?, device?}. Installs the managed runtime and pulls the requested model. Whisper and Nemotron loads validate their selected CUDA device; VibeVoice stores its pinned model and tokenizer snapshot under Omnius' ASR runtime directories.",
808777
808965
  parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }],
808778
808966
  responses: { 200: { description: "Runtime and weights ready" }, 409: { description: "Engine has no managed setup adapter" }, 500: { description: "Setup failed" } }
808779
808967
  }
808780
808968
  },
808969
+ "/v1/asr/engines/{engineId}/models/{modelId}/pull": {
808970
+ post: {
808971
+ summary: "Pull one exact ASR model and validate its managed runtime",
808972
+ tags: ["ASR"],
808973
+ description: "Optional body: {device}. Downloads model weights into Omnius-managed storage and verifies CUDA placement for Whisper and Nemotron.",
808974
+ parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }, { name: "modelId", in: "path", required: true, schema: { type: "string" } }],
808975
+ responses: { 200: { description: "Weights are ready" }, 500: { description: "Runtime, download, or CUDA validation failed" } }
808976
+ }
808977
+ },
808978
+ "/v1/asr/engines/{engineId}/models/{modelId}/deploy": {
808979
+ post: {
808980
+ summary: "Pull, select, and activate one exact ASR model",
808981
+ tags: ["ASR"],
808982
+ description: "Optional body: {device}. Persists the selection after the managed runtime and weights are ready.",
808983
+ parameters: [{ name: "engineId", in: "path", required: true, schema: { type: "string" } }, { name: "modelId", in: "path", required: true, schema: { type: "string" } }],
808984
+ responses: { 200: { description: "Model deployed and selected" }, 500: { description: "Deploy or CUDA validation failed" } }
808985
+ }
808986
+ },
808781
808987
  "/v1/voice/asr-models": { get: { summary: "Compatibility alias of GET /v1/asr/engines", tags: ["ASR"], responses: { 200: { description: "Canonical ASR registry plus legacy model projection" } } } },
808782
808988
  "/v1/voice/asr-models/switch": { post: { summary: "Compatibility alias of POST /v1/asr/activate", tags: ["ASR"], responses: { 200: { description: "Exact selection activated" }, 400: { description: "Unknown selection" }, 409: { description: "Runtime unavailable" }, 500: { description: "Activation failed" } } } },
808783
808989
  "/v1/voice/tts": {
@@ -809452,9 +809658,9 @@ var init_chat_followup = __esm({
809452
809658
  // packages/cli/src/docker.ts
809453
809659
  import { execSync as execSync38, spawn as spawn41 } from "node:child_process";
809454
809660
  import { existsSync as existsSync179, mkdirSync as mkdirSync114, writeFileSync as writeFileSync98 } from "node:fs";
809455
- import { join as join188, resolve as resolve82, dirname as dirname63 } from "node:path";
809661
+ import { join as join188, resolve as resolve82, dirname as dirname64 } from "node:path";
809456
809662
  import { homedir as homedir64 } from "node:os";
809457
- import { fileURLToPath as fileURLToPath28 } from "node:url";
809663
+ import { fileURLToPath as fileURLToPath29 } from "node:url";
809458
809664
  function getDockerDir() {
809459
809665
  try {
809460
809666
  if (typeof __dirname !== "undefined") {
@@ -809463,7 +809669,7 @@ function getDockerDir() {
809463
809669
  } catch {
809464
809670
  }
809465
809671
  try {
809466
- const thisDir = dirname63(fileURLToPath28(import.meta.url));
809672
+ const thisDir = dirname64(fileURLToPath29(import.meta.url));
809467
809673
  return join188(thisDir, "..", "..", "..", "docker");
809468
809674
  } catch {
809469
809675
  }
@@ -809929,8 +810135,8 @@ __export(serve_exports, {
809929
810135
  import * as http5 from "node:http";
809930
810136
  import * as https3 from "node:https";
809931
810137
  import { createRequire as createRequire9 } from "node:module";
809932
- import { fileURLToPath as fileURLToPath29 } from "node:url";
809933
- import { dirname as dirname64, join as join190, resolve as resolve83 } from "node:path";
810138
+ import { fileURLToPath as fileURLToPath30 } from "node:url";
810139
+ import { dirname as dirname65, join as join190, resolve as resolve83 } from "node:path";
809934
810140
  import { homedir as homedir65 } from "node:os";
809935
810141
  import { spawn as spawn42, execSync as execSync39 } from "node:child_process";
809936
810142
  import {
@@ -809959,7 +810165,7 @@ function memoryDbPaths3(baseDir = process.cwd()) {
809959
810165
  }
809960
810166
  function readServerPackageIdentity() {
809961
810167
  try {
809962
- const thisDir = dirname64(fileURLToPath29(import.meta.url));
810168
+ const thisDir = dirname65(fileURLToPath30(import.meta.url));
809963
810169
  const candidates = [
809964
810170
  join190(thisDir, "..", "package.json"),
809965
810171
  join190(thisDir, "..", "..", "package.json"),
@@ -813777,7 +813983,7 @@ async function handleV1Update(req3, res, requestId) {
813777
813983
  );
813778
813984
  const fs14 = require4("node:fs");
813779
813985
  const nodeBin = process.execPath;
813780
- const nodeDir = dirname64(nodeBin);
813986
+ const nodeDir = dirname65(nodeBin);
813781
813987
  const { execSync: es } = require4("node:child_process");
813782
813988
  const isWin2 = process.platform === "win32";
813783
813989
  let npmBin = "";
@@ -813792,7 +813998,7 @@ async function handleV1Update(req3, res, requestId) {
813792
813998
  const dir = join190(homedir65(), ".omnius");
813793
813999
  fs14.mkdirSync(dir, { recursive: true });
813794
814000
  const logFd = fs14.openSync(logPath3, "w");
813795
- const npmPrefix = dirname64(nodeDir);
814001
+ const npmPrefix = dirname65(nodeDir);
813796
814002
  let globalBinDir = "";
813797
814003
  try {
813798
814004
  if (isWin2) {
@@ -816780,16 +816986,13 @@ data: ${JSON.stringify(data)}
816780
816986
  const engines = listAsrEngines().map((engine) => {
816781
816987
  const selected = engine.id === listen.currentEngine;
816782
816988
  const unavailableReason = getAsrEngineUnavailableReason(engine.id);
816989
+ const selectedModel = selected ? listen.currentModel : engine.models[0]?.id;
816783
816990
  const readiness = unavailableReason ? {
816784
816991
  installed: false,
816785
816992
  weightsReady: false,
816786
816993
  active: false,
816787
816994
  lastError: unavailableReason
816788
- } : engine.id === "vibevoice-transformers" ? vibe : {
816789
- installed: true,
816790
- weightsReady: true,
816791
- active: selected && listen.isActive
816792
- };
816995
+ } : engine.id === "vibevoice-transformers" ? vibe : getManagedAsrReadiness(engine.id, selectedModel ?? engine.models[0].id);
816793
816996
  return {
816794
816997
  ...engine,
816795
816998
  availability: unavailableReason ? "disabled" : "available",
@@ -816798,6 +817001,7 @@ data: ${JSON.stringify(data)}
816798
817001
  readiness,
816799
817002
  models: engine.models.map((model) => ({
816800
817003
  ...model,
817004
+ readiness: engine.id === "vibevoice-transformers" ? vibe : getManagedAsrReadiness(engine.id, model.id),
816801
817005
  selected: selected && model.id === listen.currentModel,
816802
817006
  isActive: selected && model.id === listen.currentModel && readiness.active
816803
817007
  }))
@@ -816823,35 +817027,76 @@ data: ${JSON.stringify(data)}
816823
817027
  modelId: listen.currentModel
816824
817028
  },
816825
817029
  state: getRuntimeStatus(),
816826
- vibevoice: getVibeVoiceAsrReadiness()
817030
+ vibevoice: getVibeVoiceAsrReadiness(),
817031
+ runtimes: listAsrEngines().filter((engine) => engine.id === "openai-whisper" || engine.id === "nemotron-streaming").flatMap((engine) => engine.models.map((model) => getManagedAsrReadiness(engine.id, model.id)))
816827
817032
  });
816828
817033
  return;
816829
817034
  }
817035
+ const asrPullMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/models\/([^/]+)\/pull$/);
817036
+ if (asrPullMatch && method === "POST") {
817037
+ const engineId = decodeURIComponent(asrPullMatch[1] || "");
817038
+ const modelId = decodeURIComponent(asrPullMatch[2] || "");
817039
+ const body = await parseJsonBody(req3);
817040
+ try {
817041
+ const selection = resolveAsrSelection({ engineId, modelId });
817042
+ const readiness = selection.engineId === "vibevoice-transformers" ? (await ensureVibeVoiceAsrSetup(), getVibeVoiceAsrReadiness()) : ensureManagedAsrModel({ ...selection, device: body?.device });
817043
+ jsonResponse(res, 200, { ok: true, action: "pull", selection, readiness });
817044
+ } catch (err) {
817045
+ jsonResponse(res, 500, {
817046
+ error: "asr_pull_failed",
817047
+ engineId,
817048
+ modelId,
817049
+ message: err instanceof Error ? err.message : String(err)
817050
+ });
817051
+ }
817052
+ return;
817053
+ }
817054
+ const asrDeployMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/models\/([^/]+)\/deploy$/);
817055
+ if (asrDeployMatch && method === "POST") {
817056
+ const engineId = decodeURIComponent(asrDeployMatch[1] || "");
817057
+ const modelId = decodeURIComponent(asrDeployMatch[2] || "");
817058
+ const body = await parseJsonBody(req3);
817059
+ try {
817060
+ const selection = resolveAsrSelection({ engineId, modelId });
817061
+ const activated = await getDaemonListenEngine().activateSelection(selection, {
817062
+ setup: true,
817063
+ device: body?.device
817064
+ });
817065
+ saveGlobalSettings({ asrEngine: activated.selection.engineId, asrModel: activated.selection.modelId });
817066
+ jsonResponse(res, 200, { ok: true, action: "deploy", ...activated, state: getRuntimeStatus() });
817067
+ } catch (err) {
817068
+ jsonResponse(res, 500, {
817069
+ error: "asr_deploy_failed",
817070
+ engineId,
817071
+ modelId,
817072
+ message: err instanceof Error ? err.message : String(err)
817073
+ });
817074
+ }
817075
+ return;
817076
+ }
816830
817077
  const asrSetupMatch = pathname.match(/^\/v1\/asr\/engines\/([^/]+)\/setup$/);
816831
817078
  if (asrSetupMatch && method === "POST") {
816832
817079
  const engineId = decodeURIComponent(asrSetupMatch[1] || "");
816833
- if (engineId !== "vibevoice-transformers") {
816834
- jsonResponse(res, 409, {
816835
- error: "setup_not_managed_here",
817080
+ const body = await parseJsonBody(req3);
817081
+ try {
817082
+ const current = getDaemonListenEngine();
817083
+ const selection = resolveAsrSelection({
816836
817084
  engineId,
816837
- message: "Only the VibeVoice managed setup is exposed by this endpoint in this release."
817085
+ modelId: body?.modelId ?? body?.model ?? (current.currentEngine === engineId ? current.currentModel : void 0)
816838
817086
  });
816839
- return;
816840
- }
816841
- try {
816842
- await ensureVibeVoiceAsrSetup();
817087
+ const readiness = selection.engineId === "vibevoice-transformers" ? (await ensureVibeVoiceAsrSetup(), getVibeVoiceAsrReadiness()) : ensureManagedAsrModel({ ...selection, device: body?.device });
816843
817088
  jsonResponse(res, 200, {
816844
817089
  ok: true,
816845
- engineId,
816846
- readiness: getVibeVoiceAsrReadiness(),
816847
- plan: getVibeVoiceAsrSetupPlan()
817090
+ selection,
817091
+ readiness,
817092
+ ...selection.engineId === "vibevoice-transformers" ? { plan: getVibeVoiceAsrSetupPlan() } : {}
816848
817093
  });
816849
817094
  } catch (err) {
816850
817095
  jsonResponse(res, 500, {
816851
817096
  error: "asr_setup_failed",
816852
817097
  engineId,
816853
817098
  message: err instanceof Error ? err.message : String(err),
816854
- readiness: getVibeVoiceAsrReadiness()
817099
+ readiness: engineId === "vibevoice-transformers" ? getVibeVoiceAsrReadiness() : void 0
816855
817100
  });
816856
817101
  }
816857
817102
  return;
@@ -820961,6 +821206,7 @@ var init_serve = __esm({
820961
821206
  init_project_preferences();
820962
821207
  init_internal_output();
820963
821208
  init_voice_runtime();
821209
+ init_py_embed();
820964
821210
  init_voice();
820965
821211
  init_voicebox();
820966
821212
  init_audit_log();
@@ -821150,9 +821396,9 @@ var init_clipboard_media = __esm({
821150
821396
 
821151
821397
  // packages/cli/src/tui/interactive.ts
821152
821398
  import { cwd } from "node:process";
821153
- import { resolve as resolve84, join as join192, dirname as dirname65, extname as extname23, relative as relative23, sep as sep10 } from "node:path";
821399
+ import { resolve as resolve84, join as join192, dirname as dirname66, extname as extname23, relative as relative23, sep as sep10 } from "node:path";
821154
821400
  import { createRequire as createRequire10 } from "node:module";
821155
- import { fileURLToPath as fileURLToPath30 } from "node:url";
821401
+ import { fileURLToPath as fileURLToPath31 } from "node:url";
821156
821402
  import { createHash as createHash68 } from "node:crypto";
821157
821403
  import {
821158
821404
  readFileSync as readFileSync149,
@@ -821211,7 +821457,7 @@ function formatTimeAgo2(date) {
821211
821457
  function getVersion4() {
821212
821458
  try {
821213
821459
  const require5 = createRequire10(import.meta.url);
821214
- const thisDir = dirname65(fileURLToPath30(import.meta.url));
821460
+ const thisDir = dirname66(fileURLToPath31(import.meta.url));
821215
821461
  const candidates = [
821216
821462
  join192(thisDir, "..", "package.json"),
821217
821463
  join192(thisDir, "..", "..", "package.json"),
@@ -833541,7 +833787,7 @@ var init_config6 = __esm({
833541
833787
  // -- Voice & audio --
833542
833788
  voice: "Enable TTS voice feedback (true/false)",
833543
833789
  voiceModel: "TTS voice model id (built-in, LuxTTS clone, Supertonic, MisoTTS, or selected Voicebox model)",
833544
- asrEngine: "ASR engine id (openai-whisper, transcribe-cli, nemotron-streaming, vibevoice-transformers)",
833790
+ asrEngine: "ASR engine id (openai-whisper, nemotron-streaming, vibevoice-transformers)",
833545
833791
  asrModel: "Exact model id within the selected ASR engine",
833546
833792
  // -- Agent autonomy --
833547
833793
  commandsMode: "Agent slash-command access: auto (agent can invoke) or manual (user-only)",
@@ -833958,8 +834204,8 @@ init_updater();
833958
834204
  init_typed_node_events();
833959
834205
  init_dist5();
833960
834206
  import { parseArgs as nodeParseArgs2 } from "node:util";
833961
- import { fileURLToPath as fileURLToPath31 } from "node:url";
833962
- import { dirname as dirname66, join as join196 } from "node:path";
834207
+ import { fileURLToPath as fileURLToPath32 } from "node:url";
834208
+ import { dirname as dirname67, join as join196 } from "node:path";
833963
834209
  import { createRequire as createRequire11 } from "node:module";
833964
834210
 
833965
834211
  // packages/cli/src/cli.ts
@@ -834128,7 +834374,7 @@ init_output();
834128
834374
  function getVersion5() {
834129
834375
  try {
834130
834376
  const require5 = createRequire11(import.meta.url);
834131
- const pkgPath = join196(dirname66(fileURLToPath31(import.meta.url)), "..", "package.json");
834377
+ const pkgPath = join196(dirname67(fileURLToPath32(import.meta.url)), "..", "package.json");
834132
834378
  const pkg = require5(pkgPath);
834133
834379
  return pkg.version;
834134
834380
  } catch {