omnius 1.0.248 → 1.0.249

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
@@ -585341,10 +585341,18 @@ __export(listen_exports, {
585341
585341
  isAudioPath: () => isAudioPath,
585342
585342
  isTranscribablePath: () => isTranscribablePath,
585343
585343
  isVideoPath: () => isVideoPath,
585344
+ transcribeFileViaWhisper: () => transcribeFileViaWhisper,
585344
585345
  waitForTranscribeCli: () => waitForTranscribeCli
585345
585346
  });
585346
585347
  import { spawn as spawn25, execSync as execSync48 } from "node:child_process";
585347
- import { accessSync, constants, existsSync as existsSync98, mkdirSync as mkdirSync59, writeFileSync as writeFileSync50, readdirSync as readdirSync30 } from "node:fs";
585348
+ import {
585349
+ accessSync,
585350
+ constants,
585351
+ existsSync as existsSync98,
585352
+ mkdirSync as mkdirSync59,
585353
+ writeFileSync as writeFileSync50,
585354
+ readdirSync as readdirSync30
585355
+ } from "node:fs";
585348
585356
  import { join as join113, dirname as dirname35 } from "node:path";
585349
585357
  import { homedir as homedir33 } from "node:os";
585350
585358
  import { fileURLToPath as fileURLToPath12 } from "node:url";
@@ -585368,7 +585376,18 @@ function findMicCaptureCommand() {
585368
585376
  execSync48("which arecord", { stdio: "pipe" });
585369
585377
  return {
585370
585378
  cmd: "arecord",
585371
- args: ["-f", "S16_LE", "-r", "16000", "-c", "1", "-t", "raw", "-q", "-"]
585379
+ args: [
585380
+ "-f",
585381
+ "S16_LE",
585382
+ "-r",
585383
+ "16000",
585384
+ "-c",
585385
+ "1",
585386
+ "-t",
585387
+ "raw",
585388
+ "-q",
585389
+ "-"
585390
+ ]
585372
585391
  };
585373
585392
  } catch {
585374
585393
  }
@@ -585378,7 +585397,20 @@ function findMicCaptureCommand() {
585378
585397
  execSync48("which sox", { stdio: "pipe" });
585379
585398
  return {
585380
585399
  cmd: "sox",
585381
- args: ["-d", "-t", "raw", "-r", "16000", "-c", "1", "-b", "16", "-e", "signed-integer", "-"]
585400
+ args: [
585401
+ "-d",
585402
+ "-t",
585403
+ "raw",
585404
+ "-r",
585405
+ "16000",
585406
+ "-c",
585407
+ "1",
585408
+ "-b",
585409
+ "16",
585410
+ "-e",
585411
+ "signed-integer",
585412
+ "-"
585413
+ ]
585382
585414
  };
585383
585415
  } catch {
585384
585416
  }
@@ -585485,7 +585517,12 @@ async function transcribeFileViaWhisper(filePath, model) {
585485
585517
  const j = JSON.parse(raw);
585486
585518
  if (j.error) return null;
585487
585519
  if (typeof j.text !== "string") return null;
585488
- return { text: j.text.trim(), duration: null, speakers: [], segments: [] };
585520
+ return {
585521
+ text: j.text.trim(),
585522
+ duration: null,
585523
+ speakers: [],
585524
+ segments: []
585525
+ };
585489
585526
  } catch {
585490
585527
  return null;
585491
585528
  }
