ccstatusline 2.1.4 → 2.1.6

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.
@@ -39365,6 +39365,15 @@ async function getExistingStatusLine() {
39365
39365
  return settings.statusLine?.command ?? null;
39366
39366
  }
39367
39367
 
39368
+ // src/utils/clone-settings.ts
39369
+ function cloneSettings(settings) {
39370
+ const cloneFn = globalThis.structuredClone;
39371
+ if (typeof cloneFn === "function") {
39372
+ return cloneFn(settings);
39373
+ }
39374
+ return JSON.parse(JSON.stringify(settings));
39375
+ }
39376
+
39368
39377
  // src/utils/config.ts
39369
39378
  import * as fs3 from "fs";
39370
39379
  import * as os3 from "os";
@@ -51469,7 +51478,7 @@ import { execSync as execSync3 } from "child_process";
51469
51478
  import * as fs5 from "fs";
51470
51479
  import * as path4 from "path";
51471
51480
  var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
51472
- var PACKAGE_VERSION = "2.1.4";
51481
+ var PACKAGE_VERSION = "2.1.6";
51473
51482
  function getPackageVersion() {
51474
51483
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51475
51484
  return PACKAGE_VERSION;
@@ -51488,7 +51497,7 @@ function getPackageVersion() {
51488
51497
  }
51489
51498
  return "";
51490
51499
  }
51491
- function getTerminalWidth() {
51500
+ function probeTerminalWidth() {
51492
51501
  if (process.platform === "win32") {
51493
51502
  return null;
51494
51503
  }
@@ -51522,38 +51531,11 @@ function getTerminalWidth() {
51522
51531
  } catch {}
51523
51532
  return null;
51524
51533
  }
51534
+ function getTerminalWidth() {
51535
+ return probeTerminalWidth();
51536
+ }
51525
51537
  function canDetectTerminalWidth() {
51526
- if (process.platform === "win32") {
51527
- return false;
51528
- }
51529
- try {
51530
- const tty2 = execSync3("ps -o tty= -p $(ps -o ppid= -p $$)", {
51531
- encoding: "utf8",
51532
- stdio: ["pipe", "pipe", "ignore"],
51533
- shell: "/bin/sh"
51534
- }).trim();
51535
- if (tty2 && tty2 !== "??" && tty2 !== "?") {
51536
- const width = execSync3(`stty size < /dev/${tty2} | awk '{print $2}'`, {
51537
- encoding: "utf8",
51538
- stdio: ["pipe", "pipe", "ignore"],
51539
- shell: "/bin/sh"
51540
- }).trim();
51541
- const parsed = parseInt(width, 10);
51542
- if (!isNaN(parsed) && parsed > 0) {
51543
- return true;
51544
- }
51545
- }
51546
- } catch {}
51547
- try {
51548
- const width = execSync3("tput cols 2>/dev/null", {
51549
- encoding: "utf8",
51550
- stdio: ["pipe", "pipe", "ignore"]
51551
- }).trim();
51552
- const parsed = parseInt(width, 10);
51553
- return !isNaN(parsed) && parsed > 0;
51554
- } catch {
51555
- return false;
51556
- }
51538
+ return probeTerminalWidth() !== null;
51557
51539
  }
51558
51540
 
51559
51541
  // node_modules/ink-select-input/build/Indicator.js
@@ -52433,6 +52415,49 @@ function getGitChangeCounts(context) {
52433
52415
  };
52434
52416
  }
52435
52417
 
52418
+ // src/widgets/shared/editor-display.ts
52419
+ function makeModifierText(modifiers) {
52420
+ return modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined;
52421
+ }
52422
+
52423
+ // src/widgets/shared/metadata.ts
52424
+ function isMetadataFlagEnabled(item, key) {
52425
+ return item.metadata?.[key] === "true";
52426
+ }
52427
+ function toggleMetadataFlag(item, key) {
52428
+ return {
52429
+ ...item,
52430
+ metadata: {
52431
+ ...item.metadata,
52432
+ [key]: (!isMetadataFlagEnabled(item, key)).toString()
52433
+ }
52434
+ };
52435
+ }
52436
+
52437
+ // src/widgets/shared/git-no-git.ts
52438
+ var HIDE_NO_GIT_KEY = "hideNoGit";
52439
+ var TOGGLE_NO_GIT_ACTION = "toggle-nogit";
52440
+ var HIDE_NO_GIT_KEYBIND = {
52441
+ key: "h",
52442
+ label: "(h)ide 'no git' message",
52443
+ action: TOGGLE_NO_GIT_ACTION
52444
+ };
52445
+ function isHideNoGitEnabled(item) {
52446
+ return isMetadataFlagEnabled(item, HIDE_NO_GIT_KEY);
52447
+ }
52448
+ function getHideNoGitModifierText(item) {
52449
+ return makeModifierText(isHideNoGitEnabled(item) ? ["hide 'no git'"] : []);
52450
+ }
52451
+ function handleToggleNoGitAction(action, item) {
52452
+ if (action !== TOGGLE_NO_GIT_ACTION) {
52453
+ return null;
52454
+ }
52455
+ return toggleMetadataFlag(item, HIDE_NO_GIT_KEY);
52456
+ }
52457
+ function getHideNoGitKeybinds() {
52458
+ return [HIDE_NO_GIT_KEYBIND];
52459
+ }
52460
+
52436
52461
  // src/widgets/GitBranch.ts
