omnius 1.0.143 → 1.0.144

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
@@ -4287,6 +4287,55 @@ var init_shell = __esm({
4287
4287
  const timeout2 = args["timeout"] ?? this.defaultTimeout;
4288
4288
  const stdinInput = args["stdin"];
4289
4289
  const result = await this.runCommand(command, timeout2, stdinInput);
4290
+ return this.finalizeResult(command, timeout2, start2, result);
4291
+ }
4292
+ async *executeStream(args) {
4293
+ const start2 = performance.now();
4294
+ const command = args["command"];
4295
+ const timeout2 = args["timeout"] ?? this.defaultTimeout;
4296
+ const stdinInput = args["stdin"];
4297
+ const pending2 = [];
4298
+ let wake = null;
4299
+ let done = false;
4300
+ let finalResult = null;
4301
+ let finalError = null;
4302
+ const notify2 = () => {
4303
+ wake?.();
4304
+ wake = null;
4305
+ };
4306
+ const enqueue = (chunk) => {
4307
+ if (!chunk)
4308
+ return;
4309
+ pending2.push(chunk);
4310
+ notify2();
4311
+ };
4312
+ this.runCommand(command, timeout2, stdinInput, enqueue).then((result) => this.finalizeResult(command, timeout2, start2, result)).then((result) => {
4313
+ finalResult = result;
4314
+ }).catch((err) => {
4315
+ finalError = err;
4316
+ }).finally(() => {
4317
+ done = true;
4318
+ notify2();
4319
+ });
4320
+ while (!done || pending2.length > 0) {
4321
+ if (pending2.length > 0) {
4322
+ yield pending2.shift();
4323
+ continue;
4324
+ }
4325
+ await new Promise((resolve55) => {
4326
+ wake = resolve55;
4327
+ });
4328
+ }
4329
+ if (finalError)
4330
+ throw finalError;
4331
+ return finalResult ?? {
4332
+ success: false,
4333
+ output: "",
4334
+ error: "Shell command did not return a result",
4335
+ durationMs: performance.now() - start2
4336
+ };
4337
+ }
4338
+ async finalizeResult(command, timeout2, start2, result) {
4290
4339
  if (result.success === false || result.output && result.output.length < 800) {
4291
4340
  const looksTruncated = /\|\s*(tail|head|sed\s+-n|cut\s+|awk\s+'NR)\b/.test(command);
4292
4341
  if (looksTruncated && result.output) {
@@ -4344,7 +4393,7 @@ ${elevatedResult.stderr}` : ""),
4344
4393
  const combined = (result.error ?? "") + result.output;
4345
4394
  return PERMISSION_ERROR_RE.test(combined);
4346
4395
  }
4347
- runCommand(command, timeout2, stdinInput) {
4396
+ runCommand(command, timeout2, stdinInput, onOutput) {
4348
4397
  const start2 = performance.now();
4349
4398
  const isWin2 = process.platform === "win32";
4350
4399
  let pwdDir = mkdtempSync(join5(tmpdir(), "omnius-shell-"));
@@ -4435,13 +4484,17 @@ exit $__omnius_exit
4435
4484
  }, timeout2);
4436
4485
  let exitFlushTimer = null;
4437
4486
  child.stdout.on("data", (data) => {
4438
- stdout += data.toString();
4487
+ const text = data.toString();
4488
+ stdout += text;
4489
+ onOutput?.(text);
4439
4490
  if (stdout.length > maxBuf) {
4440
4491
  stdout = stdout.slice(0, maxBuf);
4441
4492
  }
4442
4493
  });
4443
4494
  child.stderr.on("data", (data) => {
4444
- stderr += data.toString();
4495
+ const text = data.toString();
4496
+ stderr += text;
4497
+ onOutput?.(text);
4445
4498
  if (stderr.length > maxBuf) {
4446
4499
  stderr = stderr.slice(0, maxBuf);
4447
4500
  }
@@ -549672,7 +549725,8 @@ ${header}${truncatedCache}`
549672
549725
  const progress = String(iterResult.value);
549673
549726
  this.emit({
549674
549727
  type: "status",
549675
- content: `${tc.name}: ${progress}`,
549728
+ toolName: tc.name,
549729
+ content: progress,
549676
549730
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
549677
549731
  });
549678
549732
  iterResult = await gen.next();
@@ -576454,13 +576508,32 @@ function refreshThemeVars() {
576454
576508
  TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
576455
576509
  TEXT_DIM = tuiTextDim();
576456
576510
  }
576511
+ function sanitizeSponsorHeaderText(value2, max = SPONSOR_HEADER_LABEL_MAX) {
576512
+ const cleaned = stripAnsi(String(value2 ?? "")).replace(/[\x00-\x1F\x7F]/g, " ").replace(/\s+/g, " ").trim();
576513
+ if (cleaned.length <= max) return cleaned;
576514
+ return cleaned.slice(0, max).trimEnd();
576515
+ }
576516
+ function sanitizeSponsorHeaderLink(value2) {
576517
+ const raw = sanitizeSponsorHeaderText(value2, 2048);
576518
+ if (!raw) return "";
576519
+ try {
576520
+ const url = new URL(raw);
576521
+ return url.protocol === "http:" || url.protocol === "https:" ? url.href : "";
576522
+ } catch {
576523
+ return "";
576524
+ }
576525
+ }
576526
+ function sanitizeSponsorHeaderColor(value2) {
576527
+ const color = Number(value2);
576528
+ return Number.isInteger(color) && color >= 0 && color <= 255 ? color : 214;
576529
+ }
576457
576530
  function setTerminalTitle(task, version4) {
576458
576531
  if (!process.stdout.isTTY) return;
576459
576532
  const ver = version4 ? `Omnius v${version4}` : "Omnius";
576460
576533
  const title = task ? `${task.slice(0, 60)} · ${ver}` : ver;
576461
576534
  process.stdout.write(`\x1B]2;${title}\x07`);
576462
576535
  }
576463
- var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_ACCENT_GREEN, HEADER_ACCENT_BOLD_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, StatusBar;
576536
+ var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_ACCENT_GREEN, HEADER_ACCENT_BOLD_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, SPONSOR_HEADER_LABEL_MAX, StatusBar;
576464
576537
  var init_status_bar = __esm({
576465
576538
  "packages/cli/src/tui/status-bar.ts"() {
576466
576539
  "use strict";
@@ -576654,6 +576727,7 @@ var init_status_bar = __esm({
576654
576727
  RESET4 = "\x1B[0m";
576655
576728
  CURSOR_BLINK_BLOCK = "\x1B[1 q";
576656
576729
  _isWindows = process.platform === "win32";
576730
+ SPONSOR_HEADER_LABEL_MAX = 48;
576657
576731
  StatusBar = class _StatusBar {
576658
576732
  metrics = {
576659
576733
  promptTokens: 0,
@@ -576807,7 +576881,7 @@ var init_status_bar = __esm({
576807
576881
  _suggestions = [];
576808
576882
  /** Currently highlighted suggestion index (-1 = none) */
576809
576883
  _suggestIndex = -1;
576810
- /** Sponsor header data for unicode box injection */
576884
+ /** Sponsor label/link shown in the normal header identity slot */
576811
576885
  _sponsorHeader = null;
576812
576886
  /** Whether suggestions were triggered by direct typing (instant) vs history navigation (delayed) */
576813
576887
  _suggestFromHistory = false;
@@ -577038,9 +577112,26 @@ var init_status_bar = __esm({
577038
577112
  this._headerBackendUrl = backendUrl2;
577039
577113
  this.refreshHeaderAndFooter();
577040
577114
  }
577041
- /** Set sponsor header data for unicode box injection */
577115
+ /** Set sponsor label/link for the normal header identity slot */
577042
577116
  setSponsorHeader(header) {
577043
- this._sponsorHeader = header;
577117
+ if (!header) {
577118
+ this._sponsorHeader = null;
577119
+ this.refreshHeaderAndFooter();
577120
+ return;
577121
+ }
577122
+ const message2 = sanitizeSponsorHeaderText(
577123
+ header.message || header.linkText
577124
+ );
577125
+ const linkText = sanitizeSponsorHeaderText(
577126
+ header.linkText || header.message
577127
+ );
577128
+ const label = message2 || linkText;
577129
+ this._sponsorHeader = label ? {
577130
+ message: label,
577131
+ linkUrl: sanitizeSponsorHeaderLink(header.linkUrl),
577132
+ linkText: linkText || label,
577133
+ primaryColor: sanitizeSponsorHeaderColor(header.primaryColor)
577134
+ } : null;
577044
577135
  this.refreshHeaderAndFooter();
577045
577136
  }
577046
577137
  // ── Header Panel System ──────────────────────────────────────────────
@@ -584610,9 +584701,9 @@ function formatExpandedContextDiagnostic(specs, math) {
584610
584701
  memBits.push(`RAM ${fmtGB(specs.availableRamGB)}/${fmtGB(specs.totalRamGB)}${specs.unifiedMemory ? " unified" : ""}`);
584611
584702
  const mem = memBits.join(", ");
584612
584703
  const kv = `KV ${fmtKB(math.kvBytesPerToken)}/tok (${math.kvSource})`;
584613
- const fit2 = `fit ${fmtK(math.memoryFit)}, arch ${math.archCtx !== null ? fmtK(math.archCtx) : "n/a"}, floor ${fmtK(math.floor)}`;
584704
+ const fit3 = `fit ${fmtK(math.memoryFit)}, arch ${math.archCtx !== null ? fmtK(math.archCtx) : "n/a"}, floor ${fmtK(math.floor)}`;
584614
584705
  const limit = `→ ${fmtK(math.numCtx)} (${math.limitedBy === "floor" ? "min floor" : math.limitedBy === "arch" ? "arch-capped" : "memory-fit"})`;
584615
- return `[${mem} | model ${fmtGB(math.modelSizeGB)} | ${kv} | ${fit2} ${limit}]`;
584706
+ return `[${mem} | model ${fmtGB(math.modelSizeGB)} | ${kv} | ${fit3} ${limit}]`;
584616
584707
  }
584617
584708
  async function ensureExpandedContext(modelName, backendUrl2) {
584618
584709
  if (modelName.includes("cloud") || modelName.includes(":cloud")) {
@@ -589092,9 +589183,12 @@ var init_daemon = __esm({
589092
589183
  // packages/cli/src/tui/sponsor-wizard.ts
589093
589184
  var sponsor_wizard_exports = {};
589094
589185
  __export(sponsor_wizard_exports, {
589186
+ endpointModelCountLabel: () => endpointModelCountLabel,
589095
589187
  loadSponsorConfig: () => loadSponsorConfig,
589188
+ refreshEnabledEndpointModels: () => refreshEnabledEndpointModels,
589096
589189
  runSponsorWizard: () => runSponsorWizard,
589097
589190
  saveSponsorConfig: () => saveSponsorConfig,
589191
+ selectedModelsForEndpoint: () => selectedModelsForEndpoint,
589098
589192
  showSponsorDashboard: () => showSponsorDashboard
589099
589193
  });
589100
589194
  import { existsSync as existsSync103, readFileSync as readFileSync82, writeFileSync as writeFileSync52, mkdirSync as mkdirSync56 } from "node:fs";
@@ -589267,70 +589361,117 @@ async function discoverEndpoints(ollamaUrl, repoRoot) {
589267
589361
  }
589268
589362
  return endpoints;
589269
589363
  }
589270
- async function stepModelSelection(ep, rl, availableRows) {
589271
- if (!ep.models || ep.models.length === 0) return null;
589272
- let modelSizes = {};
589273
- if (ep.kind === "ollama") {
589274
- try {
589275
- const resp = await fetch(`${ep.url}/api/tags`, { signal: AbortSignal.timeout(5e3) });
589276
- if (resp.ok) {
589277
- const data = await resp.json();
589278
- for (const m2 of data.models || []) {
589279
- if (m2.size) modelSizes[m2.name] = `${(m2.size / 1e9).toFixed(1)}GB`;
589280
- }
589364
+ async function refreshEnabledEndpointModels(config) {
589365
+ await Promise.all(
589366
+ config.endpoints.filter((ep) => ep.enabled).map(async (ep) => {
589367
+ const models = await fetchEndpointModelNames(ep.url, ep.authHeader);
589368
+ if (models.length === 0) return;
589369
+ ep.models = models;
589370
+ if (Array.isArray(ep.selectedModels)) {
589371
+ const available = new Set(models);
589372
+ ep.selectedModels = ep.selectedModels.filter((name10) => available.has(name10));
589373
+ if (ep.selectedModels.length === models.length) ep.selectedModels = void 0;
589281
589374
  }
589282
- } catch {
589283
- }
589375
+ })
589376
+ );
589377
+ }
589378
+ function selectedModelsForEndpoint(ep) {
589379
+ return Array.isArray(ep.selectedModels) ? ep.selectedModels : ep.models;
589380
+ }
589381
+ function endpointModelCountLabel(ep) {
589382
+ if (ep.models.length === 0) return "all models";
589383
+ if (Array.isArray(ep.selectedModels)) {
589384
+ return `${ep.selectedModels.length}/${ep.models.length} models`;
589284
589385
  }
589285
- const currentSelection = new Set(
589286
- ep.selectedModels && ep.selectedModels.length > 0 ? ep.selectedModels : ep.models
589386
+ return `all ${ep.models.length} models`;
589387
+ }
589388
+ async function stepModelSelection(config, rl, availableRows) {
589389
+ const enabled2 = config.endpoints.filter((ep) => ep.enabled);
589390
+ const totalKnownModels = enabled2.reduce((sum, ep) => sum + ep.models.length, 0);
589391
+ if (totalKnownModels === 0) {
589392
+ renderWarning("No model lists were returned; sponsorship will expose each enabled endpoint's full model set.");
589393
+ return true;
589394
+ }
589395
+ const modelSizesByUrl = /* @__PURE__ */ new Map();
589396
+ await Promise.all(
589397
+ enabled2.filter((ep) => ep.kind === "ollama" && ep.models.length > 0).map(async (ep) => {
589398
+ const modelSizes = {};
589399
+ try {
589400
+ const resp = await fetch(`${ep.url}/api/tags`, { signal: AbortSignal.timeout(5e3) });
589401
+ if (resp.ok) {
589402
+ const data = await resp.json();
589403
+ for (const m2 of data.models || []) {
589404
+ if (m2.size) modelSizes[m2.name] = `${(m2.size / 1e9).toFixed(1)}GB`;
589405
+ }
589406
+ }
589407
+ } catch {
589408
+ }
589409
+ if (Object.keys(modelSizes).length > 0) {
589410
+ modelSizesByUrl.set(ep.url, modelSizes);
589411
+ }
589412
+ })
589287
589413
  );
589288
- const items = [
589289
- { key: "hdr", label: `Select Models — ${ep.label}`, modelName: "", selected: false }
589290
- ];
589291
- for (const name10 of ep.models) {
589292
- const sel = currentSelection.has(name10);
589293
- const size = modelSizes[name10] ? ` (${modelSizes[name10]})` : "";
589414
+ const selectedByUrl = new Map(
589415
+ enabled2.map((ep) => [ep.url, new Set(selectedModelsForEndpoint(ep))])
589416
+ );
589417
+ const renderModelLabel = (item) => {
589418
+ const size = modelSizesByUrl.get(item.endpoint?.url || "")?.[item.modelName];
589419
+ return `${item.selected ? "[x]" : "[ ]"} ${item.modelName}${size ? ` (${size})` : ""}`;
589420
+ };
589421
+ const items = [{ key: "hdr", label: "Select Models to Sponsor", modelName: "", selected: false }];
589422
+ for (const ep of enabled2) {
589294
589423
  items.push({
589295
- key: `model:${name10}`,
589296
- label: `${sel ? "[x]" : "[ ]"} ${name10}${size}`,
589297
- modelName: name10,
589298
- selected: sel
589424
+ key: `endpoint:${ep.url}`,
589425
+ label: `${ep.label}`,
589426
+ detail: ep.models.length > 0 ? `${ep.models.length} discovered model${ep.models.length === 1 ? "" : "s"}` : "No model list returned; endpoint will expose all models",
589427
+ endpoint: ep,
589428
+ modelName: "",
589429
+ selected: false
589299
589430
  });
589431
+ for (const name10 of ep.models) {
589432
+ const item = {
589433
+ key: `model:${encodeURIComponent(ep.url)}:${encodeURIComponent(name10)}`,
589434
+ label: "",
589435
+ endpoint: ep,
589436
+ modelName: name10,
589437
+ selected: selectedByUrl.get(ep.url)?.has(name10) ?? true,
589438
+ isModel: true
589439
+ };
589440
+ item.label = renderModelLabel(item);
589441
+ items.push(item);
589442
+ }
589300
589443
  }
589301
589444
  items.push({ key: "sep", label: "", modelName: "", selected: false });
589302
589445
  items.push({ key: "all", label: " [A] Select all", modelName: "", selected: false });
589303
589446
  items.push({ key: "none", label: " [N] Select none", modelName: "", selected: false });
589304
589447
  items.push({ key: "done", label: selectColors.green(" Done →"), modelName: "", selected: false });
589448
+ const endpointSkipKeys = enabled2.map((ep) => `endpoint:${ep.url}`);
589305
589449
  const result = await tuiSelect({
589306
589450
  items,
589307
- title: `Model Selection${ep.label}`,
589451
+ title: "Step 2/6Model Selection",
589308
589452
  rl,
589309
- skipKeys: ["hdr", "sep"],
589453
+ skipKeys: ["hdr", "sep", ...endpointSkipKeys],
589310
589454
  availableRows,
589311
589455
  onAction: (item, action) => {
589312
- if (action === "space" && item.key.startsWith("model:")) {
589456
+ if (action === "space" && item.isModel) {
589313
589457
  item.selected = !item.selected;
589314
- const size = modelSizes[item.modelName] ? ` (${modelSizes[item.modelName]})` : "";
589315
- item.label = `${item.selected ? "[x]" : "[ ]"} ${item.modelName}${size}`;
589458
+ item.label = renderModelLabel(item);
589316
589459
  return true;
589317
589460
  }
589318
589461
  return false;
589319
589462
  },
589320
589463
  onEnter: (item, _helpers) => {
589321
- if (item.key.startsWith("model:")) {
589464
+ if (item.isModel) {
589322
589465
  item.selected = !item.selected;
589323
- const size = modelSizes[item.modelName] ? ` (${modelSizes[item.modelName]})` : "";
589324
- item.label = `${item.selected ? "[x]" : "[ ]"} ${item.modelName}${size}`;
589466
+ item.label = renderModelLabel(item);
589325
589467
  _helpers.render();
589326
589468
  return true;
589327
589469
  }
589328
589470
  if (item.key === "all") {
589329
589471
  for (const it of items) {
589330
- if (it.key.startsWith("model:")) {
589472
+ if (it.isModel) {
589331
589473
  it.selected = true;
589332
- const size = modelSizes[it.modelName] ? ` (${modelSizes[it.modelName]})` : "";
589333
- it.label = `[x] ${it.modelName}${size}`;
589474
+ it.label = renderModelLabel(it);
589334
589475
  }
589335
589476
  }
589336
589477
  _helpers.render();
@@ -589338,10 +589479,9 @@ async function stepModelSelection(ep, rl, availableRows) {
589338
589479
  }
589339
589480
  if (item.key === "none") {
589340
589481
  for (const it of items) {
589341
- if (it.key.startsWith("model:")) {
589482
+ if (it.isModel) {
589342
589483
  it.selected = false;
589343
- const size = modelSizes[it.modelName] ? ` (${modelSizes[it.modelName]})` : "";
589344
- it.label = `[ ] ${it.modelName}${size}`;
589484
+ it.label = renderModelLabel(it);
589345
589485
  }
589346
589486
  }
589347
589487
  _helpers.render();
@@ -589352,11 +589492,28 @@ async function stepModelSelection(ep, rl, availableRows) {
589352
589492
  renderRow: (item, focused, _isActive) => {
589353
589493
  const prefix = focused ? selectColors.blue("❯ ") : " ";
589354
589494
  if (item.key === "hdr") return selectColors.bold(item.label);
589495
+ if (item.key.startsWith("endpoint:")) {
589496
+ return `${selectColors.bold(item.label)}${item.detail ? `
589497
+ ${selectColors.dim(item.detail)}` : ""}`;
589498
+ }
589355
589499
  return `${prefix}${item.label}`;
589356
589500
  }
589357
589501
  });
589358
589502
  if (!result.confirmed) return null;
589359
- return items.filter((it) => it.key.startsWith("model:") && it.selected).map((it) => it.modelName);
589503
+ const modelItems = items.filter((it) => it.isModel && it.endpoint);
589504
+ if (modelItems.length > 0 && !modelItems.some((it) => it.selected)) {
589505
+ renderWarning("Select at least one model before continuing.");
589506
+ return stepModelSelection(config, rl, availableRows);
589507
+ }
589508
+ for (const ep of enabled2) {
589509
+ if (ep.models.length === 0) {
589510
+ ep.selectedModels = void 0;
589511
+ continue;
589512
+ }
589513
+ const selected = modelItems.filter((it) => it.endpoint === ep && it.selected).map((it) => it.modelName);
589514
+ ep.selectedModels = selected.length === ep.models.length ? void 0 : selected;
589515
+ }
589516
+ return true;
589360
589517
  }
589361
589518
  async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
589362
589519
  const discovered = await discoverEndpoints(ollamaUrl, repoRoot);
@@ -589365,6 +589522,9 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
589365
589522
  if (!existing) {
589366
589523
  config.endpoints.push(disc);
589367
589524
  } else {
589525
+ existing.kind = disc.kind;
589526
+ existing.label = disc.label;
589527
+ if (disc.authHeader) existing.authHeader = disc.authHeader;
589368
589528
  existing.models = disc.models;
589369
589529
  }
589370
589530
  }
@@ -589372,8 +589532,8 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
589372
589532
  { key: "hdr", label: "Select Endpoints to Sponsor", isToggleable: false }
589373
589533
  ];
589374
589534
  for (const ep of config.endpoints) {
589375
- const selected = ep.selectedModels && ep.selectedModels.length > 0 ? ep.selectedModels : ep.models;
589376
- const modelCount = ep.selectedModels && ep.selectedModels.length > 0 ? `${ep.selectedModels.length}/${ep.models.length} models` : ep.models.length > 0 ? `all ${ep.models.length} models` : "all models";
589535
+ const selected = selectedModelsForEndpoint(ep);
589536
+ const modelCount = endpointModelCountLabel(ep);
589377
589537
  const modelPreview = selected.length > 0 ? selected.slice(0, 3).join(", ") + (selected.length > 3 ? ` +${selected.length - 3} more` : "") : modelCount;
589378
589538
  items.push({
589379
589539
  key: ep.url,
@@ -589396,7 +589556,7 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
589396
589556
  });
589397
589557
  const result = await tuiSelect({
589398
589558
  items,
589399
- title: "Step 1/5 — Endpoint Selection",
589559
+ title: "Step 1/6 — Endpoint Selection",
589400
589560
  rl,
589401
589561
  skipKeys: ["hdr", "sep"],
589402
589562
  availableRows,
@@ -589466,13 +589626,11 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
589466
589626
  renderWarning("Select at least one endpoint before continuing.");
589467
589627
  return stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot);
589468
589628
  }
589469
- for (const ep of config.endpoints) {
589470
- if (!ep.enabled || ep.models.length === 0) continue;
589471
- const selected = await stepModelSelection(ep, rl, availableRows);
589472
- if (selected === null) {
589473
- return stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot);
589474
- }
589475
- ep.selectedModels = selected.length === ep.models.length ? void 0 : selected;
589629
+ renderInfo("Fetching models from enabled endpoints...");
589630
+ await refreshEnabledEndpointModels(config);
589631
+ const selected = await stepModelSelection(config, rl, availableRows);
589632
+ if (selected === null) {
589633
+ return stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot);
589476
589634
  }
589477
589635
  return true;
589478
589636
  }
@@ -589512,7 +589670,7 @@ async function stepHeader(config, rl, availableRows) {
589512
589670
  const linkIdx = items.findIndex((i2) => i2.key === "link");
589513
589671
  const result = await tuiSelect({
589514
589672
  items,
589515
- title: "Step 2/5 — Sponsor Header",
589673
+ title: "Step 3/6 — Sponsor Header",
589516
589674
  rl,
589517
589675
  skipKeys: ["hdr", "sep"],
589518
589676
  availableRows,
@@ -589520,7 +589678,7 @@ async function stepHeader(config, rl, availableRows) {
589520
589678
  if (item.key === "label") {
589521
589679
  helpers.getInput("Sponsor label:", config.header.message).then((text) => {
589522
589680
  if (text !== null && text.trim()) {
589523
- config.header.message = text.trim().slice(0, 80);
589681
+ config.header.message = text.trim().slice(0, 48);
589524
589682
  config.header.messageEnabled = true;
589525
589683
  }
589526
589684
  helpers.updateItem(labelIdx, { detail: labelDetail() });
@@ -589535,7 +589693,7 @@ async function stepHeader(config, rl, availableRows) {
589535
589693
  config.header.linkUrl = url.trim();
589536
589694
  config.header.linkEnabled = true;
589537
589695
  helpers.getInput("Link text:", config.header.linkText || config.header.message).then((text) => {
589538
- config.header.linkText = text !== null && text.trim() ? text.trim().slice(0, 80) : config.header.message;
589696
+ config.header.linkText = text !== null && text.trim() ? text.trim().slice(0, 48) : config.header.message;
589539
589697
  helpers.updateItem(linkIdx, { detail: linkDetail() });
589540
589698
  helpers.render();
589541
589699
  });
@@ -589569,7 +589727,7 @@ async function stepHeader(config, rl, availableRows) {
589569
589727
  renderWarning("Set a short sponsor label before continuing.");
589570
589728
  return stepHeader(config, rl, availableRows);
589571
589729
  }
589572
- config.header.message = config.header.message.trim().slice(0, 80);
589730
+ config.header.message = config.header.message.trim().slice(0, 48);
589573
589731
  config.header.messageEnabled = true;
589574
589732
  config.header.linkEnabled = Boolean(config.header.linkUrl.trim());
589575
589733
  if (config.header.linkEnabled && !config.header.linkText.trim()) {
@@ -589615,7 +589773,7 @@ async function stepTransport(config, rl, availableRows) {
589615
589773
  const concIdx = items.findIndex((i2) => i2.key === "conc");
589616
589774
  const result = await tuiSelect({
589617
589775
  items,
589618
- title: "Step 3/5 — Transport & Rate Limits",
589776
+ title: "Step 4/6 — Transport & Rate Limits",
589619
589777
  rl,
589620
589778
  skipKeys: ["hdr_transport", "hdr_limits", "sep"],
589621
589779
  availableRows,
@@ -589751,7 +589909,7 @@ async function stepCohere(config, rl, availableRows) {
589751
589909
  ];
589752
589910
  const result = await tuiSelect({
589753
589911
  items,
589754
- title: "Step 4/5 — COHERE Distributed Intelligence",
589912
+ title: "Step 5/6 — COHERE Distributed Intelligence",
589755
589913
  rl,
589756
589914
  skipKeys: ["hdr", "desc1", "desc2", "desc3", "desc4", "desc5", "desc6", "desc7", "desc8", "desc9", "desc10", "desc11", "desc12", "desc13", "desc14", "desc15", "desc16", "sep1", "sep2"],
589757
589915
  availableRows,
@@ -589802,7 +589960,7 @@ async function stepReview(config, rl, availableRows) {
589802
589960
  ];
589803
589961
  const result = await tuiSelect({
589804
589962
  items,
589805
- title: "Step 5/5 — Review & Go Live",
589963
+ title: "Step 6/6 — Review & Go Live",
589806
589964
  rl,
589807
589965
  skipKeys: ["hdr", "sep", "info_ep", "info_msg", "info_link", "info_transport", "info_limits", "info_cohere"],
589808
589966
  availableRows
@@ -598505,7 +598663,7 @@ sleep 1
598505
598663
  return url.replace(/\/+$/, "");
598506
598664
  }
598507
598665
  };
598508
- const selectedModelsForEndpoint = (ep) => ep.selectedModels && ep.selectedModels.length > 0 ? ep.selectedModels : ep.models || [];
598666
+ const selectedModelsForEndpoint2 = (ep) => Array.isArray(ep.selectedModels) ? ep.selectedModels : ep.models || [];
598509
598667
  const enabledEps = config.endpoints.filter((e2) => e2.enabled);
598510
598668
  if (enabledEps.length === 0) {
598511
598669
  renderWarning("No sponsor endpoint is enabled.");
@@ -598527,14 +598685,14 @@ sleep 1
598527
598685
  tunnelAlreadyActive = false;
598528
598686
  p2pAlreadyActive = false;
598529
598687
  }
598530
- let allModels = enabledEps.flatMap(selectedModelsForEndpoint);
598531
- if (selectedModelsForEndpoint(primaryEndpoint).length === 0) {
598688
+ let allModels = [...new Set(enabledEps.flatMap(selectedModelsForEndpoint2))];
598689
+ if (selectedModelsForEndpoint2(primaryEndpoint).length === 0) {
598532
598690
  try {
598533
598691
  const fetchedModels = await fetchModels(primaryUrl, primaryAuthKey);
598534
598692
  const fetchedNames = fetchedModels.map((m2) => m2.name).filter(Boolean);
598535
598693
  if (fetchedNames.length > 0) {
598536
598694
  primaryEndpoint.models = fetchedNames;
598537
- allModels = enabledEps.flatMap(selectedModelsForEndpoint);
598695
+ allModels = [...new Set(enabledEps.flatMap(selectedModelsForEndpoint2))];
598538
598696
  }
598539
598697
  } catch (err) {
598540
598698
  renderWarning(
@@ -601325,15 +601483,15 @@ async function renderImageModelList(ctx3) {
601325
601483
  renderInfo("");
601326
601484
  renderInfo(c3.bold(category));
601327
601485
  for (const preset of presets) {
601328
- const fit2 = rateImagePresetForHardware(preset, specs);
601486
+ const fit3 = rateImagePresetForHardware(preset, specs);
601329
601487
  const primary = category === "Primary hyper-realistic baseline" ? c3.cyan(" ★") : "";
601330
601488
  const disk = ctx3 ? imageModelDiskStats(ctx3, preset, ollamaSizes) : { downloaded: false, bytes: 0, paths: [] };
601331
601489
  const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
601332
- renderInfo(`${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${primary}${diskInfo}`);
601490
+ renderInfo(`${imageFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${c3.bold(preset.label)}${primary}${diskInfo}`);
601333
601491
  renderInfo(` id: ${preset.id}`);
601334
- renderInfo(` type: ${preset.backend} · ${preset.sizeClass ?? "unknown size"} · ${fit2.label}`);
601492
+ renderInfo(` type: ${preset.backend} · ${preset.sizeClass ?? "unknown size"} · ${fit3.label}`);
601335
601493
  renderImagePresetDetail(" quality: ", preset.quality ?? preset.note);
601336
- renderImagePresetDetail(" fit: ", fit2.note);
601494
+ renderImagePresetDetail(" fit: ", fit3.note);
601337
601495
  if (preset.deployment) renderImagePresetDetail(" deploy: ", preset.deployment);
601338
601496
  }
601339
601497
  }
@@ -601452,13 +601610,13 @@ async function showImageModelsMenu(ctx3, hasLocal) {
601452
601610
  const specs = detectSystemSpecs();
601453
601611
  const ollamaSizes = await fetchOllamaModelSizes(ctx3).catch(() => /* @__PURE__ */ new Map());
601454
601612
  const buildModelItem = (preset) => {
601455
- const fit2 = rateImagePresetForHardware(preset, specs);
601613
+ const fit3 = rateImagePresetForHardware(preset, specs);
601456
601614
  const disk = imageModelDiskStats(ctx3, preset, ollamaSizes);
601457
601615
  const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
601458
601616
  return {
601459
601617
  key: `model:${preset.id}`,
601460
- label: `${downloaded}${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
601461
- detail: `${fit2.score}/100 ${fit2.label} · ${preset.category ?? preset.backend} · ${preset.sizeClass ?? preset.id}${downloadedModelSuffix(disk)}`
601618
+ label: `${downloaded}${imageFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${preset.label}`,
601619
+ detail: `${fit3.score}/100 ${fit3.label} · ${preset.category ?? preset.backend} · ${preset.sizeClass ?? preset.id}${downloadedModelSuffix(disk)}`
601462
601620
  };
601463
601621
  };
601464
601622
  const items = [
@@ -601523,8 +601681,8 @@ async function showImageModelsMenu(ctx3, hasLocal) {
601523
601681
  const save2 = hasLocal ? ctx3.saveLocalSettings : ctx3.saveSettings;
601524
601682
  save2({ imageModel: model, imageBackend: backend });
601525
601683
  renderInfo(`Image model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`);
601526
- const fit2 = preset ? rateImagePresetForHardware(preset, specs) : void 0;
601527
- if (fit2) renderInfo(`Hardware fit: ${fit2.score}/100 ${fit2.label} — ${fit2.note}`);
601684
+ const fit3 = preset ? rateImagePresetForHardware(preset, specs) : void 0;
601685
+ if (fit3) renderInfo(`Hardware fit: ${fit3.score}/100 ${fit3.label} — ${fit3.note}`);
601528
601686
  if (preset?.install) renderInfo(`Prewarm command: ${preset.install}`);
601529
601687
  await prewarmImageModel(ctx3, model, backend);
601530
601688
  }
@@ -601735,15 +601893,15 @@ async function renderVideoModelList(ctx3) {
601735
601893
  renderInfo("");
601736
601894
  renderInfo(c3.bold(category));
601737
601895
  for (const preset of presets) {
601738
- const fit2 = rateVideoPresetForHardware(preset, specs);
601896
+ const fit3 = rateVideoPresetForHardware(preset, specs);
601739
601897
  const disk = videoModelDiskStats(ctx3, preset);
601740
601898
  const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
601741
- renderInfo(`${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`);
601899
+ renderInfo(`${imageFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`);
601742
601900
  renderInfo(` id: ${preset.id}`);
601743
- renderInfo(` type: ${preset.backend} · ${preset.sizeClass} · ${preset.kinds.join("/")} · ${fit2.label}`);
601901
+ renderInfo(` type: ${preset.backend} · ${preset.sizeClass} · ${preset.kinds.join("/")} · ${fit3.label}`);
601744
601902
  renderImagePresetDetail(" quality: ", preset.quality);
601745
601903
  renderImagePresetDetail(" output: ", preset.output);
601746
- renderImagePresetDetail(" fit: ", fit2.note);
601904
+ renderImagePresetDetail(" fit: ", fit3.note);
601747
601905
  renderImagePresetDetail(" deploy: ", preset.deployment);
601748
601906
  if (preset.licenseNote) renderImagePresetDetail(" license: ", preset.licenseNote);
601749
601907
  }
@@ -601753,13 +601911,13 @@ async function showVideoModelsMenu(ctx3, hasLocal) {
601753
601911
  const settings = resolveSettings(ctx3.repoRoot);
601754
601912
  const specs = detectSystemSpecs();
601755
601913
  const buildModelItem = (preset) => {
601756
- const fit2 = rateVideoPresetForHardware(preset, specs);
601914
+ const fit3 = rateVideoPresetForHardware(preset, specs);
601757
601915
  const disk = videoModelDiskStats(ctx3, preset);
601758
601916
  const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
601759
601917
  return {
601760
601918
  key: `model:${preset.id}`,
601761
- label: `${downloaded}${imageFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
601762
- detail: `${fit2.label} · ${preset.category} · ${preset.kinds.join("/")}${downloadedModelSuffix(disk)}`
601919
+ label: `${downloaded}${imageFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${preset.label}`,
601920
+ detail: `${fit3.label} · ${preset.category} · ${preset.kinds.join("/")}${downloadedModelSuffix(disk)}`
601763
601921
  };
601764
601922
  };
601765
601923
  const items = [
@@ -601821,8 +601979,8 @@ async function showVideoModelsMenu(ctx3, hasLocal) {
601821
601979
  save2({ videoModel: model, videoBackend: backend });
601822
601980
  renderInfo(`Video model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`);
601823
601981
  if (preset) {
601824
- const fit2 = rateVideoPresetForHardware(preset, specs);
601825
- renderInfo(`Hardware fit: ${fit2.score}/100 ${fit2.label} — ${fit2.note}`);
601982
+ const fit3 = rateVideoPresetForHardware(preset, specs);
601983
+ renderInfo(`Hardware fit: ${fit3.score}/100 ${fit3.label} — ${fit3.note}`);
601826
601984
  if (preset.licenseNote) renderInfo(`License: ${preset.licenseNote}`);
601827
601985
  if (preset.install) renderInfo(`Prewarm command: ${preset.install}`);
601828
601986
  }
@@ -602046,15 +602204,15 @@ async function renderAudioModelList(ctx3, kind) {
602046
602204
  renderInfo("");
602047
602205
  renderInfo(c3.bold(category));
602048
602206
  for (const preset of presets) {
602049
- const fit2 = rateAudioPresetForHardware(preset, specs);
602207
+ const fit3 = rateAudioPresetForHardware(preset, specs);
602050
602208
  const disk = audioModelDiskStats(ctx3, preset);
602051
602209
  const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
602052
- renderInfo(`${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`);
602210
+ renderInfo(`${audioFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`);
602053
602211
  renderInfo(` id: ${preset.id}`);
602054
- renderInfo(` type: ${preset.backend} · ${preset.sizeClass} · ${fit2.label}`);
602212
+ renderInfo(` type: ${preset.backend} · ${preset.sizeClass} · ${fit3.label}`);
602055
602213
  renderImagePresetDetail(" quality: ", preset.quality);
602056
602214
  renderImagePresetDetail(" output: ", preset.output);
602057
- renderImagePresetDetail(" fit: ", fit2.note);
602215
+ renderImagePresetDetail(" fit: ", fit3.note);
602058
602216
  renderImagePresetDetail(" deploy: ", preset.deployment);
602059
602217
  }
602060
602218
  }
@@ -602072,13 +602230,13 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
602072
602230
  const activeModel = activeAudioModel(settings, kind);
602073
602231
  const title = kind === "music" ? "Music Generation" : "Sound Generation";
602074
602232
  const buildModelItem = (preset) => {
602075
- const fit2 = rateAudioPresetForHardware(preset, specs);
602233
+ const fit3 = rateAudioPresetForHardware(preset, specs);
602076
602234
  const disk = audioModelDiskStats(ctx3, preset);
602077
602235
  const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
602078
602236
  return {
602079
602237
  key: `model:${preset.id}`,
602080
- label: `${downloaded}${audioFitIcon(fit2.score)} ${String(fit2.score).padStart(3)}/100 ${preset.label}`,
602081
- detail: `${fit2.label} · ${preset.category} · ${preset.sizeClass}${downloadedModelSuffix(disk)}`
602238
+ label: `${downloaded}${audioFitIcon(fit3.score)} ${String(fit3.score).padStart(3)}/100 ${preset.label}`,
602239
+ detail: `${fit3.label} · ${preset.category} · ${preset.sizeClass}${downloadedModelSuffix(disk)}`
602082
602240
  };
602083
602241
  };
602084
602242
  const setupItems = kind === "music" ? [
@@ -602149,8 +602307,8 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
602149
602307
  save2(payload);
602150
602308
  renderInfo(`${kind === "music" ? "Music" : "Sound"} model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`);
602151
602309
  if (preset) {
602152
- const fit2 = rateAudioPresetForHardware(preset, specs);
602153
- renderInfo(`Hardware fit: ${fit2.score}/100 ${fit2.label} - ${fit2.note}`);
602310
+ const fit3 = rateAudioPresetForHardware(preset, specs);
602311
+ renderInfo(`Hardware fit: ${fit3.score}/100 ${fit3.label} - ${fit3.note}`);
602154
602312
  renderInfo(`Prewarm command: ${preset.install}`);
602155
602313
  }
602156
602314
  await prewarmAudioModel(ctx3, kind, model, backend);
@@ -603901,6 +604059,21 @@ async function handleEndpoint(arg, ctx3, local = false) {
603901
604059
  async function handleSponsoredEndpoint(ctx3, local) {
603902
604060
  renderInfo("Scanning for sponsored inference endpoints...");
603903
604061
  const sponsors = [];
604062
+ const cleanSponsorHeaderText = (value2, max = 48) => {
604063
+ const cleaned = String(value2 ?? "").replace(/\x1B\[[0-?]*[ -/]*[@-~]|\x1B\].*?(?:\x07|\x1B\\)/g, "").replace(/[\x00-\x1F\x7F]/g, " ").replace(/\s+/g, " ").trim();
604064
+ if (cleaned.length <= max) return cleaned;
604065
+ return cleaned.slice(0, max).trimEnd();
604066
+ };
604067
+ const cleanSponsorLinkUrl = (value2) => {
604068
+ const raw = cleanSponsorHeaderText(value2, 2048);
604069
+ if (!raw) return "";
604070
+ try {
604071
+ const url = new URL(raw);
604072
+ return url.protocol === "http:" || url.protocol === "https:" ? url.href : "";
604073
+ } catch {
604074
+ return "";
604075
+ }
604076
+ };
603904
604077
  const parseSponsorHeader = (raw, fallbackName) => {
603905
604078
  let header = raw?.header;
603906
604079
  if (typeof header === "string") {
@@ -603910,15 +604083,36 @@ async function handleSponsoredEndpoint(ctx3, local) {
603910
604083
  header = void 0;
603911
604084
  }
603912
604085
  }
603913
- const message2 = String(
604086
+ if (header && raw?.banner && typeof raw.banner === "object") {
604087
+ const hasTopLevelHeader = raw?.message != null || raw?.linkUrl != null || raw?.link_url != null || raw?.linkText != null || raw?.link_text != null;
604088
+ const headerMessage = cleanSponsorHeaderText(header?.message ?? "");
604089
+ const headerLinkUrl = cleanSponsorLinkUrl(
604090
+ header?.linkUrl ?? header?.link_url ?? ""
604091
+ );
604092
+ const headerLinkText = cleanSponsorHeaderText(
604093
+ header?.linkText ?? header?.link_text ?? ""
604094
+ );
604095
+ const bannerMessage = cleanSponsorHeaderText(raw.banner?.message ?? "");
604096
+ const bannerLinkUrl = cleanSponsorLinkUrl(
604097
+ raw.banner?.linkUrl ?? raw.banner?.link_url ?? ""
604098
+ );
604099
+ const bannerLinkText = cleanSponsorHeaderText(
604100
+ raw.banner?.linkText ?? raw.banner?.link_text ?? ""
604101
+ );
604102
+ const hasLegacyBannerPayload = Boolean(bannerMessage) || Boolean(bannerLinkUrl) || Boolean(bannerLinkText);
604103
+ if (!hasTopLevelHeader && hasLegacyBannerPayload && headerMessage === bannerMessage && headerLinkUrl === bannerLinkUrl && headerLinkText === bannerLinkText) {
604104
+ header = void 0;
604105
+ }
604106
+ }
604107
+ const message2 = cleanSponsorHeaderText(
603914
604108
  header?.message ?? raw?.message ?? raw?.name ?? fallbackName ?? ""
603915
- ).trim();
603916
- const linkUrl = String(
604109
+ );
604110
+ const linkUrl = cleanSponsorLinkUrl(
603917
604111
  header?.linkUrl ?? header?.link_url ?? raw?.linkUrl ?? raw?.link_url ?? ""
603918
- ).trim();
603919
- const linkText = String(
604112
+ );
604113
+ const linkText = cleanSponsorHeaderText(
603920
604114
  header?.linkText ?? header?.link_text ?? raw?.linkText ?? raw?.link_text ?? ""
603921
- ).trim();
604115
+ );
603922
604116
  const primaryColor = Number(header?.primaryColor ?? header?.primary_color ?? 214);
603923
604117
  if (!message2 && !linkUrl && !linkText) return void 0;
603924
604118
  return {
@@ -604062,7 +604256,11 @@ async function handleSponsoredEndpoint(ctx3, local) {
604062
604256
  );
604063
604257
  for (const s2 of saved) {
604064
604258
  if (!sponsors.some((sp) => sp.url === s2.url)) {
604065
- sponsors.push({ ...s2, source: "saved" });
604259
+ sponsors.push({
604260
+ ...s2,
604261
+ source: "saved",
604262
+ header: parseSponsorHeader(s2, s2.name || "Unknown Sponsor")
604263
+ });
604066
604264
  }
604067
604265
  }
604068
604266
  }
@@ -604216,15 +604414,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
604216
604414
  );
604217
604415
  return;
604218
604416
  }
604219
- const selectedHeader = selected.header ?? parseSponsorHeader(
604220
- {
604221
- ...selected,
604222
- message: selected.banner?.message,
604223
- linkUrl: selected.banner?.linkUrl,
604224
- linkText: selected.banner?.linkText
604225
- },
604226
- selected.name
604227
- );
604417
+ const selectedHeader = selected.header ?? parseSponsorHeader(selected, selected.name);
604228
604418
  if (selectedHeader) selected.header = selectedHeader;
604229
604419
  if (selectedHeader && ctx3.setSponsorHeader) {
604230
604420
  ctx3.setSponsorHeader({
@@ -629897,6 +630087,111 @@ ${caption}\r
629897
630087
  }
629898
630088
  });
629899
630089
 
630090
+ // packages/cli/src/tui/shell-live-block.ts
630091
+ function createShellLiveBlockState(command) {
630092
+ return {
630093
+ command,
630094
+ lines: [],
630095
+ currentLine: "",
630096
+ startedAt: Date.now(),
630097
+ status: "running",
630098
+ maxRows: 8
630099
+ };
630100
+ }
630101
+ function appendShellLiveChunk(state, chunk) {
630102
+ const cleaned = chunk.replace(ANSI_OR_OSC_RE, "");
630103
+ for (const char of cleaned) {
630104
+ if (char === "\r") {
630105
+ state.currentLine = "";
630106
+ continue;
630107
+ }
630108
+ if (char === "\n") {
630109
+ pushShellLiveLine(state, state.currentLine);
630110
+ state.currentLine = "";
630111
+ continue;
630112
+ }
630113
+ if (char === "\b") {
630114
+ state.currentLine = state.currentLine.slice(0, -1);
630115
+ continue;
630116
+ }
630117
+ const code8 = char.charCodeAt(0);
630118
+ if (char === " ") {
630119
+ state.currentLine += " ";
630120
+ } else if (code8 >= 32 && code8 !== 127) {
630121
+ state.currentLine += char;
630122
+ }
630123
+ }
630124
+ }
630125
+ function finishShellLiveBlock(state, success) {
630126
+ if (state.currentLine.trim()) {
630127
+ pushShellLiveLine(state, state.currentLine);
630128
+ state.currentLine = "";
630129
+ }
630130
+ state.status = success ? "ok" : "failed";
630131
+ }
630132
+ function buildShellLiveBlockLines(state, width) {
630133
+ const w = Math.max(36, width);
630134
+ const inner = Math.max(1, w - 4);
630135
+ const elapsed = Math.max(0, Date.now() - state.startedAt);
630136
+ const status = state.status === "running" ? `live ${formatElapsed(elapsed)}` : state.status;
630137
+ const title = ` Shell ${status} `;
630138
+ const top = `╭${fitWithFill(`─${title}`, w - 2, "─")}╮`;
630139
+ const bottom = `╰${"─".repeat(w - 2)}╯`;
630140
+ const visibleLines = [...state.lines];
630141
+ if (state.currentLine) visibleLines.push(state.currentLine);
630142
+ const hidden = Math.max(0, visibleLines.length - state.maxRows);
630143
+ const body = visibleLines.slice(-state.maxRows);
630144
+ const rows = [
630145
+ top,
630146
+ contentRow(`$ ${state.command}`, inner),
630147
+ contentRow("", inner)
630148
+ ];
630149
+ if (hidden > 0) rows.push(contentRow(`... ${hidden} earlier line${hidden === 1 ? "" : "s"}`, inner));
630150
+ if (body.length === 0) {
630151
+ rows.push(contentRow("(waiting for output)", inner));
630152
+ } else {
630153
+ for (const line of body) rows.push(contentRow(line, inner));
630154
+ }
630155
+ rows.push(bottom);
630156
+ return rows;
630157
+ }
630158
+ function pushShellLiveLine(state, line) {
630159
+ state.lines.push(line);
630160
+ const maxStored = Math.max(20, state.maxRows * 6);
630161
+ if (state.lines.length > maxStored) {
630162
+ state.lines.splice(0, state.lines.length - maxStored);
630163
+ }
630164
+ }
630165
+ function contentRow(value2, inner) {
630166
+ return `│ ${fit2(value2, inner)} │`;
630167
+ }
630168
+ function fit2(value2, width) {
630169
+ const plain = value2.replace(ANSI_OR_OSC_RE, "").replace(/\s+$/g, "");
630170
+ const chars = Array.from(plain);
630171
+ if (chars.length > width) {
630172
+ return chars.slice(0, Math.max(0, width - 1)).join("") + "…";
630173
+ }
630174
+ return plain + " ".repeat(width - chars.length);
630175
+ }
630176
+ function fitWithFill(value2, width, fill) {
630177
+ const chars = Array.from(value2);
630178
+ if (chars.length > width) return chars.slice(0, width).join("");
630179
+ return value2 + fill.repeat(width - chars.length);
630180
+ }
630181
+ function formatElapsed(ms) {
630182
+ const seconds = Math.floor(ms / 1e3);
630183
+ if (seconds < 60) return `${seconds}s`;
630184
+ const minutes = Math.floor(seconds / 60);
630185
+ return `${minutes}m${String(seconds % 60).padStart(2, "0")}s`;
630186
+ }
630187
+ var ANSI_OR_OSC_RE;
630188
+ var init_shell_live_block = __esm({
630189
+ "packages/cli/src/tui/shell-live-block.ts"() {
630190
+ "use strict";
630191
+ ANSI_OR_OSC_RE = /\x1B\[[0-?]*[ -/]*[@-~]|\x1B\].*?(?:\x07|\x1B\\)/g;
630192
+ }
630193
+ });
630194
+
629900
630195
  // packages/cli/src/api/task-manager-singleton.ts
629901
630196
  function getSharedTaskManager() {
629902
630197
  if (!_singleton) {
@@ -657276,6 +657571,17 @@ ${entry.fullContent}`
657276
657571
  });
657277
657572
  }
657278
657573
  }
657574
+ let liveShellBlock = null;
657575
+ const scheduleLiveShellRepaint = () => {
657576
+ if (!liveShellBlock || liveShellBlock.repaintTimer || !statusBar?.isActive)
657577
+ return;
657578
+ liveShellBlock.repaintTimer = setTimeout(() => {
657579
+ if (!liveShellBlock) return;
657580
+ liveShellBlock.repaintTimer = null;
657581
+ if (statusBar?.isActive) statusBar.refreshDisplay();
657582
+ }, 33);
657583
+ liveShellBlock.repaintTimer.unref?.();
657584
+ };
657279
657585
  runner.onEvent((event) => {
657280
657586
  emotionEngine?.appraise(event);
657281
657587
  switch (event.type) {
@@ -657363,6 +657669,18 @@ ${entry.fullContent}`
657363
657669
  event.toolArgs ?? {},
657364
657670
  config.verbose
657365
657671
  );
657672
+ const liveShellStatusBar = statusBar;
657673
+ if (event.toolName === "shell" && liveShellStatusBar?.isActive) {
657674
+ const command = String(event.toolArgs?.command ?? "");
657675
+ const state = createShellLiveBlockState(command);
657676
+ const id = `shell-live-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
657677
+ liveShellBlock = { id, state, repaintTimer: null };
657678
+ liveShellStatusBar.registerDynamicBlock(
657679
+ id,
657680
+ (width) => buildShellLiveBlockLines(state, width)
657681
+ );
657682
+ liveShellStatusBar.appendDynamicBlock(id);
657683
+ }
657366
657684
  });
657367
657685
  }
657368
657686
  if (event.toolName) sessionToolsUsed.add(event.toolName);
@@ -657418,6 +657736,15 @@ ${entry.fullContent}`
657418
657736
  statusBar?.setActiveTool(null);
657419
657737
  const toolDurationMs = toolCallStartMs > 0 ? Date.now() - toolCallStartMs : 0;
657420
657738
  toolCallStartMs = 0;
657739
+ if (event.toolName === "shell" && liveShellBlock && !isNeovimActive()) {
657740
+ if (liveShellBlock.repaintTimer) {
657741
+ clearTimeout(liveShellBlock.repaintTimer);
657742
+ liveShellBlock.repaintTimer = null;
657743
+ }
657744
+ finishShellLiveBlock(liveShellBlock.state, event.success ?? false);
657745
+ if (statusBar?.isActive) statusBar.refreshDisplay();
657746
+ liveShellBlock = null;
657747
+ }
657421
657748
  if (isSuccessfulTaskCompleteResult) {
657422
657749
  } else if (isNeovimActive()) {
657423
657750
  const ok3 = event.success ?? false;
@@ -657587,6 +657914,11 @@ ${entry.fullContent}`
657587
657914
  case "status":
657588
657915
  if (_apiCallbacks?.onStatus)
657589
657916
  _apiCallbacks.onStatus(event.content ?? "");
657917
+ if (event.toolName === "shell" && liveShellBlock && !isNeovimActive()) {
657918
+ appendShellLiveChunk(liveShellBlock.state, event.content ?? "");
657919
+ scheduleLiveShellRepaint();
657920
+ break;
657921
+ }
657590
657922
  if (!config.debug) break;
657591
657923
  if (isNeovimActive()) {
657592
657924
  writeToNeovimOutput(`\x1B[38;5;250m${event.content ?? ""}\x1B[0m\r
@@ -663960,6 +664292,7 @@ var init_interactive = __esm({
663960
664292
  init_telegram_bridge();
663961
664293
  init_platforms();
663962
664294
  init_status_bar();
664295
+ init_shell_live_block();
663963
664296
  init_daemon_registry();
663964
664297
  init_dist9();
663965
664298
  init_overlay_lock();
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.143",
3
+ "version": "1.0.144",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.143",
9
+ "version": "1.0.144",
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.143",
3
+ "version": "1.0.144",
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",