@@ -585545,7 +585582,16 @@ function findLiveWhisperScript() {
585545
585582
  if (existsSync98(nvmBase)) {
585546
585583
  try {
585547
585584
  for (const ver of readdirSync30(nvmBase)) {
585548
- const p2 = join113(nvmBase, ver, "lib", "node_modules", "omnius", "dist", "scripts", "live-whisper.py");
585585
+ const p2 = join113(
585586
+ nvmBase,
585587
+ ver,
585588
+ "lib",
585589
+ "node_modules",
585590
+ "omnius",
585591
+ "dist",
585592
+ "scripts",
585593
+ "live-whisper.py"
585594
+ );
585549
585595
  if (existsSync98(p2)) return p2;
585550
585596
  }
585551
585597
  } catch {
@@ -585566,7 +585612,10 @@ function ensureVenvForTranscribeCli() {
585566
585612
  process.env.PATH = `${venvBin}${pathSep2}${currentPath}`;
585567
585613
  }
585568
585614
  try {
585569
- execSync48(`"${venvPython2}" -c "import numpy"`, { stdio: "pipe", timeout: 1e4 });
585615
+ execSync48(`"${venvPython2}" -c "import numpy"`, {
585616
+ stdio: "pipe",
585617
+ timeout: 1e4
585618
+ });
585570
585619
  return true;
585571
585620
  } catch {
585572
585621
  return false;
@@ -585698,21 +585747,29 @@ var init_listen = __esm({
585698
585747
  }
585699
585748
  } catch {
585700
585749
  }
585701
- this.process = spawn25(pyPath, [
585702
- this.scriptPath,
585703
- "--model",
585704
- this.model,
585705
- "--chunk-seconds",
585706
- "3",
585707
- "--window-seconds",
585708
- "10"
585709
- ], {
585710
- stdio: ["pipe", "pipe", "pipe"],
585711
- env: { ...process.env }
585712
- });
585750
+ this.process = spawn25(
585751
+ pyPath,
585752
+ [
585753
+ this.scriptPath,
585754
+ "--model",
585755
+ this.model,
585756
+ "--chunk-seconds",
585757
+ "3",
585758
+ "--window-seconds",
585759
+ "10"
585760
+ ],
585761
+ {
585762
+ stdio: ["pipe", "pipe", "pipe"],
585763
+ env: { ...process.env }
585764
+ }
585765
+ );
585713
585766
  return new Promise((resolve67, reject) => {
585714
585767
  const timeout2 = setTimeout(() => {
585715
- reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
585768
+ reject(
585769
+ new Error(
585770
+ "Whisper fallback: model load timeout (5 min). First run downloads the model."
585771
+ )
585772
+ );
585716
585773
  }, 3e5);
585717
585774
  const rl = createInterface2({ input: this.process.stdout });
585718
585775
  onReadlineLine(rl, (line) => {
@@ -585752,7 +585809,9 @@ var init_listen = __esm({
585752
585809
  onChildClose(this.process, (code8) => {
585753
585810
  if (!this._ready) {
585754
585811
  clearTimeout(timeout2);
585755
- reject(new Error(`Whisper worker exited with code ${code8} before ready`));
585812
+ reject(
585813
+ new Error(`Whisper worker exited with code ${code8} before ready`)
585814
+ );
585756
585815
  }
585757
585816
  });
585758
585817
  });
@@ -585825,7 +585884,8 @@ var init_listen = __esm({
585825
585884
  }
585826
585885
  /** Check if transcribe-cli is available. */
585827
585886
  async isAvailable() {
585828
- if (this.transcribeCliAvailable !== null) return this.transcribeCliAvailable;
585887
+ if (this.transcribeCliAvailable !== null)
585888
+ return this.transcribeCliAvailable;
585829
585889
  try {
585830
585890
  const mod3 = await this.loadTranscribeCli();
585831
585891
  this.transcribeCliAvailable = mod3 !== null;
@@ -585869,7 +585929,13 @@ var init_listen = __esm({
585869
585929
  try {
585870
585930
  const { readdirSync: readdirSync53 } = await import("node:fs");
585871
585931
  for (const ver of readdirSync53(nvmBase)) {
585872
- const tcPath = join113(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
585932
+ const tcPath = join113(
585933
+ nvmBase,
585934
+ ver,
585935
+ "lib",
585936
+ "node_modules",
585937
+ "transcribe-cli"
585938
+ );
585873
585939
  if (existsSync98(join113(tcPath, "dist", "index.js"))) {
585874
585940
  const { createRequire: createRequire10 } = await import("node:module");
585875
585941
  const req3 = createRequire10(import.meta.url);
@@ -585900,7 +585966,10 @@ var init_listen = __esm({
585900
585966
  }
585901
585967
  if (!tc) {
585902
585968
  try {
585903
- execSync48("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
585969
+ execSync48("npm i -g transcribe-cli", {
585970
+ stdio: "pipe",
585971
+ timeout: 18e4
585972
+ });
585904
585973
  this.transcribeCliAvailable = null;
585905
585974
  tc = await this.loadTranscribeCli();
585906
585975
  } catch {
@@ -585914,14 +585983,26 @@ var init_listen = __esm({
585914
585983
  if (TranscribeLive) {
585915
585984
  let tcUpToDate = false;
585916
585985
  try {
585917
- const tcPkgPath = join113(dirname35(__require.resolve?.("transcribe-cli/package.json") || ""), "package.json");
585986
+ const tcPkgPath = join113(
585987
+ dirname35(__require.resolve?.("transcribe-cli/package.json") || ""),
585988
+ "package.json"
585989
+ );
585918
585990
  if (existsSync98(tcPkgPath)) {
585919
- const tcPkg = JSON.parse(__require("fs").readFileSync(tcPkgPath, "utf8"));
585991
+ const tcPkg = JSON.parse(
585992
+ __require("fs").readFileSync(tcPkgPath, "utf8")
585993
+ );
585920
585994
  tcUpToDate = tcPkg.version && tcPkg.version >= "2.0.1";
585921
585995
  }
585922
585996
  } catch {
585923
585997
  try {
585924
- const out = execSync48("npm list -g transcribe-cli --depth=0 --json", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 1e4 });
585998
+ const out = execSync48(
585999
+ "npm list -g transcribe-cli --depth=0 --json",
586000
+ {
586001
+ encoding: "utf-8",
586002
+ stdio: ["pipe", "pipe", "pipe"],
586003
+ timeout: 1e4
586004
+ }
586005
+ );
585925
586006
  const parsed = JSON.parse(out);
585926
586007
  const ver = parsed?.dependencies?.["transcribe-cli"]?.version || "";
585927
586008
  tcUpToDate = ver >= "2.0.1";
@@ -585930,7 +586011,10 @@ var init_listen = __esm({
585930
586011
  }
585931
586012
  if (!tcUpToDate) {
585932
586013
  try {
585933
- execSync48("npm i -g transcribe-cli@latest", { stdio: "pipe", timeout: 12e4 });
586014
+ execSync48("npm i -g transcribe-cli@latest", {
586015
+ stdio: "pipe",
586016
+ timeout: 12e4
586017
+ });
585934
586018
  this.transcribeCliAvailable = null;
585935
586019
  const reloaded = await this.loadTranscribeCli();
585936
586020
  if (reloaded?.TranscribeLive) {
@@ -585961,18 +586045,24 @@ var init_listen = __esm({
585961
586045
  sampleWidth: 2,
585962
586046
  chunkDuration: 3
585963
586047
  });
585964
- this.liveTranscriber.on("transcript", (evt) => {
585965
- if (!evt.text.trim()) return;
585966
- this.lastTranscriptTime = Date.now();
585967
- this.pendingText = evt.text.trim();
585968
- this.emit("transcript", this.pendingText, evt.isFinal);
585969
- if (this.config.mode === "auto") this.resetSilenceTimer();
585970
- });
586048
+ this.liveTranscriber.on(
586049
+ "transcript",
586050
+ (evt) => {
586051
+ if (!evt.text.trim()) return;
586052
+ this.lastTranscriptTime = Date.now();
586053
+ this.pendingText = evt.text.trim();
586054
+ this.emit("transcript", this.pendingText, evt.isFinal);
586055
+ if (this.config.mode === "auto") this.resetSilenceTimer();
586056
+ }
586057
+ );
585971
586058
  this.liveTranscriber.on("error", (err) => {
585972
586059
  this.emit("error", err);
585973
586060
  });
585974
586061
  await new Promise((resolve67, reject) => {
585975
- const timeout2 = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
586062
+ const timeout2 = setTimeout(
586063
+ () => reject(new Error("Model load timeout (60s)")),
586064
+ 6e4
586065
+ );
585976
586066
  this.liveTranscriber.on("ready", () => {
585977
586067
  clearTimeout(timeout2);
585978
586068
  resolve67();
@@ -586005,7 +586095,10 @@ var init_listen = __esm({
586005
586095
  return `No transcription backend available.${hint} live-whisper.py not found.`;
586006
586096
  }
586007
586097
  try {
586008
- const fallback = new WhisperFallbackTranscriber(this.config.model, scriptPath2);
586098
+ const fallback = new WhisperFallbackTranscriber(
586099
+ this.config.model,
586100
+ scriptPath2
586101
+ );
586009
586102
  usedFallback = true;
586010
586103
  fallback.on("status", (msg) => {
586011
586104
  this.emit("info", msg);
@@ -586186,7 +586279,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
586186
586279
  }
586187
586280
  if (!tc) {
586188
586281
  try {
586189
- execSync48("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
586282
+ execSync48("npm i -g transcribe-cli", {
586283
+ stdio: "pipe",
586284
+ timeout: 18e4
586285
+ });
586190
586286
  this.transcribeCliAvailable = null;
586191
586287
  tc = await this.loadTranscribeCli();
586192
586288
  } catch {
@@ -586202,7 +586298,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
586202
586298
  chunkDuration: 3
586203
586299
  });
586204
586300
  await new Promise((resolve67, reject) => {
586205
- const timeout2 = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
586301
+ const timeout2 = setTimeout(
586302
+ () => reject(new Error("Model load timeout (60s)")),
586303
+ 6e4
586304
+ );
586206
586305
  transcriber.on("ready", () => {
586207
586306
  clearTimeout(timeout2);
586208
586307
  resolve67();
@@ -586219,7 +586318,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
586219
586318
  const scriptPath2 = findLiveWhisperScript();
586220
586319
  if (!scriptPath2) return null;
586221
586320
  try {
586222
- const fallback = new WhisperFallbackTranscriber(this.config.model, scriptPath2);
586321
+ const fallback = new WhisperFallbackTranscriber(
586322
+ this.config.model,
586323
+ scriptPath2
586324
+ );
586223
586325
  await fallback.start();
586224
586326
  return fallback;
586225
586327
  } catch {
@@ -586239,7 +586341,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
586239
586341
  }
586240
586342
  if (!tc) {
586241
586343
  try {
586242
- execSync48("npm i -g transcribe-cli", { stdio: "pipe", timeout: 18e4 });
586344
+ execSync48("npm i -g transcribe-cli", {
586345
+ stdio: "pipe",
586346
+ timeout: 18e4
586347
+ });
586243
586348
  this.transcribeCliAvailable = null;
586244
586349
  tc = await this.loadTranscribeCli();
586245
586350
  } catch {
@@ -586284,7 +586389,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
586284
586389
  return fb;
586285
586390
  }
586286
586391
  if (lastErr) {
586287
- this.emit("error", lastErr instanceof Error ? lastErr : new Error(String(lastErr)));
586392
+ this.emit(
586393
+ "error",
586394
+ lastErr instanceof Error ? lastErr : new Error(String(lastErr))
586395
+ );
586288
586396
  }
586289
586397
  return null;
586290
586398
  }
@@ -592813,7 +592921,12 @@ function formatMarkdownLine(line) {
592813
592921
  }
592814
592922
  if (/^>\s?/.test(line)) {
592815
592923
  const content = line.replace(/^>\s?/, "");
592816
- return fg256(MD.blockquote, "│ ") + c3.italic(fg256(MD.blockquote, formatInlineMarkdown(content)));
592924
+ const formattedContent = formatInlineMarkdown(content);
592925
+ const bqColor = MD.blockquote;
592926
+ const bqPrefix = `\x1B[38;5;${bqColor}m│ \x1B[0m\x1B[3m\x1B[38;5;${bqColor}m`;
592927
+ const avail = getTermWidth() - 4;
592928
+ const wrapped = wrapLinesWithPrefix(formattedContent, bqPrefix, avail);
592929
+ return wrapped.map((l2) => l2 + "\x1B[0m").join("\n");
592817
592930
  }
592818
592931
  if (/^\|(.+)\|/.test(line)) {
592819
592932
  if (/^\|[\s:_-]+\|/.test(line)) {
@@ -592991,6 +593104,53 @@ function wrapToolTextLine(text2, width) {
592991
593104
  out.push(remaining);
592992
593105
  return out;
592993
593106
  }
593107
+ function wrapLinesWithPrefix(content, prefix, maxWidth) {
593108
+ const pLen = visibleLen(prefix);
593109
+ const avail = Math.max(4, maxWidth - pLen);
593110
+ const out = [];
593111
+ for (const srcLine of content.split("\n")) {
593112
+ const trimmed = srcLine.trimEnd();
593113
+ if (!trimmed) {
593114
+ out.push(prefix);
593115
+ continue;
593116
+ }
593117
+ const visLen = visibleLen(trimmed);
593118
+ if (visLen <= avail) {
593119
+ out.push(prefix + trimmed);
593120
+ continue;
593121
+ }
593122
+ let remaining = trimmed;
593123
+ while (visibleLen(remaining) > avail) {
593124
+ let breakAt = remaining.length;
593125
+ let bestBreak = remaining.lastIndexOf(" ", avail);
593126
+ if (bestBreak > 0) {
593127
+ breakAt = bestBreak;
593128
+ } else {
593129
+ breakAt = findVisibleBreak(remaining, avail);
593130
+ }
593131
+ out.push(prefix + remaining.slice(0, breakAt).trimEnd());
593132
+ remaining = remaining.slice(breakAt).trimStart();
593133
+ }
593134
+ if (remaining) out.push(prefix + remaining);
593135
+ }
593136
+ return out;
593137
+ }
593138
+ function findVisibleBreak(text2, targetLen) {
593139
+ let visible = 0;
593140
+ let offset = 0;
593141
+ const tokenRe = /\x1B\[[0-?]*[ -/]*[@-~]|\x1B\][^\x07]*(?:\x07|\x1B\\)|./gs;
593142
+ for (const match of text2.matchAll(tokenRe)) {
593143
+ const token = match[0];
593144
+ if (token.startsWith("\x1B")) {
593145
+ offset = match.index + token.length;
593146
+ continue;
593147
+ }
593148
+ visible++;
593149
+ offset = match.index + token.length;
593150
+ if (visible >= targetLen) break;
593151
+ }
593152
+ return offset;
593153
+ }
592994
593154
  function buildToolTopBorder(title, metrics2, width, colorCode, metricsColorCode = 222) {
592995
593155
  const border = toolColorSeq(colorCode);
592996
593156
  const titleColor = toolColorSeq(colorCode, true);
@@ -593685,7 +593845,9 @@ function renderToolCallStart(toolName, args, verboseOrOpts) {
593685
593845
  }
593686
593846
  function renderToolLine(content, isLast = false) {
593687
593847
  const connector = isLast ? "└" : "├";
593688
- process.stdout.write(` ${c3.dim(connector)}─ ${content}
593848
+ const prefix = ` ${c3.dim(connector)}─ `;
593849
+ const lines = wrapLinesWithPrefix(content, prefix, getTermWidth());
593850
+ process.stdout.write(`${lines.join("\n")}
593689
593851
  `);
593690
593852
  }
593691
593853
  function renderToolResult(toolName, success, output, verboseOrOpts) {
@@ -593897,8 +594059,10 @@ function renderError(message2) {
593897
594059
  breakTelegramCoalesce();
593898
594060
  const redir = _contentWriteHook?.redirect?.();
593899
594061
  const icon = _emojisEnabled ? "\x1B[38;5;198m✖\x1B[0m" : "\x1B[38;5;198mE\x1B[0m";
594062
+ const prefix = `${icon} \x1B[38;5;198m`;
594063
+ const lines = wrapLinesWithPrefix(message2, prefix, getTermWidth());
593900
594064
  const text2 = `
593901
- ${icon} \x1B[38;5;198m${message2}\x1B[0m
594065
+ ${lines.map((l2) => l2 + "\x1B[0m").join("\n")}
593902
594066
  `;
593903
594067
  if (redir) {
593904
594068
  redir(text2);
@@ -593913,7 +594077,9 @@ function renderInfo(message2) {
593913
594077
  const redir = _contentWriteHook?.redirect?.();
593914
594078
  const dim = dimFg();
593915
594079
  const icon = `${dim}∙\x1B[0m`;
593916
- const text2 = `${icon} ${dim}${message2}\x1B[0m
594080
+ const prefix = `${icon} ${dim}`;
594081
+ const lines = wrapLinesWithPrefix(message2, prefix, getTermWidth());
594082
+ const text2 = `${lines.map((l2) => l2 + "\x1B[0m").join("\n")}
593917
594083
  `;
593918
594084
  if (redir) {
593919
594085
  redir(text2);
@@ -593927,7 +594093,9 @@ function renderWarning(message2) {
593927
594093
  breakTelegramCoalesce();
593928
594094
  const redir = _contentWriteHook?.redirect?.();
593929
594095
  const icon = "\x1B[38;5;214m!\x1B[0m";
593930
- const text2 = `${icon} \x1B[38;5;214m${message2}\x1B[0m
594096
+ const prefix = `${icon} \x1B[38;5;214m`;
594097
+ const lines = wrapLinesWithPrefix(message2, prefix, getTermWidth());
594098
+ const text2 = `${lines.map((l2) => l2 + "\x1B[0m").join("\n")}
593931
594099
  `;
593932
594100
  if (redir) {
593933
594101
  redir(text2);
@@ -593940,7 +594108,9 @@ function renderWarning(message2) {
593940
594108
  function renderVerbose(message2) {
593941
594109
  breakTelegramCoalesce();
593942
594110
  const redir = _contentWriteHook?.redirect?.();
593943
- const text2 = ` ${accentFg()}▹\x1B[0m ${c3.dim(message2)}
594111
+ const prefix = ` ${accentFg()}▹\x1B[0m ${dimFg()}`;
594112
+ const lines = wrapLinesWithPrefix(message2, prefix, getTermWidth());
594113
+ const text2 = `${lines.map((l2) => l2 + "\x1B[0m").join("\n")}
593944
594114
  `;
593945
594115
  if (redir) {
593946
594116
  redir(text2);
@@ -619386,7 +619556,9 @@ except Exception as exc:
619386
619556
  try {
619387
619557
  await this.generateCloneRef(modelId);
619388
619558
  const meta = this.loadCloneMeta();
619389
- meta[`${modelId}-ref.wav`] = modelId === "glados" ? "GLaDOS" : "Overwatch";
619559
+ meta[`${modelId}-ref.wav`] = {
619560
+ name: modelId === "glados" ? "GLaDOS" : "Overwatch"
619561
+ };
619390
619562
  this.saveCloneMeta(meta);
619391
619563
  } catch {
619392
619564
  }
@@ -619518,8 +619690,17 @@ except Exception as exc:
619518
619690
  } catch (err) {
619519
619691
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
619520
619692
  }
619693
+ let transcript;
619694
+ if (this.misottsActive) {
619695
+ try {
619696
+ const { transcribeFileViaWhisper: transcribeFileViaWhisper2 } = await Promise.resolve().then(() => (init_listen(), listen_exports));
619697
+ const result = await transcribeFileViaWhisper2(destPath, "base");
619698
+ if (result?.text) transcript = result.text;
619699
+ } catch {
619700
+ }
619701
+ }
619521
619702
  const meta = this.loadCloneMeta();
619522
- meta[destFilename] = srcName.replace(/[-_]/g, " ");
619703
+ meta[destFilename] = { name: srcName.replace(/[-_]/g, " "), transcript };
619523
619704
  this.saveCloneMeta(meta);
619524
619705
  this.luxttsCloneRef = destPath;
619525
619706
  this.misottsCloneRef = destPath;
@@ -619579,7 +619760,15 @@ except Exception as exc:
619579
619760
  const p2 = _VoiceEngine.cloneMetaFile();
619580
619761
  if (!existsSync119(p2)) return {};
619581
619762
  try {
619582
- return JSON.parse(readFileSync97(p2, "utf8"));
619763
+ const raw = JSON.parse(readFileSync97(p2, "utf8"));
619764
+ if (typeof Object.values(raw)[0] === "string") {
619765
+ const migrated = {};
619766
+ for (const [k, v] of Object.entries(raw)) {
619767
+ migrated[k] = { name: v };
619768
+ }
619769
+ return migrated;
619770
+ }
619771
+ return raw;
619583
619772
  } catch {
619584
619773
  return {};
619585
619774
  }
@@ -619618,12 +619807,14 @@ except Exception as exc:
619618
619807
  size = statSync44(p2).size;
619619
619808
  } catch {
619620
619809
  }
619810
+ const entry = meta[f2];
619811
+ const displayName = typeof entry === "string" ? entry : entry?.name ?? f2.replace(/\.[^.]+$/, "").replace(/[-_]/g, " ");
619621
619812
  return {
619622
619813
  filename: f2,
619623
619814
  path: p2,
619624
- name: meta[f2] ?? f2.replace(/\.[^.]+$/, "").replace(/[-_]/g, " "),
619815
+ name: displayName,
619625
619816
  size,
619626
- isActive: this.luxttsCloneRef === p2
619817
+ isActive: this.luxttsCloneRef === p2 || this.misottsCloneRef === p2
619627
619818
  };
619628
619819
  });
619629
619820
  }
@@ -619648,7 +619839,11 @@ except Exception as exc:
619648
619839
  /** Rename a clone reference's friendly name (stored in meta.json). */
619649
619840
  renameCloneRef(filename, newName) {
619650
619841
  const meta = this.loadCloneMeta();
619651
- meta[filename] = newName;
619842
+ const existing = meta[filename];
619843
+ meta[filename] = {
619844
+ name: newName,
619845
+ transcript: typeof existing === "string" ? void 0 : existing?.transcript
619846
+ };
619652
619847
  this.saveCloneMeta(meta);
619653
619848
  }
619654
619849
  /** Set the active clone reference by filename. */
@@ -619656,6 +619851,7 @@ except Exception as exc:
619656
619851
  const p2 = join131(luxttsCloneRefsDir(), filename);
619657
619852
  if (!existsSync119(p2)) return `File not found: ${filename}`;
619658
619853
  this.luxttsCloneRef = p2;
619854
+ this.misottsCloneRef = p2;
619659
619855
  return `Active clone voice set to: ${filename}`;
619660
619856
  }
619661
619857
  /**
@@ -621993,6 +622189,7 @@ def main():
621993
622189
  try:
621994
622190
  text = req["text"]
621995
622191
  clone_ref = req.get("clone_ref", "")
622192
+ clone_transcript = req.get("clone_transcript", "")
621996
622193
  output_path = req["output_path"]
621997
622194
  max_len_ms = float(req.get("max_audio_length_ms", 30000))
621998
622195
  temperature = float(req.get("temperature", 0.9))
@@ -622005,7 +622202,7 @@ def main():
622005
622202
  prompt_audio = torchaudio.functional.resample(
622006
622203
  prompt_audio.squeeze(0), orig_freq=sr, new_freq=generator.sample_rate
622007
622204
  )
622008
- context.append(Segment(speaker=0, text="", audio=prompt_audio))
622205
+ context.append(Segment(speaker=0, text=clone_transcript, audio=prompt_audio))
622009
622206
 
622010
622207
  audio = generator.generate(
622011
622208
  text=text, speaker=0,
@@ -622134,10 +622331,15 @@ if __name__ == "__main__":
622134
622331
  );
622135
622332
  try {
622136
622333
  const settings = this.getMisottsSettings();
622334
+ const cloneName = this.misottsCloneRef.split("/").pop() ?? "";
622335
+ const meta = this.loadCloneMeta();
622336
+ const cloneEntry = meta[cloneName];
622337
+ const cloneTranscript = typeof cloneEntry === "string" ? void 0 : cloneEntry?.transcript;
622137
622338
  await this.misottsRequest({
622138
622339
  action: "synthesize",
622139
622340
  text: cleaned,
622140
622341
  clone_ref: this.misottsCloneRef,
622342
+ clone_transcript: cloneTranscript ?? "",
622141
622343
  output_path: wavPath,
622142
622344
  max_audio_length_ms: maxAudioLengthMs ?? settings.maxAudioLengthMs,
622143
622345
  temperature: settings.temperature,
@@ -622277,10 +622479,15 @@ if __name__ == "__main__":
622277
622479
  const wavPath = join131(tmpdir21(), `omnius-misotts-buf-${Date.now()}.wav`);
622278
622480
  try {
622279
622481
  const settings = this.getMisottsSettings();
622482
+ const cloneName = this.misottsCloneRef.split("/").pop() ?? "";
622483
+ const meta = this.loadCloneMeta();
622484
+ const cloneEntry = meta[cloneName];
622485
+ const cloneTranscript = typeof cloneEntry === "string" ? void 0 : cloneEntry?.transcript;
622280
622486
  await this.misottsRequest({
622281
622487
  action: "synthesize",
622282
622488
  text: cleaned,
622283
622489
  clone_ref: this.misottsCloneRef,
622490
+ clone_transcript: cloneTranscript ?? "",
622284
622491
  output_path: wavPath,
622285
622492
  max_audio_length_ms: settings.maxAudioLengthMs,
622286
622493
  temperature: settings.temperature,
@@ -626119,9 +626326,11 @@ async function handleSlashCommand(input, ctx3) {
626119
626326
  return "handled";
626120
626327
  }
626121
626328
  if (!cloneArg) {
626329
+ const isMisottsClone = currentVoiceModel === "misotts" || currentVoiceModel === "personaplex";
626330
+ const instruction = isMisottsClone ? "Drag and drop an audio file (will auto-transcribe via Whisper for MisoTTS)" : "Drag and drop an audio file to use as voice clone reference";
626122
626331
  const dropResult = await showDropPanel({
626123
626332
  title: "Voice Clone — Drop Audio File",
626124
- instruction: "Drag and drop an audio file to use as voice clone reference",
626333
+ instruction,
626125
626334
  allowedExtensions: [
626126
626335
  ".wav",
626127
626336
  ".mp3",
@@ -632772,6 +632981,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
632772
632981
  const clones = ctx3.voiceListClones?.() ?? [];
632773
632982
  const activeClone = clones.find((c8) => c8.isActive);
632774
632983
  const cloneStatus = activeClone ? `clone: ${selectColors.cyan(activeClone.name)}` : "no clone active";
632984
+ const isMisotts = currentModel === "misotts";
632985
+ const isLuxtts = currentModel === "luxtts";
632986
+ const isSupertonic = currentModel === "supertonic";
632987
+ const hasCloneBackend = isMisotts || isLuxtts;
632988
+ const cloneBackendLabel = isMisotts ? "MisoTTS" : isLuxtts ? "LuxTTS" : "Voice";
632775
632989
  const items = [
632776
632990
  { key: "header-status", label: selectColors.dim("─── Voice Status ───") },
632777
632991
  {
@@ -632803,36 +633017,79 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
632803
633017
  key: "system",
632804
633018
  label: "Change TTS System",
632805
633019
  detail: "onnx / mlx / luxtts / misotts / supertonic3"
632806
- },
632807
- {
632808
- key: "supertonic",
632809
- label: "Supertonic3 Settings",
632810
- detail: "voice style, language, speed, quality, profiles"
632811
- },
632812
- {
632813
- key: "misotts",
632814
- label: "MisoTTS 8B Settings",
632815
- detail: "temperature, topk, max audio length"
632816
- },
632817
- { key: "clone", label: "Clone Voice", detail: "drag & drop audio file" },
632818
- {
632819
- key: "list",
632820
- label: "Manage Clone Voices",
632821
- detail: `${clones.length} clone(s)`
632822
- },
633020
+ }
633021
+ ];
633022
+ if (isMisotts) {
633023
+ items.push(
633024
+ {
633025
+ key: "header-misotts",
633026
+ label: selectColors.dim("─── Settings: MisoTTS 8B ───")
633027
+ },
633028
+ {
633029
+ key: "misotts",
633030
+ label: "Temperature, Top-K, Max Length",
633031
+ detail: `temp=${ctx3.voiceGetMisottsSettings?.()?.temperature ?? 0.9} topk=${ctx3.voiceGetMisottsSettings?.()?.topk ?? 50}`
633032
+ }
633033
+ );
633034
+ } else if (isSupertonic) {
633035
+ items.push(
633036
+ {
633037
+ key: "header-supertonic",
633038
+ label: selectColors.dim("─── Settings: Supertonic3 ───")
633039
+ },
633040
+ {
633041
+ key: "supertonic",
633042
+ label: "Voice Style, Language, Speed, Quality, Expression",
633043
+ detail: `voice=${ctx3.voiceGetSupertonicSettings?.()?.voiceName ?? "M4"} lang=${ctx3.voiceGetSupertonicSettings?.()?.lang ?? "en"}`
633044
+ }
633045
+ );
633046
+ } else {
633047
+ items.push(
633048
+ {
633049
+ key: "supertonic",
633050
+ label: "Supertonic3 Settings",
633051
+ detail: "voice style, language, speed, quality, profiles"
633052
+ },
633053
+ {
633054
+ key: "misotts",
633055
+ label: "MisoTTS 8B Settings",
633056
+ detail: "temperature, topk, max audio length"
633057
+ }
633058
+ );
633059
+ }
633060
+ if (hasCloneBackend) {
633061
+ items.push(
633062
+ {
633063
+ key: "header-clone",
633064
+ label: selectColors.dim(`─── Clone: ${cloneBackendLabel} ───`)
633065
+ },
633066
+ {
633067
+ key: "clone",
633068
+ label: `Clone Voice (${cloneBackendLabel})`,
633069
+ detail: "drag & drop audio file"
633070
+ },
633071
+ {
633072
+ key: "list",
633073
+ label: "Manage Clone Voices",
633074
+ detail: `${clones.length} clone(s)`
633075
+ }
633076
+ );
633077
+ }
633078
+ items.push(
632823
633079
  { key: "header-test", label: selectColors.dim("─── Preview ───") },
632824
633080
  {
632825
633081
  key: "preview",
632826
633082
  label: "Preview Voice",
632827
633083
  detail: "speak a random test phrase (or press p)"
632828
633084
  }
632829
- ];
633085
+ );
633086
+ const skipKeys = items.filter((i2) => i2.key.startsWith("header-") || i2.key === "info-voice").map((i2) => i2.key);
632830
633087
  const result = await tuiSelect({
632831
633088
  items,
632832
633089
  title: "Voice Configuration",
632833
633090
  rl: ctx3.rl,
632834
633091
  availableRows: ctx3.availableContentRows?.(),
632835
- skipKeys: ["header-status", "header-config", "info-voice", "header-test"],
633092
+ skipKeys,
632836
633093
  customKeyHint: " p preview",
632837
633094
  onCustomKey(item, key, helpers) {
632838
633095
  if (key === "p" || key === "P") {
@@ -633106,9 +633363,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
633106
633363
  continue;
633107
633364
  }
633108
633365
  case "clone": {
633366
+ const isMisottsClone = ctx3.voiceGetModel?.() === "misotts";
633367
+ const instruction = isMisottsClone ? "Drag and drop an audio file (will auto-transcribe via Whisper for MisoTTS)" : "Drag and drop an audio file to use as voice clone reference";
633109
633368
  const dropResult = await showDropPanel({
633110
633369
  title: "Voice Clone — Drop Audio File",
633111
- instruction: "Drag and drop an audio file to use as voice clone reference",
633370
+ instruction,
633112
633371
  allowedExtensions: [
633113
633372
  ".wav",
633114
633373
  ".mp3",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.248",
3
+ "version": "1.0.249",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.248",
9
+ "version": "1.0.249",
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.248",
3
+ "version": "1.0.249",
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",