52437
52462
  class GitBranchWidget {
52438
52463
  getDefaultColor() {
@@ -52448,31 +52473,16 @@ class GitBranchWidget {
52448
52473
  return "Git";
52449
52474
  }
52450
52475
  getEditorDisplay(item) {
52451
- const hideNoGit = item.metadata?.hideNoGit === "true";
52452
- const modifiers = [];
52453
- if (hideNoGit) {
52454
- modifiers.push("hide 'no git'");
52455
- }
52456
52476
  return {
52457
52477
  displayText: this.getDisplayName(),
52458
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52478
+ modifierText: getHideNoGitModifierText(item)
52459
52479
  };
52460
52480
  }
52461
52481
  handleEditorAction(action, item) {
52462
- if (action === "toggle-nogit") {
52463
- const currentState = item.metadata?.hideNoGit === "true";
52464
- return {
52465
- ...item,
52466
- metadata: {
52467
- ...item.metadata,
52468
- hideNoGit: (!currentState).toString()
52469
- }
52470
- };
52471
- }
52472
- return null;
52482
+ return handleToggleNoGitAction(action, item);
52473
52483
  }
52474
52484
  render(item, context, settings) {
52475
- const hideNoGit = item.metadata?.hideNoGit === "true";
52485
+ const hideNoGit = isHideNoGitEnabled(item);
52476
52486
  if (context.isPreview) {
52477
52487
  return item.rawValue ? "main" : "⎇ main";
52478
52488
  }
@@ -52488,9 +52498,7 @@ class GitBranchWidget {
52488
52498
  return runGit("branch --show-current", context);
52489
52499
  }
52490
52500
  getCustomKeybinds() {
52491
- return [
52492
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52493
- ];
52501
+ return getHideNoGitKeybinds();
52494
52502
  }
52495
52503
  supportsRawValue() {
52496
52504
  return true;
@@ -52514,31 +52522,16 @@ class GitChangesWidget {
52514
52522
  return "Git";
52515
52523
  }
52516
52524
  getEditorDisplay(item) {
52517
- const hideNoGit = item.metadata?.hideNoGit === "true";
52518
- const modifiers = [];
52519
- if (hideNoGit) {
52520
- modifiers.push("hide 'no git'");
52521
- }
52522
52525
  return {
52523
52526
  displayText: this.getDisplayName(),
52524
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52527
+ modifierText: getHideNoGitModifierText(item)
52525
52528
  };
52526
52529
  }
52527
52530
  handleEditorAction(action, item) {
52528
- if (action === "toggle-nogit") {
52529
- const currentState = item.metadata?.hideNoGit === "true";
52530
- return {
52531
- ...item,
52532
- metadata: {
52533
- ...item.metadata,
52534
- hideNoGit: (!currentState).toString()
52535
- }
52536
- };
52537
- }
52538
- return null;
52531
+ return handleToggleNoGitAction(action, item);
52539
52532
  }
52540
52533
  render(item, context, _settings) {
52541
- const hideNoGit = item.metadata?.hideNoGit === "true";
52534
+ const hideNoGit = isHideNoGitEnabled(item);
52542
52535
  if (context.isPreview) {
52543
52536
  return "(+42,-10)";
52544
52537
  }
@@ -52549,9 +52542,7 @@ class GitChangesWidget {
52549
52542
  return `(+${changes.insertions},-${changes.deletions})`;
52550
52543
  }
52551
52544
  getCustomKeybinds() {
52552
- return [
52553
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52554
- ];
52545
+ return getHideNoGitKeybinds();
52555
52546
  }
52556
52547
  supportsRawValue() {
52557
52548
  return false;
@@ -52575,31 +52566,16 @@ class GitInsertionsWidget {
52575
52566
  return "Git";
52576
52567
  }
52577
52568
  getEditorDisplay(item) {
52578
- const hideNoGit = item.metadata?.hideNoGit === "true";
52579
- const modifiers = [];
52580
- if (hideNoGit) {
52581
- modifiers.push("hide 'no git'");
52582
- }
52583
52569
  return {
52584
52570
  displayText: this.getDisplayName(),
52585
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52571
+ modifierText: getHideNoGitModifierText(item)
52586
52572
  };
52587
52573
  }
52588
52574
  handleEditorAction(action, item) {
52589
- if (action === "toggle-nogit") {
52590
- const currentState = item.metadata?.hideNoGit === "true";
52591
- return {
52592
- ...item,
52593
- metadata: {
52594
- ...item.metadata,
52595
- hideNoGit: (!currentState).toString()
52596
- }
52597
- };
52598
- }
52599
- return null;
52575
+ return handleToggleNoGitAction(action, item);
52600
52576
  }
52601
52577
  render(item, context, _settings) {
52602
- const hideNoGit = item.metadata?.hideNoGit === "true";
52578
+ const hideNoGit = isHideNoGitEnabled(item);
52603
52579
  if (context.isPreview) {
52604
52580
  return "+42";
52605
52581
  }
@@ -52610,9 +52586,7 @@ class GitInsertionsWidget {
52610
52586
  return `+${changes.insertions}`;
52611
52587
  }
52612
52588
  getCustomKeybinds() {
52613
- return [
52614
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52615
- ];
52589
+ return getHideNoGitKeybinds();
52616
52590
  }
52617
52591
  supportsRawValue() {
52618
52592
  return false;
@@ -52636,31 +52610,16 @@ class GitDeletionsWidget {
52636
52610
  return "Git";
52637
52611
  }
52638
52612
  getEditorDisplay(item) {
52639
- const hideNoGit = item.metadata?.hideNoGit === "true";
52640
- const modifiers = [];
52641
- if (hideNoGit) {
52642
- modifiers.push("hide 'no git'");
52643
- }
52644
52613
  return {
52645
52614
  displayText: this.getDisplayName(),
52646
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52615
+ modifierText: getHideNoGitModifierText(item)
52647
52616
  };
52648
52617
  }
52649
52618
  handleEditorAction(action, item) {
52650
- if (action === "toggle-nogit") {
52651
- const currentState = item.metadata?.hideNoGit === "true";
52652
- return {
52653
- ...item,
52654
- metadata: {
52655
- ...item.metadata,
52656
- hideNoGit: (!currentState).toString()
52657
- }
52658
- };
52659
- }
52660
- return null;
52619
+ return handleToggleNoGitAction(action, item);
52661
52620
  }
52662
52621
  render(item, context, _settings) {
52663
- const hideNoGit = item.metadata?.hideNoGit === "true";
52622
+ const hideNoGit = isHideNoGitEnabled(item);
52664
52623
  if (context.isPreview) {
52665
52624
  return "-10";
52666
52625
  }
@@ -52671,9 +52630,7 @@ class GitDeletionsWidget {
52671
52630
  return `-${changes.deletions}`;
52672
52631
  }
52673
52632
  getCustomKeybinds() {
52674
- return [
52675
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52676
- ];
52633
+ return getHideNoGitKeybinds();
52677
52634
  }
52678
52635
  supportsRawValue() {
52679
52636
  return false;
@@ -52697,31 +52654,16 @@ class GitRootDirWidget {
52697
52654
  return "Git";
52698
52655
  }
52699
52656
  getEditorDisplay(item) {
52700
- const hideNoGit = item.metadata?.hideNoGit === "true";
52701
- const modifiers = [];
52702
- if (hideNoGit) {
52703
- modifiers.push("hide 'no git'");
52704
- }
52705
52657
  return {
52706
52658
  displayText: this.getDisplayName(),
52707
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52659
+ modifierText: getHideNoGitModifierText(item)
52708
52660
  };
52709
52661
  }
52710
52662
  handleEditorAction(action, item) {
52711
- if (action === "toggle-nogit") {
52712
- const currentState = item.metadata?.hideNoGit === "true";
52713
- return {
52714
- ...item,
52715
- metadata: {
52716
- ...item.metadata,
52717
- hideNoGit: (!currentState).toString()
52718
- }
52719
- };
52720
- }
52721
- return null;
52663
+ return handleToggleNoGitAction(action, item);
52722
52664
  }
52723
52665
  render(item, context, _settings) {
52724
- const hideNoGit = item.metadata?.hideNoGit === "true";
52666
+ const hideNoGit = isHideNoGitEnabled(item);
52725
52667
  if (context.isPreview) {
52726
52668
  return "my-repo";
52727
52669
  }
@@ -52745,9 +52687,7 @@ class GitRootDirWidget {
52745
52687
  return lastPart && lastPart.length > 0 ? lastPart : normalizedRootDir;
52746
52688
  }
52747
52689
  getCustomKeybinds() {
52748
- return [
52749
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52750
- ];
52690
+ return getHideNoGitKeybinds();
52751
52691
  }
52752
52692
  supportsRawValue() {
52753
52693
  return false;
@@ -52771,31 +52711,16 @@ class GitWorktreeWidget {
52771
52711
  return "Git";
52772
52712
  }
52773
52713
  getEditorDisplay(item) {
52774
- const hideNoGit = item.metadata?.hideNoGit === "true";
52775
- const modifiers = [];
52776
- if (hideNoGit) {
52777
- modifiers.push("hide 'no git'");
52778
- }
52779
52714
  return {
52780
52715
  displayText: this.getDisplayName(),
52781
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52716
+ modifierText: getHideNoGitModifierText(item)
52782
52717
  };
52783
52718
  }
52784
52719
  handleEditorAction(action, item) {
52785
- if (action === "toggle-nogit") {
52786
- const currentState = item.metadata?.hideNoGit === "true";
52787
- return {
52788
- ...item,
52789
- metadata: {
52790
- ...item.metadata,
52791
- hideNoGit: (!currentState).toString()
52792
- }
52793
- };
52794
- }
52795
- return null;
52720
+ return handleToggleNoGitAction(action, item);
52796
52721
  }
52797
52722
  render(item, context) {
52798
- const hideNoGit = item.metadata?.hideNoGit === "true";
52723
+ const hideNoGit = isHideNoGitEnabled(item);
52799
52724
  if (context.isPreview)
52800
52725
  return item.rawValue ? "main" : "\uD81A\uDC30 main";
52801
52726
  if (!isInsideGitWorkTree(context)) {
@@ -52823,9 +52748,7 @@ class GitWorktreeWidget {
52823
52748
  return worktree.length > 0 ? worktree : null;
52824
52749
  }
52825
52750
  getCustomKeybinds() {
52826
- return [
52827
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52828
- ];
52751
+ return getHideNoGitKeybinds();
52829
52752
  }
52830
52753
  supportsRawValue() {
52831
52754
  return true;
@@ -53109,30 +53032,77 @@ function truncateStyledText(text, maxWidth, options = {}) {
53109
53032
  }
53110
53033
 
53111
53034
  // src/utils/model-context.ts
53035
+ var DEFAULT_CONTEXT_WINDOW_SIZE = 200000;
53036
+ var USABLE_CONTEXT_RATIO = 0.8;
53112
53037
  function toValidWindowSize(value) {
53113
53038
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
53114
53039
  return null;
53115
53040
  }
53116
53041
  return value;
53117
53042
  }
53118
- function getContextConfig(modelId, contextWindowSize) {
53043
+ function parseContextWindowSize(modelIdentifier) {
53044
+ const delimitedMatch = /(?:\(|\[)\s*(\d+(?:[,_]\d+)*(?:\.\d+)?)\s*([km])\s*(?:\)|\])/i.exec(modelIdentifier);
53045
+ if (delimitedMatch) {
53046
+ const delimitedValue = delimitedMatch[1];
53047
+ const delimitedUnit = delimitedMatch[2];
53048
+ if (!delimitedValue || !delimitedUnit) {
53049
+ return null;
53050
+ }
53051
+ const parsed2 = Number.parseFloat(delimitedValue.replace(/[,_]/g, ""));
53052
+ if (Number.isFinite(parsed2) && parsed2 > 0) {
53053
+ return Math.round(parsed2 * (delimitedUnit.toLowerCase() === "m" ? 1e6 : 1000));
53054
+ }
53055
+ }
53056
+ const contextMatch = /\b(\d+(?:[,_]\d+)*(?:\.\d+)?)\s*([km])(?:\s*(?:token\s*)?context)?\b/i.exec(modelIdentifier);
53057
+ if (!contextMatch) {
53058
+ return null;
53059
+ }
53060
+ const contextValue = contextMatch[1];
53061
+ const contextUnit = contextMatch[2];
53062
+ if (!contextValue || !contextUnit) {
53063
+ return null;
53064
+ }
53065
+ const parsed = Number.parseFloat(contextValue.replace(/[,_]/g, ""));
53066
+ if (!Number.isFinite(parsed) || parsed <= 0) {
53067
+ return null;
53068
+ }
53069
+ return Math.round(parsed * (contextUnit.toLowerCase() === "m" ? 1e6 : 1000));
53070
+ }
53071
+ function getModelContextIdentifier(model) {
53072
+ if (typeof model === "string") {
53073
+ const trimmed = model.trim();
53074
+ return trimmed.length > 0 ? trimmed : undefined;
53075
+ }
53076
+ if (!model) {
53077
+ return;
53078
+ }
53079
+ const id = model.id?.trim();
53080
+ const displayName = model.display_name?.trim();
53081
+ if (id && displayName) {
53082
+ return `${id} ${displayName}`;
53083
+ }
53084
+ return id ?? displayName;
53085
+ }
53086
+ function getContextConfig(modelIdentifier, contextWindowSize) {
53119
53087
  const statusWindowSize = toValidWindowSize(contextWindowSize);
53120
53088
  if (statusWindowSize !== null) {
53121
53089
  return {
53122
53090
  maxTokens: statusWindowSize,
53123
- usableTokens: Math.floor(statusWindowSize * 0.8)
53091
+ usableTokens: Math.floor(statusWindowSize * USABLE_CONTEXT_RATIO)
53124
53092
  };
53125
53093
  }
53126
53094
  const defaultConfig = {
53127
- maxTokens: 200000,
53128
- usableTokens: 160000
53095
+ maxTokens: DEFAULT_CONTEXT_WINDOW_SIZE,
53096
+ usableTokens: Math.floor(DEFAULT_CONTEXT_WINDOW_SIZE * USABLE_CONTEXT_RATIO)
53129
53097
  };
53130
- if (!modelId)
53098
+ if (!modelIdentifier) {
53131
53099
  return defaultConfig;
53132
- if (modelId.toLowerCase().includes("[1m]")) {
53100
+ }
53101
+ const inferredWindowSize = parseContextWindowSize(modelIdentifier);
53102
+ if (inferredWindowSize !== null) {
53133
53103
  return {
53134
- maxTokens: 1e6,
53135
- usableTokens: 800000
53104
+ maxTokens: inferredWindowSize,
53105
+ usableTokens: Math.floor(inferredWindowSize * USABLE_CONTEXT_RATIO)
53136
53106
  };
53137
53107
  }
53138
53108
  return defaultConfig;
@@ -53147,9 +53117,8 @@ function calculateContextPercentage(context) {
53147
53117
  if (!context.tokenMetrics) {
53148
53118
  return 0;
53149
53119
  }
53150
- const model = context.data?.model;
53151
- const modelId = typeof model === "string" ? model : model?.id;
53152
- const contextConfig = getContextConfig(modelId, contextWindowMetrics.windowSize);
53120
+ const modelIdentifier = getModelContextIdentifier(context.data?.model);
53121
+ const contextConfig = getContextConfig(modelIdentifier, contextWindowMetrics.windowSize);
53153
53122
  return Math.min(100, context.tokenMetrics.contextLength / contextConfig.maxTokens * 100);
53154
53123
  }
53155
53124
 
@@ -53161,6 +53130,36 @@ function formatTokens(count) {
53161
53130
  return `${(count / 1000).toFixed(1)}k`;
53162
53131
  return count.toString();
53163
53132
  }
53133
+ function resolveEffectiveTerminalWidth(detectedWidth, settings, context) {
53134
+ if (!detectedWidth) {
53135
+ return null;
53136
+ }
53137
+ const flexMode = settings.flexMode;
53138
+ if (context.isPreview) {
53139
+ if (flexMode === "full") {
53140
+ return detectedWidth - 6;
53141
+ }
53142
+ if (flexMode === "full-minus-40") {
53143
+ return detectedWidth - 40;
53144
+ }
53145
+ if (flexMode === "full-until-compact") {
53146
+ return detectedWidth - 6;
53147
+ }
53148
+ return null;
53149
+ }
53150
+ if (flexMode === "full") {
53151
+ return detectedWidth - 6;
53152
+ }
53153
+ if (flexMode === "full-minus-40") {
53154
+ return detectedWidth - 40;
53155
+ }
53156
+ if (flexMode === "full-until-compact") {
53157
+ const threshold = settings.compactThreshold;
53158
+ const contextPercentage = calculateContextPercentage(context);
53159
+ return contextPercentage >= threshold ? detectedWidth - 40 : detectedWidth - 6;
53160
+ }
53161
+ return null;
53162
+ }
53164
53163
  function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, globalSeparatorOffset = 0, preRenderedWidgets, preCalculatedMaxWidths) {
53165
53164
  const powerlineConfig = settings.powerline;
53166
53165
  const config2 = powerlineConfig ?? {};
@@ -53186,33 +53185,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
53186
53185
  if (filteredWidgets.length === 0)
53187
53186
  return "";
53188
53187
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
53189
- let terminalWidth = null;
53190
- if (detectedWidth) {
53191
- const flexMode = settings.flexMode;
53192
- if (context.isPreview) {
53193
- if (flexMode === "full") {
53194
- terminalWidth = detectedWidth - 6;
53195
- } else if (flexMode === "full-minus-40") {
53196
- terminalWidth = detectedWidth - 40;
53197
- } else if (flexMode === "full-until-compact") {
53198
- terminalWidth = detectedWidth - 6;
53199
- }
53200
- } else {
53201
- if (flexMode === "full") {
53202
- terminalWidth = detectedWidth - 6;
53203
- } else if (flexMode === "full-minus-40") {
53204
- terminalWidth = detectedWidth - 40;
53205
- } else if (flexMode === "full-until-compact") {
53206
- const threshold = settings.compactThreshold;
53207
- const contextPercentage = calculateContextPercentage(context);
53208
- if (contextPercentage >= threshold) {
53209
- terminalWidth = detectedWidth - 40;
53210
- } else {
53211
- terminalWidth = detectedWidth - 6;
53212
- }
53213
- }
53214
- }
53215
- }
53188
+ const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
53216
53189
  const widgetElements = [];
53217
53190
  let widgetColorIndex = 0;
53218
53191
  const preRenderedIndices = [];
@@ -53538,33 +53511,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
53538
53511
  return applyColors(text, fgColor, bgColor, shouldBold, colorLevel);
53539
53512
  };
53540
53513
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
53541
- let terminalWidth = null;
53542
- if (detectedWidth) {
53543
- const flexMode = settings.flexMode;
53544
- if (context.isPreview) {
53545
- if (flexMode === "full") {
53546
- terminalWidth = detectedWidth - 6;
53547
- } else if (flexMode === "full-minus-40") {
53548
- terminalWidth = detectedWidth - 40;
53549
- } else if (flexMode === "full-until-compact") {
53550
- terminalWidth = detectedWidth - 6;
53551
- }
53552
- } else {
53553
- if (flexMode === "full") {
53554
- terminalWidth = detectedWidth - 6;
53555
- } else if (flexMode === "full-minus-40") {
53556
- terminalWidth = detectedWidth - 40;
53557
- } else if (flexMode === "full-until-compact") {
53558
- const threshold = settings.compactThreshold;
53559
- const contextPercentage = calculateContextPercentage(context);
53560
- if (contextPercentage >= threshold) {
53561
- terminalWidth = detectedWidth - 40;
53562
- } else {
53563
- terminalWidth = detectedWidth - 6;
53564
- }
53565
- }
53566
- }
53567
- }
53514
+ const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
53568
53515
  const elements = [];
53569
53516
  let hasFlexSeparator = false;
53570
53517
  for (let i = 0;i < widgets.length; i++) {
@@ -53746,6 +53693,11 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
53746
53693
  return statusLine;
53747
53694
  }
53748
53695
 
53696
+ // src/widgets/shared/raw-or-labeled.ts
53697
+ function formatRawOrLabeledValue(item, labelPrefix, value) {
53698
+ return item.rawValue ? value : `${labelPrefix}${value}`;
53699
+ }
53700
+
53749
53701
  // src/widgets/TokensInput.ts
53750
53702
  class TokensInputWidget {
53751
53703
  getDefaultColor() {
@@ -53765,14 +53717,14 @@ class TokensInputWidget {
53765
53717
  }
53766
53718
  render(item, context, settings) {
53767
53719
  if (context.isPreview) {
53768
- return item.rawValue ? "15.2k" : "In: 15.2k";
53720
+ return formatRawOrLabeledValue(item, "In: ", "15.2k");
53769
53721
  }
53770
53722
  const inputTotalTokens = getContextWindowInputTotalTokens(context.data);
53771
53723
  if (inputTotalTokens !== null) {
53772
- return item.rawValue ? formatTokens(inputTotalTokens) : `In: ${formatTokens(inputTotalTokens)}`;
53724
+ return formatRawOrLabeledValue(item, "In: ", formatTokens(inputTotalTokens));
53773
53725
  }
53774
53726
  if (context.tokenMetrics) {
53775
- return item.rawValue ? formatTokens(context.tokenMetrics.inputTokens) : `In: ${formatTokens(context.tokenMetrics.inputTokens)}`;
53727
+ return formatRawOrLabeledValue(item, "In: ", formatTokens(context.tokenMetrics.inputTokens));
53776
53728
  }
53777
53729
  return null;
53778
53730
  }
@@ -53802,14 +53754,14 @@ class TokensOutputWidget {
53802
53754
  }
53803
53755
  render(item, context, settings) {
53804
53756
  if (context.isPreview) {
53805
- return item.rawValue ? "3.4k" : "Out: 3.4k";
53757
+ return formatRawOrLabeledValue(item, "Out: ", "3.4k");
53806
53758
  }
53807
53759
  const outputTotalTokens = getContextWindowOutputTotalTokens(context.data);
53808
53760
  if (outputTotalTokens !== null) {
53809
- return item.rawValue ? formatTokens(outputTotalTokens) : `Out: ${formatTokens(outputTotalTokens)}`;
53761
+ return formatRawOrLabeledValue(item, "Out: ", formatTokens(outputTotalTokens));
53810
53762
  }
53811
53763
  if (context.tokenMetrics) {
53812
- return item.rawValue ? formatTokens(context.tokenMetrics.outputTokens) : `Out: ${formatTokens(context.tokenMetrics.outputTokens)}`;
53764
+ return formatRawOrLabeledValue(item, "Out: ", formatTokens(context.tokenMetrics.outputTokens));
53813
53765
  }
53814
53766
  return null;
53815
53767
  }
@@ -53839,10 +53791,10 @@ class TokensCachedWidget {
53839
53791
  }
53840
53792
  render(item, context, settings) {
53841
53793
  if (context.isPreview) {
53842
- return item.rawValue ? "12k" : "Cached: 12k";
53794
+ return formatRawOrLabeledValue(item, "Cached: ", "12k");
53843
53795
  }
53844
53796
  if (context.tokenMetrics) {
53845
- return item.rawValue ? formatTokens(context.tokenMetrics.cachedTokens) : `Cached: ${formatTokens(context.tokenMetrics.cachedTokens)}`;
53797
+ return formatRawOrLabeledValue(item, "Cached: ", formatTokens(context.tokenMetrics.cachedTokens));
53846
53798
  }
53847
53799
  return null;
53848
53800
  }
@@ -53872,10 +53824,10 @@ class TokensTotalWidget {
53872
53824
  }
53873
53825
  render(item, context, settings) {
53874
53826
  if (context.isPreview) {
53875
- return item.rawValue ? "30.6k" : "Total: 30.6k";
53827
+ return formatRawOrLabeledValue(item, "Total: ", "30.6k");
53876
53828
  }
53877
53829
  if (context.tokenMetrics) {
53878
- return item.rawValue ? formatTokens(context.tokenMetrics.totalTokens) : `Total: ${formatTokens(context.tokenMetrics.totalTokens)}`;
53830
+ return formatRawOrLabeledValue(item, "Total: ", formatTokens(context.tokenMetrics.totalTokens));
53879
53831
  }
53880
53832
  return null;
53881
53833
  }
@@ -53923,6 +53875,22 @@ class ContextLengthWidget {
53923
53875
  return true;
53924
53876
  }
53925
53877
  }
53878
+ // src/widgets/shared/context-inverse.ts
53879
+ var INVERSE_KEY = "inverse";
53880
+ var TOGGLE_INVERSE_ACTION = "toggle-inverse";
53881
+ function isContextInverse(item) {
53882
+ return isMetadataFlagEnabled(item, INVERSE_KEY);
53883
+ }
53884
+ function getContextInverseModifierText(item) {
53885
+ return makeModifierText(isContextInverse(item) ? ["remaining"] : []);
53886
+ }
53887
+ function handleContextInverseAction(action, item) {
53888
+ if (action !== TOGGLE_INVERSE_ACTION) {
53889
+ return null;
53890
+ }
53891
+ return toggleMetadataFlag(item, INVERSE_KEY);
53892
+ }
53893
+
53926
53894
  // src/widgets/ContextPercentage.ts
53927
53895
  class ContextPercentageWidget {
53928
53896
  getDefaultColor() {
@@ -53938,47 +53906,31 @@ class ContextPercentageWidget {
53938
53906
  return "Context";
53939
53907
  }
53940
53908
  getEditorDisplay(item) {
53941
- const isInverse = item.metadata?.inverse === "true";
53942
- const modifiers = [];
53943
- if (isInverse) {
53944
- modifiers.push("remaining");
53945
- }
53946
53909
  return {
53947
53910
  displayText: this.getDisplayName(),
53948
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
53911
+ modifierText: getContextInverseModifierText(item)
53949
53912
  };
53950
53913
  }
53951
53914
  handleEditorAction(action, item) {
53952
- if (action === "toggle-inverse") {
53953
- const currentState = item.metadata?.inverse === "true";
53954
- return {
53955
- ...item,
53956
- metadata: {
53957
- ...item.metadata,
53958
- inverse: (!currentState).toString()
53959
- }
53960
- };
53961
- }
53962
- return null;
53915
+ return handleContextInverseAction(action, item);
53963
53916
  }
53964
53917
  render(item, context, settings) {
53965
- const isInverse = item.metadata?.inverse === "true";
53918
+ const isInverse = isContextInverse(item);
53966
53919
  const contextWindowMetrics = getContextWindowMetrics(context.data);
53967
53920
  if (context.isPreview) {
53968
53921
  const previewValue = isInverse ? "90.7%" : "9.3%";
53969
- return item.rawValue ? previewValue : `Ctx: ${previewValue}`;
53922
+ return formatRawOrLabeledValue(item, "Ctx: ", previewValue);
53970
53923
  }
53971
53924
  if (contextWindowMetrics.usedPercentage !== null) {
53972
53925
  const displayPercentage = isInverse ? 100 - contextWindowMetrics.usedPercentage : contextWindowMetrics.usedPercentage;
53973
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
53926
+ return formatRawOrLabeledValue(item, "Ctx: ", `${displayPercentage.toFixed(1)}%`);
53974
53927
  }
53975
53928
  if (context.tokenMetrics) {
53976
- const model = context.data?.model;
53977
- const modelId = typeof model === "string" ? model : model?.id;
53978
- const contextConfig = getContextConfig(modelId, contextWindowMetrics.windowSize);
53929
+ const modelIdentifier = getModelContextIdentifier(context.data?.model);
53930
+ const contextConfig = getContextConfig(modelIdentifier, contextWindowMetrics.windowSize);
53979
53931
  const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.maxTokens * 100);
53980
53932
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53981
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
53933
+ return formatRawOrLabeledValue(item, "Ctx: ", `${displayPercentage.toFixed(1)}%`);
53982
53934
  }
53983
53935
  return null;
53984
53936
  }
@@ -54009,48 +53961,32 @@ class ContextPercentageUsableWidget {
54009
53961
  return "Context";
54010
53962
  }
54011
53963
  getEditorDisplay(item) {
54012
- const isInverse = item.metadata?.inverse === "true";
54013
- const modifiers = [];
54014
- if (isInverse) {
54015
- modifiers.push("remaining");
54016
- }
54017
53964
  return {
54018
53965
  displayText: this.getDisplayName(),
54019
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
53966
+ modifierText: getContextInverseModifierText(item)
54020
53967
  };
54021
53968
  }
54022
53969
  handleEditorAction(action, item) {
54023
- if (action === "toggle-inverse") {
54024
- const currentState = item.metadata?.inverse === "true";
54025
- return {
54026
- ...item,
54027
- metadata: {
54028
- ...item.metadata,
54029
- inverse: (!currentState).toString()
54030
- }
54031
- };
54032
- }
54033
- return null;
53970
+ return handleContextInverseAction(action, item);
54034
53971
  }
54035
53972
  render(item, context, settings) {
54036
- const isInverse = item.metadata?.inverse === "true";
54037
- const model = context.data?.model;
54038
- const modelId = typeof model === "string" ? model : model?.id;
53973
+ const isInverse = isContextInverse(item);
53974
+ const modelIdentifier = getModelContextIdentifier(context.data?.model);
54039
53975
  const contextWindowMetrics = getContextWindowMetrics(context.data);
54040
- const contextConfig = getContextConfig(modelId, contextWindowMetrics.windowSize);
53976
+ const contextConfig = getContextConfig(modelIdentifier, contextWindowMetrics.windowSize);
54041
53977
  if (context.isPreview) {
54042
53978
  const previewValue = isInverse ? "88.4%" : "11.6%";
54043
- return item.rawValue ? previewValue : `Ctx(u): ${previewValue}`;
53979
+ return formatRawOrLabeledValue(item, "Ctx(u): ", previewValue);
54044
53980
  }
54045
53981
  if (contextWindowMetrics.contextLengthTokens !== null) {
54046
53982
  const usedPercentage = Math.min(100, contextWindowMetrics.contextLengthTokens / contextConfig.usableTokens * 100);
54047
53983
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
54048
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
53984
+ return formatRawOrLabeledValue(item, "Ctx(u): ", `${displayPercentage.toFixed(1)}%`);
54049
53985
  }
54050
53986
  if (context.tokenMetrics) {
54051
53987
  const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.usableTokens * 100);
54052
53988
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
54053
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
53989
+ return formatRawOrLabeledValue(item, "Ctx(u): ", `${displayPercentage.toFixed(1)}%`);
54054
53990
  }
54055
53991
  return null;
54056
53992
  }
@@ -56069,17 +56005,56 @@ function makeUsageProgressBar(percent, width = 15) {
56069
56005
  return "[" + "█".repeat(filled) + "░".repeat(empty2) + "]";
56070
56006
  }
56071
56007
 
56072
- // src/widgets/BlockTimer.ts
56073
- function getDisplayMode(item) {
56008
+ // src/widgets/shared/usage-display.ts
56009
+ function getUsageDisplayMode(item) {
56074
56010
  const mode = item.metadata?.display;
56075
56011
  if (mode === "progress" || mode === "progress-short") {
56076
56012
  return mode;
56077
56013
  }
56078
56014
  return "time";
56079
56015
  }
56080
- function isInverted(item) {
56081
- return item.metadata?.invert === "true";
56016
+ function isUsageProgressMode(mode) {
56017
+ return mode === "progress" || mode === "progress-short";
56018
+ }
56019
+ function getUsageProgressBarWidth(mode) {
56020
+ return mode === "progress" ? 32 : 16;
56021
+ }
56022
+ function isUsageInverted(item) {
56023
+ return isMetadataFlagEnabled(item, "invert");
56024
+ }
56025
+ function getUsageDisplayModifierText(item) {
56026
+ const mode = getUsageDisplayMode(item);
56027
+ const modifiers = [];
56028
+ if (mode === "progress") {
56029
+ modifiers.push("progress bar");
56030
+ } else if (mode === "progress-short") {
56031
+ modifiers.push("short bar");
56032
+ }
56033
+ if (isUsageInverted(item)) {
56034
+ modifiers.push("inverted");
56035
+ }
56036
+ return makeModifierText(modifiers);
56037
+ }
56038
+ function cycleUsageDisplayMode(item) {
56039
+ const currentMode = getUsageDisplayMode(item);
56040
+ const nextMode = currentMode === "time" ? "progress" : currentMode === "progress" ? "progress-short" : "time";
56041
+ const nextMetadata = {
56042
+ ...item.metadata ?? {},
56043
+ display: nextMode
56044
+ };
56045
+ if (nextMode === "time") {
56046
+ delete nextMetadata.invert;
56047
+ }
56048
+ return {
56049
+ ...item,
56050
+ metadata: nextMetadata
56051
+ };
56052
+ }
56053
+ function toggleUsageInverted(item) {
56054
+ return toggleMetadataFlag(item, "invert");
56082
56055
  }
56056
+
56057
+ // src/widgets/BlockTimer.ts
56083
56058
  function makeTimerProgressBar(percent, width) {
56084
56059
  const clampedPercent = Math.max(0, Math.min(100, percent));
56085
56060
  const filledWidth = Math.floor(clampedPercent / 100 * width);
@@ -56101,90 +56076,51 @@ class BlockTimerWidget {
56101
56076
  return "Usage";
56102
56077
  }
56103
56078
  getEditorDisplay(item) {
56104
- const mode = getDisplayMode(item);
56105
- const modifiers = [];
56106
- if (mode === "progress") {
56107
- modifiers.push("progress bar");
56108
- } else if (mode === "progress-short") {
56109
- modifiers.push("short bar");
56110
- }
56111
- if (isInverted(item)) {
56112
- modifiers.push("inverted");
56113
- }
56114
56079
  return {
56115
56080
  displayText: this.getDisplayName(),
56116
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56081
+ modifierText: getUsageDisplayModifierText(item)
56117
56082
  };
56118
56083
  }
56119
56084
  handleEditorAction(action, item) {
56120
56085
  if (action === "toggle-progress") {
56121
- const currentMode = getDisplayMode(item);
56122
- let nextMode;
56123
- if (currentMode === "time") {
56124
- nextMode = "progress";
56125
- } else if (currentMode === "progress") {
56126
- nextMode = "progress-short";
56127
- } else {
56128
- nextMode = "time";
56129
- }
56130
- const nextMetadata = {
56131
- ...item.metadata ?? {},
56132
- display: nextMode
56133
- };
56134
- if (nextMode === "time") {
56135
- delete nextMetadata.invert;
56136
- }
56137
- return {
56138
- ...item,
56139
- metadata: nextMetadata
56140
- };
56086
+ return cycleUsageDisplayMode(item);
56141
56087
  }
56142
56088
  if (action === "toggle-invert") {
56143
- return {
56144
- ...item,
56145
- metadata: {
56146
- ...item.metadata,
56147
- invert: (!isInverted(item)).toString()
56148
- }
56149
- };
56089
+ return toggleUsageInverted(item);
56150
56090
  }
56151
56091
  return null;
56152
56092
  }
56153
56093
  render(item, context, settings) {
56154
- const displayMode = getDisplayMode(item);
56155
- const inverted = isInverted(item);
56094
+ const displayMode = getUsageDisplayMode(item);
56095
+ const inverted = isUsageInverted(item);
56156
56096
  if (context.isPreview) {
56157
56097
  const previewPercent = inverted ? 26.1 : 73.9;
56158
- const prefix = item.rawValue ? "" : "Block ";
56159
- if (displayMode === "progress" || displayMode === "progress-short") {
56160
- const barWidth = displayMode === "progress" ? 32 : 16;
56098
+ if (isUsageProgressMode(displayMode)) {
56099
+ const barWidth = getUsageProgressBarWidth(displayMode);
56161
56100
  const progressBar = makeTimerProgressBar(previewPercent, barWidth);
56162
- return `${prefix}[${progressBar}] ${previewPercent.toFixed(1)}%`;
56101
+ return formatRawOrLabeledValue(item, "Block ", `[${progressBar}] ${previewPercent.toFixed(1)}%`);
56163
56102
  }
56164
- return item.rawValue ? "3hr 45m" : "Block: 3hr 45m";
56103
+ return formatRawOrLabeledValue(item, "Block: ", "3hr 45m");
56165
56104
  }
56166
56105
  const usageData = fetchUsageData();
56167
56106
  const window2 = resolveUsageWindowWithFallback(usageData, context.blockMetrics);
56168
56107
  if (!window2) {
56169
- if (displayMode === "progress" || displayMode === "progress-short") {
56170
- const barWidth = displayMode === "progress" ? 32 : 16;
56108
+ if (isUsageProgressMode(displayMode)) {
56109
+ const barWidth = getUsageProgressBarWidth(displayMode);
56171
56110
  const emptyBar = "░".repeat(barWidth);
56172
- return item.rawValue ? `[${emptyBar}] 0.0%` : `Block [${emptyBar}] 0.0%`;
56111
+ return formatRawOrLabeledValue(item, "Block ", `[${emptyBar}] 0.0%`);
56173
56112
  }
56174
- return item.rawValue ? "0hr 0m" : "Block: 0hr 0m";
56113
+ return formatRawOrLabeledValue(item, "Block: ", "0hr 0m");
56175
56114
  }
56176
- if (displayMode === "progress" || displayMode === "progress-short") {
56177
- const barWidth = displayMode === "progress" ? 32 : 16;
56115
+ if (isUsageProgressMode(displayMode)) {
56116
+ const barWidth = getUsageProgressBarWidth(displayMode);
56178
56117
  const percent = inverted ? window2.remainingPercent : window2.elapsedPercent;
56179
56118
  const progressBar = makeTimerProgressBar(percent, barWidth);
56180
56119
  const percentage = percent.toFixed(1);
56181
- if (item.rawValue) {
56182
- return `[${progressBar}] ${percentage}%`;
56183
- }
56184
- return `Block [${progressBar}] ${percentage}%`;
56120
+ return formatRawOrLabeledValue(item, "Block ", `[${progressBar}] ${percentage}%`);
56185
56121
  }
56186
56122
  const elapsedTime = formatUsageDuration(window2.elapsedMs);
56187
- return item.rawValue ? elapsedTime : `Block: ${elapsedTime}`;
56123
+ return formatRawOrLabeledValue(item, "Block: ", elapsedTime);
56188
56124
  }
56189
56125
  getCustomKeybinds() {
56190
56126
  return [
@@ -56619,17 +56555,6 @@ class SessionNameWidget {
56619
56555
  }
56620
56556
  }
56621
56557
  // src/widgets/SessionUsage.ts
56622
- function getDisplayMode2(item) {
56623
- const mode = item.metadata?.display;
56624
- if (mode === "progress" || mode === "progress-short") {
56625
- return mode;
56626
- }
56627
- return "time";
56628
- }
56629
- function isInverted2(item) {
56630
- return item.metadata?.invert === "true";
56631
- }
56632
-
56633
56558
  class SessionUsageWidget {
56634
56559
  getDefaultColor() {
56635
56560
  return "brightBlue";
@@ -56644,67 +56569,32 @@ class SessionUsageWidget {
56644
56569
  return "Usage";
56645
56570
  }
56646
56571
  getEditorDisplay(item) {
56647
- const mode = getDisplayMode2(item);
56648
- const modifiers = [];
56649
- if (mode === "progress") {
56650
- modifiers.push("progress bar");
56651
- } else if (mode === "progress-short") {
56652
- modifiers.push("short bar");
56653
- }
56654
- if (isInverted2(item)) {
56655
- modifiers.push("inverted");
56656
- }
56657
56572
  return {
56658
56573
  displayText: this.getDisplayName(),
56659
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56574
+ modifierText: getUsageDisplayModifierText(item)
56660
56575
  };
56661
56576
  }
56662
56577
  handleEditorAction(action, item) {
56663
56578
  if (action === "toggle-progress") {
56664
- const currentMode = getDisplayMode2(item);
56665
- let nextMode;
56666
- if (currentMode === "time") {
56667
- nextMode = "progress";
56668
- } else if (currentMode === "progress") {
56669
- nextMode = "progress-short";
56670
- } else {
56671
- nextMode = "time";
56672
- }
56673
- const nextMetadata = {
56674
- ...item.metadata ?? {},
56675
- display: nextMode
56676
- };
56677
- if (nextMode === "time") {
56678
- delete nextMetadata.invert;
56679
- }
56680
- return {
56681
- ...item,
56682
- metadata: nextMetadata
56683
- };
56579
+ return cycleUsageDisplayMode(item);
56684
56580
  }
56685
56581
  if (action === "toggle-invert") {
56686
- return {
56687
- ...item,
56688
- metadata: {
56689
- ...item.metadata,
56690
- invert: (!isInverted2(item)).toString()
56691
- }
56692
- };
56582
+ return toggleUsageInverted(item);
56693
56583
  }
56694
56584
  return null;
56695
56585
  }
56696
56586
  render(item, context, settings) {
56697
- const displayMode = getDisplayMode2(item);
56698
- const inverted = isInverted2(item);
56587
+ const displayMode = getUsageDisplayMode(item);
56588
+ const inverted = isUsageInverted(item);
56699
56589
  if (context.isPreview) {
56700
56590
  const previewPercent = 20;
56701
56591
  const renderedPercent = inverted ? 100 - previewPercent : previewPercent;
56702
- if (displayMode === "progress" || displayMode === "progress-short") {
56703
- const width = displayMode === "progress" ? 32 : 16;
56592
+ if (isUsageProgressMode(displayMode)) {
56593
+ const width = getUsageProgressBarWidth(displayMode);
56704
56594
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56705
- return item.rawValue ? progressDisplay : `Session: ${progressDisplay}`;
56595
+ return formatRawOrLabeledValue(item, "Session: ", progressDisplay);
56706
56596
  }
56707
- return item.rawValue ? `${previewPercent.toFixed(1)}%` : `Session: ${previewPercent.toFixed(1)}%`;
56597
+ return formatRawOrLabeledValue(item, "Session: ", `${previewPercent.toFixed(1)}%`);
56708
56598
  }
56709
56599
  const data = fetchUsageData();
56710
56600
  if (data.error)
@@ -56712,13 +56602,13 @@ class SessionUsageWidget {
56712
56602
  if (data.sessionUsage === undefined)
56713
56603
  return null;
56714
56604
  const percent = Math.max(0, Math.min(100, data.sessionUsage));
56715
- if (displayMode === "progress" || displayMode === "progress-short") {
56716
- const width = displayMode === "progress" ? 32 : 16;
56605
+ if (isUsageProgressMode(displayMode)) {
56606
+ const width = getUsageProgressBarWidth(displayMode);
56717
56607
  const renderedPercent = inverted ? 100 - percent : percent;
56718
56608
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56719
- return item.rawValue ? progressDisplay : `Session: ${progressDisplay}`;
56609
+ return formatRawOrLabeledValue(item, "Session: ", progressDisplay);
56720
56610
  }
56721
- return item.rawValue ? `${percent.toFixed(1)}%` : `Session: ${percent.toFixed(1)}%`;
56611
+ return formatRawOrLabeledValue(item, "Session: ", `${percent.toFixed(1)}%`);
56722
56612
  }
56723
56613
  getCustomKeybinds() {
56724
56614
  return [
@@ -56734,17 +56624,6 @@ class SessionUsageWidget {
56734
56624
  }
56735
56625
  }
56736
56626
  // src/widgets/WeeklyUsage.ts
56737
- function getDisplayMode3(item) {
56738
- const mode = item.metadata?.display;
56739
- if (mode === "progress" || mode === "progress-short") {
56740
- return mode;
56741
- }
56742
- return "time";
56743
- }
56744
- function isInverted3(item) {
56745
- return item.metadata?.invert === "true";
56746
- }
56747
-
56748
56627
  class WeeklyUsageWidget {
56749
56628
  getDefaultColor() {
56750
56629
  return "brightBlue";
@@ -56759,67 +56638,32 @@ class WeeklyUsageWidget {
56759
56638
  return "Usage";
56760
56639
  }
56761
56640
  getEditorDisplay(item) {
56762
- const mode = getDisplayMode3(item);
56763
- const modifiers = [];
56764
- if (mode === "progress") {
56765
- modifiers.push("progress bar");
56766
- } else if (mode === "progress-short") {
56767
- modifiers.push("short bar");
56768
- }
56769
- if (isInverted3(item)) {
56770
- modifiers.push("inverted");
56771
- }
56772
56641
  return {
56773
56642
  displayText: this.getDisplayName(),
56774
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56643
+ modifierText: getUsageDisplayModifierText(item)
56775
56644
  };
56776
56645
  }
56777
56646
  handleEditorAction(action, item) {
56778
56647
  if (action === "toggle-progress") {
56779
- const currentMode = getDisplayMode3(item);
56780
- let nextMode;
56781
- if (currentMode === "time") {
56782
- nextMode = "progress";
56783
- } else if (currentMode === "progress") {
56784
- nextMode = "progress-short";
56785
- } else {
56786
- nextMode = "time";
56787
- }
56788
- const nextMetadata = {
56789
- ...item.metadata ?? {},
56790
- display: nextMode
56791
- };
56792
- if (nextMode === "time") {
56793
- delete nextMetadata.invert;
56794
- }
56795
- return {
56796
- ...item,
56797
- metadata: nextMetadata
56798
- };
56648
+ return cycleUsageDisplayMode(item);
56799
56649
  }
56800
56650
  if (action === "toggle-invert") {
56801
- return {
56802
- ...item,
56803
- metadata: {
56804
- ...item.metadata,
56805
- invert: (!isInverted3(item)).toString()
56806
- }
56807
- };
56651
+ return toggleUsageInverted(item);
56808
56652
  }
56809
56653
  return null;
56810
56654
  }
56811
56655
  render(item, context, settings) {
56812
- const displayMode = getDisplayMode3(item);
56813
- const inverted = isInverted3(item);
56656
+ const displayMode = getUsageDisplayMode(item);
56657
+ const inverted = isUsageInverted(item);
56814
56658
  if (context.isPreview) {
56815
56659
  const previewPercent = 12;
56816
56660
  const renderedPercent = inverted ? 100 - previewPercent : previewPercent;
56817
- if (displayMode === "progress" || displayMode === "progress-short") {
56818
- const width = displayMode === "progress" ? 32 : 16;
56661
+ if (isUsageProgressMode(displayMode)) {
56662
+ const width = getUsageProgressBarWidth(displayMode);
56819
56663
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56820
- return item.rawValue ? progressDisplay : `Weekly: ${progressDisplay}`;
56664
+ return formatRawOrLabeledValue(item, "Weekly: ", progressDisplay);
56821
56665
  }
56822
- return item.rawValue ? `${previewPercent.toFixed(1)}%` : `Weekly: ${previewPercent.toFixed(1)}%`;
56666
+ return formatRawOrLabeledValue(item, "Weekly: ", `${previewPercent.toFixed(1)}%`);
56823
56667
  }
56824
56668
  const data = fetchUsageData();
56825
56669
  if (data.error)
@@ -56827,13 +56671,13 @@ class WeeklyUsageWidget {
56827
56671
  if (data.weeklyUsage === undefined)
56828
56672
  return null;
56829
56673
  const percent = Math.max(0, Math.min(100, data.weeklyUsage));
56830
- if (displayMode === "progress" || displayMode === "progress-short") {
56831
- const width = displayMode === "progress" ? 32 : 16;
56674
+ if (isUsageProgressMode(displayMode)) {
56675
+ const width = getUsageProgressBarWidth(displayMode);
56832
56676
  const renderedPercent = inverted ? 100 - percent : percent;
56833
56677
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56834
- return item.rawValue ? progressDisplay : `Weekly: ${progressDisplay}`;
56678
+ return formatRawOrLabeledValue(item, "Weekly: ", progressDisplay);
56835
56679
  }
56836
- return item.rawValue ? `${percent.toFixed(1)}%` : `Weekly: ${percent.toFixed(1)}%`;
56680
+ return formatRawOrLabeledValue(item, "Weekly: ", `${percent.toFixed(1)}%`);
56837
56681
  }
56838
56682
  getCustomKeybinds() {
56839
56683
  return [
@@ -56849,16 +56693,6 @@ class WeeklyUsageWidget {
56849
56693
  }
56850
56694
  }
56851
56695
  // src/widgets/ResetTimer.ts
56852
- function getDisplayMode4(item) {
56853
- const mode = item.metadata?.display;
56854
- if (mode === "progress" || mode === "progress-short") {
56855
- return mode;
56856
- }
56857
- return "time";
56858
- }
56859
- function isInverted4(item) {
56860
- return item.metadata?.invert === "true";
56861
- }
56862
56696
  function makeTimerProgressBar2(percent, width) {
56863
56697
  const clampedPercent = Math.max(0, Math.min(100, percent));
56864
56698
  const filledWidth = Math.floor(clampedPercent / 100 * width);
@@ -56880,67 +56714,31 @@ class ResetTimerWidget {
56880
56714
  return "Usage";
56881
56715
  }
56882
56716
  getEditorDisplay(item) {
56883
- const mode = getDisplayMode4(item);
56884
- const modifiers = [];
56885
- if (mode === "progress") {
56886
- modifiers.push("progress bar");
56887
- } else if (mode === "progress-short") {
56888
- modifiers.push("short bar");
56889
- }
56890
- if (isInverted4(item)) {
56891
- modifiers.push("inverted");
56892
- }
56893
56717
  return {
56894
56718
  displayText: this.getDisplayName(),
56895
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56719
+ modifierText: getUsageDisplayModifierText(item)
56896
56720
  };
56897
56721
  }
56898
56722
  handleEditorAction(action, item) {
56899
56723
  if (action === "toggle-progress") {
56900
- const currentMode = getDisplayMode4(item);
56901
- let nextMode;
56902
- if (currentMode === "time") {
56903
- nextMode = "progress";
56904
- } else if (currentMode === "progress") {
56905
- nextMode = "progress-short";
56906
- } else {
56907
- nextMode = "time";
56908
- }
56909
- const nextMetadata = {
56910
- ...item.metadata ?? {},
56911
- display: nextMode
56912
- };
56913
- if (nextMode === "time") {
56914
- delete nextMetadata.invert;
56915
- }
56916
- return {
56917
- ...item,
56918
- metadata: nextMetadata
56919
- };
56724
+ return cycleUsageDisplayMode(item);
56920
56725
  }
56921
56726
  if (action === "toggle-invert") {
56922
- return {
56923
- ...item,
56924
- metadata: {
56925
- ...item.metadata,
56926
- invert: (!isInverted4(item)).toString()
56927
- }
56928
- };
56727
+ return toggleUsageInverted(item);
56929
56728
  }
56930
56729
  return null;
56931
56730
  }
56932
56731
  render(item, context, settings) {
56933
- const displayMode = getDisplayMode4(item);
56934
- const inverted = isInverted4(item);
56732
+ const displayMode = getUsageDisplayMode(item);
56733
+ const inverted = isUsageInverted(item);
56935
56734
  if (context.isPreview) {
56936
56735
  const previewPercent = inverted ? 90 : 10;
56937
- const prefix = item.rawValue ? "" : "Reset ";
56938
- if (displayMode === "progress" || displayMode === "progress-short") {
56939
- const barWidth = displayMode === "progress" ? 32 : 16;
56736
+ if (isUsageProgressMode(displayMode)) {
56737
+ const barWidth = getUsageProgressBarWidth(displayMode);
56940
56738
  const progressBar = makeTimerProgressBar2(previewPercent, barWidth);
56941
- return `${prefix}[${progressBar}] ${previewPercent.toFixed(1)}%`;
56739
+ return formatRawOrLabeledValue(item, "Reset ", `[${progressBar}] ${previewPercent.toFixed(1)}%`);
56942
56740
  }
56943
- return item.rawValue ? "4hr 30m" : "Reset: 4hr 30m";
56741
+ return formatRawOrLabeledValue(item, "Reset: ", "4hr 30m");
56944
56742
  }
56945
56743
  const usageData = fetchUsageData();
56946
56744
  const window2 = resolveUsageWindowWithFallback(usageData, context.blockMetrics);
@@ -56950,18 +56748,15 @@ class ResetTimerWidget {
56950
56748
  }
56951
56749
  return null;
56952
56750
  }
56953
- if (displayMode === "progress" || displayMode === "progress-short") {
56954
- const barWidth = displayMode === "progress" ? 32 : 16;
56751
+ if (isUsageProgressMode(displayMode)) {
56752
+ const barWidth = getUsageProgressBarWidth(displayMode);
56955
56753
  const percent = inverted ? window2.remainingPercent : window2.elapsedPercent;
56956
56754
  const progressBar = makeTimerProgressBar2(percent, barWidth);
56957
56755
  const percentage = percent.toFixed(1);
56958
- if (item.rawValue) {
56959
- return `[${progressBar}] ${percentage}%`;
56960
- }
56961
- return `Reset [${progressBar}] ${percentage}%`;
56756
+ return formatRawOrLabeledValue(item, "Reset ", `[${progressBar}] ${percentage}%`);
56962
56757
  }
56963
56758
  const remainingTime = formatUsageDuration(window2.remainingMs);
56964
- return item.rawValue ? remainingTime : `Reset: ${remainingTime}`;
56759
+ return formatRawOrLabeledValue(item, "Reset: ", remainingTime);
56965
56760
  }
56966
56761
  getCustomKeybinds() {
56967
56762
  return [
@@ -56977,7 +56772,7 @@ class ResetTimerWidget {
56977
56772
  }
56978
56773
  }
56979
56774
  // src/widgets/ContextBar.ts
56980
- function getDisplayMode5(item) {
56775
+ function getDisplayMode(item) {
56981
56776
  return item.metadata?.display === "progress" ? "progress" : "progress-short";
56982
56777
  }
56983
56778
 
@@ -56995,7 +56790,7 @@ class ContextBarWidget {
56995
56790
  return "Context";
56996
56791
  }
56997
56792
  getEditorDisplay(item) {
56998
- const mode = getDisplayMode5(item);
56793
+ const mode = getDisplayMode(item);
56999
56794
  const modifiers = [];
57000
56795
  if (mode === "progress-short") {
57001
56796
  modifiers.push("short bar");
@@ -57009,7 +56804,7 @@ class ContextBarWidget {
57009
56804
  if (action !== "toggle-progress") {
57010
56805
  return null;
57011
56806
  }
57012
- const currentMode = getDisplayMode5(item);
56807
+ const currentMode = getDisplayMode(item);
57013
56808
  const nextMode = currentMode === "progress-short" ? "progress" : "progress-short";
57014
56809
  return {
57015
56810
  ...item,
@@ -57020,7 +56815,7 @@ class ContextBarWidget {
57020
56815
  };
57021
56816
  }
57022
56817
  render(item, context, settings) {
57023
- const displayMode = getDisplayMode5(item);
56818
+ const displayMode = getDisplayMode(item);
57024
56819
  const barWidth = displayMode === "progress" ? 32 : 16;
57025
56820
  if (context.isPreview) {
57026
56821
  const previewDisplay = `${makeUsageProgressBar(25, barWidth)} 50k/200k (25%)`;
@@ -57033,9 +56828,8 @@ class ContextBarWidget {
57033
56828
  used = context.tokenMetrics.contextLength;
57034
56829
  }
57035
56830
  if (total === null && context.tokenMetrics) {
57036
- const model = context.data?.model;
57037
- const modelId = typeof model === "string" ? model : model?.id;
57038
- total = getContextConfig(modelId).maxTokens;
56831
+ const modelIdentifier = getModelContextIdentifier(context.data?.model);
56832
+ total = getContextConfig(modelIdentifier).maxTokens;
57039
56833
  }
57040
56834
  if (used === null || total === null || total <= 0) {
57041
56835
  return null;
@@ -57453,6 +57247,111 @@ var ConfirmDialog = ({ message, onConfirm, onCancel, inline = false }) => {
57453
57247
  }, undefined, true, undefined, this);
57454
57248
  };
57455
57249
 
57250
+ // src/tui/components/color-menu/mutations.ts
57251
+ function updateWidgetById(widgets, widgetId, updater) {
57252
+ return widgets.map((widget) => widget.id === widgetId ? updater(widget) : widget);
57253
+ }
57254
+ function setWidgetColor(widgets, widgetId, color, editingBackground) {
57255
+ return updateWidgetById(widgets, widgetId, (widget) => {
57256
+ if (editingBackground) {
57257
+ return {
57258
+ ...widget,
57259
+ backgroundColor: color
57260
+ };
57261
+ }
57262
+ return {
57263
+ ...widget,
57264
+ color
57265
+ };
57266
+ });
57267
+ }
57268
+ function toggleWidgetBold(widgets, widgetId) {
57269
+ return updateWidgetById(widgets, widgetId, (widget) => ({
57270
+ ...widget,
57271
+ bold: !widget.bold
57272
+ }));
57273
+ }
57274
+ function resetWidgetStyling(widgets, widgetId) {
57275
+ return updateWidgetById(widgets, widgetId, (widget) => {
57276
+ const {
57277
+ color,
57278
+ backgroundColor,
57279
+ bold,
57280
+ ...restWidget
57281
+ } = widget;
57282
+ return restWidget;
57283
+ });
57284
+ }
57285
+ function clearAllWidgetStyling(widgets) {
57286
+ return widgets.map((widget) => {
57287
+ const {
57288
+ color,
57289
+ backgroundColor,
57290
+ bold,
57291
+ ...restWidget
57292
+ } = widget;
57293
+ return restWidget;
57294
+ });
57295
+ }
57296
+ function getDefaultForegroundColor(widget) {
57297
+ if (widget.type === "separator" || widget.type === "flex-separator") {
57298
+ return "white";
57299
+ }
57300
+ const widgetImpl = getWidget(widget.type);
57301
+ return widgetImpl ? widgetImpl.getDefaultColor() : "white";
57302
+ }
57303
+ function getNextIndex(currentIndex, length, direction) {
57304
+ if (direction === "right") {
57305
+ return (currentIndex + 1) % length;
57306
+ }
57307
+ return currentIndex === 0 ? length - 1 : currentIndex - 1;
57308
+ }
57309
+ function cycleWidgetColor({
57310
+ widgets,
57311
+ widgetId,
57312
+ direction,
57313
+ editingBackground,
57314
+ colors,
57315
+ backgroundColors
57316
+ }) {
57317
+ return updateWidgetById(widgets, widgetId, (widget) => {
57318
+ if (editingBackground) {
57319
+ if (backgroundColors.length === 0) {
57320
+ return widget;
57321
+ }
57322
+ const currentBgColor = widget.backgroundColor ?? "";
57323
+ let currentBgColorIndex = backgroundColors.indexOf(currentBgColor);
57324
+ if (currentBgColorIndex === -1) {
57325
+ currentBgColorIndex = 0;
57326
+ }
57327
+ const nextBgColorIndex = getNextIndex(currentBgColorIndex, backgroundColors.length, direction);
57328
+ const nextBgColor = backgroundColors[nextBgColorIndex];
57329
+ return {
57330
+ ...widget,
57331
+ backgroundColor: nextBgColor === "" ? undefined : nextBgColor
57332
+ };
57333
+ }
57334
+ if (colors.length === 0) {
57335
+ return widget;
57336
+ }
57337
+ const defaultColor = getDefaultForegroundColor(widget);
57338
+ let currentColor = widget.color ?? defaultColor;
57339
+ if (currentColor === "dim") {
57340
+ currentColor = defaultColor;
57341
+ }
57342
+ let currentColorIndex = colors.indexOf(currentColor);
57343
+ if (currentColorIndex === -1) {
57344
+ currentColorIndex = 0;
57345
+ }
57346
+ const nextColorIndex = getNextIndex(currentColorIndex, colors.length, direction);
57347
+ const nextColor = colors[nextColorIndex];
57348
+ return {
57349
+ ...widget,
57350
+ color: nextColor
57351
+ };
57352
+ });
57353
+ }
57354
+
57456
57355
  // src/tui/components/ColorMenu.tsx
57457
57356
  var jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
57458
57357
  var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
@@ -57493,16 +57392,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57493
57392
  const hexColor = `hex:${hexInput}`;
57494
57393
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
57495
57394
  if (selectedWidget2) {
57496
- const newItems = widgets.map((widget) => {
57497
- if (widget.id === highlightedItemId) {
57498
- if (editingBackground) {
57499
- return { ...widget, backgroundColor: hexColor };
57500
- } else {
57501
- return { ...widget, color: hexColor };
57502
- }
57503
- }
57504
- return widget;
57505
- });
57395
+ const newItems = setWidgetColor(widgets, selectedWidget2.id, hexColor, editingBackground);
57506
57396
  onUpdate(newItems);
57507
57397
  }
57508
57398
  setHexInputMode(false);
@@ -57531,16 +57421,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57531
57421
  const ansiColor = `ansi256:${code}`;
57532
57422
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
57533
57423
  if (selectedWidget2) {
57534
- const newItems = widgets.map((widget) => {
57535
- if (widget.id === highlightedItemId) {
57536
- if (editingBackground) {
57537
- return { ...widget, backgroundColor: ansiColor };
57538
- } else {
57539
- return { ...widget, color: ansiColor };
57540
- }
57541
- }
57542
- return widget;
57543
- });
57424
+ const newItems = setWidgetColor(widgets, selectedWidget2.id, ansiColor, editingBackground);
57544
57425
  onUpdate(newItems);
57545
57426
  setAnsi256InputMode(false);
57546
57427
  setAnsi256Input("");
@@ -57590,12 +57471,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57590
57471
  if (highlightedItemId && highlightedItemId !== "back") {
57591
57472
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
57592
57473
  if (selectedWidget2) {
57593
- const newItems = widgets.map((widget) => {
57594
- if (widget.id === selectedWidget2.id) {
57595
- return { ...widget, bold: !widget.bold };
57596
- }
57597
- return widget;
57598
- });
57474
+ const newItems = toggleWidgetBold(widgets, selectedWidget2.id);
57599
57475
  onUpdate(newItems);
57600
57476
  }
57601
57477
  }
@@ -57603,13 +57479,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57603
57479
  if (highlightedItemId && highlightedItemId !== "back") {
57604
57480
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
57605
57481
  if (selectedWidget2) {
57606
- const newItems = widgets.map((widget) => {
57607
- if (widget.id === selectedWidget2.id) {
57608
- const { color, backgroundColor, bold, ...restWidget } = widget;
57609
- return restWidget;
57610
- }
57611
- return widget;
57612
- });
57482
+ const newItems = resetWidgetStyling(widgets, selectedWidget2.id);
57613
57483
  onUpdate(newItems);
57614
57484
  }
57615
57485
  }
@@ -57619,47 +57489,13 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57619
57489
  if (highlightedItemId && highlightedItemId !== "back") {
57620
57490
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
57621
57491
  if (selectedWidget2) {
57622
- const newItems = widgets.map((widget) => {
57623
- if (widget.id === selectedWidget2.id) {
57624
- if (editingBackground) {
57625
- const currentBgColor = widget.backgroundColor ?? "";
57626
- let currentBgColorIndex = bgColors.indexOf(currentBgColor);
57627
- if (currentBgColorIndex === -1)
57628
- currentBgColorIndex = 0;
57629
- let nextBgColorIndex;
57630
- if (key.rightArrow) {
57631
- nextBgColorIndex = (currentBgColorIndex + 1) % bgColors.length;
57632
- } else {
57633
- nextBgColorIndex = currentBgColorIndex === 0 ? bgColors.length - 1 : currentBgColorIndex - 1;
57634
- }
57635
- const nextBgColor = bgColors[nextBgColorIndex];
57636
- return { ...widget, backgroundColor: nextBgColor === "" ? undefined : nextBgColor };
57637
- } else {
57638
- let defaultColor = "white";
57639
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
57640
- const widgetImpl = getWidget(widget.type);
57641
- if (widgetImpl) {
57642
- defaultColor = widgetImpl.getDefaultColor();
57643
- }
57644
- }
57645
- let currentColor2 = widget.color ?? defaultColor;
57646
- if (currentColor2 === "dim") {
57647
- currentColor2 = defaultColor;
57648
- }
57649
- let currentColorIndex = colors.indexOf(currentColor2);
57650
- if (currentColorIndex === -1)
57651
- currentColorIndex = 0;
57652
- let nextColorIndex;
57653
- if (key.rightArrow) {
57654
- nextColorIndex = (currentColorIndex + 1) % colors.length;
57655
- } else {
57656
- nextColorIndex = currentColorIndex === 0 ? colors.length - 1 : currentColorIndex - 1;
57657
- }
57658
- const nextColor = colors[nextColorIndex];
57659
- return { ...widget, color: nextColor };
57660
- }
57661
- }
57662
- return widget;
57492
+ const newItems = cycleWidgetColor({
57493
+ widgets,
57494
+ widgetId: selectedWidget2.id,
57495
+ direction: key.rightArrow ? "right" : "left",
57496
+ editingBackground,
57497
+ colors,
57498
+ backgroundColors: bgColors
57663
57499
  });
57664
57500
  onUpdate(newItems);
57665
57501
  }
@@ -57815,10 +57651,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
57815
57651
  children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmDialog, {
57816
57652
  inline: true,
57817
57653
  onConfirm: () => {
57818
- const newItems = widgets.map((widget) => {
57819
- const { color, backgroundColor, bold, ...restWidget } = widget;
57820
- return restWidget;
57821
- });
57654
+ const newItems = clearAllWidgetStyling(widgets);
57822
57655
  onUpdate(newItems);
57823
57656
  setShowClearConfirm(false);
57824
57657
  },
@@ -58506,6 +58339,317 @@ var InstallMenu = ({
58506
58339
  };
58507
58340
  // src/tui/components/ItemsEditor.tsx
58508
58341
  var import_react37 = __toESM(require_react(), 1);
58342
+
58343
+ // src/tui/components/items-editor/input-handlers.ts
58344
+ function setPickerState(setWidgetPicker, normalizeState, updater) {
58345
+ setWidgetPicker((prev) => {
58346
+ if (!prev) {
58347
+ return prev;
58348
+ }
58349
+ return normalizeState(updater(prev));
58350
+ });
58351
+ }
58352
+ function getPickerCategories(widgetCategories) {
58353
+ return [...widgetCategories];
58354
+ }
58355
+ function normalizePickerState(state, widgetCatalog, widgetCategories) {
58356
+ const filteredCategories = getPickerCategories(widgetCategories);
58357
+ const selectedCategory = state.selectedCategory && filteredCategories.includes(state.selectedCategory) ? state.selectedCategory : filteredCategories[0] ?? null;
58358
+ const hasTopLevelSearch = state.level === "category" && state.categoryQuery.trim().length > 0;
58359
+ const effectiveCategory = hasTopLevelSearch ? "All" : selectedCategory ?? "All";
58360
+ const effectiveQuery = hasTopLevelSearch ? state.categoryQuery : state.widgetQuery;
58361
+ const filteredWidgets = filterWidgetCatalog(widgetCatalog, effectiveCategory, effectiveQuery);
58362
+ const hasSelectedType = state.selectedType ? filteredWidgets.some((entry) => entry.type === state.selectedType) : false;
58363
+ return {
58364
+ ...state,
58365
+ selectedCategory,
58366
+ selectedType: hasSelectedType ? state.selectedType : filteredWidgets[0]?.type ?? null
58367
+ };
58368
+ }
58369
+ function getPickerViewState(widgetPicker, widgetCatalog, widgetCategories) {
58370
+ const filteredCategories = getPickerCategories(widgetCategories);
58371
+ const selectedCategory = widgetPicker.selectedCategory && filteredCategories.includes(widgetPicker.selectedCategory) ? widgetPicker.selectedCategory : filteredCategories[0] ?? null;
58372
+ const hasTopLevelSearch = widgetPicker.level === "category" && widgetPicker.categoryQuery.trim().length > 0;
58373
+ const topLevelSearchEntries = hasTopLevelSearch ? filterWidgetCatalog(widgetCatalog, "All", widgetPicker.categoryQuery) : [];
58374
+ const topLevelSelectedEntry = topLevelSearchEntries.find((entry) => entry.type === widgetPicker.selectedType) ?? topLevelSearchEntries[0];
58375
+ const filteredWidgets = filterWidgetCatalog(widgetCatalog, selectedCategory ?? "All", widgetPicker.widgetQuery);
58376
+ const selectedEntry = filteredWidgets.find((entry) => entry.type === widgetPicker.selectedType) ?? filteredWidgets[0];
58377
+ return {
58378
+ filteredCategories,
58379
+ selectedCategory,
58380
+ hasTopLevelSearch,
58381
+ topLevelSearchEntries,
58382
+ topLevelSelectedEntry,
58383
+ filteredWidgets,
58384
+ selectedEntry
58385
+ };
58386
+ }
58387
+ function handlePickerInputMode({
58388
+ input,
58389
+ key,
58390
+ widgetPicker,
58391
+ widgetCatalog,
58392
+ widgetCategories,
58393
+ setWidgetPicker,
58394
+ applyWidgetPickerSelection
58395
+ }) {
58396
+ const normalizeState = (state) => normalizePickerState(state, widgetCatalog, widgetCategories);
58397
+ const {
58398
+ filteredCategories,
58399
+ selectedCategory,
58400
+ hasTopLevelSearch,
58401
+ topLevelSearchEntries,
58402
+ topLevelSelectedEntry,
58403
+ filteredWidgets,
58404
+ selectedEntry
58405
+ } = getPickerViewState(widgetPicker, widgetCatalog, widgetCategories);
58406
+ if (widgetPicker.level === "category") {
58407
+ if (key.escape) {
58408
+ if (widgetPicker.categoryQuery.length > 0) {
58409
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58410
+ ...prev,
58411
+ categoryQuery: ""
58412
+ }));
58413
+ } else {
58414
+ setWidgetPicker(null);
58415
+ }
58416
+ } else if (key.return) {
58417
+ if (hasTopLevelSearch) {
58418
+ if (topLevelSelectedEntry) {
58419
+ applyWidgetPickerSelection(topLevelSelectedEntry.type);
58420
+ }
58421
+ } else if (selectedCategory) {
58422
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58423
+ ...prev,
58424
+ level: "widget",
58425
+ selectedCategory
58426
+ }));
58427
+ }
58428
+ } else if (key.upArrow || key.downArrow) {
58429
+ if (hasTopLevelSearch) {
58430
+ if (topLevelSearchEntries.length === 0) {
58431
+ return;
58432
+ }
58433
+ let currentIndex = topLevelSearchEntries.findIndex((entry) => entry.type === widgetPicker.selectedType);
58434
+ if (currentIndex === -1) {
58435
+ currentIndex = 0;
58436
+ }
58437
+ const nextIndex = key.downArrow ? Math.min(topLevelSearchEntries.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58438
+ const nextType = topLevelSearchEntries[nextIndex]?.type ?? null;
58439
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58440
+ ...prev,
58441
+ selectedType: nextType
58442
+ }));
58443
+ } else {
58444
+ if (filteredCategories.length === 0) {
58445
+ return;
58446
+ }
58447
+ let currentIndex = filteredCategories.findIndex((category) => category === selectedCategory);
58448
+ if (currentIndex === -1) {
58449
+ currentIndex = 0;
58450
+ }
58451
+ const nextIndex = key.downArrow ? Math.min(filteredCategories.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58452
+ const nextCategory = filteredCategories[nextIndex] ?? null;
58453
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58454
+ ...prev,
58455
+ selectedCategory: nextCategory
58456
+ }));
58457
+ }
58458
+ } else if (key.backspace || key.delete) {
58459
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58460
+ ...prev,
58461
+ categoryQuery: prev.categoryQuery.slice(0, -1)
58462
+ }));
58463
+ } else if (input && !key.ctrl && !key.meta && !key.tab) {
58464
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58465
+ ...prev,
58466
+ categoryQuery: prev.categoryQuery + input
58467
+ }));
58468
+ }
58469
+ } else {
58470
+ if (key.escape) {
58471
+ if (widgetPicker.widgetQuery.length > 0) {
58472
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58473
+ ...prev,
58474
+ widgetQuery: ""
58475
+ }));
58476
+ } else {
58477
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58478
+ ...prev,
58479
+ level: "category"
58480
+ }));
58481
+ }
58482
+ } else if (key.return) {
58483
+ if (selectedEntry) {
58484
+ applyWidgetPickerSelection(selectedEntry.type);
58485
+ }
58486
+ } else if (key.upArrow || key.downArrow) {
58487
+ if (filteredWidgets.length === 0) {
58488
+ return;
58489
+ }
58490
+ let currentIndex = filteredWidgets.findIndex((entry) => entry.type === widgetPicker.selectedType);
58491
+ if (currentIndex === -1) {
58492
+ currentIndex = 0;
58493
+ }
58494
+ const nextIndex = key.downArrow ? Math.min(filteredWidgets.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58495
+ const nextType = filteredWidgets[nextIndex]?.type ?? null;
58496
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58497
+ ...prev,
58498
+ selectedType: nextType
58499
+ }));
58500
+ } else if (key.backspace || key.delete) {
58501
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58502
+ ...prev,
58503
+ widgetQuery: prev.widgetQuery.slice(0, -1)
58504
+ }));
58505
+ } else if (input && !key.ctrl && !key.meta && !key.tab) {
58506
+ setPickerState(setWidgetPicker, normalizeState, (prev) => ({
58507
+ ...prev,
58508
+ widgetQuery: prev.widgetQuery + input
58509
+ }));
58510
+ }
58511
+ }
58512
+ }
58513
+ function handleMoveInputMode({
58514
+ key,
58515
+ widgets,
58516
+ selectedIndex,
58517
+ onUpdate,
58518
+ setSelectedIndex,
58519
+ setMoveMode
58520
+ }) {
58521
+ if (key.upArrow && selectedIndex > 0) {
58522
+ const newWidgets = [...widgets];
58523
+ const temp = newWidgets[selectedIndex];
58524
+ const prev = newWidgets[selectedIndex - 1];
58525
+ if (temp && prev) {
58526
+ [newWidgets[selectedIndex], newWidgets[selectedIndex - 1]] = [prev, temp];
58527
+ }
58528
+ onUpdate(newWidgets);
58529
+ setSelectedIndex(selectedIndex - 1);
58530
+ } else if (key.downArrow && selectedIndex < widgets.length - 1) {
58531
+ const newWidgets = [...widgets];
58532
+ const temp = newWidgets[selectedIndex];
58533
+ const next = newWidgets[selectedIndex + 1];
58534
+ if (temp && next) {
58535
+ [newWidgets[selectedIndex], newWidgets[selectedIndex + 1]] = [next, temp];
58536
+ }
58537
+ onUpdate(newWidgets);
58538
+ setSelectedIndex(selectedIndex + 1);
58539
+ } else if (key.escape || key.return) {
58540
+ setMoveMode(false);
58541
+ }
58542
+ }
58543
+ function handleNormalInputMode({
58544
+ input,
58545
+ key,
58546
+ widgets,
58547
+ selectedIndex,
58548
+ separatorChars,
58549
+ onBack,
58550
+ onUpdate,
58551
+ setSelectedIndex,
58552
+ setMoveMode,
58553
+ setShowClearConfirm,
58554
+ openWidgetPicker,
58555
+ getVisibleCustomKeybinds,
58556
+ setCustomEditorWidget
58557
+ }) {
58558
+ if (key.upArrow && widgets.length > 0) {
58559
+ setSelectedIndex(Math.max(0, selectedIndex - 1));
58560
+ } else if (key.downArrow && widgets.length > 0) {
58561
+ setSelectedIndex(Math.min(widgets.length - 1, selectedIndex + 1));
58562
+ } else if (key.leftArrow && widgets.length > 0) {
58563
+ openWidgetPicker("change");
58564
+ } else if (key.rightArrow && widgets.length > 0) {
58565
+ openWidgetPicker("change");
58566
+ } else if (key.return && widgets.length > 0) {
58567
+ setMoveMode(true);
58568
+ } else if (input === "a") {
58569
+ openWidgetPicker("add");
58570
+ } else if (input === "i") {
58571
+ openWidgetPicker("insert");
58572
+ } else if (input === "d" && widgets.length > 0) {
58573
+ const newWidgets = widgets.filter((_, i) => i !== selectedIndex);
58574
+ onUpdate(newWidgets);
58575
+ if (selectedIndex >= newWidgets.length && selectedIndex > 0) {
58576
+ setSelectedIndex(selectedIndex - 1);
58577
+ }
58578
+ } else if (input === "c") {
58579
+ if (widgets.length > 0) {
58580
+ setShowClearConfirm(true);
58581
+ }
58582
+ } else if (input === " " && widgets.length > 0) {
58583
+ const currentWidget = widgets[selectedIndex];
58584
+ if (currentWidget && currentWidget.type === "separator") {
58585
+ const currentChar = currentWidget.character ?? "|";
58586
+ const currentCharIndex = separatorChars.indexOf(currentChar);
58587
+ const nextChar = separatorChars[(currentCharIndex + 1) % separatorChars.length];
58588
+ const newWidgets = [...widgets];
58589
+ newWidgets[selectedIndex] = { ...currentWidget, character: nextChar };
58590
+ onUpdate(newWidgets);
58591
+ }
58592
+ } else if (input === "r" && widgets.length > 0) {
58593
+ const currentWidget = widgets[selectedIndex];
58594
+ if (currentWidget && currentWidget.type !== "separator" && currentWidget.type !== "flex-separator") {
58595
+ const widgetImpl = getWidget(currentWidget.type);
58596
+ if (!widgetImpl?.supportsRawValue()) {
58597
+ return;
58598
+ }
58599
+ const newWidgets = [...widgets];
58600
+ newWidgets[selectedIndex] = { ...currentWidget, rawValue: !currentWidget.rawValue };
58601
+ onUpdate(newWidgets);
58602
+ }
58603
+ } else if (input === "m" && widgets.length > 0) {
58604
+ const currentWidget = widgets[selectedIndex];
58605
+ if (currentWidget && selectedIndex < widgets.length - 1 && currentWidget.type !== "separator" && currentWidget.type !== "flex-separator") {
58606
+ const newWidgets = [...widgets];
58607
+ let nextMergeState;
58608
+ if (currentWidget.merge === undefined) {
58609
+ nextMergeState = true;
58610
+ } else if (currentWidget.merge === true) {
58611
+ nextMergeState = "no-padding";
58612
+ } else {
58613
+ nextMergeState = undefined;
58614
+ }
58615
+ if (nextMergeState === undefined) {
58616
+ const { merge: merge2, ...rest } = currentWidget;
58617
+ newWidgets[selectedIndex] = rest;
58618
+ } else {
58619
+ newWidgets[selectedIndex] = { ...currentWidget, merge: nextMergeState };
58620
+ }
58621
+ onUpdate(newWidgets);
58622
+ }
58623
+ } else if (key.escape) {
58624
+ onBack();
58625
+ } else if (widgets.length > 0) {
58626
+ const currentWidget = widgets[selectedIndex];
58627
+ if (currentWidget && currentWidget.type !== "separator" && currentWidget.type !== "flex-separator") {
58628
+ const widgetImpl = getWidget(currentWidget.type);
58629
+ if (!widgetImpl?.getCustomKeybinds) {
58630
+ return;
58631
+ }
58632
+ const customKeybinds = getVisibleCustomKeybinds(widgetImpl, currentWidget);
58633
+ const matchedKeybind = customKeybinds.find((kb) => kb.key === input);
58634
+ if (matchedKeybind && !key.ctrl) {
58635
+ if (widgetImpl.handleEditorAction) {
58636
+ const updatedWidget = widgetImpl.handleEditorAction(matchedKeybind.action, currentWidget);
58637
+ if (updatedWidget) {
58638
+ const newWidgets = [...widgets];
58639
+ newWidgets[selectedIndex] = updatedWidget;
58640
+ onUpdate(newWidgets);
58641
+ } else if (widgetImpl.renderEditor) {
58642
+ setCustomEditorWidget({ widget: currentWidget, impl: widgetImpl, action: matchedKeybind.action });
58643
+ }
58644
+ } else if (widgetImpl.renderEditor) {
58645
+ setCustomEditorWidget({ widget: currentWidget, impl: widgetImpl, action: matchedKeybind.action });
58646
+ }
58647
+ }
58648
+ }
58649
+ }
58650
+ }
58651
+
58652
+ // src/tui/components/ItemsEditor.tsx
58509
58653
  var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
58510
58654
  var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
58511
58655
  const [selectedIndex, setSelectedIndex] = import_react37.useState(0);
@@ -58541,23 +58685,6 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
58541
58685
  const handleEditorCancel = () => {
58542
58686
  setCustomEditorWidget(null);
58543
58687
  };
58544
- const getFilteredCategories = (query) => {
58545
- return [...widgetCategories];
58546
- };
58547
- const normalizePickerState = (state) => {
58548
- const filteredCategories = getFilteredCategories(state.categoryQuery);
58549
- const selectedCategory = state.selectedCategory && filteredCategories.includes(state.selectedCategory) ? state.selectedCategory : filteredCategories[0] ?? null;
58550
- const hasTopLevelSearch = state.level === "category" && state.categoryQuery.trim().length > 0;
58551
- const effectiveCategory = hasTopLevelSearch ? "All" : selectedCategory ?? "All";
58552
- const effectiveQuery = hasTopLevelSearch ? state.categoryQuery : state.widgetQuery;
58553
- const filteredWidgets = filterWidgetCatalog(widgetCatalog, effectiveCategory, effectiveQuery);
58554
- const hasSelectedType = state.selectedType ? filteredWidgets.some((entry) => entry.type === state.selectedType) : false;
58555
- return {
58556
- ...state,
58557
- selectedCategory,
58558
- selectedType: hasSelectedType ? state.selectedType : filteredWidgets[0]?.type ?? null
58559
- };
58560
- };
58561
58688
  const shouldShowCustomKeybind = (widget, keybind) => {
58562
58689
  if (keybind.action !== "toggle-invert") {
58563
58690
  return true;
@@ -58584,7 +58711,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
58584
58711
  categoryQuery: "",
58585
58712
  widgetQuery: "",
58586
58713
  selectedType
58587
- }));
58714
+ }, widgetCatalog, widgetCategories));
58588
58715
  };
58589
58716
  const applyWidgetPickerSelection = (selectedType) => {
58590
58717
  if (!widgetPicker) {
@@ -58620,238 +58747,43 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
58620
58747
  return;
58621
58748
  }
58622
58749
  if (widgetPicker) {
58623
- const filteredCategories = getFilteredCategories(widgetPicker.categoryQuery);
58624
- const selectedCategory = widgetPicker.selectedCategory && filteredCategories.includes(widgetPicker.selectedCategory) ? widgetPicker.selectedCategory : filteredCategories[0] ?? null;
58625
- const hasTopLevelSearch = widgetPicker.level === "category" && widgetPicker.categoryQuery.trim().length > 0;
58626
- const topLevelSearchEntries2 = hasTopLevelSearch ? filterWidgetCatalog(widgetCatalog, "All", widgetPicker.categoryQuery) : [];
58627
- const topLevelSelectedEntry = topLevelSearchEntries2.find((entry) => entry.type === widgetPicker.selectedType) ?? topLevelSearchEntries2[0];
58628
- const filteredWidgets = filterWidgetCatalog(widgetCatalog, selectedCategory ?? "All", widgetPicker.widgetQuery);
58629
- const selectedEntry = filteredWidgets.find((entry) => entry.type === widgetPicker.selectedType) ?? filteredWidgets[0];
58630
- if (widgetPicker.level === "category") {
58631
- if (key.escape) {
58632
- if (widgetPicker.categoryQuery.length > 0) {
58633
- setWidgetPicker((prev) => prev ? normalizePickerState({
58634
- ...prev,
58635
- categoryQuery: ""
58636
- }) : prev);
58637
- } else {
58638
- setWidgetPicker(null);
58639
- }
58640
- } else if (key.return) {
58641
- if (hasTopLevelSearch) {
58642
- if (topLevelSelectedEntry) {
58643
- applyWidgetPickerSelection(topLevelSelectedEntry.type);
58644
- }
58645
- } else if (selectedCategory) {
58646
- setWidgetPicker((prev) => prev ? normalizePickerState({
58647
- ...prev,
58648
- level: "widget",
58649
- selectedCategory
58650
- }) : prev);
58651
- }
58652
- } else if (key.upArrow || key.downArrow) {
58653
- if (hasTopLevelSearch) {
58654
- if (topLevelSearchEntries2.length === 0) {
58655
- return;
58656
- }
58657
- let currentIndex = topLevelSearchEntries2.findIndex((entry) => entry.type === widgetPicker.selectedType);
58658
- if (currentIndex === -1) {
58659
- currentIndex = 0;
58660
- }
58661
- const nextIndex = key.downArrow ? Math.min(topLevelSearchEntries2.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58662
- const nextType = topLevelSearchEntries2[nextIndex]?.type ?? null;
58663
- setWidgetPicker((prev) => prev ? normalizePickerState({
58664
- ...prev,
58665
- selectedType: nextType
58666
- }) : prev);
58667
- } else {
58668
- if (filteredCategories.length === 0) {
58669
- return;
58670
- }
58671
- let currentIndex = filteredCategories.findIndex((category) => category === selectedCategory);
58672
- if (currentIndex === -1) {
58673
- currentIndex = 0;
58674
- }
58675
- const nextIndex = key.downArrow ? Math.min(filteredCategories.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58676
- const nextCategory = filteredCategories[nextIndex] ?? null;
58677
- setWidgetPicker((prev) => prev ? normalizePickerState({
58678
- ...prev,
58679
- selectedCategory: nextCategory
58680
- }) : prev);
58681
- }
58682
- } else if (key.backspace || key.delete) {
58683
- setWidgetPicker((prev) => prev ? normalizePickerState({
58684
- ...prev,
58685
- categoryQuery: prev.categoryQuery.slice(0, -1)
58686
- }) : prev);
58687
- } else if (input && !key.ctrl && !key.meta && !key.tab) {
58688
- setWidgetPicker((prev) => prev ? normalizePickerState({
58689
- ...prev,
58690
- categoryQuery: prev.categoryQuery + input
58691
- }) : prev);
58692
- }
58693
- } else {
58694
- if (key.escape) {
58695
- if (widgetPicker.widgetQuery.length > 0) {
58696
- setWidgetPicker((prev) => prev ? normalizePickerState({
58697
- ...prev,
58698
- widgetQuery: ""
58699
- }) : prev);
58700
- } else {
58701
- setWidgetPicker((prev) => prev ? normalizePickerState({
58702
- ...prev,
58703
- level: "category"
58704
- }) : prev);
58705
- }
58706
- } else if (key.return) {
58707
- if (selectedEntry) {
58708
- applyWidgetPickerSelection(selectedEntry.type);
58709
- }
58710
- } else if (key.upArrow || key.downArrow) {
58711
- if (filteredWidgets.length === 0) {
58712
- return;
58713
- }
58714
- let currentIndex = filteredWidgets.findIndex((entry) => entry.type === widgetPicker.selectedType);
58715
- if (currentIndex === -1) {
58716
- currentIndex = 0;
58717
- }
58718
- const nextIndex = key.downArrow ? Math.min(filteredWidgets.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
58719
- const nextType = filteredWidgets[nextIndex]?.type ?? null;
58720
- setWidgetPicker((prev) => prev ? normalizePickerState({
58721
- ...prev,
58722
- selectedType: nextType
58723
- }) : prev);
58724
- } else if (key.backspace || key.delete) {
58725
- setWidgetPicker((prev) => prev ? normalizePickerState({
58726
- ...prev,
58727
- widgetQuery: prev.widgetQuery.slice(0, -1)
58728
- }) : prev);
58729
- } else if (input && !key.ctrl && !key.meta && !key.tab) {
58730
- setWidgetPicker((prev) => prev ? normalizePickerState({
58731
- ...prev,
58732
- widgetQuery: prev.widgetQuery + input
58733
- }) : prev);
58734
- }
58735
- }
58750
+ handlePickerInputMode({
58751
+ input,
58752
+ key,
58753
+ widgetPicker,
58754
+ widgetCatalog,
58755
+ widgetCategories,
58756
+ setWidgetPicker,
58757
+ applyWidgetPickerSelection
58758
+ });
58736
58759
  return;
58737
58760
  }
58738
58761
  if (moveMode) {
58739
- if (key.upArrow && selectedIndex > 0) {
58740
- const newWidgets = [...widgets];
58741
- const temp = newWidgets[selectedIndex];
58742
- const prev = newWidgets[selectedIndex - 1];
58743
- if (temp && prev) {
58744
- [newWidgets[selectedIndex], newWidgets[selectedIndex - 1]] = [prev, temp];
58745
- }
58746
- onUpdate(newWidgets);
58747
- setSelectedIndex(selectedIndex - 1);
58748
- } else if (key.downArrow && selectedIndex < widgets.length - 1) {
58749
- const newWidgets = [...widgets];
58750
- const temp = newWidgets[selectedIndex];
58751
- const next = newWidgets[selectedIndex + 1];
58752
- if (temp && next) {
58753
- [newWidgets[selectedIndex], newWidgets[selectedIndex + 1]] = [next, temp];
58754
- }
58755
- onUpdate(newWidgets);
58756
- setSelectedIndex(selectedIndex + 1);
58757
- } else if (key.escape || key.return) {
58758
- setMoveMode(false);
58759
- }
58760
- } else {
58761
- if (key.upArrow && widgets.length > 0) {
58762
- setSelectedIndex(Math.max(0, selectedIndex - 1));
58763
- } else if (key.downArrow && widgets.length > 0) {
58764
- setSelectedIndex(Math.min(widgets.length - 1, selectedIndex + 1));
58765
- } else if (key.leftArrow && widgets.length > 0) {
58766
- openWidgetPicker("change");
58767
- } else if (key.rightArrow && widgets.length > 0) {
58768
- openWidgetPicker("change");
58769
- } else if (key.return && widgets.length > 0) {
58770
- setMoveMode(true);
58771
- } else if (input === "a") {
58772
- openWidgetPicker("add");
58773
- } else if (input === "i") {
58774
- openWidgetPicker("insert");
58775
- } else if (input === "d" && widgets.length > 0) {
58776
- const newWidgets = widgets.filter((_, i) => i !== selectedIndex);
58777
- onUpdate(newWidgets);
58778
- if (selectedIndex >= newWidgets.length && selectedIndex > 0) {
58779
- setSelectedIndex(selectedIndex - 1);
58780
- }
58781
- } else if (input === "c") {
58782
- if (widgets.length > 0) {
58783
- setShowClearConfirm(true);
58784
- }
58785
- } else if (input === " " && widgets.length > 0) {
58786
- const currentWidget2 = widgets[selectedIndex];
58787
- if (currentWidget2 && currentWidget2.type === "separator") {
58788
- const currentChar = currentWidget2.character ?? "|";
58789
- const currentCharIndex = separatorChars.indexOf(currentChar);
58790
- const nextChar = separatorChars[(currentCharIndex + 1) % separatorChars.length];
58791
- const newWidgets = [...widgets];
58792
- newWidgets[selectedIndex] = { ...currentWidget2, character: nextChar };
58793
- onUpdate(newWidgets);
58794
- }
58795
- } else if (input === "r" && widgets.length > 0) {
58796
- const currentWidget2 = widgets[selectedIndex];
58797
- if (currentWidget2 && currentWidget2.type !== "separator" && currentWidget2.type !== "flex-separator") {
58798
- const widgetImpl = getWidget(currentWidget2.type);
58799
- if (!widgetImpl?.supportsRawValue()) {
58800
- return;
58801
- }
58802
- const newWidgets = [...widgets];
58803
- newWidgets[selectedIndex] = { ...currentWidget2, rawValue: !currentWidget2.rawValue };
58804
- onUpdate(newWidgets);
58805
- }
58806
- } else if (input === "m" && widgets.length > 0) {
58807
- const currentWidget2 = widgets[selectedIndex];
58808
- if (currentWidget2 && selectedIndex < widgets.length - 1 && currentWidget2.type !== "separator" && currentWidget2.type !== "flex-separator") {
58809
- const newWidgets = [...widgets];
58810
- let nextMergeState;
58811
- if (currentWidget2.merge === undefined) {
58812
- nextMergeState = true;
58813
- } else if (currentWidget2.merge === true) {
58814
- nextMergeState = "no-padding";
58815
- } else {
58816
- nextMergeState = undefined;
58817
- }
58818
- if (nextMergeState === undefined) {
58819
- const { merge: merge2, ...rest } = currentWidget2;
58820
- newWidgets[selectedIndex] = rest;
58821
- } else {
58822
- newWidgets[selectedIndex] = { ...currentWidget2, merge: nextMergeState };
58823
- }
58824
- onUpdate(newWidgets);
58825
- }
58826
- } else if (key.escape) {
58827
- onBack();
58828
- } else if (widgets.length > 0) {
58829
- const currentWidget2 = widgets[selectedIndex];
58830
- if (currentWidget2 && currentWidget2.type !== "separator" && currentWidget2.type !== "flex-separator") {
58831
- const widgetImpl = getWidget(currentWidget2.type);
58832
- if (widgetImpl) {
58833
- if (widgetImpl.getCustomKeybinds) {
58834
- const customKeybinds2 = getVisibleCustomKeybinds(widgetImpl, currentWidget2);
58835
- const matchedKeybind = customKeybinds2.find((kb) => kb.key === input);
58836
- if (matchedKeybind && !key.ctrl) {
58837
- if (widgetImpl.handleEditorAction) {
58838
- const updatedWidget = widgetImpl.handleEditorAction(matchedKeybind.action, currentWidget2);
58839
- if (updatedWidget) {
58840
- const newWidgets = [...widgets];
58841
- newWidgets[selectedIndex] = updatedWidget;
58842
- onUpdate(newWidgets);
58843
- } else if (widgetImpl.renderEditor) {
58844
- setCustomEditorWidget({ widget: currentWidget2, impl: widgetImpl, action: matchedKeybind.action });
58845
- }
58846
- } else if (widgetImpl.renderEditor) {
58847
- setCustomEditorWidget({ widget: currentWidget2, impl: widgetImpl, action: matchedKeybind.action });
58848
- }
58849
- }
58850
- }
58851
- }
58852
- }
58853
- }
58762
+ handleMoveInputMode({
58763
+ key,
58764
+ widgets,
58765
+ selectedIndex,
58766
+ onUpdate,
58767
+ setSelectedIndex,
58768
+ setMoveMode
58769
+ });
58770
+ return;
58854
58771
  }
58772
+ handleNormalInputMode({
58773
+ input,
58774
+ key,
58775
+ widgets,
58776
+ selectedIndex,
58777
+ separatorChars,
58778
+ onBack,
58779
+ onUpdate,
58780
+ setSelectedIndex,
58781
+ setMoveMode,
58782
+ setShowClearConfirm,
58783
+ openWidgetPicker,
58784
+ getVisibleCustomKeybinds,
58785
+ setCustomEditorWidget
58786
+ });
58855
58787
  });
58856
58788
  const getWidgetDisplay = (widget) => {
58857
58789
  if (widget.type === "separator") {
@@ -58871,7 +58803,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
58871
58803
  };
58872
58804
  const hasFlexSeparator = widgets.some((widget) => widget.type === "flex-separator");
58873
58805
  const widthDetectionAvailable = canDetectTerminalWidth();
58874
- const pickerCategories = widgetPicker ? getFilteredCategories(widgetPicker.categoryQuery) : [];
58806
+ const pickerCategories = widgetPicker ? [...widgetCategories] : [];
58875
58807
  const selectedPickerCategory = widgetPicker ? widgetPicker.selectedCategory && pickerCategories.includes(widgetPicker.selectedCategory) ? widgetPicker.selectedCategory : pickerCategories[0] ?? null : null;
58876
58808
  const topLevelSearchEntries = widgetPicker && widgetPicker.level === "category" && widgetPicker.categoryQuery.trim().length > 0 ? filterWidgetCatalog(widgetCatalog, "All", widgetPicker.categoryQuery) : [];
58877
58809
  const selectedTopLevelSearchEntry = widgetPicker ? topLevelSearchEntries.find((entry) => entry.type === widgetPicker.selectedType) ?? topLevelSearchEntries[0] : null;
@@ -59659,6 +59591,30 @@ var MainMenu = ({ onSelect, isClaudeInstalled, hasChanges, initialSelection = 0,
59659
59591
  var import_react42 = __toESM(require_react(), 1);
59660
59592
  import * as os10 from "os";
59661
59593
 
59594
+ // src/utils/powerline-settings.ts
59595
+ function resolveEnabledPowerlineTheme(theme) {
59596
+ if (!theme || theme === "custom") {
59597
+ return getDefaultPowerlineTheme();
59598
+ }
59599
+ return theme;
59600
+ }
59601
+ function buildEnabledPowerlineSettings(settings, removeManualSeparators) {
59602
+ const powerlineConfig = settings.powerline;
59603
+ const lines = removeManualSeparators ? settings.lines.map((line) => line.filter((item) => item.type !== "separator" && item.type !== "flex-separator")) : settings.lines;
59604
+ return {
59605
+ ...settings,
59606
+ powerline: {
59607
+ ...powerlineConfig,
59608
+ enabled: true,
59609
+ theme: resolveEnabledPowerlineTheme(powerlineConfig.theme),
59610
+ separators: powerlineConfig.separators,
59611
+ separatorInvertBackground: powerlineConfig.separatorInvertBackground
59612
+ },
59613
+ defaultPadding: " ",
59614
+ lines
59615
+ };
59616
+ }
59617
+
59662
59618
  // src/tui/components/PowerlineSeparatorEditor.tsx
59663
59619
  var import_react40 = __toESM(require_react(), 1);
59664
59620
  var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
@@ -60271,19 +60227,7 @@ var PowerlineSetup = ({
60271
60227
  if (hasSeparatorItems) {
60272
60228
  setConfirmingEnable(true);
60273
60229
  } else {
60274
- const theme = !powerlineConfig.theme || powerlineConfig.theme === "custom" ? getDefaultPowerlineTheme() : powerlineConfig.theme;
60275
- const updatedSettings = {
60276
- ...settings,
60277
- powerline: {
60278
- ...powerlineConfig,
60279
- enabled: true,
60280
- theme,
60281
- separators: powerlineConfig.separators,
60282
- separatorInvertBackground: powerlineConfig.separatorInvertBackground
60283
- },
60284
- defaultPadding: " "
60285
- };
60286
- onUpdate(updatedSettings);
60230
+ onUpdate(buildEnabledPowerlineSettings(settings, false));
60287
60231
  }
60288
60232
  } else {
60289
60233
  const newConfig = { ...powerlineConfig, enabled: false };
@@ -60513,20 +60457,7 @@ var PowerlineSetup = ({
60513
60457
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ConfirmDialog, {
60514
60458
  inline: true,
60515
60459
  onConfirm: () => {
60516
- const theme = !powerlineConfig.theme || powerlineConfig.theme === "custom" ? getDefaultPowerlineTheme() : powerlineConfig.theme;
60517
- const updatedSettings = {
60518
- ...settings,
60519
- powerline: {
60520
- ...powerlineConfig,
60521
- enabled: true,
60522
- theme,
60523
- separators: powerlineConfig.separators,
60524
- separatorInvertBackground: powerlineConfig.separatorInvertBackground
60525
- },
60526
- defaultPadding: " ",
60527
- lines: settings.lines.map((line) => line.filter((item) => item.type !== "separator" && item.type !== "flex-separator"))
60528
- };
60529
- onUpdate(updatedSettings);
60460
+ onUpdate(buildEnabledPowerlineSettings(settings, true));
60530
60461
  setConfirmingEnable(false);
60531
60462
  },
60532
60463
  onCancel: () => {
@@ -60695,8 +60626,19 @@ var PowerlineSetup = ({
60695
60626
  };
60696
60627
  // src/tui/components/StatusLinePreview.tsx
60697
60628
  var import_react43 = __toESM(require_react(), 1);
60629
+
60630
+ // src/utils/separator-index.ts
60631
+ function countSeparatorSlots(widgets) {
60632
+ const nonMergedWidgets = widgets.filter((_, idx) => idx === widgets.length - 1 || !widgets[idx]?.merge);
60633
+ return Math.max(0, nonMergedWidgets.length - 1);
60634
+ }
60635
+ function advanceGlobalSeparatorIndex(currentIndex, widgets) {
60636
+ return currentIndex + countSeparatorSlots(widgets);
60637
+ }
60638
+
60639
+ // src/tui/components/StatusLinePreview.tsx
60698
60640
  var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
60699
- var renderSingleLine = (widgets, terminalWidth, widthDetectionAvailable, settings, lineIndex, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
60641
+ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
60700
60642
  const context = {
60701
60643
  terminalWidth,
60702
60644
  isPreview: true,
@@ -60706,7 +60648,6 @@ var renderSingleLine = (widgets, terminalWidth, widthDetectionAvailable, setting
60706
60648
  return renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
60707
60649
  };
60708
60650
  var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange }) => {
60709
- const widthDetectionAvailable = import_react43.default.useMemo(() => canDetectTerminalWidth(), []);
60710
60651
  const { renderedLines, anyTruncated } = import_react43.default.useMemo(() => {
60711
60652
  if (!settings)
60712
60653
  return { renderedLines: [], anyTruncated: false };
@@ -60719,19 +60660,16 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
60719
60660
  const lineItems = lines[i];
60720
60661
  if (lineItems && lineItems.length > 0) {
60721
60662
  const preRenderedWidgets = preRenderedLines[i] ?? [];
60722
- const renderResult = renderSingleLine(lineItems, terminalWidth, widthDetectionAvailable, settings, i, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths);
60663
+ const renderResult = renderSingleLine(lineItems, terminalWidth, settings, i, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths);
60723
60664
  result.push(renderResult.line);
60724
60665
  if (renderResult.wasTruncated) {
60725
60666
  truncated = true;
60726
60667
  }
60727
- const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
60728
- if (nonMergedWidgets.length > 1) {
60729
- globalSeparatorIndex += nonMergedWidgets.length - 1;
60730
- }
60668
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
60731
60669
  }
60732
60670
  }
60733
60671
  return { renderedLines: result, anyTruncated: truncated };
60734
- }, [lines, terminalWidth, widthDetectionAvailable, settings]);
60672
+ }, [lines, terminalWidth, settings]);
60735
60673
  import_react43.default.useEffect(() => {
60736
60674
  onTruncationChange?.(anyTruncated);
60737
60675
  }, [anyTruncated, onTruncationChange]);
@@ -60766,6 +60704,59 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
60766
60704
  };
60767
60705
  // src/tui/components/TerminalOptionsMenu.tsx
60768
60706
  var import_react44 = __toESM(require_react(), 1);
60707
+
60708
+ // src/utils/color-sanitize.ts
60709
+ function isCustomColor(value) {
60710
+ if (!value) {
60711
+ return false;
60712
+ }
60713
+ return value.startsWith("ansi256:") || value.startsWith("hex:");
60714
+ }
60715
+ function isIncompatibleForLevel(value, nextLevel) {
60716
+ if (!isCustomColor(value)) {
60717
+ return false;
60718
+ }
60719
+ if (nextLevel === 2) {
60720
+ return Boolean(value?.startsWith("hex:"));
60721
+ }
60722
+ if (nextLevel === 3) {
60723
+ return Boolean(value?.startsWith("ansi256:"));
60724
+ }
60725
+ return true;
60726
+ }
60727
+ function resetWidgetForegroundToDefault(widget, nextWidget) {
60728
+ if (widget.type === "separator" || widget.type === "flex-separator") {
60729
+ return nextWidget;
60730
+ }
60731
+ const widgetImpl = getWidget(widget.type);
60732
+ if (!widgetImpl) {
60733
+ return nextWidget;
60734
+ }
60735
+ return {
60736
+ ...nextWidget,
60737
+ color: widgetImpl.getDefaultColor()
60738
+ };
60739
+ }
60740
+ function hasCustomWidgetColors(lines) {
60741
+ return lines.some((line) => line.some((widget) => isCustomColor(widget.color) || isCustomColor(widget.backgroundColor)));
60742
+ }
60743
+ function sanitizeLinesForColorLevel(lines, nextLevel) {
60744
+ return lines.map((line) => line.map((widget) => {
60745
+ let nextWidget = { ...widget };
60746
+ if (isIncompatibleForLevel(widget.color, nextLevel)) {
60747
+ nextWidget = resetWidgetForegroundToDefault(widget, nextWidget);
60748
+ }
60749
+ if (isIncompatibleForLevel(widget.backgroundColor, nextLevel)) {
60750
+ nextWidget = {
60751
+ ...nextWidget,
60752
+ backgroundColor: undefined
60753
+ };
60754
+ }
60755
+ return nextWidget;
60756
+ }));
60757
+ }
60758
+
60759
+ // src/tui/components/TerminalOptionsMenu.tsx
60769
60760
  var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
60770
60761
  var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60771
60762
  const [showColorWarning, setShowColorWarning] = import_react44.useState(false);
@@ -60777,7 +60768,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60777
60768
  } else if (selectedIndex === 0) {
60778
60769
  onBack("width");
60779
60770
  } else if (selectedIndex === 1) {
60780
- const hasCustomColors = settings.lines.some((line) => line.some((widget) => Boolean(widget.color && (widget.color.startsWith("ansi256:") || widget.color.startsWith("hex:"))) || Boolean(widget.backgroundColor && (widget.backgroundColor.startsWith("ansi256:") || widget.backgroundColor.startsWith("hex:")))));
60771
+ const hasCustomColors = hasCustomWidgetColors(settings.lines);
60781
60772
  const currentLevel = settings.colorLevel;
60782
60773
  const nextLevel = (currentLevel + 1) % 4;
60783
60774
  if (hasCustomColors && (currentLevel === 2 && nextLevel !== 2 || currentLevel === 3 && nextLevel !== 3)) {
@@ -60785,47 +60776,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60785
60776
  setPendingColorLevel(nextLevel);
60786
60777
  } else {
60787
60778
  source_default.level = nextLevel;
60788
- const cleanedLines = settings.lines.map((line) => line.map((widget) => {
60789
- const newWidget = { ...widget };
60790
- if (nextLevel === 2) {
60791
- if (widget.color?.startsWith("hex:")) {
60792
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60793
- const widgetImpl = getWidget(widget.type);
60794
- if (widgetImpl) {
60795
- newWidget.color = widgetImpl.getDefaultColor();
60796
- }
60797
- }
60798
- }
60799
- if (widget.backgroundColor?.startsWith("hex:")) {
60800
- newWidget.backgroundColor = undefined;
60801
- }
60802
- } else if (nextLevel === 3) {
60803
- if (widget.color?.startsWith("ansi256:")) {
60804
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60805
- const widgetImpl = getWidget(widget.type);
60806
- if (widgetImpl) {
60807
- newWidget.color = widgetImpl.getDefaultColor();
60808
- }
60809
- }
60810
- }
60811
- if (widget.backgroundColor?.startsWith("ansi256:")) {
60812
- newWidget.backgroundColor = undefined;
60813
- }
60814
- } else {
60815
- if (widget.color?.startsWith("ansi256:") || widget.color?.startsWith("hex:")) {
60816
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60817
- const widgetImpl = getWidget(widget.type);
60818
- if (widgetImpl) {
60819
- newWidget.color = widgetImpl.getDefaultColor();
60820
- }
60821
- }
60822
- }
60823
- if (widget.backgroundColor?.startsWith("ansi256:") || widget.backgroundColor?.startsWith("hex:")) {
60824
- newWidget.backgroundColor = undefined;
60825
- }
60826
- }
60827
- return newWidget;
60828
- }));
60779
+ const cleanedLines = sanitizeLinesForColorLevel(settings.lines, nextLevel);
60829
60780
  onUpdate({
60830
60781
  ...settings,
60831
60782
  lines: cleanedLines,
@@ -60837,23 +60788,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60837
60788
  const handleColorConfirm = () => {
60838
60789
  if (pendingColorLevel !== null) {
60839
60790
  source_default.level = pendingColorLevel;
60840
- const cleanedLines = settings.lines.map((line) => line.map((widget) => {
60841
- const newWidget = { ...widget };
60842
- if (pendingColorLevel !== 2 && pendingColorLevel !== 3 || pendingColorLevel === 2 && (widget.color?.startsWith("hex:") || widget.backgroundColor?.startsWith("hex:")) || pendingColorLevel === 3 && (widget.color?.startsWith("ansi256:") || widget.backgroundColor?.startsWith("ansi256:"))) {
60843
- if (widget.color?.startsWith("ansi256:") || widget.color?.startsWith("hex:")) {
60844
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60845
- const widgetImpl = getWidget(widget.type);
60846
- if (widgetImpl) {
60847
- newWidget.color = widgetImpl.getDefaultColor();
60848
- }
60849
- }
60850
- }
60851
- if (widget.backgroundColor?.startsWith("ansi256:") || widget.backgroundColor?.startsWith("hex:")) {
60852
- newWidget.backgroundColor = undefined;
60853
- }
60854
- }
60855
- return newWidget;
60856
- }));
60791
+ const cleanedLines = sanitizeLinesForColorLevel(settings.lines, pendingColorLevel);
60857
60792
  onUpdate({
60858
60793
  ...settings,
60859
60794
  lines: cleanedLines,
@@ -61215,7 +61150,7 @@ var App2 = () => {
61215
61150
  loadSettings().then((loadedSettings) => {
61216
61151
  source_default.level = loadedSettings.colorLevel;
61217
61152
  setSettings(loadedSettings);
61218
- setOriginalSettings(JSON.parse(JSON.stringify(loadedSettings)));
61153
+ setOriginalSettings(cloneSettings(loadedSettings));
61219
61154
  });
61220
61155
  isInstalled().then(setIsClaudeInstalled);
61221
61156
  const fontStatus = checkPowerlineFonts();
@@ -61254,7 +61189,7 @@ var App2 = () => {
61254
61189
  if (key.ctrl && input === "s" && settings) {
61255
61190
  (async () => {
61256
61191
  await saveSettings(settings);
61257
- setOriginalSettings(JSON.parse(JSON.stringify(settings)));
61192
+ setOriginalSettings(cloneSettings(settings));
61258
61193
  setHasChanges(false);
61259
61194
  setFlashMessage({
61260
61195
  text: "✓ Configuration saved",
@@ -61367,7 +61302,7 @@ ${GITHUB_REPO_URL}`,
61367
61302
  break;
61368
61303
  case "save":
61369
61304
  await saveSettings(settings);
61370
- setOriginalSettings(JSON.parse(JSON.stringify(settings)));
61305
+ setOriginalSettings(cloneSettings(settings));
61371
61306
  setHasChanges(false);
61372
61307
  exit();
61373
61308
  break;
@@ -61433,7 +61368,7 @@ ${GITHUB_REPO_URL}`,
61433
61368
  install: 5,
61434
61369
  starGithub: hasChanges ? 8 : 7
61435
61370
  };
61436
- setMenuSelections({ ...menuSelections, main: menuMap[value] ?? 0 });
61371
+ setMenuSelections((prev) => ({ ...prev, main: menuMap[value] ?? 0 }));
61437
61372
  }
61438
61373
  handleMainMenuSelect(value);
61439
61374
  },
@@ -61447,12 +61382,12 @@ ${GITHUB_REPO_URL}`,
61447
61382
  screen === "lines" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(LineSelector, {
61448
61383
  lines: settings.lines,
61449
61384
  onSelect: (line) => {
61450
- setMenuSelections({ ...menuSelections, lines: line });
61385
+ setMenuSelections((prev) => ({ ...prev, lines: line }));
61451
61386
  handleLineSelect(line);
61452
61387
  },
61453
61388
  onLinesUpdate: updateLines,
61454
61389
  onBack: () => {
61455
- setMenuSelections({ ...menuSelections, main: 0 });
61390
+ setMenuSelections((prev) => ({ ...prev, main: 0 }));
61456
61391
  setScreen("main");
61457
61392
  },
61458
61393
  initialSelection: menuSelections.lines,
@@ -61465,7 +61400,7 @@ ${GITHUB_REPO_URL}`,
61465
61400
  updateLine(selectedLine, widgets);
61466
61401
  },
61467
61402
  onBack: () => {
61468
- setMenuSelections({ ...menuSelections, lines: selectedLine });
61403
+ setMenuSelections((prev) => ({ ...prev, lines: selectedLine }));
61469
61404
  setScreen("lines");
61470
61405
  },
61471
61406
  lineNumber: selectedLine + 1,
@@ -61475,12 +61410,12 @@ ${GITHUB_REPO_URL}`,
61475
61410
  lines: settings.lines,
61476
61411
  onLinesUpdate: updateLines,
61477
61412
  onSelect: (line) => {
61478
- setMenuSelections({ ...menuSelections, lines: line });
61413
+ setMenuSelections((prev) => ({ ...prev, lines: line }));
61479
61414
  setSelectedLine(line);
61480
61415
  setScreen("colors");
61481
61416
  },
61482
61417
  onBack: () => {
61483
- setMenuSelections({ ...menuSelections, main: 1 });
61418
+ setMenuSelections((prev) => ({ ...prev, main: 1 }));
61484
61419
  setScreen("main");
61485
61420
  },
61486
61421
  initialSelection: menuSelections.lines,
@@ -61511,7 +61446,7 @@ ${GITHUB_REPO_URL}`,
61511
61446
  if (target === "width") {
61512
61447
  setScreen("terminalWidth");
61513
61448
  } else {
61514
- setMenuSelections({ ...menuSelections, main: 3 });
61449
+ setMenuSelections((prev) => ({ ...prev, main: 3 }));
61515
61450
  setScreen("main");
61516
61451
  }
61517
61452
  }
@@ -61531,7 +61466,7 @@ ${GITHUB_REPO_URL}`,
61531
61466
  setSettings(updatedSettings);
61532
61467
  },
61533
61468
  onBack: () => {
61534
- setMenuSelections({ ...menuSelections, main: 4 });
61469
+ setMenuSelections((prev) => ({ ...prev, main: 4 }));
61535
61470
  setScreen("main");
61536
61471
  }
61537
61472
  }, undefined, false, undefined, this),
@@ -61589,6 +61524,17 @@ function runTUI() {
61589
61524
  render_default(/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(App2, {}, undefined, false, undefined, this));
61590
61525
  }
61591
61526
  // src/types/StatusJSON.ts
61527
+ var CoercedNumberSchema = exports_external.preprocess((value) => {
61528
+ if (typeof value !== "string") {
61529
+ return value;
61530
+ }
61531
+ const trimmed = value.trim();
61532
+ if (trimmed.length === 0) {
61533
+ return value;
61534
+ }
61535
+ const parsed = Number(trimmed);
61536
+ return Number.isFinite(parsed) ? parsed : value;
61537
+ }, exports_external.number());
61592
61538
  var StatusJSONSchema = exports_external.looseObject({
61593
61539
  hook_event_name: exports_external.string().optional(),
61594
61540
  session_id: exports_external.string().optional(),
@@ -61608,27 +61554,27 @@ var StatusJSONSchema = exports_external.looseObject({
61608
61554
  version: exports_external.string().optional(),
61609
61555
  output_style: exports_external.object({ name: exports_external.string().optional() }).optional(),
61610
61556
  cost: exports_external.object({
61611
- total_cost_usd: exports_external.number().optional(),
61612
- total_duration_ms: exports_external.number().optional(),
61613
- total_api_duration_ms: exports_external.number().optional(),
61614
- total_lines_added: exports_external.number().optional(),
61615
- total_lines_removed: exports_external.number().optional()
61557
+ total_cost_usd: CoercedNumberSchema.optional(),
61558
+ total_duration_ms: CoercedNumberSchema.optional(),
61559
+ total_api_duration_ms: CoercedNumberSchema.optional(),
61560
+ total_lines_added: CoercedNumberSchema.optional(),
61561
+ total_lines_removed: CoercedNumberSchema.optional()
61616
61562
  }).optional(),
61617
61563
  context_window: exports_external.object({
61618
- context_window_size: exports_external.number().nullable().optional(),
61619
- total_input_tokens: exports_external.number().nullable().optional(),
61620
- total_output_tokens: exports_external.number().nullable().optional(),
61564
+ context_window_size: CoercedNumberSchema.nullable().optional(),
61565
+ total_input_tokens: CoercedNumberSchema.nullable().optional(),
61566
+ total_output_tokens: CoercedNumberSchema.nullable().optional(),
61621
61567
  current_usage: exports_external.union([
61622
- exports_external.number(),
61568
+ CoercedNumberSchema,
61623
61569
  exports_external.object({
61624
- input_tokens: exports_external.number().optional(),
61625
- output_tokens: exports_external.number().optional(),
61626
- cache_creation_input_tokens: exports_external.number().optional(),
61627
- cache_read_input_tokens: exports_external.number().optional()
61570
+ input_tokens: CoercedNumberSchema.optional(),
61571
+ output_tokens: CoercedNumberSchema.optional(),
61572
+ cache_creation_input_tokens: CoercedNumberSchema.optional(),
61573
+ cache_read_input_tokens: CoercedNumberSchema.optional()
61628
61574
  })
61629
61575
  ]).nullable().optional(),
61630
- used_percentage: exports_external.number().nullable().optional(),
61631
- remaining_percentage: exports_external.number().nullable().optional()
61576
+ used_percentage: CoercedNumberSchema.nullable().optional(),
61577
+ remaining_percentage: CoercedNumberSchema.nullable().optional()
61632
61578
  }).nullable().optional()
61633
61579
  });
61634
61580
 
@@ -61699,12 +61645,10 @@ async function renderMultipleLines(data) {
61699
61645
  const line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
61700
61646
  const strippedLine = getVisibleText(line).trim();
61701
61647
  if (strippedLine.length > 0) {
61702
- const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
61703
- if (nonMergedWidgets.length > 1)
61704
- globalSeparatorIndex += nonMergedWidgets.length - 1;
61705
61648
  let outputLine = line.replace(/ /g, " ");
61706
61649
  outputLine = "\x1B[0m" + outputLine;
61707
61650
  console.log(outputLine);
61651
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
61708
61652
  }
61709
61653
  }
61710
61654
  }