omnius 1.0.267 → 1.0.269

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
@@ -554725,7 +554725,7 @@ var init_verifierRunner = __esm({
554725
554725
  continue;
554726
554726
  const { stdout, stderr } = await execFileAsync5(bin, args, {
554727
554727
  cwd: workDir,
554728
- timeout: 6e4,
554728
+ timeout: 15e3,
554729
554729
  maxBuffer: 1024 * 1024
554730
554730
  });
554731
554731
  outputs.push(`$ ${cmd}
@@ -557139,6 +557139,23 @@ var init_ollama_pool = __esm({
557139
557139
  scored.sort((a2, b) => b.score - a2.score);
557140
557140
  return scored[0].inst;
557141
557141
  }
557142
+ _lastEagerCleanup = 0;
557143
+ triggerEagerCleanup() {
557144
+ if (process.env["NODE_ENV"] === "test" || process.env["VITEST"])
557145
+ return;
557146
+ const now2 = Date.now();
557147
+ if (now2 - this._lastEagerCleanup < 5e3)
557148
+ return;
557149
+ this._lastEagerCleanup = now2;
557150
+ Promise.resolve().then(() => (init_ollama_pool_cleanup(), ollama_pool_cleanup_exports)).then((mod3) => mod3.cleanupStaleOllamaProcesses({
557151
+ dryRun: false,
557152
+ useInference: "auto",
557153
+ baseInstanceUrl: this.config.baseInstanceUrl,
557154
+ poolPortStart: this.config.spawnPortStart,
557155
+ poolStatus: null
557156
+ })).catch(() => {
557157
+ });
557158
+ }
557142
557159
  buildSlot(inst, agentId) {
557143
557160
  return {
557144
557161
  instanceId: inst.state.id,
@@ -557151,6 +557168,7 @@ var init_ollama_pool = __esm({
557151
557168
  release: (success) => {
557152
557169
  inst.release(success);
557153
557170
  this.wakeNextSlotWaiter();
557171
+ this.triggerEagerCleanup();
557154
557172
  }
557155
557173
  };
557156
557174
  }
@@ -557163,7 +557181,13 @@ var init_ollama_pool = __esm({
557163
557181
  this.recordAffinity(agentId, pick.state.id);
557164
557182
  return this.buildSlot(pick, agentId);
557165
557183
  }
557166
- await new Promise((resolve70) => this.slotWaiters.push(resolve70));
557184
+ await new Promise((resolve70, reject) => {
557185
+ const timer = setTimeout(() => reject(new Error("No GPU slot available after 30s. All slots occupied.")), 3e4);
557186
+ this.slotWaiters.push(() => {
557187
+ clearTimeout(timer);
557188
+ resolve70();
557189
+ });
557190
+ });
557167
557191
  }
557168
557192
  }
557169
557193
  wakeNextSlotWaiter() {
@@ -557292,7 +557316,7 @@ var init_ollama_pool = __esm({
557292
557316
  elasticSpawnCap(gpus) {
557293
557317
  return this.config.maxSpawnedInstances > 0 ? this.config.maxSpawnedInstances : Math.max(0, gpus.length - 1);
557294
557318
  }
557295
- async getGpusForPlacement(maxAgeMs = 3e3) {
557319
+ async getGpusForPlacement(maxAgeMs = 3e4) {
557296
557320
  const now2 = Date.now();
557297
557321
  if (this.gpuCache && now2 - this.gpuCache.takenAtMs <= maxAgeMs) {
557298
557322
  return this.gpuCache.gpus;
@@ -557366,7 +557390,12 @@ var init_ollama_pool = __esm({
557366
557390
  }
557367
557391
  const gpuUuid = gpu?.uuid || null;
557368
557392
  const gpuIndex = gpu?.index ?? null;
557369
- const { proc, ready } = await this.spawner({ port, gpuUuid, gpuIndex, config: this.config });
557393
+ const { proc, ready } = await this.spawner({
557394
+ port,
557395
+ gpuUuid,
557396
+ gpuIndex,
557397
+ config: this.config
557398
+ });
557370
557399
  try {
557371
557400
  await ready;
557372
557401
  } catch (err) {
@@ -561870,7 +561899,7 @@ function partitionToolCalls(calls, readOnlyHints) {
561870
561899
  }
561871
561900
  return batches;
561872
561901
  }
561873
- async function withConcurrencyLimit(fns, limit = 5) {
561902
+ async function withConcurrencyLimit(fns, limit = 8) {
561874
561903
  const results = new Array(fns.length);
561875
561904
  let nextIdx = 0;
561876
561905
  async function runNext() {
@@ -561883,7 +561912,7 @@ async function withConcurrencyLimit(fns, limit = 5) {
561883
561912
  await Promise.all(workers);
561884
561913
  return results;
561885
561914
  }
561886
- async function executeBatch(batch2, executeFn, concurrencyLimit = 5) {
561915
+ async function executeBatch(batch2, executeFn, concurrencyLimit = 8) {
561887
561916
  if (!batch2.concurrent || batch2.calls.length === 1) {
561888
561917
  const results = [];
561889
561918
  for (const call of batch2.calls) {
@@ -562496,8 +562525,18 @@ var init_app_state = __esm({
562496
562525
  function stableValueKey(value2) {
562497
562526
  if (value2 === null || typeof value2 !== "object")
562498
562527
  return JSON.stringify(value2);
562499
- if (Array.isArray(value2))
562528
+ if (Array.isArray(value2)) {
562529
+ if (value2.length > 256)
562530
+ return `[${value2.length}items]`;
562500
562531
  return `[${value2.map(stableValueKey).join(",")}]`;
562532
+ }
562533
+ const raw = JSON.stringify(value2);
562534
+ if (raw.length > 10240) {
562535
+ let hash = 5381;
562536
+ for (let i2 = 0; i2 < raw.length; i2++)
562537
+ hash = (hash << 5) + hash + raw.charCodeAt(i2) | 0;
562538
+ return `{size:${raw.length},hash:${Math.abs(hash).toString(36)}}`;
562539
+ }
562501
562540
  const record = value2;
562502
562541
  return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableValueKey(record[key])}`).join(",")}}`;
562503
562542
  }
@@ -562511,6 +562550,8 @@ var init_streaming_executor = __esm({
562511
562550
  insertionOrder = [];
562512
562551
  config;
562513
562552
  executeFn = null;
562553
+ /** Resolver for notification-based wait (delay-1: replaces 1ms spin loop) */
562554
+ _notifyResolve = null;
562514
562555
  constructor(config) {
562515
562556
  this.config = {
562516
562557
  maxConcurrent: config?.maxConcurrent ?? 5,
@@ -562588,6 +562629,18 @@ var init_streaming_executor = __esm({
562588
562629
  }
562589
562630
  return results;
562590
562631
  }
562632
+ /** Signal the notification promise (wake waitAll if sleeping) */
562633
+ _signalChange() {
562634
+ const r2 = this._notifyResolve;
562635
+ this._notifyResolve = null;
562636
+ r2?.();
562637
+ }
562638
+ /** Create a new notification promise for waitAll to await */
562639
+ _waitForChange() {
562640
+ return new Promise((resolve70) => {
562641
+ this._notifyResolve = resolve70;
562642
+ });
562643
+ }
562591
562644
  /**
562592
562645
  * Wait for all queued/executing tools to complete.
562593
562646
  */
@@ -562603,7 +562656,7 @@ var init_streaming_executor = __esm({
562603
562656
  this.processQueue();
562604
562657
  } else {
562605
562658
  this.processQueue();
562606
- await new Promise((r2) => setTimeout(r2, 1));
562659
+ await this._waitForChange();
562607
562660
  }
562608
562661
  }
562609
562662
  }
@@ -562740,6 +562793,7 @@ var init_streaming_executor = __esm({
562740
562793
  break;
562741
562794
  }
562742
562795
  }
562796
+ this._signalChange();
562743
562797
  }
562744
562798
  startExecution(entry) {
562745
562799
  entry.state = "executing";
@@ -563908,7 +563962,11 @@ function captureToolchainVersions() {
563908
563962
  const out = {};
563909
563963
  for (const probe of TOOLCHAIN_PROBES) {
563910
563964
  try {
563911
- const v = execSync47(probe.cmd, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 1500 }).trim();
563965
+ const v = execSync47(probe.cmd, {
563966
+ encoding: "utf8",
563967
+ stdio: ["ignore", "pipe", "ignore"],
563968
+ timeout: 500
563969
+ }).trim();
563912
563970
  out[probe.name] = v.split(/\r?\n/)[0].slice(0, 200);
563913
563971
  } catch {
563914
563972
  out[probe.name] = null;
@@ -563929,7 +563987,10 @@ function freeDiskBytes(path12 = "/tmp") {
563929
563987
  const st = statSync35(path12);
563930
563988
  if (!st.isDirectory())
563931
563989
  return -1;
563932
- const out = execSync47(`df -P -k ${JSON.stringify(path12)} | tail -1`, { encoding: "utf8", timeout: 1500 });
563990
+ const out = execSync47(`df -P -k ${JSON.stringify(path12)} | tail -1`, {
563991
+ encoding: "utf8",
563992
+ timeout: 500
563993
+ });
563933
563994
  const cols = out.trim().split(/\s+/);
563934
563995
  const availKb = parseInt(cols[3] ?? "0", 10);
563935
563996
  if (!Number.isFinite(availKb))
@@ -581407,21 +581468,30 @@ var init_cascadeBackend = __esm({
581407
581468
  } catch (err) {
581408
581469
  this.consecutiveFailures++;
581409
581470
  if (this.isTransientError(err) && this.consecutiveFailures >= this.maxFailures) {
581410
- const nextIdx = this.findNextAvailableEndpoint();
581411
- if (nextIdx !== null && nextIdx !== this.activeIndex) {
581471
+ const candidates = this.endpoints.filter((_ep, i2) => i2 !== this.activeIndex && _ep.modelAvailable !== false);
581472
+ if (candidates.length > 0) {
581412
581473
  const from3 = this.endpoints[this.activeIndex];
581413
- const to = this.endpoints[nextIdx];
581414
581474
  const reason = `${this.consecutiveFailures} consecutive failures: ${err instanceof Error ? err.message : String(err)}`;
581415
- this.activeIndex = nextIdx;
581416
- this.consecutiveFailures = 0;
581417
- this.onSwitch?.(from3, to, reason);
581418
- const newBackend = this.getActiveBackend();
581475
+ const promises = candidates.map((ep) => {
581476
+ const bk = this.backends.get(ep.url);
581477
+ return bk.chatCompletion(request).then((result) => ({ result, from: ep }));
581478
+ });
581419
581479
  try {
581420
- const result = await newBackend.chatCompletion(request);
581480
+ const { result, from: from4 } = await Promise.race(promises);
581481
+ const winnerIdx = this.endpoints.indexOf(from4);
581482
+ if (winnerIdx >= 0) {
581483
+ this.activeIndex = winnerIdx;
581484
+ this.onSwitch?.(from4, from4, reason);
581485
+ }
581486
+ this.consecutiveFailures = 0;
581421
581487
  return result;
581422
- } catch (cascadeErr) {
581423
- this.consecutiveFailures++;
581424
- throw cascadeErr;
581488
+ } catch {
581489
+ this.consecutiveFailures += candidates.length;
581490
+ throw err;
581491
+ } finally {
581492
+ for (const p2 of promises)
581493
+ p2.catch(() => {
581494
+ });
581425
581495
  }
581426
581496
  }
581427
581497
  }
@@ -581636,7 +581706,7 @@ function createSteeringIngress(input) {
581636
581706
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
581637
581707
  };
581638
581708
  }
581639
- async function interpretSteeringIngress(backend, ingress, timeoutMs = 15e3) {
581709
+ async function interpretSteeringIngress(backend, ingress, timeoutMs = 8e3) {
581640
581710
  const first2 = await backend.chatCompletion({
581641
581711
  messages: [
581642
581712
  {
@@ -594350,6 +594420,175 @@ var init_task_complete_box = __esm({
594350
594420
  }
594351
594421
  });
594352
594422
 
594423
+ // packages/cli/src/tui/syntax-highlight.ts
594424
+ var syntax_highlight_exports = {};
594425
+ __export(syntax_highlight_exports, {
594426
+ detectLanguage: () => detectLanguage2,
594427
+ getHighlightStatus: () => getHighlightStatus,
594428
+ highlightBlock: () => highlightBlock,
594429
+ highlightCode: () => highlightCode,
594430
+ isAvailable: () => isAvailable,
594431
+ prewarm: () => prewarm
594432
+ });
594433
+ function highlightingDisabled() {
594434
+ return !isTTY2 || noColorEnv || disableEnv;
594435
+ }
594436
+ async function loadHighlighter() {
594437
+ if (_state.attempted) return _state.fn;
594438
+ _state.attempted = true;
594439
+ if (highlightingDisabled()) {
594440
+ _state.reason = !isTTY2 ? "non-tty" : noColorEnv ? "NO_COLOR set" : "OMNIUS_TUI_HIGHLIGHT=0";
594441
+ return null;
594442
+ }
594443
+ try {
594444
+ const { createRequire: createRequire10 } = await import("node:module");
594445
+ const req3 = createRequire10(import.meta.url);
594446
+ let resolved = null;
594447
+ try {
594448
+ resolved = req3.resolve("cli-highlight");
594449
+ } catch {
594450
+ _state.reason = "cli-highlight not installed";
594451
+ return null;
594452
+ }
594453
+ const mod3 = await import(resolved).catch(() => null);
594454
+ if (!mod3) {
594455
+ _state.reason = "cli-highlight failed to load";
594456
+ return null;
594457
+ }
594458
+ const m2 = mod3;
594459
+ const candidate = m2.highlight ?? m2.default ?? null;
594460
+ if (typeof candidate !== "function") {
594461
+ _state.reason = "cli-highlight export shape unrecognized";
594462
+ return null;
594463
+ }
594464
+ _state.fn = candidate;
594465
+ return candidate;
594466
+ } catch (err) {
594467
+ _state.reason = `import threw: ${err?.message ?? String(err)}`;
594468
+ return null;
594469
+ }
594470
+ }
594471
+ function loadHighlighterSync() {
594472
+ if (highlightingDisabled()) return null;
594473
+ return _state.fn;
594474
+ }
594475
+ async function prewarm() {
594476
+ await loadHighlighter();
594477
+ }
594478
+ function isAvailable() {
594479
+ if (highlightingDisabled()) return false;
594480
+ return _state.attempted && _state.fn !== null;
594481
+ }
594482
+ function getHighlightStatus() {
594483
+ return {
594484
+ available: isAvailable(),
594485
+ attempted: _state.attempted,
594486
+ reason: _state.reason,
594487
+ isTTY: isTTY2,
594488
+ noColor: noColorEnv,
594489
+ disabledByEnv: disableEnv
594490
+ };
594491
+ }
594492
+ function highlightCode(code8, language) {
594493
+ if (!code8) return code8;
594494
+ const fn = loadHighlighterSync();
594495
+ if (!fn) return code8;
594496
+ const lang = (language ?? detectLanguage2(code8) ?? "").trim();
594497
+ try {
594498
+ if (lang) {
594499
+ return fn(code8, { language: lang, ignoreIllegals: true });
594500
+ }
594501
+ return fn(code8, { ignoreIllegals: true });
594502
+ } catch {
594503
+ return code8;
594504
+ }
594505
+ }
594506
+ function detectLanguage2(text2) {
594507
+ if (!text2) return null;
594508
+ const trimmed = text2.trimStart();
594509
+ const shebang = trimmed.match(/^#!\s*\/[^\n]+/);
594510
+ if (shebang) {
594511
+ const sb = shebang[0];
594512
+ if (/python/.test(sb)) return "python";
594513
+ if (/(?:^|[\s/])(?:bash|sh|zsh)\b/.test(sb)) return "bash";
594514
+ if (/node/.test(sb)) return "javascript";
594515
+ if (/ruby/.test(sb)) return "ruby";
594516
+ if (/perl/.test(sb)) return "perl";
594517
+ }
594518
+ if (/^[\s\n]*[{[]/.test(trimmed)) {
594519
+ try {
594520
+ JSON.parse(trimmed);
594521
+ return "json";
594522
+ } catch {
594523
+ }
594524
+ }
594525
+ if (/^[-a-zA-Z_][\w-]*:\s/.test(trimmed) && /\n[-a-zA-Z_][\w-]*:\s/.test(trimmed)) {
594526
+ return "yaml";
594527
+ }
594528
+ if (/^(?:async def |def |class |import |from )/.test(trimmed) && /(?::\s*$|->|self\b)/m.test(trimmed)) {
594529
+ return "python";
594530
+ }
594531
+ if (/^(?:import |export |const |let |var |function |class |interface |type |async )/.test(trimmed)) {
594532
+ if (/(:\s*(?:string|number|boolean|any|unknown|void)\b|\binterface\b|\btype\s+\w+\s*=)/.test(trimmed)) {
594533
+ return "typescript";
594534
+ }
594535
+ return "javascript";
594536
+ }
594537
+ if (/(?:^|\n)\s*(?:fn |use |let mut |impl |struct |enum |trait )/.test(trimmed)) {
594538
+ return "rust";
594539
+ }
594540
+ if (/(?:^package \w+|\nfunc \w+\s*\()/.test(trimmed)) {
594541
+ return "go";
594542
+ }
594543
+ if (/^\s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)\b/i.test(trimmed)) {
594544
+ return "sql";
594545
+ }
594546
+ if (/^[\s\n]*<(?:!DOCTYPE|html|\?xml|\w+)/i.test(trimmed)) {
594547
+ return "html";
594548
+ }
594549
+ if (/^(?:---|\+\+\+|@@|diff )/.test(trimmed)) {
594550
+ return "diff";
594551
+ }
594552
+ if (/^\s*(?:\$\s|sudo |apt |brew |npm |pnpm |yarn |git |docker |kubectl |curl |wget )/.test(trimmed)) {
594553
+ return "bash";
594554
+ }
594555
+ return null;
594556
+ }
594557
+ function highlightBlock(code8, language) {
594558
+ if (!code8) return [""];
594559
+ const fn = loadHighlighterSync();
594560
+ if (!fn) return code8.split("\n");
594561
+ const lang = (language ?? detectLanguage2(code8) ?? "").trim();
594562
+ try {
594563
+ const out = lang ? fn(code8, { language: lang, ignoreIllegals: true }) : fn(code8, { ignoreIllegals: true });
594564
+ const lines = out.split("\n");
594565
+ const inputLines = code8.split("\n");
594566
+ if (lines.length === inputLines.length) return lines;
594567
+ if (lines.length < inputLines.length) {
594568
+ while (lines.length < inputLines.length) lines.push("");
594569
+ } else {
594570
+ lines.length = inputLines.length;
594571
+ }
594572
+ return lines;
594573
+ } catch {
594574
+ return code8.split("\n");
594575
+ }
594576
+ }
594577
+ var isTTY2, noColorEnv, disableEnv, _state;
594578
+ var init_syntax_highlight = __esm({
594579
+ "packages/cli/src/tui/syntax-highlight.ts"() {
594580
+ "use strict";
594581
+ isTTY2 = process.stdout?.isTTY ?? false;
594582
+ noColorEnv = process.env["NO_COLOR"] !== void 0 && process.env["NO_COLOR"] !== "";
594583
+ disableEnv = process.env["OMNIUS_TUI_HIGHLIGHT"] === "0";
594584
+ _state = {
594585
+ attempted: false,
594586
+ fn: null,
594587
+ reason: ""
594588
+ };
594589
+ }
594590
+ });
594591
+
594353
594592
  // packages/cli/src/tui/model-picker.ts
594354
594593
  import { totalmem as totalmem4 } from "node:os";
594355
594594
  function isImageGenModel(name10, family) {
@@ -595471,6 +595710,20 @@ function buildToolDivider(width, colorCode) {
595471
595710
  const border = toolColorSeq(colorCode);
595472
595711
  return `${border}${BOX_TJ_L2}${BOX_H2.repeat(Math.max(0, width - 2))}${BOX_TJ_R2}${toolResetSeq()}`;
595473
595712
  }
595713
+ function buildRoutingHeader(title, _metrics, width, colorCode, _metricsColorCode = 222) {
595714
+ const border = toolColorSeq(colorCode);
595715
+ const titleColor = toolColorSeq(colorCode, true);
595716
+ const reset = toolResetSeq();
595717
+ const w = Math.max(40, width);
595718
+ const titleVisible = stripAnsi(title);
595719
+ const titleChip = ` ${titleVisible} `;
595720
+ const shortBoxWidth = titleChip.length + 7;
595721
+ const line1 = `${border}${BOX_TL2}${BOX_H2}${border}${BOX_TJ_L2}${titleColor}${titleChip}${reset}${border}${BOX_TJ_R2}${BOX_H2}${BOX_H2}${BOX_TR2}${reset}`;
595722
+ const gap = Math.max(0, shortBoxWidth - 1);
595723
+ const dashCount = Math.max(0, w - shortBoxWidth - 2);
595724
+ const line2 = `${border}${BOX_TJ_L2}${reset}` + " ".repeat(gap) + `${border}╰${BOX_H2.repeat(dashCount)}${BOX_TJ_R2}${reset}`;
595725
+ return [line1, line2];
595726
+ }
595474
595727
  function buildToolBottom(width, colorCode) {
595475
595728
  const border = toolColorSeq(colorCode);
595476
595729
  return `${border}${BOX_BL2}${BOX_H2.repeat(Math.max(0, width - 2))}${BOX_BR2}${toolResetSeq()}`;
@@ -595616,26 +595869,38 @@ function buildCombinedToolBoxLines(toolName, callArgs, success, output, opts, wi
595616
595869
  { label: "Provenance", items: provenance }
595617
595870
  ];
595618
595871
  const colorCode = success ? toolColorCode(toolName) : TOOL_ERROR_COLOR_CODE;
595619
- const lines = [
595620
- buildToolTopBorder(
595872
+ const triggerTexts = formatToolArgsForBox(toolName, callArgs, opts.verbose);
595873
+ const lines = [];
595874
+ if (triggerTexts.length === 0) {
595875
+ const [r1, r2] = buildRoutingHeader(
595621
595876
  `${status} ${label}`,
595622
595877
  metrics2,
595623
595878
  w,
595624
595879
  colorCode,
595625
595880
  success ? void 0 : TOOL_ERROR_COLOR_CODE
595626
- )
595627
- ];
595628
- const triggerTexts = formatToolArgsForBox(toolName, callArgs, opts.verbose);
595629
- for (const text2 of triggerTexts) {
595630
- const pipe3 = " ";
595631
- const chunks = wrapToolTextLine(text2, innerWidth, pipe3);
595632
- for (const chunk of chunks) {
595633
- lines.push(
595634
- buildToolContentRow(formatToolBoxLine(chunk, "tool"), w, colorCode)
595635
- );
595881
+ );
595882
+ lines.push(r1, r2);
595883
+ } else {
595884
+ lines.push(
595885
+ buildToolTopBorder(
595886
+ `${status} ${label}`,
595887
+ metrics2,
595888
+ w,
595889
+ colorCode,
595890
+ success ? void 0 : TOOL_ERROR_COLOR_CODE
595891
+ )
595892
+ );
595893
+ for (const text2 of triggerTexts) {
595894
+ const pipe3 = " ";
595895
+ const chunks = wrapToolTextLine(text2, innerWidth, pipe3);
595896
+ for (const chunk of chunks) {
595897
+ lines.push(
595898
+ buildToolContentRow(formatToolBoxLine(chunk, "tool"), w, colorCode)
595899
+ );
595900
+ }
595636
595901
  }
595902
+ lines.push(buildToolDivider(w, colorCode));
595637
595903
  }
595638
- lines.push(buildToolDivider(w, colorCode));
595639
595904
  if (resultBody.length > 0) {
595640
595905
  for (const bodyLine of resultBody) {
595641
595906
  const text2 = sanitizeToolBoxContent(bodyLine.text);
@@ -596007,11 +596272,22 @@ function buildToolResultBody(toolName, success, output, verbose) {
596007
596272
  }
596008
596273
  if (toolName === "task_complete") {
596009
596274
  const summary = output && output.trim() ? output : "Done";
596010
- return summary.split("\n").map((line) => ({
596275
+ const maxLines2 = resolveToolOutputMaxLines(verbose);
596276
+ const lines = summary.split("\n");
596277
+ const body = lines.slice(0, maxLines2).map((line) => ({
596011
596278
  text: line,
596012
596279
  mode: "wrap",
596013
596280
  kind: "markdown"
596014
596281
  }));
596282
+ const remaining = lines.length - maxLines2;
596283
+ if (remaining > 0) {
596284
+ body.push({
596285
+ text: `... ${remaining} more lines`,
596286
+ mode: "wrap",
596287
+ kind: "dim"
596288
+ });
596289
+ }
596290
+ return body;
596015
596291
  }
596016
596292
  const filtered = output.split("\n").map(sanitizeToolBoxContent).map((line) => debug ? line : stripTrustTierWrapperForTui(line)).filter((line) => {
596017
596293
  const trimmed = line.trim();
@@ -596058,10 +596334,29 @@ function diffBodyLines(output, verbose) {
596058
596334
  for (const line of lines.slice(0, maxLines)) {
596059
596335
  const m2 = line.match(DIFF_LINE_RE);
596060
596336
  if (m2) {
596061
- const colored = m2[1] === "+" ? c3.green(line) : c3.red(line);
596337
+ const marker = m2[1];
596338
+ const codeStart = m2.index + m2[0].length;
596339
+ const prefix = line.slice(0, codeStart);
596340
+ const code8 = line.slice(codeStart);
596341
+ let hlCode = code8;
596342
+ if (isAvailable() && code8.trim()) {
596343
+ const hl = highlightCode(code8);
596344
+ if (hl !== code8) hlCode = hl;
596345
+ }
596346
+ const colorSeq = marker === "+" ? "\x1B[32m" : "\x1B[31m";
596347
+ const resetRe = /\x1B\[0m/g;
596348
+ const adjusted = hlCode.replace(resetRe, `\x1B[0m${colorSeq}`);
596349
+ const colored = `${colorSeq}${prefix}${adjusted}\x1B[0m`;
596062
596350
  body.push({ text: colored, mode: "truncate", kind: "plain" });
596063
596351
  } else {
596064
- body.push({ text: line, mode: "wrap", kind: "dim" });
596352
+ let formatted = line;
596353
+ if (isAvailable() && line.trim()) {
596354
+ const hl = highlightCode(line);
596355
+ formatted = hl !== line ? hl : c3.dim(line);
596356
+ } else {
596357
+ formatted = c3.dim(line);
596358
+ }
596359
+ body.push({ text: formatted, mode: "wrap", kind: "plain" });
596065
596360
  }
596066
596361
  }
596067
596362
  if (lines.length > maxLines) {
@@ -596081,11 +596376,16 @@ function codePreviewLines(output, maxLines) {
596081
596376
  const shown = lines.slice(start2, start2 + maxLines);
596082
596377
  if (shown.length === 0)
596083
596378
  return [{ text: "(empty file)", mode: "wrap", kind: "dim" }];
596084
- const body = shown.map((line) => ({
596085
- text: line,
596379
+ let hlLines = null;
596380
+ if (isAvailable()) {
596381
+ const codeBlock = shown.join("\n");
596382
+ const hl = highlightBlock(codeBlock);
596383
+ if (hl.length === shown.length) hlLines = hl;
596384
+ }
596385
+ const body = shown.map((line, i2) => ({
596386
+ text: hlLines ? hlLines[i2] ?? line : line,
596086
596387
  mode: "truncate",
596087
596388
  kind: "plain"
596088
- // show content in default terminal color, not dim
596089
596389
  }));
596090
596390
  const remaining = lines.length - start2 - shown.length;
596091
596391
  if (remaining > 0) {
@@ -596580,6 +596880,7 @@ var init_render = __esm({
596580
596880
  init_config();
596581
596881
  init_text_selection();
596582
596882
  init_task_complete_box();
596883
+ init_syntax_highlight();
596583
596884
  init_model_picker();
596584
596885
  init_secret_redactor();
596585
596886
  c3 = {
@@ -610028,10 +610329,10 @@ ${CONTENT_BG_SEQ}`);
610028
610329
  // packages/cli/src/tui/tui-select.ts
610029
610330
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
610030
610331
  function ansi3(code8, text2) {
610031
- return isTTY2 ? `\x1B[${code8}m${text2}\x1B[0m` : text2;
610332
+ return isTTY3 ? `\x1B[${code8}m${text2}\x1B[0m` : text2;
610032
610333
  }
610033
610334
  function fg2563(code8, text2) {
610034
- return isTTY2 ? `\x1B[38;5;${code8}m${text2}\x1B[0m` : text2;
610335
+ return isTTY3 ? `\x1B[38;5;${code8}m${text2}\x1B[0m` : text2;
610035
610336
  }
610036
610337
  function stripAnsi3(s2) {
610037
610338
  return s2.replace(/\x1B\[[0-9;]*m/g, "");
@@ -610684,14 +610985,14 @@ ${tuiBgSeq()}`);
610684
610985
  }
610685
610986
  });
610686
610987
  }
610687
- var isTTY2, MENU_ACTIVE_GREEN_256, selectColors, nonInteractiveSelectSurface;
610988
+ var isTTY3, MENU_ACTIVE_GREEN_256, selectColors, nonInteractiveSelectSurface;
610688
610989
  var init_tui_select = __esm({
610689
610990
  "packages/cli/src/tui/tui-select.ts"() {
610690
610991
  "use strict";
610691
610992
  init_overlay_lock();
610692
610993
  init_theme();
610693
610994
  init_layout2();
610694
- isTTY2 = process.stdout.isTTY ?? false;
610995
+ isTTY3 = process.stdout.isTTY ?? false;
610695
610996
  MENU_ACTIVE_GREEN_256 = 154;
610696
610997
  selectColors = {
610697
610998
  blue: (t2) => fg2563(39, t2),
@@ -616167,7 +616468,7 @@ var init_format = __esm({
616167
616468
  import { existsSync as existsSync116 } from "node:fs";
616168
616469
  import { extname as extname17, resolve as resolve55 } from "node:path";
616169
616470
  function ansi4(code8, text2) {
616170
- return isTTY3 ? `\x1B[${code8}m${text2}\x1B[0m` : text2;
616471
+ return isTTY4 ? `\x1B[${code8}m${text2}\x1B[0m` : text2;
616171
616472
  }
616172
616473
  function stripAnsi4(s2) {
616173
616474
  return s2.replace(/\x1B\[[0-9;]*m/g, "");
@@ -616338,13 +616639,13 @@ function showDropPanel(opts) {
616338
616639
  render2();
616339
616640
  });
616340
616641
  }
616341
- var isTTY3, dc;
616642
+ var isTTY4, dc;
616342
616643
  var init_drop_panel = __esm({
616343
616644
  "packages/cli/src/tui/drop-panel.ts"() {
616344
616645
  "use strict";
616345
616646
  init_overlay_lock();
616346
616647
  init_layout2();
616347
- isTTY3 = process.stdout.isTTY ?? false;
616648
+ isTTY4 = process.stdout.isTTY ?? false;
616348
616649
  dc = {
616349
616650
  bold: (t2) => ansi4("1", t2),
616350
616651
  dim: (t2) => ansi4("38;5;250", t2),
@@ -618643,17 +618944,17 @@ import { tmpdir as tmpdir20 } from "node:os";
618643
618944
  import { join as join131 } from "node:path";
618644
618945
  import { execSync as execSync54 } from "node:child_process";
618645
618946
  function isNeovimActive() {
618646
- return _state !== null && !_state.cleanedUp;
618947
+ return _state2 !== null && !_state2.cleanedUp;
618647
618948
  }
618648
618949
  function isNeovimFocused() {
618649
- return _state?.focused ?? false;
618950
+ return _state2?.focused ?? false;
618650
618951
  }
618651
618952
  function refocusNeovim() {
618652
- if (!_state || _state.cleanedUp || _state.focused) return;
618653
- toggleFocus(_state);
618953
+ if (!_state2 || _state2.cleanedUp || _state2.focused) return;
618954
+ toggleFocus(_state2);
618654
618955
  }
618655
618956
  async function startNeovimMode(opts) {
618656
- if (_state && !_state.cleanedUp) {
618957
+ if (_state2 && !_state2.cleanedUp) {
618657
618958
  return "Neovim mode is already active. Use /neovim to exit first.";
618658
618959
  }
618659
618960
  let nvimPath;
@@ -618694,7 +618995,7 @@ async function startNeovimMode(opts) {
618694
618995
  const ptyCols = opts.cols;
618695
618996
  const topOffset = opts.topOffset ?? 0;
618696
618997
  const ptyRows = Math.max(5, opts.contentRows);
618697
- if (isTTY4) {
618998
+ if (isTTY5) {
618698
618999
  const L = layout();
618699
619000
  const bottomBound = L.contentBottom;
618700
619001
  process.stdout.write(
@@ -618743,7 +619044,7 @@ async function startNeovimMode(opts) {
618743
619044
  installedFilteredListeners: [],
618744
619045
  cleanedUp: false
618745
619046
  };
618746
- _state = state;
619047
+ _state2 = state;
618747
619048
  const toolbarBtns = [];
618748
619049
  {
618749
619050
  const btns = [
@@ -618763,7 +619064,7 @@ async function startNeovimMode(opts) {
618763
619064
  }
618764
619065
  }
618765
619066
  function renderToolbar() {
618766
- if (!isTTY4) return;
619067
+ if (!isTTY5) return;
618767
619068
  const L = layout();
618768
619069
  const hdrRow = L.headerContent;
618769
619070
  const fg2 = 252;
@@ -618824,7 +619125,7 @@ async function startNeovimMode(opts) {
618824
619125
  stdin.setRawMode(true);
618825
619126
  }
618826
619127
  stdin.resume();
618827
- if (isTTY4) {
619128
+ if (isTTY5) {
618828
619129
  process.stdout.write("\x1B[?1002h\x1B[?1006h");
618829
619130
  }
618830
619131
  state.stdinHandler = (data) => {
@@ -618891,12 +619192,12 @@ async function startNeovimMode(opts) {
618891
619192
  return null;
618892
619193
  }
618893
619194
  function stopNeovimMode() {
618894
- if (!_state || _state.cleanedUp) return Promise.resolve();
619195
+ if (!_state2 || _state2.cleanedUp) return Promise.resolve();
618895
619196
  try {
618896
- _state.pty?.write("\x1B:qa!\r");
619197
+ _state2.pty?.write("\x1B:qa!\r");
618897
619198
  } catch {
618898
619199
  }
618899
- const s2 = _state;
619200
+ const s2 = _state2;
618900
619201
  return new Promise((resolve70) => {
618901
619202
  setTimeout(() => {
618902
619203
  if (s2 && !s2.cleanedUp) {
@@ -618907,18 +619208,18 @@ function stopNeovimMode() {
618907
619208
  });
618908
619209
  }
618909
619210
  function writeToNeovimOutput(text2) {
618910
- if (!_state || _state.cleanedUp || !_state.nvim || !_state.outputChanId) return;
619211
+ if (!_state2 || _state2.cleanedUp || !_state2.nvim || !_state2.outputChanId) return;
618911
619212
  const normalized = text2.replace(/(?<!\r)\n/g, "\r\n");
618912
- _state.nvim.request("nvim_chan_send", [_state.outputChanId, normalized]).catch(() => {
619213
+ _state2.nvim.request("nvim_chan_send", [_state2.outputChanId, normalized]).catch(() => {
618913
619214
  });
618914
619215
  }
618915
619216
  async function notifyNeovimFileChange(filePath) {
618916
- if (!_state || _state.cleanedUp || !_state.nvim) return;
619217
+ if (!_state2 || _state2.cleanedUp || !_state2.nvim) return;
618917
619218
  try {
618918
- await _state.nvim.command("checktime");
619219
+ await _state2.nvim.command("checktime");
618919
619220
  if (filePath) {
618920
619221
  const escaped = filePath.replace(/'/g, "''");
618921
- await _state.nvim.command(
619222
+ await _state2.nvim.command(
618922
619223
  `if bufexists('${escaped}') | execute 'buffer ' . bufnr('${escaped}') | endif`
618923
619224
  );
618924
619225
  }
@@ -618926,10 +619227,10 @@ async function notifyNeovimFileChange(filePath) {
618926
619227
  }
618927
619228
  }
618928
619229
  function resizeNeovim(cols, contentRows) {
618929
- if (!_state || _state.cleanedUp || !_state.pty) return;
619230
+ if (!_state2 || _state2.cleanedUp || !_state2.pty) return;
618930
619231
  const rows = Math.max(5, contentRows);
618931
619232
  try {
618932
- _state.pty.resize(cols, rows);
619233
+ _state2.pty.resize(cols, rows);
618933
619234
  } catch {
618934
619235
  }
618935
619236
  }
@@ -619104,7 +619405,7 @@ function doCleanup(state) {
619104
619405
  } catch {
619105
619406
  }
619106
619407
  }
619107
- _state = null;
619408
+ _state2 = null;
619108
619409
  process.stdout.write(
619109
619410
  `\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?1015l\x1B[?1004l\x1B[?2004l\x1B[1;${termRows()}r`
619110
619411
  // reset scroll region to full terminal
@@ -619123,16 +619424,16 @@ function doCleanup(state) {
619123
619424
  }
619124
619425
  state.opts.onExit?.();
619125
619426
  }
619126
- var isTTY4, PTY_MODE_ENABLE_RE, STDIN_MOUSE_FOCUS_RE, _state;
619427
+ var isTTY5, PTY_MODE_ENABLE_RE, STDIN_MOUSE_FOCUS_RE, _state2;
619127
619428
  var init_neovim_mode = __esm({
619128
619429
  "packages/cli/src/tui/neovim-mode.ts"() {
619129
619430
  "use strict";
619130
619431
  init_setup();
619131
619432
  init_layout2();
619132
- isTTY4 = process.stdout.isTTY ?? false;
619433
+ isTTY5 = process.stdout.isTTY ?? false;
619133
619434
  PTY_MODE_ENABLE_RE = /\x1B\[\?(?:1004|2004)h/g;
619134
619435
  STDIN_MOUSE_FOCUS_RE = /\x1B\[<[\d;]+[Mm]|\x1B\[M[\s\S]{3}|\x1B\[[IO]|\x1BO[ABCD]/g;
619135
- _state = null;
619436
+ _state2 = null;
619136
619437
  }
619137
619438
  });
619138
619439
 
@@ -644066,7 +644367,7 @@ function setCarouselWriter(writer) {
644066
644367
  chromeWrite2 = writer;
644067
644368
  }
644068
644369
  function fg(code8, text2) {
644069
- return isTTY5 ? `\x1B[38;5;${code8}m${text2}\x1B[0m` : text2;
644370
+ return isTTY6 ? `\x1B[38;5;${code8}m${text2}\x1B[0m` : text2;
644070
644371
  }
644071
644372
  function displayWidth(str) {
644072
644373
  let w = 0;
@@ -644104,12 +644405,12 @@ function createRow(phraseIndices, speed, direction, bank2) {
644104
644405
  const phrases = phraseIndices.map((i2) => bank2[i2 % bank2.length]);
644105
644406
  return { phrases, offset: 0, speed, direction, renderedPlain: "" };
644106
644407
  }
644107
- var isTTY5, chromeWrite2, PHRASES, Carousel;
644408
+ var isTTY6, chromeWrite2, PHRASES, Carousel;
644108
644409
  var init_carousel = __esm({
644109
644410
  "packages/cli/src/tui/carousel.ts"() {
644110
644411
  "use strict";
644111
644412
  init_layout2();
644112
- isTTY5 = process.stdout.isTTY ?? false;
644413
+ isTTY6 = process.stdout.isTTY ?? false;
644113
644414
  chromeWrite2 = ((data) => {
644114
644415
  process.stdout.write(data);
644115
644416
  });
@@ -644221,7 +644522,7 @@ var init_carousel = __esm({
644221
644522
  * Sets scroll region to row 5+ for all content/readline.
644222
644523
  */
644223
644524
  start() {
644224
- if (!isTTY5) return 0;
644525
+ if (!isTTY6) return 0;
644225
644526
  this.started = true;
644226
644527
  setHeaderHeight(this.reservedRows);
644227
644528
  const L = layout();
@@ -644253,7 +644554,7 @@ var init_carousel = __esm({
644253
644554
  * Row 4 is left blank as a separator.
644254
644555
  */
644255
644556
  renderFrame() {
644256
- if (!isTTY5) return;
644557
+ if (!isTTY6) return;
644257
644558
  const L = layout();
644258
644559
  let buf = "\x1B7";
644259
644560
  buf += "\x1B[?7l";
@@ -644330,7 +644631,7 @@ var init_carousel = __esm({
644330
644631
  process.stdout.removeListener("resize", this.resizeHandler);
644331
644632
  this.resizeHandler = null;
644332
644633
  }
644333
- if (!isTTY5 || !this.started) return;
644634
+ if (!isTTY6 || !this.started) return;
644334
644635
  const L = layout();
644335
644636
  let buf = "\x1B7";
644336
644637
  for (let i2 = 0; i2 < this.reservedRows; i2++) {
@@ -644566,13 +644867,13 @@ function createAnimatedBanner(id, name10, frameBuilders, frameDurationMs, author
644566
644867
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
644567
644868
  };
644568
644869
  }
644569
- var isTTY6, chromeWrite3, MNEMONIC_ADJECTIVES, MNEMONIC_NOUNS, BannerRenderer;
644870
+ var isTTY7, chromeWrite3, MNEMONIC_ADJECTIVES, MNEMONIC_NOUNS, BannerRenderer;
644570
644871
  var init_banner = __esm({
644571
644872
  "packages/cli/src/tui/banner.ts"() {
644572
644873
  "use strict";
644573
644874
  init_theme();
644574
644875
  init_layout2();
644575
- isTTY6 = process.stdout.isTTY ?? false;
644876
+ isTTY7 = process.stdout.isTTY ?? false;
644576
644877
  chromeWrite3 = ((data) => {
644577
644878
  process.stdout.write(data);
644578
644879
  });
@@ -644734,7 +645035,7 @@ var init_banner = __esm({
644734
645035
  * Returns the number of rows reserved (3 banner + 1 separator = 4).
644735
645036
  */
644736
645037
  start() {
644737
- if (!isTTY6 || !this.currentDesign) return 0;
645038
+ if (!isTTY7 || !this.currentDesign) return 0;
644738
645039
  this.renderCurrentFrame();
644739
645040
  this._resizeHandler = () => {
644740
645041
  setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
@@ -644775,7 +645076,7 @@ var init_banner = __esm({
644775
645076
  }
644776
645077
  /** Render the current frame into the top 3 rows (public for refresh callbacks) */
644777
645078
  renderCurrentFrame() {
644778
- if (!isTTY6 || !this.currentDesign) return;
645079
+ if (!isTTY7 || !this.currentDesign) return;
644779
645080
  const frame = this.currentDesign.frames[this.currentFrame];
644780
645081
  if (!frame) return;
644781
645082
  this.width = termCols();
@@ -645179,175 +645480,6 @@ var init_carousel_descriptors = __esm({
645179
645480
  }
645180
645481
  });
645181
645482
 
645182
- // packages/cli/src/tui/syntax-highlight.ts
645183
- var syntax_highlight_exports = {};
645184
- __export(syntax_highlight_exports, {
645185
- detectLanguage: () => detectLanguage2,
645186
- getHighlightStatus: () => getHighlightStatus,
645187
- highlightBlock: () => highlightBlock,
645188
- highlightCode: () => highlightCode,
645189
- isAvailable: () => isAvailable,
645190
- prewarm: () => prewarm
645191
- });
645192
- function highlightingDisabled() {
645193
- return !isTTY7 || noColorEnv || disableEnv;
645194
- }
645195
- async function loadHighlighter() {
645196
- if (_state2.attempted) return _state2.fn;
645197
- _state2.attempted = true;
645198
- if (highlightingDisabled()) {
645199
- _state2.reason = !isTTY7 ? "non-tty" : noColorEnv ? "NO_COLOR set" : "OMNIUS_TUI_HIGHLIGHT=0";
645200
- return null;
645201
- }
645202
- try {
645203
- const { createRequire: createRequire10 } = await import("node:module");
645204
- const req3 = createRequire10(import.meta.url);
645205
- let resolved = null;
645206
- try {
645207
- resolved = req3.resolve("cli-highlight");
645208
- } catch {
645209
- _state2.reason = "cli-highlight not installed";
645210
- return null;
645211
- }
645212
- const mod3 = await import(resolved).catch(() => null);
645213
- if (!mod3) {
645214
- _state2.reason = "cli-highlight failed to load";
645215
- return null;
645216
- }
645217
- const m2 = mod3;
645218
- const candidate = m2.highlight ?? m2.default ?? null;
645219
- if (typeof candidate !== "function") {
645220
- _state2.reason = "cli-highlight export shape unrecognized";
645221
- return null;
645222
- }
645223
- _state2.fn = candidate;
645224
- return candidate;
645225
- } catch (err) {
645226
- _state2.reason = `import threw: ${err?.message ?? String(err)}`;
645227
- return null;
645228
- }
645229
- }
645230
- function loadHighlighterSync() {
645231
- if (highlightingDisabled()) return null;
645232
- return _state2.fn;
645233
- }
645234
- async function prewarm() {
645235
- await loadHighlighter();
645236
- }
645237
- function isAvailable() {
645238
- if (highlightingDisabled()) return false;
645239
- return _state2.attempted && _state2.fn !== null;
645240
- }
645241
- function getHighlightStatus() {
645242
- return {
645243
- available: isAvailable(),
645244
- attempted: _state2.attempted,
645245
- reason: _state2.reason,
645246
- isTTY: isTTY7,
645247
- noColor: noColorEnv,
645248
- disabledByEnv: disableEnv
645249
- };
645250
- }
645251
- function highlightCode(code8, language) {
645252
- if (!code8) return code8;
645253
- const fn = loadHighlighterSync();
645254
- if (!fn) return code8;
645255
- const lang = (language ?? detectLanguage2(code8) ?? "").trim();
645256
- try {
645257
- if (lang) {
645258
- return fn(code8, { language: lang, ignoreIllegals: true });
645259
- }
645260
- return fn(code8, { ignoreIllegals: true });
645261
- } catch {
645262
- return code8;
645263
- }
645264
- }
645265
- function detectLanguage2(text2) {
645266
- if (!text2) return null;
645267
- const trimmed = text2.trimStart();
645268
- const shebang = trimmed.match(/^#!\s*\/[^\n]+/);
645269
- if (shebang) {
645270
- const sb = shebang[0];
645271
- if (/python/.test(sb)) return "python";
645272
- if (/(?:^|[\s/])(?:bash|sh|zsh)\b/.test(sb)) return "bash";
645273
- if (/node/.test(sb)) return "javascript";
645274
- if (/ruby/.test(sb)) return "ruby";
645275
- if (/perl/.test(sb)) return "perl";
645276
- }
645277
- if (/^[\s\n]*[{[]/.test(trimmed)) {
645278
- try {
645279
- JSON.parse(trimmed);
645280
- return "json";
645281
- } catch {
645282
- }
645283
- }
645284
- if (/^[-a-zA-Z_][\w-]*:\s/.test(trimmed) && /\n[-a-zA-Z_][\w-]*:\s/.test(trimmed)) {
645285
- return "yaml";
645286
- }
645287
- if (/^(?:async def |def |class |import |from )/.test(trimmed) && /(?::\s*$|->|self\b)/m.test(trimmed)) {
645288
- return "python";
645289
- }
645290
- if (/^(?:import |export |const |let |var |function |class |interface |type |async )/.test(trimmed)) {
645291
- if (/(:\s*(?:string|number|boolean|any|unknown|void)\b|\binterface\b|\btype\s+\w+\s*=)/.test(trimmed)) {
645292
- return "typescript";
645293
- }
645294
- return "javascript";
645295
- }
645296
- if (/(?:^|\n)\s*(?:fn |use |let mut |impl |struct |enum |trait )/.test(trimmed)) {
645297
- return "rust";
645298
- }
645299
- if (/(?:^package \w+|\nfunc \w+\s*\()/.test(trimmed)) {
645300
- return "go";
645301
- }
645302
- if (/^\s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)\b/i.test(trimmed)) {
645303
- return "sql";
645304
- }
645305
- if (/^[\s\n]*<(?:!DOCTYPE|html|\?xml|\w+)/i.test(trimmed)) {
645306
- return "html";
645307
- }
645308
- if (/^(?:---|\+\+\+|@@|diff )/.test(trimmed)) {
645309
- return "diff";
645310
- }
645311
- if (/^\s*(?:\$\s|sudo |apt |brew |npm |pnpm |yarn |git |docker |kubectl |curl |wget )/.test(trimmed)) {
645312
- return "bash";
645313
- }
645314
- return null;
645315
- }
645316
- function highlightBlock(code8, language) {
645317
- if (!code8) return [""];
645318
- const fn = loadHighlighterSync();
645319
- if (!fn) return code8.split("\n");
645320
- const lang = (language ?? detectLanguage2(code8) ?? "").trim();
645321
- try {
645322
- const out = lang ? fn(code8, { language: lang, ignoreIllegals: true }) : fn(code8, { ignoreIllegals: true });
645323
- const lines = out.split("\n");
645324
- const inputLines = code8.split("\n");
645325
- if (lines.length === inputLines.length) return lines;
645326
- if (lines.length < inputLines.length) {
645327
- while (lines.length < inputLines.length) lines.push("");
645328
- } else {
645329
- lines.length = inputLines.length;
645330
- }
645331
- return lines;
645332
- } catch {
645333
- return code8.split("\n");
645334
- }
645335
- }
645336
- var isTTY7, noColorEnv, disableEnv, _state2;
645337
- var init_syntax_highlight = __esm({
645338
- "packages/cli/src/tui/syntax-highlight.ts"() {
645339
- "use strict";
645340
- isTTY7 = process.stdout?.isTTY ?? false;
645341
- noColorEnv = process.env["NO_COLOR"] !== void 0 && process.env["NO_COLOR"] !== "";
645342
- disableEnv = process.env["OMNIUS_TUI_HIGHLIGHT"] === "0";
645343
- _state2 = {
645344
- attempted: false,
645345
- fn: null,
645346
- reason: ""
645347
- };
645348
- }
645349
- });
645350
-
645351
645483
  // packages/cli/src/tui/stream-renderer.ts
645352
645484
  function fg2564(code8, text2) {
645353
645485
  return isTTY8 ? `\x1B[38;5;${code8}m${text2}\x1B[0m` : text2;
@@ -645361,6 +645493,23 @@ function italicText(text2) {
645361
645493
  function dimItalic(text2) {
645362
645494
  return isTTY8 ? `\x1B[3m\x1B[38;5;${tuiTextDim()}m${text2}\x1B[0m` : text2;
645363
645495
  }
645496
+ function thinkingBoxTop(width) {
645497
+ const inner = Math.max(4, width);
645498
+ const title = " Processing ";
645499
+ return `╭─┤${title}├${"─".repeat(Math.max(0, inner - 6 - title.length))}╮`;
645500
+ }
645501
+ function thinkingBoxRow(text2, width) {
645502
+ const inner = Math.max(1, width - 4);
645503
+ const plain = stripAnsi(text2);
645504
+ const truncated = plain.length > inner ? plain.slice(0, Math.max(1, inner - 1)) + "…" : text2;
645505
+ const plainLen = stripAnsi(truncated).length;
645506
+ const padding = " ".repeat(Math.max(0, inner - plainLen));
645507
+ return `│ ${truncated}${padding} │`;
645508
+ }
645509
+ function thinkingBoxBottom(width) {
645510
+ const inner = Math.max(4, width);
645511
+ return `╰${"─".repeat(inner - 2)}╯`;
645512
+ }
645364
645513
  function boldText(text2) {
645365
645514
  return isTTY8 ? `\x1B[1m${text2}\x1B[0m` : text2;
645366
645515
  }
@@ -645486,6 +645635,9 @@ var init_stream_renderer = __esm({
645486
645635
  thinkingIndicatorShown = false;
645487
645636
  thinkingTokenCount = 0;
645488
645637
  thinkingCache = "";
645638
+ /** Thinking box — compact bordered box for the thinking indicator */
645639
+ thinkingBoxOpen = false;
645640
+ thinkingBoxRowCount = 0;
645489
645641
  write(token, kind) {
645490
645642
  if (!this.enabled) return;
645491
645643
  this.tokenCount++;
@@ -645493,6 +645645,9 @@ var init_stream_renderer = __esm({
645493
645645
  this.thinkingTokenCount++;
645494
645646
  if (token && !this.showThinking) this.thinkingCache += token;
645495
645647
  if (this.showThinking) {
645648
+ if (this.thinkingBoxOpen) {
645649
+ this.closeThinkingBox(`buffered ${this.thinkingTokenCount} tokens`);
645650
+ }
645496
645651
  for (const char of token) {
645497
645652
  this.lineBuffer += char;
645498
645653
  if (char === "\n") this.flushLine("thinking");
@@ -645500,23 +645655,26 @@ var init_stream_renderer = __esm({
645500
645655
  this.scheduleFlush("thinking");
645501
645656
  return;
645502
645657
  } else {
645503
- if (!this.thinkingIndicatorShown) {
645504
- this.thinkingIndicatorShown = true;
645505
- this.writeRaw(dimText(" │ ") + dimItalic("thinking...") + "\n");
645658
+ const w = termCols();
645659
+ if (!this.thinkingBoxOpen) {
645660
+ this.thinkingBoxOpen = true;
645661
+ this.thinkingBoxRowCount = 2;
645662
+ this.writeRaw(thinkingBoxTop(w) + "\n");
645663
+ this.writeRaw(thinkingBoxRow(dimItalic("processing..."), w) + "\n");
645506
645664
  this.lineStarted = false;
645507
645665
  }
645508
645666
  if (this.thinkingTokenCount % 500 === 0) {
645509
- this.writeRaw(dimText(" │ ") + dimItalic(`thinking... (${this.thinkingTokenCount} tokens)`) + "\n");
645510
- this.lineStarted = false;
645667
+ this.updateThinkingBox(
645668
+ `processing... (${this.thinkingTokenCount} tokens)`,
645669
+ w
645670
+ );
645511
645671
  }
645512
645672
  return;
645513
645673
  }
645514
645674
  }
645515
- if (this.thinkingIndicatorShown && kind === "content") {
645516
- this.thinkingIndicatorShown = false;
645517
- this.writeRaw(dimText(" │ ") + dimItalic(`thought for ${this.thinkingTokenCount} tokens`) + "\n");
645675
+ if (this.thinkingBoxOpen && kind === "content") {
645676
+ this.closeThinkingBox(`thought for ${this.thinkingTokenCount} tokens`);
645518
645677
  this.thinkingTokenCount = 0;
645519
- this.lineStarted = false;
645520
645678
  }
645521
645679
  if (kind === "tool_args" && !this.inToolArgs) {
645522
645680
  this.flushPartial(kind);
@@ -645542,6 +645700,9 @@ var init_stream_renderer = __esm({
645542
645700
  this.writeHighlighted(this.lineBuffer, kind);
645543
645701
  this.lineBuffer = "";
645544
645702
  }
645703
+ if (this.thinkingBoxOpen) {
645704
+ this.closeThinkingBox(`processed ${this.thinkingTokenCount} tokens`);
645705
+ }
645545
645706
  if (this.lineStarted) {
645546
645707
  process.stdout.write("\n");
645547
645708
  this.lineStarted = false;
@@ -645575,7 +645736,11 @@ var init_stream_renderer = __esm({
645575
645736
  if (line.includes("<think>")) {
645576
645737
  this.inThinkBlock = true;
645577
645738
  const after = line.replace(/<think>/g, "");
645578
- if (after.trim()) this.writeHighlighted(after, this.showThinking ? "thinking" : "content");
645739
+ if (after.trim())
645740
+ this.writeHighlighted(
645741
+ after,
645742
+ this.showThinking ? "thinking" : "content"
645743
+ );
645579
645744
  return;
645580
645745
  }
645581
645746
  if (line.includes("</think>")) {
@@ -645662,7 +645827,9 @@ var init_stream_renderer = __esm({
645662
645827
  const isLast = i2 === lines.length - 1;
645663
645828
  const lp = isFirst ? usePrefix : " ";
645664
645829
  const needsNewline = !isLast || trailingNewline;
645665
- this.writeRaw(dimText(lp) + highlight(lines[i2]) + (needsNewline ? "\n" : ""));
645830
+ this.writeRaw(
645831
+ dimText(lp) + highlight(lines[i2]) + (needsNewline ? "\n" : "")
645832
+ );
645666
645833
  }
645667
645834
  this.lineStarted = !trailingNewline;
645668
645835
  };
@@ -645706,10 +645873,33 @@ var init_stream_renderer = __esm({
645706
645873
  this.writeRaw(dimText(prefix) + rendered + (hasNewline ? "\n" : ""));
645707
645874
  this.lineStarted = !hasNewline;
645708
645875
  }
645876
+ /** In-place update of the compact thinking box content row (cursor-up + rewrite) */
645877
+ updateThinkingBox(text2, width) {
645878
+ if (!this.thinkingBoxOpen) return;
645879
+ const update2 = `\x1B[${this.thinkingBoxRowCount}A` + thinkingBoxTop(width) + "\n" + thinkingBoxRow(dimItalic(text2), width) + "\n";
645880
+ this.writeRaw(update2);
645881
+ this.lineStarted = false;
645882
+ }
645883
+ /** Close the compact thinking box (cursor-up, rewrite with summary + bottom border) */
645884
+ closeThinkingBox(summary) {
645885
+ if (!this.thinkingBoxOpen) return;
645886
+ const w = termCols();
645887
+ const text2 = `\x1B[${this.thinkingBoxRowCount}A` + thinkingBoxTop(w) + "\n" + thinkingBoxRow(dimItalic(summary), w) + "\n" + thinkingBoxBottom(w) + "\n";
645888
+ this.writeRaw(text2);
645889
+ this.thinkingBoxOpen = false;
645890
+ this.thinkingBoxRowCount = 0;
645891
+ this.lineStarted = false;
645892
+ this.thinkingIndicatorShown = false;
645893
+ }
645709
645894
  /** Toggle visibility of full thinking content */
645710
645895
  setThinkingVisible(visible) {
645711
645896
  this.showThinking = visible;
645712
- if (visible) this.thinkingCache = "";
645897
+ if (visible) {
645898
+ if (this.thinkingBoxOpen) {
645899
+ this.closeThinkingBox(`buffered ${this.thinkingTokenCount} tokens`);
645900
+ }
645901
+ this.thinkingCache = "";
645902
+ }
645713
645903
  }
645714
645904
  /** Emit the cached (pre-toggle) thinking content to stdout as dim italic
645715
645905
  * lines. Uses writeRaw so _cursorCol / lineStarted tracking stays in sync
@@ -645814,7 +646004,8 @@ var init_stream_renderer = __esm({
645814
646004
  looksLikeJsonBlob(text2) {
645815
646005
  if (/\\u[0-9a-fA-F]{4}/.test(text2)) return true;
645816
646006
  if (/^\s*\{?"content"\s*:/.test(text2)) return true;
645817
- if (text2.includes("\\n") && this.looksLikeJson(text2) && text2.length > 100) return true;
646007
+ if (text2.includes("\\n") && this.looksLikeJson(text2) && text2.length > 100)
646008
+ return true;
645818
646009
  return false;
645819
646010
  }
645820
646011
  /**
@@ -645825,12 +646016,30 @@ var init_stream_renderer = __esm({
645825
646016
  const colorKey = dim ? PASTEL.toolArg : PASTEL.key;
645826
646017
  const colorStr = dim ? PASTEL.toolArg : PASTEL.string;
645827
646018
  let result = line;
645828
- result = result.replace(/"([^"]*)"(\s*:)/g, (_m, key, colon) => fg2564(colorKey, `"${key}"`) + fg2564(PASTEL.colon, colon));
645829
- result = result.replace(/(:\s*)"([^"]*)"/g, (_m, prefix, val) => fg2564(PASTEL.colon, prefix) + fg2564(colorStr, `"${val}"`));
645830
- result = result.replace(/(:\s*)(\d+\.?\d*)/g, (_m, prefix, num2) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.number, num2));
645831
- result = result.replace(/(:\s*)(true|false)/g, (_m, prefix, bool) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.boolean, bool));
645832
- result = result.replace(/(:\s*)(null)/g, (_m, prefix, n2) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.null, n2));
645833
- result = result.replace(/([{}[\]])/g, (_m, b) => fg2564(PASTEL.bracket, b));
646019
+ result = result.replace(
646020
+ /"([^"]*)"(\s*:)/g,
646021
+ (_m, key, colon) => fg2564(colorKey, `"${key}"`) + fg2564(PASTEL.colon, colon)
646022
+ );
646023
+ result = result.replace(
646024
+ /(:\s*)"([^"]*)"/g,
646025
+ (_m, prefix, val) => fg2564(PASTEL.colon, prefix) + fg2564(colorStr, `"${val}"`)
646026
+ );
646027
+ result = result.replace(
646028
+ /(:\s*)(\d+\.?\d*)/g,
646029
+ (_m, prefix, num2) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.number, num2)
646030
+ );
646031
+ result = result.replace(
646032
+ /(:\s*)(true|false)/g,
646033
+ (_m, prefix, bool) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.boolean, bool)
646034
+ );
646035
+ result = result.replace(
646036
+ /(:\s*)(null)/g,
646037
+ (_m, prefix, n2) => fg2564(PASTEL.colon, prefix) + fg2564(PASTEL.null, n2)
646038
+ );
646039
+ result = result.replace(
646040
+ /([{}[\]])/g,
646041
+ (_m, b) => fg2564(PASTEL.bracket, b)
646042
+ );
645834
646043
  return dim ? dimText(result) : result;
645835
646044
  }
645836
646045
  /**
@@ -645838,16 +646047,34 @@ var init_stream_renderer = __esm({
645838
646047
  */
645839
646048
  highlightCode(line) {
645840
646049
  let result = line;
645841
- result = result.replace(/"([^"]*)"/g, (_m, s2) => fg2564(PASTEL.string, `"${s2}"`));
645842
- result = result.replace(/'([^']*)'/g, (_m, s2) => fg2564(PASTEL.string, `'${s2}'`));
645843
- result = result.replace(/\b(\d+\.?\d*)\b/g, (_m, n2) => fg2564(PASTEL.number, n2));
645844
- result = result.replace(/\b(true|false|null|undefined|None|True|False)\b/g, (_m, kw) => fg2564(PASTEL.boolean, kw));
646050
+ result = result.replace(
646051
+ /"([^"]*)"/g,
646052
+ (_m, s2) => fg2564(PASTEL.string, `"${s2}"`)
646053
+ );
646054
+ result = result.replace(
646055
+ /'([^']*)'/g,
646056
+ (_m, s2) => fg2564(PASTEL.string, `'${s2}'`)
646057
+ );
646058
+ result = result.replace(
646059
+ /\b(\d+\.?\d*)\b/g,
646060
+ (_m, n2) => fg2564(PASTEL.number, n2)
646061
+ );
646062
+ result = result.replace(
646063
+ /\b(true|false|null|undefined|None|True|False)\b/g,
646064
+ (_m, kw) => fg2564(PASTEL.boolean, kw)
646065
+ );
645845
646066
  result = result.replace(
645846
646067
  /\b(function|const|let|var|return|if|else|for|while|import|export|from|class|async|await|def|self|try|catch|finally|throw|new|typeof|instanceof|type|interface|enum|struct|impl|fn|pub|mod|use|match|trait|where|mut|ref|move|yield|switch|case|default|break|continue|do|in|of|extends|implements|super|this|static|abstract|override|readonly|declare|namespace|package|func|go|chan|select|defer|range|map)\b/g,
645847
646068
  (_m, kw) => fg2564(PASTEL.keyword, kw)
645848
646069
  );
645849
- result = result.replace(/:\s*([A-Z]\w*)/g, (_m, t2) => ": " + fg2564(147, t2));
645850
- result = result.replace(/(\/\/.*$|#.*$)/gm, (_m, cm) => fg2564(PASTEL.comment, cm));
646070
+ result = result.replace(
646071
+ /:\s*([A-Z]\w*)/g,
646072
+ (_m, t2) => ": " + fg2564(147, t2)
646073
+ );
646074
+ result = result.replace(
646075
+ /(\/\/.*$|#.*$)/gm,
646076
+ (_m, cm) => fg2564(PASTEL.comment, cm)
646077
+ );
645851
646078
  return result;
645852
646079
  }
645853
646080
  // -------------------------------------------------------------------------
@@ -645895,16 +646122,34 @@ var init_stream_renderer = __esm({
645895
646122
  return fg2564(PASTEL.comment, line);
645896
646123
  }
645897
646124
  let result = line;
645898
- result = result.replace(/"([^"]*)"/g, (_m, s2) => fg2564(PASTEL.string, `"${s2}"`));
645899
- result = result.replace(/'([^']*)'/g, (_m, s2) => fg2564(PASTEL.string, `'${s2}'`));
645900
- result = result.replace(/(\$\{[^}]+\}|\$[A-Za-z_]\w*|\$[0-9?@#*!$-])/g, (_m, v) => fg2564(PASTEL.shellVar, v));
645901
- result = result.replace(/((?:^|\s))(--?[a-zA-Z][\w-]*)/g, (_m, ws, flag) => ws + fg2564(PASTEL.shellFlag, flag));
645902
- result = result.replace(/(\|{1,2}|>{1,2}|<{1,2}|&{1,2}|;)/g, (_m, op) => fg2564(PASTEL.shellOp, op));
646125
+ result = result.replace(
646126
+ /"([^"]*)"/g,
646127
+ (_m, s2) => fg2564(PASTEL.string, `"${s2}"`)
646128
+ );
646129
+ result = result.replace(
646130
+ /'([^']*)'/g,
646131
+ (_m, s2) => fg2564(PASTEL.string, `'${s2}'`)
646132
+ );
646133
+ result = result.replace(
646134
+ /(\$\{[^}]+\}|\$[A-Za-z_]\w*|\$[0-9?@#*!$-])/g,
646135
+ (_m, v) => fg2564(PASTEL.shellVar, v)
646136
+ );
646137
+ result = result.replace(
646138
+ /((?:^|\s))(--?[a-zA-Z][\w-]*)/g,
646139
+ (_m, ws, flag) => ws + fg2564(PASTEL.shellFlag, flag)
646140
+ );
646141
+ result = result.replace(
646142
+ /(\|{1,2}|>{1,2}|<{1,2}|&{1,2}|;)/g,
646143
+ (_m, op) => fg2564(PASTEL.shellOp, op)
646144
+ );
645903
646145
  result = result.replace(
645904
646146
  /^(\s*)(npm|npx|node|pnpm|yarn|git|docker|kubectl|curl|wget|cat|grep|find|ls|cd|cp|mv|rm|mkdir|chmod|chown|echo|printf|sed|awk|sort|uniq|head|tail|wc|tar|gzip|make|cargo|go|pip|python|python3|ruby|gem|brew|apt|yum|dnf|pacman|sudo|ssh|scp|rsync|man)\b/,
645905
646147
  (_m, ws, cmd) => ws + boldText(fg2564(PASTEL.keyword, cmd))
645906
646148
  );
645907
- result = result.replace(/(#[^{].*$)/gm, (_m, cm) => fg2564(PASTEL.comment, cm));
646149
+ result = result.replace(
646150
+ /(#[^{].*$)/gm,
646151
+ (_m, cm) => fg2564(PASTEL.comment, cm)
646152
+ );
645908
646153
  return result;
645909
646154
  }
645910
646155
  // -------------------------------------------------------------------------
@@ -645918,7 +646163,14 @@ var init_stream_renderer = __esm({
645918
646163
  if (headingMatch) {
645919
646164
  const level = headingMatch[1].length;
645920
646165
  const text2 = headingMatch[2];
645921
- const colors2 = [PASTEL.heading1, PASTEL.heading2, PASTEL.heading3, PASTEL.heading3, 183, 183];
646166
+ const colors2 = [
646167
+ PASTEL.heading1,
646168
+ PASTEL.heading2,
646169
+ PASTEL.heading3,
646170
+ PASTEL.heading3,
646171
+ 183,
646172
+ 183
646173
+ ];
645922
646174
  return boldText(fg2564(colors2[level - 1] ?? 147, text2));
645923
646175
  }
645924
646176
  if (/^[-*_]{3,}\s*$/.test(line)) {
@@ -645944,13 +646196,34 @@ var init_stream_renderer = __esm({
645944
646196
  */
645945
646197
  highlightInline(text2) {
645946
646198
  let result = text2;
645947
- result = result.replace(/`([^`]+)`/g, (_m, code8) => fg2564(PASTEL.inlineCode, code8));
645948
- result = result.replace(/\*{3}([^*]+)\*{3}/g, (_m, t2) => boldText(italicText(t2)));
645949
- result = result.replace(/\*{2}([^*]+)\*{2}/g, (_m, t2) => boldText(t2));
645950
- result = result.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_m, t2) => italicText(t2));
645951
- result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, label, url) => boldText(fg2564(PASTEL.link, label)) + " " + dimText(fg2564(PASTEL.link, `(${url})`)));
645952
- result = result.replace(/(?<!\w)__([^_]+)__(?!\w)/g, (_m, t2) => boldText(t2));
645953
- result = result.replace(/(?<!\w)_([^_]+)_(?!\w)/g, (_m, t2) => italicText(t2));
646199
+ result = result.replace(
646200
+ /`([^`]+)`/g,
646201
+ (_m, code8) => fg2564(PASTEL.inlineCode, code8)
646202
+ );
646203
+ result = result.replace(
646204
+ /\*{3}([^*]+)\*{3}/g,
646205
+ (_m, t2) => boldText(italicText(t2))
646206
+ );
646207
+ result = result.replace(
646208
+ /\*{2}([^*]+)\*{2}/g,
646209
+ (_m, t2) => boldText(t2)
646210
+ );
646211
+ result = result.replace(
646212
+ /(?<!\*)\*([^*]+)\*(?!\*)/g,
646213
+ (_m, t2) => italicText(t2)
646214
+ );
646215
+ result = result.replace(
646216
+ /\[([^\]]+)\]\(([^)]+)\)/g,
646217
+ (_m, label, url) => boldText(fg2564(PASTEL.link, label)) + " " + dimText(fg2564(PASTEL.link, `(${url})`))
646218
+ );
646219
+ result = result.replace(
646220
+ /(?<!\w)__([^_]+)__(?!\w)/g,
646221
+ (_m, t2) => boldText(t2)
646222
+ );
646223
+ result = result.replace(
646224
+ /(?<!\w)_([^_]+)_(?!\w)/g,
646225
+ (_m, t2) => italicText(t2)
646226
+ );
645954
646227
  result = result.replace(/~~([^~]+)~~/g, (_m, t2) => dimText(t2));
645955
646228
  return result;
645956
646229
  }
@@ -704325,28 +704598,32 @@ ${entry.fullContent}`
704325
704598
  }
704326
704599
  if (lm.intervention) {
704327
704600
  contentWrite(() => {
704328
- const lines = [`⚠ ${lm.intervention}`];
704329
- if (lm.details && showAdversary) {
704330
- const det = String(lm.details);
704331
- lines.push(...det.split("\n").filter(Boolean));
704332
- }
704333
- renderBoxedBlock({
704334
- title: "Adversary",
704335
- lines,
704336
- kind: "plain"
704337
- });
704601
+ renderWarning(`Adversary: ${lm.intervention}`);
704338
704602
  });
704339
704603
  } else if (lm.details && showAdversary) {
704340
704604
  contentWrite(() => {
704341
- renderBoxedBlock({
704342
- title: "Adversary",
704343
- lines: String(lm.details).split("\n").filter(Boolean),
704344
- kind: "dim"
704345
- });
704605
+ renderInfo(
704606
+ `Adversary details: ${String(lm.details).split("\n").filter(Boolean).join(" | ")}`
704607
+ );
704346
704608
  });
704347
704609
  }
704348
704610
  }
704349
704611
  break;
704612
+ case "adversary_reaction":
704613
+ if (event.adversary) {
704614
+ const adv = event.adversary;
704615
+ const conf = adv.confidence != null ? ` (${Math.round(adv.confidence * 100)}%)` : "";
704616
+ const text2 = adv.shortText + conf;
704617
+ contentWrite(() => {
704618
+ renderWarning(`Adversary ${adv.class}: ${text2}`);
704619
+ });
704620
+ if (adv.details) {
704621
+ adversaryBuffer.push(adv.details);
704622
+ if (adversaryBuffer.length > 50)
704623
+ adversaryBuffer.splice(0, adversaryBuffer.length - 50);
704624
+ }
704625
+ }
704626
+ break;
704350
704627
  }
704351
704628
  });
704352
704629
  try {