ccstatusline 2.1.3 → 2.1.5

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.3";
51481
+ var PACKAGE_VERSION = "2.1.5";
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
@@ -52414,6 +52396,67 @@ function runGit(command, context) {
52414
52396
  function isInsideGitWorkTree(context) {
52415
52397
  return runGit("rev-parse --is-inside-work-tree", context) === "true";
52416
52398
  }
52399
+ function parseDiffShortStat(stat) {
52400
+ const insertMatch = /(\d+)\s+insertions?/.exec(stat);
52401
+ const deleteMatch = /(\d+)\s+deletions?/.exec(stat);
52402
+ return {
52403
+ insertions: insertMatch?.[1] ? parseInt(insertMatch[1], 10) : 0,
52404
+ deletions: deleteMatch?.[1] ? parseInt(deleteMatch[1], 10) : 0
52405
+ };
52406
+ }
52407
+ function getGitChangeCounts(context) {
52408
+ const unstagedStat = runGit("diff --shortstat", context) ?? "";
52409
+ const stagedStat = runGit("diff --cached --shortstat", context) ?? "";
52410
+ const unstagedCounts = parseDiffShortStat(unstagedStat);
52411
+ const stagedCounts = parseDiffShortStat(stagedStat);
52412
+ return {
52413
+ insertions: unstagedCounts.insertions + stagedCounts.insertions,
52414
+ deletions: unstagedCounts.deletions + stagedCounts.deletions
52415
+ };
52416
+ }
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
+ }
52417
52460
 
52418
52461
  // src/widgets/GitBranch.ts
52419
52462
  class GitBranchWidget {
@@ -52430,31 +52473,16 @@ class GitBranchWidget {
52430
52473
  return "Git";
52431
52474
  }
52432
52475
  getEditorDisplay(item) {
52433
- const hideNoGit = item.metadata?.hideNoGit === "true";
52434
- const modifiers = [];
52435
- if (hideNoGit) {
52436
- modifiers.push("hide 'no git'");
52437
- }
52438
52476
  return {
52439
52477
  displayText: this.getDisplayName(),
52440
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52478
+ modifierText: getHideNoGitModifierText(item)
52441
52479
  };
52442
52480
  }
52443
52481
  handleEditorAction(action, item) {
52444
- if (action === "toggle-nogit") {
52445
- const currentState = item.metadata?.hideNoGit === "true";
52446
- return {
52447
- ...item,
52448
- metadata: {
52449
- ...item.metadata,
52450
- hideNoGit: (!currentState).toString()
52451
- }
52452
- };
52453
- }
52454
- return null;
52482
+ return handleToggleNoGitAction(action, item);
52455
52483
  }
52456
52484
  render(item, context, settings) {
52457
- const hideNoGit = item.metadata?.hideNoGit === "true";
52485
+ const hideNoGit = isHideNoGitEnabled(item);
52458
52486
  if (context.isPreview) {
52459
52487
  return item.rawValue ? "main" : "⎇ main";
52460
52488
  }
@@ -52470,9 +52498,7 @@ class GitBranchWidget {
52470
52498
  return runGit("branch --show-current", context);
52471
52499
  }
52472
52500
  getCustomKeybinds() {
52473
- return [
52474
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52475
- ];
52501
+ return getHideNoGitKeybinds();
52476
52502
  }
52477
52503
  supportsRawValue() {
52478
52504
  return true;
@@ -52496,66 +52522,115 @@ class GitChangesWidget {
52496
52522
  return "Git";
52497
52523
  }
52498
52524
  getEditorDisplay(item) {
52499
- const hideNoGit = item.metadata?.hideNoGit === "true";
52500
- const modifiers = [];
52501
- if (hideNoGit) {
52502
- modifiers.push("hide 'no git'");
52503
- }
52504
52525
  return {
52505
52526
  displayText: this.getDisplayName(),
52506
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52527
+ modifierText: getHideNoGitModifierText(item)
52507
52528
  };
52508
52529
  }
52509
52530
  handleEditorAction(action, item) {
52510
- if (action === "toggle-nogit") {
52511
- const currentState = item.metadata?.hideNoGit === "true";
52512
- return {
52513
- ...item,
52514
- metadata: {
52515
- ...item.metadata,
52516
- hideNoGit: (!currentState).toString()
52517
- }
52518
- };
52519
- }
52520
- return null;
52531
+ return handleToggleNoGitAction(action, item);
52521
52532
  }
52522
- render(item, context, settings) {
52523
- const hideNoGit = item.metadata?.hideNoGit === "true";
52533
+ render(item, context, _settings) {
52534
+ const hideNoGit = isHideNoGitEnabled(item);
52524
52535
  if (context.isPreview) {
52525
52536
  return "(+42,-10)";
52526
52537
  }
52527
52538
  if (!isInsideGitWorkTree(context)) {
52528
52539
  return hideNoGit ? null : "(no git)";
52529
52540
  }
52530
- const changes = this.getGitChanges(context);
52531
- if (changes)
52532
- return `(+${changes.insertions},-${changes.deletions})`;
52533
- else
52541
+ const changes = getGitChangeCounts(context);
52542
+ return `(+${changes.insertions},-${changes.deletions})`;
52543
+ }
52544
+ getCustomKeybinds() {
52545
+ return getHideNoGitKeybinds();
52546
+ }
52547
+ supportsRawValue() {
52548
+ return false;
52549
+ }
52550
+ supportsColors(item) {
52551
+ return true;
52552
+ }
52553
+ }
52554
+ // src/widgets/GitInsertions.ts
52555
+ class GitInsertionsWidget {
52556
+ getDefaultColor() {
52557
+ return "green";
52558
+ }
52559
+ getDescription() {
52560
+ return "Shows git insertions count";
52561
+ }
52562
+ getDisplayName() {
52563
+ return "Git Insertions";
52564
+ }
52565
+ getCategory() {
52566
+ return "Git";
52567
+ }
52568
+ getEditorDisplay(item) {
52569
+ return {
52570
+ displayText: this.getDisplayName(),
52571
+ modifierText: getHideNoGitModifierText(item)
52572
+ };
52573
+ }
52574
+ handleEditorAction(action, item) {
52575
+ return handleToggleNoGitAction(action, item);
52576
+ }
52577
+ render(item, context, _settings) {
52578
+ const hideNoGit = isHideNoGitEnabled(item);
52579
+ if (context.isPreview) {
52580
+ return "+42";
52581
+ }
52582
+ if (!isInsideGitWorkTree(context)) {
52534
52583
  return hideNoGit ? null : "(no git)";
52584
+ }
52585
+ const changes = getGitChangeCounts(context);
52586
+ return `+${changes.insertions}`;
52587
+ }
52588
+ getCustomKeybinds() {
52589
+ return getHideNoGitKeybinds();
52590
+ }
52591
+ supportsRawValue() {
52592
+ return false;
52593
+ }
52594
+ supportsColors(item) {
52595
+ return true;
52596
+ }
52597
+ }
52598
+ // src/widgets/GitDeletions.ts
52599
+ class GitDeletionsWidget {
52600
+ getDefaultColor() {
52601
+ return "red";
52602
+ }
52603
+ getDescription() {
52604
+ return "Shows git deletions count";
52605
+ }
52606
+ getDisplayName() {
52607
+ return "Git Deletions";
52535
52608
  }
52536
- getGitChanges(context) {
52537
- let totalInsertions = 0;
52538
- let totalDeletions = 0;
52539
- const unstagedStat = runGit("diff --shortstat", context) ?? "";
52540
- const stagedStat = runGit("diff --cached --shortstat", context) ?? "";
52541
- if (unstagedStat) {
52542
- const insertMatch = /(\d+) insertion/.exec(unstagedStat);
52543
- const deleteMatch = /(\d+) deletion/.exec(unstagedStat);
52544
- totalInsertions += insertMatch?.[1] ? parseInt(insertMatch[1], 10) : 0;
52545
- totalDeletions += deleteMatch?.[1] ? parseInt(deleteMatch[1], 10) : 0;
52546
- }
52547
- if (stagedStat) {
52548
- const insertMatch = /(\d+) insertion/.exec(stagedStat);
52549
- const deleteMatch = /(\d+) deletion/.exec(stagedStat);
52550
- totalInsertions += insertMatch?.[1] ? parseInt(insertMatch[1], 10) : 0;
52551
- totalDeletions += deleteMatch?.[1] ? parseInt(deleteMatch[1], 10) : 0;
52552
- }
52553
- return { insertions: totalInsertions, deletions: totalDeletions };
52609
+ getCategory() {
52610
+ return "Git";
52611
+ }
52612
+ getEditorDisplay(item) {
52613
+ return {
52614
+ displayText: this.getDisplayName(),
52615
+ modifierText: getHideNoGitModifierText(item)
52616
+ };
52617
+ }
52618
+ handleEditorAction(action, item) {
52619
+ return handleToggleNoGitAction(action, item);
52620
+ }
52621
+ render(item, context, _settings) {
52622
+ const hideNoGit = isHideNoGitEnabled(item);
52623
+ if (context.isPreview) {
52624
+ return "-10";
52625
+ }
52626
+ if (!isInsideGitWorkTree(context)) {
52627
+ return hideNoGit ? null : "(no git)";
52628
+ }
52629
+ const changes = getGitChangeCounts(context);
52630
+ return `-${changes.deletions}`;
52554
52631
  }
52555
52632
  getCustomKeybinds() {
52556
- return [
52557
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52558
- ];
52633
+ return getHideNoGitKeybinds();
52559
52634
  }
52560
52635
  supportsRawValue() {
52561
52636
  return false;
@@ -52579,31 +52654,16 @@ class GitRootDirWidget {
52579
52654
  return "Git";
52580
52655
  }
52581
52656
  getEditorDisplay(item) {
52582
- const hideNoGit = item.metadata?.hideNoGit === "true";
52583
- const modifiers = [];
52584
- if (hideNoGit) {
52585
- modifiers.push("hide 'no git'");
52586
- }
52587
52657
  return {
52588
52658
  displayText: this.getDisplayName(),
52589
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52659
+ modifierText: getHideNoGitModifierText(item)
52590
52660
  };
52591
52661
  }
52592
52662
  handleEditorAction(action, item) {
52593
- if (action === "toggle-nogit") {
52594
- const currentState = item.metadata?.hideNoGit === "true";
52595
- return {
52596
- ...item,
52597
- metadata: {
52598
- ...item.metadata,
52599
- hideNoGit: (!currentState).toString()
52600
- }
52601
- };
52602
- }
52603
- return null;
52663
+ return handleToggleNoGitAction(action, item);
52604
52664
  }
52605
52665
  render(item, context, _settings) {
52606
- const hideNoGit = item.metadata?.hideNoGit === "true";
52666
+ const hideNoGit = isHideNoGitEnabled(item);
52607
52667
  if (context.isPreview) {
52608
52668
  return "my-repo";
52609
52669
  }
@@ -52627,9 +52687,7 @@ class GitRootDirWidget {
52627
52687
  return lastPart && lastPart.length > 0 ? lastPart : normalizedRootDir;
52628
52688
  }
52629
52689
  getCustomKeybinds() {
52630
- return [
52631
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52632
- ];
52690
+ return getHideNoGitKeybinds();
52633
52691
  }
52634
52692
  supportsRawValue() {
52635
52693
  return false;
@@ -52653,31 +52711,16 @@ class GitWorktreeWidget {
52653
52711
  return "Git";
52654
52712
  }
52655
52713
  getEditorDisplay(item) {
52656
- const hideNoGit = item.metadata?.hideNoGit === "true";
52657
- const modifiers = [];
52658
- if (hideNoGit) {
52659
- modifiers.push("hide 'no git'");
52660
- }
52661
52714
  return {
52662
52715
  displayText: this.getDisplayName(),
52663
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
52716
+ modifierText: getHideNoGitModifierText(item)
52664
52717
  };
52665
52718
  }
52666
52719
  handleEditorAction(action, item) {
52667
- if (action === "toggle-nogit") {
52668
- const currentState = item.metadata?.hideNoGit === "true";
52669
- return {
52670
- ...item,
52671
- metadata: {
52672
- ...item.metadata,
52673
- hideNoGit: (!currentState).toString()
52674
- }
52675
- };
52676
- }
52677
- return null;
52720
+ return handleToggleNoGitAction(action, item);
52678
52721
  }
52679
52722
  render(item, context) {
52680
- const hideNoGit = item.metadata?.hideNoGit === "true";
52723
+ const hideNoGit = isHideNoGitEnabled(item);
52681
52724
  if (context.isPreview)
52682
52725
  return item.rawValue ? "main" : "\uD81A\uDC30 main";
52683
52726
  if (!isInsideGitWorkTree(context)) {
@@ -52705,9 +52748,7 @@ class GitWorktreeWidget {
52705
52748
  return worktree.length > 0 ? worktree : null;
52706
52749
  }
52707
52750
  getCustomKeybinds() {
52708
- return [
52709
- { key: "h", label: "(h)ide 'no git' message", action: "toggle-nogit" }
52710
- ];
52751
+ return getHideNoGitKeybinds();
52711
52752
  }
52712
52753
  supportsRawValue() {
52713
52754
  return true;
@@ -53043,6 +53084,36 @@ function formatTokens(count) {
53043
53084
  return `${(count / 1000).toFixed(1)}k`;
53044
53085
  return count.toString();
53045
53086
  }
53087
+ function resolveEffectiveTerminalWidth(detectedWidth, settings, context) {
53088
+ if (!detectedWidth) {
53089
+ return null;
53090
+ }
53091
+ const flexMode = settings.flexMode;
53092
+ if (context.isPreview) {
53093
+ if (flexMode === "full") {
53094
+ return detectedWidth - 6;
53095
+ }
53096
+ if (flexMode === "full-minus-40") {
53097
+ return detectedWidth - 40;
53098
+ }
53099
+ if (flexMode === "full-until-compact") {
53100
+ return detectedWidth - 6;
53101
+ }
53102
+ return null;
53103
+ }
53104
+ if (flexMode === "full") {
53105
+ return detectedWidth - 6;
53106
+ }
53107
+ if (flexMode === "full-minus-40") {
53108
+ return detectedWidth - 40;
53109
+ }
53110
+ if (flexMode === "full-until-compact") {
53111
+ const threshold = settings.compactThreshold;
53112
+ const contextPercentage = calculateContextPercentage(context);
53113
+ return contextPercentage >= threshold ? detectedWidth - 40 : detectedWidth - 6;
53114
+ }
53115
+ return null;
53116
+ }
53046
53117
  function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, globalSeparatorOffset = 0, preRenderedWidgets, preCalculatedMaxWidths) {
53047
53118
  const powerlineConfig = settings.powerline;
53048
53119
  const config2 = powerlineConfig ?? {};
@@ -53068,33 +53139,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
53068
53139
  if (filteredWidgets.length === 0)
53069
53140
  return "";
53070
53141
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
53071
- let terminalWidth = null;
53072
- if (detectedWidth) {
53073
- const flexMode = settings.flexMode;
53074
- if (context.isPreview) {
53075
- if (flexMode === "full") {
53076
- terminalWidth = detectedWidth - 6;
53077
- } else if (flexMode === "full-minus-40") {
53078
- terminalWidth = detectedWidth - 40;
53079
- } else if (flexMode === "full-until-compact") {
53080
- terminalWidth = detectedWidth - 6;
53081
- }
53082
- } else {
53083
- if (flexMode === "full") {
53084
- terminalWidth = detectedWidth - 6;
53085
- } else if (flexMode === "full-minus-40") {
53086
- terminalWidth = detectedWidth - 40;
53087
- } else if (flexMode === "full-until-compact") {
53088
- const threshold = settings.compactThreshold;
53089
- const contextPercentage = calculateContextPercentage(context);
53090
- if (contextPercentage >= threshold) {
53091
- terminalWidth = detectedWidth - 40;
53092
- } else {
53093
- terminalWidth = detectedWidth - 6;
53094
- }
53095
- }
53096
- }
53097
- }
53142
+ const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
53098
53143
  const widgetElements = [];
53099
53144
  let widgetColorIndex = 0;
53100
53145
  const preRenderedIndices = [];
@@ -53420,33 +53465,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
53420
53465
  return applyColors(text, fgColor, bgColor, shouldBold, colorLevel);
53421
53466
  };
53422
53467
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
53423
- let terminalWidth = null;
53424
- if (detectedWidth) {
53425
- const flexMode = settings.flexMode;
53426
- if (context.isPreview) {
53427
- if (flexMode === "full") {
53428
- terminalWidth = detectedWidth - 6;
53429
- } else if (flexMode === "full-minus-40") {
53430
- terminalWidth = detectedWidth - 40;
53431
- } else if (flexMode === "full-until-compact") {
53432
- terminalWidth = detectedWidth - 6;
53433
- }
53434
- } else {
53435
- if (flexMode === "full") {
53436
- terminalWidth = detectedWidth - 6;
53437
- } else if (flexMode === "full-minus-40") {
53438
- terminalWidth = detectedWidth - 40;
53439
- } else if (flexMode === "full-until-compact") {
53440
- const threshold = settings.compactThreshold;
53441
- const contextPercentage = calculateContextPercentage(context);
53442
- if (contextPercentage >= threshold) {
53443
- terminalWidth = detectedWidth - 40;
53444
- } else {
53445
- terminalWidth = detectedWidth - 6;
53446
- }
53447
- }
53448
- }
53449
- }
53468
+ const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
53450
53469
  const elements = [];
53451
53470
  let hasFlexSeparator = false;
53452
53471
  for (let i = 0;i < widgets.length; i++) {
@@ -53628,6 +53647,11 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
53628
53647
  return statusLine;
53629
53648
  }
53630
53649
 
53650
+ // src/widgets/shared/raw-or-labeled.ts
53651
+ function formatRawOrLabeledValue(item, labelPrefix, value) {
53652
+ return item.rawValue ? value : `${labelPrefix}${value}`;
53653
+ }
53654
+
53631
53655
  // src/widgets/TokensInput.ts
53632
53656
  class TokensInputWidget {
53633
53657
  getDefaultColor() {
@@ -53647,14 +53671,14 @@ class TokensInputWidget {
53647
53671
  }
53648
53672
  render(item, context, settings) {
53649
53673
  if (context.isPreview) {
53650
- return item.rawValue ? "15.2k" : "In: 15.2k";
53674
+ return formatRawOrLabeledValue(item, "In: ", "15.2k");
53651
53675
  }
53652
53676
  const inputTotalTokens = getContextWindowInputTotalTokens(context.data);
53653
53677
  if (inputTotalTokens !== null) {
53654
- return item.rawValue ? formatTokens(inputTotalTokens) : `In: ${formatTokens(inputTotalTokens)}`;
53678
+ return formatRawOrLabeledValue(item, "In: ", formatTokens(inputTotalTokens));
53655
53679
  }
53656
53680
  if (context.tokenMetrics) {
53657
- return item.rawValue ? formatTokens(context.tokenMetrics.inputTokens) : `In: ${formatTokens(context.tokenMetrics.inputTokens)}`;
53681
+ return formatRawOrLabeledValue(item, "In: ", formatTokens(context.tokenMetrics.inputTokens));
53658
53682
  }
53659
53683
  return null;
53660
53684
  }
@@ -53684,14 +53708,14 @@ class TokensOutputWidget {
53684
53708
  }
53685
53709
  render(item, context, settings) {
53686
53710
  if (context.isPreview) {
53687
- return item.rawValue ? "3.4k" : "Out: 3.4k";
53711
+ return formatRawOrLabeledValue(item, "Out: ", "3.4k");
53688
53712
  }
53689
53713
  const outputTotalTokens = getContextWindowOutputTotalTokens(context.data);
53690
53714
  if (outputTotalTokens !== null) {
53691
- return item.rawValue ? formatTokens(outputTotalTokens) : `Out: ${formatTokens(outputTotalTokens)}`;
53715
+ return formatRawOrLabeledValue(item, "Out: ", formatTokens(outputTotalTokens));
53692
53716
  }
53693
53717
  if (context.tokenMetrics) {
53694
- return item.rawValue ? formatTokens(context.tokenMetrics.outputTokens) : `Out: ${formatTokens(context.tokenMetrics.outputTokens)}`;
53718
+ return formatRawOrLabeledValue(item, "Out: ", formatTokens(context.tokenMetrics.outputTokens));
53695
53719
  }
53696
53720
  return null;
53697
53721
  }
@@ -53721,10 +53745,10 @@ class TokensCachedWidget {
53721
53745
  }
53722
53746
  render(item, context, settings) {
53723
53747
  if (context.isPreview) {
53724
- return item.rawValue ? "12k" : "Cached: 12k";
53748
+ return formatRawOrLabeledValue(item, "Cached: ", "12k");
53725
53749
  }
53726
53750
  if (context.tokenMetrics) {
53727
- return item.rawValue ? formatTokens(context.tokenMetrics.cachedTokens) : `Cached: ${formatTokens(context.tokenMetrics.cachedTokens)}`;
53751
+ return formatRawOrLabeledValue(item, "Cached: ", formatTokens(context.tokenMetrics.cachedTokens));
53728
53752
  }
53729
53753
  return null;
53730
53754
  }
@@ -53754,10 +53778,10 @@ class TokensTotalWidget {
53754
53778
  }
53755
53779
  render(item, context, settings) {
53756
53780
  if (context.isPreview) {
53757
- return item.rawValue ? "30.6k" : "Total: 30.6k";
53781
+ return formatRawOrLabeledValue(item, "Total: ", "30.6k");
53758
53782
  }
53759
53783
  if (context.tokenMetrics) {
53760
- return item.rawValue ? formatTokens(context.tokenMetrics.totalTokens) : `Total: ${formatTokens(context.tokenMetrics.totalTokens)}`;
53784
+ return formatRawOrLabeledValue(item, "Total: ", formatTokens(context.tokenMetrics.totalTokens));
53761
53785
  }
53762
53786
  return null;
53763
53787
  }
@@ -53805,6 +53829,22 @@ class ContextLengthWidget {
53805
53829
  return true;
53806
53830
  }
53807
53831
  }
53832
+ // src/widgets/shared/context-inverse.ts
53833
+ var INVERSE_KEY = "inverse";
53834
+ var TOGGLE_INVERSE_ACTION = "toggle-inverse";
53835
+ function isContextInverse(item) {
53836
+ return isMetadataFlagEnabled(item, INVERSE_KEY);
53837
+ }
53838
+ function getContextInverseModifierText(item) {
53839
+ return makeModifierText(isContextInverse(item) ? ["remaining"] : []);
53840
+ }
53841
+ function handleContextInverseAction(action, item) {
53842
+ if (action !== TOGGLE_INVERSE_ACTION) {
53843
+ return null;
53844
+ }
53845
+ return toggleMetadataFlag(item, INVERSE_KEY);
53846
+ }
53847
+
53808
53848
  // src/widgets/ContextPercentage.ts
53809
53849
  class ContextPercentageWidget {
53810
53850
  getDefaultColor() {
@@ -53820,39 +53860,24 @@ class ContextPercentageWidget {
53820
53860
  return "Context";
53821
53861
  }
53822
53862
  getEditorDisplay(item) {
53823
- const isInverse = item.metadata?.inverse === "true";
53824
- const modifiers = [];
53825
- if (isInverse) {
53826
- modifiers.push("remaining");
53827
- }
53828
53863
  return {
53829
53864
  displayText: this.getDisplayName(),
53830
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
53865
+ modifierText: getContextInverseModifierText(item)
53831
53866
  };
53832
53867
  }
53833
53868
  handleEditorAction(action, item) {
53834
- if (action === "toggle-inverse") {
53835
- const currentState = item.metadata?.inverse === "true";
53836
- return {
53837
- ...item,
53838
- metadata: {
53839
- ...item.metadata,
53840
- inverse: (!currentState).toString()
53841
- }
53842
- };
53843
- }
53844
- return null;
53869
+ return handleContextInverseAction(action, item);
53845
53870
  }
53846
53871
  render(item, context, settings) {
53847
- const isInverse = item.metadata?.inverse === "true";
53872
+ const isInverse = isContextInverse(item);
53848
53873
  const contextWindowMetrics = getContextWindowMetrics(context.data);
53849
53874
  if (context.isPreview) {
53850
53875
  const previewValue = isInverse ? "90.7%" : "9.3%";
53851
- return item.rawValue ? previewValue : `Ctx: ${previewValue}`;
53876
+ return formatRawOrLabeledValue(item, "Ctx: ", previewValue);
53852
53877
  }
53853
53878
  if (contextWindowMetrics.usedPercentage !== null) {
53854
53879
  const displayPercentage = isInverse ? 100 - contextWindowMetrics.usedPercentage : contextWindowMetrics.usedPercentage;
53855
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
53880
+ return formatRawOrLabeledValue(item, "Ctx: ", `${displayPercentage.toFixed(1)}%`);
53856
53881
  }
53857
53882
  if (context.tokenMetrics) {
53858
53883
  const model = context.data?.model;
@@ -53860,7 +53885,7 @@ class ContextPercentageWidget {
53860
53885
  const contextConfig = getContextConfig(modelId, contextWindowMetrics.windowSize);
53861
53886
  const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.maxTokens * 100);
53862
53887
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53863
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
53888
+ return formatRawOrLabeledValue(item, "Ctx: ", `${displayPercentage.toFixed(1)}%`);
53864
53889
  }
53865
53890
  return null;
53866
53891
  }
@@ -53891,48 +53916,33 @@ class ContextPercentageUsableWidget {
53891
53916
  return "Context";
53892
53917
  }
53893
53918
  getEditorDisplay(item) {
53894
- const isInverse = item.metadata?.inverse === "true";
53895
- const modifiers = [];
53896
- if (isInverse) {
53897
- modifiers.push("remaining");
53898
- }
53899
53919
  return {
53900
53920
  displayText: this.getDisplayName(),
53901
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
53921
+ modifierText: getContextInverseModifierText(item)
53902
53922
  };
53903
53923
  }
53904
53924
  handleEditorAction(action, item) {
53905
- if (action === "toggle-inverse") {
53906
- const currentState = item.metadata?.inverse === "true";
53907
- return {
53908
- ...item,
53909
- metadata: {
53910
- ...item.metadata,
53911
- inverse: (!currentState).toString()
53912
- }
53913
- };
53914
- }
53915
- return null;
53925
+ return handleContextInverseAction(action, item);
53916
53926
  }
53917
53927
  render(item, context, settings) {
53918
- const isInverse = item.metadata?.inverse === "true";
53928
+ const isInverse = isContextInverse(item);
53919
53929
  const model = context.data?.model;
53920
53930
  const modelId = typeof model === "string" ? model : model?.id;
53921
53931
  const contextWindowMetrics = getContextWindowMetrics(context.data);
53922
53932
  const contextConfig = getContextConfig(modelId, contextWindowMetrics.windowSize);
53923
53933
  if (context.isPreview) {
53924
53934
  const previewValue = isInverse ? "88.4%" : "11.6%";
53925
- return item.rawValue ? previewValue : `Ctx(u): ${previewValue}`;
53935
+ return formatRawOrLabeledValue(item, "Ctx(u): ", previewValue);
53926
53936
  }
53927
53937
  if (contextWindowMetrics.contextLengthTokens !== null) {
53928
53938
  const usedPercentage = Math.min(100, contextWindowMetrics.contextLengthTokens / contextConfig.usableTokens * 100);
53929
53939
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53930
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
53940
+ return formatRawOrLabeledValue(item, "Ctx(u): ", `${displayPercentage.toFixed(1)}%`);
53931
53941
  }
53932
53942
  if (context.tokenMetrics) {
53933
53943
  const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.usableTokens * 100);
53934
53944
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53935
- return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
53945
+ return formatRawOrLabeledValue(item, "Ctx(u): ", `${displayPercentage.toFixed(1)}%`);
53936
53946
  }
53937
53947
  return null;
53938
53948
  }
@@ -55951,17 +55961,56 @@ function makeUsageProgressBar(percent, width = 15) {
55951
55961
  return "[" + "█".repeat(filled) + "░".repeat(empty2) + "]";
55952
55962
  }
55953
55963
 
55954
- // src/widgets/BlockTimer.ts
55955
- function getDisplayMode(item) {
55964
+ // src/widgets/shared/usage-display.ts
55965
+ function getUsageDisplayMode(item) {
55956
55966
  const mode = item.metadata?.display;
55957
55967
  if (mode === "progress" || mode === "progress-short") {
55958
55968
  return mode;
55959
55969
  }
55960
55970
  return "time";
55961
55971
  }
55962
- function isInverted(item) {
55963
- return item.metadata?.invert === "true";
55972
+ function isUsageProgressMode(mode) {
55973
+ return mode === "progress" || mode === "progress-short";
55974
+ }
55975
+ function getUsageProgressBarWidth(mode) {
55976
+ return mode === "progress" ? 32 : 16;
55977
+ }
55978
+ function isUsageInverted(item) {
55979
+ return isMetadataFlagEnabled(item, "invert");
55980
+ }
55981
+ function getUsageDisplayModifierText(item) {
55982
+ const mode = getUsageDisplayMode(item);
55983
+ const modifiers = [];
55984
+ if (mode === "progress") {
55985
+ modifiers.push("progress bar");
55986
+ } else if (mode === "progress-short") {
55987
+ modifiers.push("short bar");
55988
+ }
55989
+ if (isUsageInverted(item)) {
55990
+ modifiers.push("inverted");
55991
+ }
55992
+ return makeModifierText(modifiers);
55993
+ }
55994
+ function cycleUsageDisplayMode(item) {
55995
+ const currentMode = getUsageDisplayMode(item);
55996
+ const nextMode = currentMode === "time" ? "progress" : currentMode === "progress" ? "progress-short" : "time";
55997
+ const nextMetadata = {
55998
+ ...item.metadata ?? {},
55999
+ display: nextMode
56000
+ };
56001
+ if (nextMode === "time") {
56002
+ delete nextMetadata.invert;
56003
+ }
56004
+ return {
56005
+ ...item,
56006
+ metadata: nextMetadata
56007
+ };
55964
56008
  }
56009
+ function toggleUsageInverted(item) {
56010
+ return toggleMetadataFlag(item, "invert");
56011
+ }
56012
+
56013
+ // src/widgets/BlockTimer.ts
55965
56014
  function makeTimerProgressBar(percent, width) {
55966
56015
  const clampedPercent = Math.max(0, Math.min(100, percent));
55967
56016
  const filledWidth = Math.floor(clampedPercent / 100 * width);
@@ -55983,90 +56032,51 @@ class BlockTimerWidget {
55983
56032
  return "Usage";
55984
56033
  }
55985
56034
  getEditorDisplay(item) {
55986
- const mode = getDisplayMode(item);
55987
- const modifiers = [];
55988
- if (mode === "progress") {
55989
- modifiers.push("progress bar");
55990
- } else if (mode === "progress-short") {
55991
- modifiers.push("short bar");
55992
- }
55993
- if (isInverted(item)) {
55994
- modifiers.push("inverted");
55995
- }
55996
56035
  return {
55997
56036
  displayText: this.getDisplayName(),
55998
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56037
+ modifierText: getUsageDisplayModifierText(item)
55999
56038
  };
56000
56039
  }
56001
56040
  handleEditorAction(action, item) {
56002
56041
  if (action === "toggle-progress") {
56003
- const currentMode = getDisplayMode(item);
56004
- let nextMode;
56005
- if (currentMode === "time") {
56006
- nextMode = "progress";
56007
- } else if (currentMode === "progress") {
56008
- nextMode = "progress-short";
56009
- } else {
56010
- nextMode = "time";
56011
- }
56012
- const nextMetadata = {
56013
- ...item.metadata ?? {},
56014
- display: nextMode
56015
- };
56016
- if (nextMode === "time") {
56017
- delete nextMetadata.invert;
56018
- }
56019
- return {
56020
- ...item,
56021
- metadata: nextMetadata
56022
- };
56042
+ return cycleUsageDisplayMode(item);
56023
56043
  }
56024
56044
  if (action === "toggle-invert") {
56025
- return {
56026
- ...item,
56027
- metadata: {
56028
- ...item.metadata,
56029
- invert: (!isInverted(item)).toString()
56030
- }
56031
- };
56045
+ return toggleUsageInverted(item);
56032
56046
  }
56033
56047
  return null;
56034
56048
  }
56035
56049
  render(item, context, settings) {
56036
- const displayMode = getDisplayMode(item);
56037
- const inverted = isInverted(item);
56050
+ const displayMode = getUsageDisplayMode(item);
56051
+ const inverted = isUsageInverted(item);
56038
56052
  if (context.isPreview) {
56039
56053
  const previewPercent = inverted ? 26.1 : 73.9;
56040
- const prefix = item.rawValue ? "" : "Block ";
56041
- if (displayMode === "progress" || displayMode === "progress-short") {
56042
- const barWidth = displayMode === "progress" ? 32 : 16;
56054
+ if (isUsageProgressMode(displayMode)) {
56055
+ const barWidth = getUsageProgressBarWidth(displayMode);
56043
56056
  const progressBar = makeTimerProgressBar(previewPercent, barWidth);
56044
- return `${prefix}[${progressBar}] ${previewPercent.toFixed(1)}%`;
56057
+ return formatRawOrLabeledValue(item, "Block ", `[${progressBar}] ${previewPercent.toFixed(1)}%`);
56045
56058
  }
56046
- return item.rawValue ? "3hr 45m" : "Block: 3hr 45m";
56059
+ return formatRawOrLabeledValue(item, "Block: ", "3hr 45m");
56047
56060
  }
56048
56061
  const usageData = fetchUsageData();
56049
56062
  const window2 = resolveUsageWindowWithFallback(usageData, context.blockMetrics);
56050
56063
  if (!window2) {
56051
- if (displayMode === "progress" || displayMode === "progress-short") {
56052
- const barWidth = displayMode === "progress" ? 32 : 16;
56064
+ if (isUsageProgressMode(displayMode)) {
56065
+ const barWidth = getUsageProgressBarWidth(displayMode);
56053
56066
  const emptyBar = "░".repeat(barWidth);
56054
- return item.rawValue ? `[${emptyBar}] 0.0%` : `Block [${emptyBar}] 0.0%`;
56067
+ return formatRawOrLabeledValue(item, "Block ", `[${emptyBar}] 0.0%`);
56055
56068
  }
56056
- return item.rawValue ? "0hr 0m" : "Block: 0hr 0m";
56069
+ return formatRawOrLabeledValue(item, "Block: ", "0hr 0m");
56057
56070
  }
56058
- if (displayMode === "progress" || displayMode === "progress-short") {
56059
- const barWidth = displayMode === "progress" ? 32 : 16;
56071
+ if (isUsageProgressMode(displayMode)) {
56072
+ const barWidth = getUsageProgressBarWidth(displayMode);
56060
56073
  const percent = inverted ? window2.remainingPercent : window2.elapsedPercent;
56061
56074
  const progressBar = makeTimerProgressBar(percent, barWidth);
56062
56075
  const percentage = percent.toFixed(1);
56063
- if (item.rawValue) {
56064
- return `[${progressBar}] ${percentage}%`;
56065
- }
56066
- return `Block [${progressBar}] ${percentage}%`;
56076
+ return formatRawOrLabeledValue(item, "Block ", `[${progressBar}] ${percentage}%`);
56067
56077
  }
56068
56078
  const elapsedTime = formatUsageDuration(window2.elapsedMs);
56069
- return item.rawValue ? elapsedTime : `Block: ${elapsedTime}`;
56079
+ return formatRawOrLabeledValue(item, "Block: ", elapsedTime);
56070
56080
  }
56071
56081
  getCustomKeybinds() {
56072
56082
  return [
@@ -56501,17 +56511,6 @@ class SessionNameWidget {
56501
56511
  }
56502
56512
  }
56503
56513
  // src/widgets/SessionUsage.ts
56504
- function getDisplayMode2(item) {
56505
- const mode = item.metadata?.display;
56506
- if (mode === "progress" || mode === "progress-short") {
56507
- return mode;
56508
- }
56509
- return "time";
56510
- }
56511
- function isInverted2(item) {
56512
- return item.metadata?.invert === "true";
56513
- }
56514
-
56515
56514
  class SessionUsageWidget {
56516
56515
  getDefaultColor() {
56517
56516
  return "brightBlue";
@@ -56526,67 +56525,32 @@ class SessionUsageWidget {
56526
56525
  return "Usage";
56527
56526
  }
56528
56527
  getEditorDisplay(item) {
56529
- const mode = getDisplayMode2(item);
56530
- const modifiers = [];
56531
- if (mode === "progress") {
56532
- modifiers.push("progress bar");
56533
- } else if (mode === "progress-short") {
56534
- modifiers.push("short bar");
56535
- }
56536
- if (isInverted2(item)) {
56537
- modifiers.push("inverted");
56538
- }
56539
56528
  return {
56540
56529
  displayText: this.getDisplayName(),
56541
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56530
+ modifierText: getUsageDisplayModifierText(item)
56542
56531
  };
56543
56532
  }
56544
56533
  handleEditorAction(action, item) {
56545
56534
  if (action === "toggle-progress") {
56546
- const currentMode = getDisplayMode2(item);
56547
- let nextMode;
56548
- if (currentMode === "time") {
56549
- nextMode = "progress";
56550
- } else if (currentMode === "progress") {
56551
- nextMode = "progress-short";
56552
- } else {
56553
- nextMode = "time";
56554
- }
56555
- const nextMetadata = {
56556
- ...item.metadata ?? {},
56557
- display: nextMode
56558
- };
56559
- if (nextMode === "time") {
56560
- delete nextMetadata.invert;
56561
- }
56562
- return {
56563
- ...item,
56564
- metadata: nextMetadata
56565
- };
56535
+ return cycleUsageDisplayMode(item);
56566
56536
  }
56567
56537
  if (action === "toggle-invert") {
56568
- return {
56569
- ...item,
56570
- metadata: {
56571
- ...item.metadata,
56572
- invert: (!isInverted2(item)).toString()
56573
- }
56574
- };
56538
+ return toggleUsageInverted(item);
56575
56539
  }
56576
56540
  return null;
56577
56541
  }
56578
56542
  render(item, context, settings) {
56579
- const displayMode = getDisplayMode2(item);
56580
- const inverted = isInverted2(item);
56543
+ const displayMode = getUsageDisplayMode(item);
56544
+ const inverted = isUsageInverted(item);
56581
56545
  if (context.isPreview) {
56582
56546
  const previewPercent = 20;
56583
56547
  const renderedPercent = inverted ? 100 - previewPercent : previewPercent;
56584
- if (displayMode === "progress" || displayMode === "progress-short") {
56585
- const width = displayMode === "progress" ? 32 : 16;
56548
+ if (isUsageProgressMode(displayMode)) {
56549
+ const width = getUsageProgressBarWidth(displayMode);
56586
56550
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56587
- return item.rawValue ? progressDisplay : `Session: ${progressDisplay}`;
56551
+ return formatRawOrLabeledValue(item, "Session: ", progressDisplay);
56588
56552
  }
56589
- return item.rawValue ? `${previewPercent.toFixed(1)}%` : `Session: ${previewPercent.toFixed(1)}%`;
56553
+ return formatRawOrLabeledValue(item, "Session: ", `${previewPercent.toFixed(1)}%`);
56590
56554
  }
56591
56555
  const data = fetchUsageData();
56592
56556
  if (data.error)
@@ -56594,13 +56558,13 @@ class SessionUsageWidget {
56594
56558
  if (data.sessionUsage === undefined)
56595
56559
  return null;
56596
56560
  const percent = Math.max(0, Math.min(100, data.sessionUsage));
56597
- if (displayMode === "progress" || displayMode === "progress-short") {
56598
- const width = displayMode === "progress" ? 32 : 16;
56561
+ if (isUsageProgressMode(displayMode)) {
56562
+ const width = getUsageProgressBarWidth(displayMode);
56599
56563
  const renderedPercent = inverted ? 100 - percent : percent;
56600
56564
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56601
- return item.rawValue ? progressDisplay : `Session: ${progressDisplay}`;
56565
+ return formatRawOrLabeledValue(item, "Session: ", progressDisplay);
56602
56566
  }
56603
- return item.rawValue ? `${percent.toFixed(1)}%` : `Session: ${percent.toFixed(1)}%`;
56567
+ return formatRawOrLabeledValue(item, "Session: ", `${percent.toFixed(1)}%`);
56604
56568
  }
56605
56569
  getCustomKeybinds() {
56606
56570
  return [
@@ -56616,17 +56580,6 @@ class SessionUsageWidget {
56616
56580
  }
56617
56581
  }
56618
56582
  // src/widgets/WeeklyUsage.ts
56619
- function getDisplayMode3(item) {
56620
- const mode = item.metadata?.display;
56621
- if (mode === "progress" || mode === "progress-short") {
56622
- return mode;
56623
- }
56624
- return "time";
56625
- }
56626
- function isInverted3(item) {
56627
- return item.metadata?.invert === "true";
56628
- }
56629
-
56630
56583
  class WeeklyUsageWidget {
56631
56584
  getDefaultColor() {
56632
56585
  return "brightBlue";
@@ -56641,67 +56594,32 @@ class WeeklyUsageWidget {
56641
56594
  return "Usage";
56642
56595
  }
56643
56596
  getEditorDisplay(item) {
56644
- const mode = getDisplayMode3(item);
56645
- const modifiers = [];
56646
- if (mode === "progress") {
56647
- modifiers.push("progress bar");
56648
- } else if (mode === "progress-short") {
56649
- modifiers.push("short bar");
56650
- }
56651
- if (isInverted3(item)) {
56652
- modifiers.push("inverted");
56653
- }
56654
56597
  return {
56655
56598
  displayText: this.getDisplayName(),
56656
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56599
+ modifierText: getUsageDisplayModifierText(item)
56657
56600
  };
56658
56601
  }
56659
56602
  handleEditorAction(action, item) {
56660
56603
  if (action === "toggle-progress") {
56661
- const currentMode = getDisplayMode3(item);
56662
- let nextMode;
56663
- if (currentMode === "time") {
56664
- nextMode = "progress";
56665
- } else if (currentMode === "progress") {
56666
- nextMode = "progress-short";
56667
- } else {
56668
- nextMode = "time";
56669
- }
56670
- const nextMetadata = {
56671
- ...item.metadata ?? {},
56672
- display: nextMode
56673
- };
56674
- if (nextMode === "time") {
56675
- delete nextMetadata.invert;
56676
- }
56677
- return {
56678
- ...item,
56679
- metadata: nextMetadata
56680
- };
56604
+ return cycleUsageDisplayMode(item);
56681
56605
  }
56682
56606
  if (action === "toggle-invert") {
56683
- return {
56684
- ...item,
56685
- metadata: {
56686
- ...item.metadata,
56687
- invert: (!isInverted3(item)).toString()
56688
- }
56689
- };
56607
+ return toggleUsageInverted(item);
56690
56608
  }
56691
56609
  return null;
56692
56610
  }
56693
56611
  render(item, context, settings) {
56694
- const displayMode = getDisplayMode3(item);
56695
- const inverted = isInverted3(item);
56612
+ const displayMode = getUsageDisplayMode(item);
56613
+ const inverted = isUsageInverted(item);
56696
56614
  if (context.isPreview) {
56697
56615
  const previewPercent = 12;
56698
56616
  const renderedPercent = inverted ? 100 - previewPercent : previewPercent;
56699
- if (displayMode === "progress" || displayMode === "progress-short") {
56700
- const width = displayMode === "progress" ? 32 : 16;
56617
+ if (isUsageProgressMode(displayMode)) {
56618
+ const width = getUsageProgressBarWidth(displayMode);
56701
56619
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56702
- return item.rawValue ? progressDisplay : `Weekly: ${progressDisplay}`;
56620
+ return formatRawOrLabeledValue(item, "Weekly: ", progressDisplay);
56703
56621
  }
56704
- return item.rawValue ? `${previewPercent.toFixed(1)}%` : `Weekly: ${previewPercent.toFixed(1)}%`;
56622
+ return formatRawOrLabeledValue(item, "Weekly: ", `${previewPercent.toFixed(1)}%`);
56705
56623
  }
56706
56624
  const data = fetchUsageData();
56707
56625
  if (data.error)
@@ -56709,13 +56627,13 @@ class WeeklyUsageWidget {
56709
56627
  if (data.weeklyUsage === undefined)
56710
56628
  return null;
56711
56629
  const percent = Math.max(0, Math.min(100, data.weeklyUsage));
56712
- if (displayMode === "progress" || displayMode === "progress-short") {
56713
- const width = displayMode === "progress" ? 32 : 16;
56630
+ if (isUsageProgressMode(displayMode)) {
56631
+ const width = getUsageProgressBarWidth(displayMode);
56714
56632
  const renderedPercent = inverted ? 100 - percent : percent;
56715
56633
  const progressDisplay = `${makeUsageProgressBar(renderedPercent, width)} ${renderedPercent.toFixed(1)}%`;
56716
- return item.rawValue ? progressDisplay : `Weekly: ${progressDisplay}`;
56634
+ return formatRawOrLabeledValue(item, "Weekly: ", progressDisplay);
56717
56635
  }
56718
- return item.rawValue ? `${percent.toFixed(1)}%` : `Weekly: ${percent.toFixed(1)}%`;
56636
+ return formatRawOrLabeledValue(item, "Weekly: ", `${percent.toFixed(1)}%`);
56719
56637
  }
56720
56638
  getCustomKeybinds() {
56721
56639
  return [
@@ -56731,16 +56649,6 @@ class WeeklyUsageWidget {
56731
56649
  }
56732
56650
  }
56733
56651
  // src/widgets/ResetTimer.ts
56734
- function getDisplayMode4(item) {
56735
- const mode = item.metadata?.display;
56736
- if (mode === "progress" || mode === "progress-short") {
56737
- return mode;
56738
- }
56739
- return "time";
56740
- }
56741
- function isInverted4(item) {
56742
- return item.metadata?.invert === "true";
56743
- }
56744
56652
  function makeTimerProgressBar2(percent, width) {
56745
56653
  const clampedPercent = Math.max(0, Math.min(100, percent));
56746
56654
  const filledWidth = Math.floor(clampedPercent / 100 * width);
@@ -56762,67 +56670,31 @@ class ResetTimerWidget {
56762
56670
  return "Usage";
56763
56671
  }
56764
56672
  getEditorDisplay(item) {
56765
- const mode = getDisplayMode4(item);
56766
- const modifiers = [];
56767
- if (mode === "progress") {
56768
- modifiers.push("progress bar");
56769
- } else if (mode === "progress-short") {
56770
- modifiers.push("short bar");
56771
- }
56772
- if (isInverted4(item)) {
56773
- modifiers.push("inverted");
56774
- }
56775
56673
  return {
56776
56674
  displayText: this.getDisplayName(),
56777
- modifierText: modifiers.length > 0 ? `(${modifiers.join(", ")})` : undefined
56675
+ modifierText: getUsageDisplayModifierText(item)
56778
56676
  };
56779
56677
  }
56780
56678
  handleEditorAction(action, item) {
56781
56679
  if (action === "toggle-progress") {
56782
- const currentMode = getDisplayMode4(item);
56783
- let nextMode;
56784
- if (currentMode === "time") {
56785
- nextMode = "progress";
56786
- } else if (currentMode === "progress") {
56787
- nextMode = "progress-short";
56788
- } else {
56789
- nextMode = "time";
56790
- }
56791
- const nextMetadata = {
56792
- ...item.metadata ?? {},
56793
- display: nextMode
56794
- };
56795
- if (nextMode === "time") {
56796
- delete nextMetadata.invert;
56797
- }
56798
- return {
56799
- ...item,
56800
- metadata: nextMetadata
56801
- };
56680
+ return cycleUsageDisplayMode(item);
56802
56681
  }
56803
56682
  if (action === "toggle-invert") {
56804
- return {
56805
- ...item,
56806
- metadata: {
56807
- ...item.metadata,
56808
- invert: (!isInverted4(item)).toString()
56809
- }
56810
- };
56683
+ return toggleUsageInverted(item);
56811
56684
  }
56812
56685
  return null;
56813
56686
  }
56814
56687
  render(item, context, settings) {
56815
- const displayMode = getDisplayMode4(item);
56816
- const inverted = isInverted4(item);
56688
+ const displayMode = getUsageDisplayMode(item);
56689
+ const inverted = isUsageInverted(item);
56817
56690
  if (context.isPreview) {
56818
56691
  const previewPercent = inverted ? 90 : 10;
56819
- const prefix = item.rawValue ? "" : "Reset ";
56820
- if (displayMode === "progress" || displayMode === "progress-short") {
56821
- const barWidth = displayMode === "progress" ? 32 : 16;
56692
+ if (isUsageProgressMode(displayMode)) {
56693
+ const barWidth = getUsageProgressBarWidth(displayMode);
56822
56694
  const progressBar = makeTimerProgressBar2(previewPercent, barWidth);
56823
- return `${prefix}[${progressBar}] ${previewPercent.toFixed(1)}%`;
56695
+ return formatRawOrLabeledValue(item, "Reset ", `[${progressBar}] ${previewPercent.toFixed(1)}%`);
56824
56696
  }
56825
- return item.rawValue ? "4hr 30m" : "Reset: 4hr 30m";
56697
+ return formatRawOrLabeledValue(item, "Reset: ", "4hr 30m");
56826
56698
  }
56827
56699
  const usageData = fetchUsageData();
56828
56700
  const window2 = resolveUsageWindowWithFallback(usageData, context.blockMetrics);
@@ -56832,18 +56704,15 @@ class ResetTimerWidget {
56832
56704
  }
56833
56705
  return null;
56834
56706
  }
56835
- if (displayMode === "progress" || displayMode === "progress-short") {
56836
- const barWidth = displayMode === "progress" ? 32 : 16;
56707
+ if (isUsageProgressMode(displayMode)) {
56708
+ const barWidth = getUsageProgressBarWidth(displayMode);
56837
56709
  const percent = inverted ? window2.remainingPercent : window2.elapsedPercent;
56838
56710
  const progressBar = makeTimerProgressBar2(percent, barWidth);
56839
56711
  const percentage = percent.toFixed(1);
56840
- if (item.rawValue) {
56841
- return `[${progressBar}] ${percentage}%`;
56842
- }
56843
- return `Reset [${progressBar}] ${percentage}%`;
56712
+ return formatRawOrLabeledValue(item, "Reset ", `[${progressBar}] ${percentage}%`);
56844
56713
  }
56845
56714
  const remainingTime = formatUsageDuration(window2.remainingMs);
56846
- return item.rawValue ? remainingTime : `Reset: ${remainingTime}`;
56715
+ return formatRawOrLabeledValue(item, "Reset: ", remainingTime);
56847
56716
  }
56848
56717
  getCustomKeybinds() {
56849
56718
  return [
@@ -56859,7 +56728,7 @@ class ResetTimerWidget {
56859
56728
  }
56860
56729
  }
56861
56730
  // src/widgets/ContextBar.ts
56862
- function getDisplayMode5(item) {
56731
+ function getDisplayMode(item) {
56863
56732
  return item.metadata?.display === "progress" ? "progress" : "progress-short";
56864
56733
  }
56865
56734
 
@@ -56877,7 +56746,7 @@ class ContextBarWidget {
56877
56746
  return "Context";
56878
56747
  }
56879
56748
  getEditorDisplay(item) {
56880
- const mode = getDisplayMode5(item);
56749
+ const mode = getDisplayMode(item);
56881
56750
  const modifiers = [];
56882
56751
  if (mode === "progress-short") {
56883
56752
  modifiers.push("short bar");
@@ -56891,7 +56760,7 @@ class ContextBarWidget {
56891
56760
  if (action !== "toggle-progress") {
56892
56761
  return null;
56893
56762
  }
56894
- const currentMode = getDisplayMode5(item);
56763
+ const currentMode = getDisplayMode(item);
56895
56764
  const nextMode = currentMode === "progress-short" ? "progress" : "progress-short";
56896
56765
  return {
56897
56766
  ...item,
@@ -56902,7 +56771,7 @@ class ContextBarWidget {
56902
56771
  };
56903
56772
  }
56904
56773
  render(item, context, settings) {
56905
- const displayMode = getDisplayMode5(item);
56774
+ const displayMode = getDisplayMode(item);
56906
56775
  const barWidth = displayMode === "progress" ? 32 : 16;
56907
56776
  if (context.isPreview) {
56908
56777
  const previewDisplay = `${makeUsageProgressBar(25, barWidth)} 50k/200k (25%)`;
@@ -57141,6 +57010,8 @@ var widgetRegistry = new Map([
57141
57010
  ["output-style", new OutputStyleWidget],
57142
57011
  ["git-branch", new GitBranchWidget],
57143
57012
  ["git-changes", new GitChangesWidget],
57013
+ ["git-insertions", new GitInsertionsWidget],
57014
+ ["git-deletions", new GitDeletionsWidget],
57144
57015
  ["git-root-dir", new GitRootDirWidget],
57145
57016
  ["git-worktree", new GitWorktreeWidget],
57146
57017
  ["current-working-dir", new CurrentWorkingDirWidget],
@@ -59539,6 +59410,30 @@ var MainMenu = ({ onSelect, isClaudeInstalled, hasChanges, initialSelection = 0,
59539
59410
  var import_react42 = __toESM(require_react(), 1);
59540
59411
  import * as os10 from "os";
59541
59412
 
59413
+ // src/utils/powerline-settings.ts
59414
+ function resolveEnabledPowerlineTheme(theme) {
59415
+ if (!theme || theme === "custom") {
59416
+ return getDefaultPowerlineTheme();
59417
+ }
59418
+ return theme;
59419
+ }
59420
+ function buildEnabledPowerlineSettings(settings, removeManualSeparators) {
59421
+ const powerlineConfig = settings.powerline;
59422
+ const lines = removeManualSeparators ? settings.lines.map((line) => line.filter((item) => item.type !== "separator" && item.type !== "flex-separator")) : settings.lines;
59423
+ return {
59424
+ ...settings,
59425
+ powerline: {
59426
+ ...powerlineConfig,
59427
+ enabled: true,
59428
+ theme: resolveEnabledPowerlineTheme(powerlineConfig.theme),
59429
+ separators: powerlineConfig.separators,
59430
+ separatorInvertBackground: powerlineConfig.separatorInvertBackground
59431
+ },
59432
+ defaultPadding: " ",
59433
+ lines
59434
+ };
59435
+ }
59436
+
59542
59437
  // src/tui/components/PowerlineSeparatorEditor.tsx
59543
59438
  var import_react40 = __toESM(require_react(), 1);
59544
59439
  var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
@@ -60151,19 +60046,7 @@ var PowerlineSetup = ({
60151
60046
  if (hasSeparatorItems) {
60152
60047
  setConfirmingEnable(true);
60153
60048
  } else {
60154
- const theme = !powerlineConfig.theme || powerlineConfig.theme === "custom" ? getDefaultPowerlineTheme() : powerlineConfig.theme;
60155
- const updatedSettings = {
60156
- ...settings,
60157
- powerline: {
60158
- ...powerlineConfig,
60159
- enabled: true,
60160
- theme,
60161
- separators: powerlineConfig.separators,
60162
- separatorInvertBackground: powerlineConfig.separatorInvertBackground
60163
- },
60164
- defaultPadding: " "
60165
- };
60166
- onUpdate(updatedSettings);
60049
+ onUpdate(buildEnabledPowerlineSettings(settings, false));
60167
60050
  }
60168
60051
  } else {
60169
60052
  const newConfig = { ...powerlineConfig, enabled: false };
@@ -60393,20 +60276,7 @@ var PowerlineSetup = ({
60393
60276
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(ConfirmDialog, {
60394
60277
  inline: true,
60395
60278
  onConfirm: () => {
60396
- const theme = !powerlineConfig.theme || powerlineConfig.theme === "custom" ? getDefaultPowerlineTheme() : powerlineConfig.theme;
60397
- const updatedSettings = {
60398
- ...settings,
60399
- powerline: {
60400
- ...powerlineConfig,
60401
- enabled: true,
60402
- theme,
60403
- separators: powerlineConfig.separators,
60404
- separatorInvertBackground: powerlineConfig.separatorInvertBackground
60405
- },
60406
- defaultPadding: " ",
60407
- lines: settings.lines.map((line) => line.filter((item) => item.type !== "separator" && item.type !== "flex-separator"))
60408
- };
60409
- onUpdate(updatedSettings);
60279
+ onUpdate(buildEnabledPowerlineSettings(settings, true));
60410
60280
  setConfirmingEnable(false);
60411
60281
  },
60412
60282
  onCancel: () => {
@@ -60575,8 +60445,19 @@ var PowerlineSetup = ({
60575
60445
  };
60576
60446
  // src/tui/components/StatusLinePreview.tsx
60577
60447
  var import_react43 = __toESM(require_react(), 1);
60448
+
60449
+ // src/utils/separator-index.ts
60450
+ function countSeparatorSlots(widgets) {
60451
+ const nonMergedWidgets = widgets.filter((_, idx) => idx === widgets.length - 1 || !widgets[idx]?.merge);
60452
+ return Math.max(0, nonMergedWidgets.length - 1);
60453
+ }
60454
+ function advanceGlobalSeparatorIndex(currentIndex, widgets) {
60455
+ return currentIndex + countSeparatorSlots(widgets);
60456
+ }
60457
+
60458
+ // src/tui/components/StatusLinePreview.tsx
60578
60459
  var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
60579
- var renderSingleLine = (widgets, terminalWidth, widthDetectionAvailable, settings, lineIndex, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
60460
+ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
60580
60461
  const context = {
60581
60462
  terminalWidth,
60582
60463
  isPreview: true,
@@ -60586,7 +60467,6 @@ var renderSingleLine = (widgets, terminalWidth, widthDetectionAvailable, setting
60586
60467
  return renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
60587
60468
  };
60588
60469
  var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange }) => {
60589
- const widthDetectionAvailable = import_react43.default.useMemo(() => canDetectTerminalWidth(), []);
60590
60470
  const { renderedLines, anyTruncated } = import_react43.default.useMemo(() => {
60591
60471
  if (!settings)
60592
60472
  return { renderedLines: [], anyTruncated: false };
@@ -60599,19 +60479,16 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
60599
60479
  const lineItems = lines[i];
60600
60480
  if (lineItems && lineItems.length > 0) {
60601
60481
  const preRenderedWidgets = preRenderedLines[i] ?? [];
60602
- const renderResult = renderSingleLine(lineItems, terminalWidth, widthDetectionAvailable, settings, i, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths);
60482
+ const renderResult = renderSingleLine(lineItems, terminalWidth, settings, i, globalSeparatorIndex, preRenderedWidgets, preCalculatedMaxWidths);
60603
60483
  result.push(renderResult.line);
60604
60484
  if (renderResult.wasTruncated) {
60605
60485
  truncated = true;
60606
60486
  }
60607
- const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
60608
- if (nonMergedWidgets.length > 1) {
60609
- globalSeparatorIndex += nonMergedWidgets.length - 1;
60610
- }
60487
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
60611
60488
  }
60612
60489
  }
60613
60490
  return { renderedLines: result, anyTruncated: truncated };
60614
- }, [lines, terminalWidth, widthDetectionAvailable, settings]);
60491
+ }, [lines, terminalWidth, settings]);
60615
60492
  import_react43.default.useEffect(() => {
60616
60493
  onTruncationChange?.(anyTruncated);
60617
60494
  }, [anyTruncated, onTruncationChange]);
@@ -60646,6 +60523,59 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
60646
60523
  };
60647
60524
  // src/tui/components/TerminalOptionsMenu.tsx
60648
60525
  var import_react44 = __toESM(require_react(), 1);
60526
+
60527
+ // src/utils/color-sanitize.ts
60528
+ function isCustomColor(value) {
60529
+ if (!value) {
60530
+ return false;
60531
+ }
60532
+ return value.startsWith("ansi256:") || value.startsWith("hex:");
60533
+ }
60534
+ function isIncompatibleForLevel(value, nextLevel) {
60535
+ if (!isCustomColor(value)) {
60536
+ return false;
60537
+ }
60538
+ if (nextLevel === 2) {
60539
+ return Boolean(value?.startsWith("hex:"));
60540
+ }
60541
+ if (nextLevel === 3) {
60542
+ return Boolean(value?.startsWith("ansi256:"));
60543
+ }
60544
+ return true;
60545
+ }
60546
+ function resetWidgetForegroundToDefault(widget, nextWidget) {
60547
+ if (widget.type === "separator" || widget.type === "flex-separator") {
60548
+ return nextWidget;
60549
+ }
60550
+ const widgetImpl = getWidget(widget.type);
60551
+ if (!widgetImpl) {
60552
+ return nextWidget;
60553
+ }
60554
+ return {
60555
+ ...nextWidget,
60556
+ color: widgetImpl.getDefaultColor()
60557
+ };
60558
+ }
60559
+ function hasCustomWidgetColors(lines) {
60560
+ return lines.some((line) => line.some((widget) => isCustomColor(widget.color) || isCustomColor(widget.backgroundColor)));
60561
+ }
60562
+ function sanitizeLinesForColorLevel(lines, nextLevel) {
60563
+ return lines.map((line) => line.map((widget) => {
60564
+ let nextWidget = { ...widget };
60565
+ if (isIncompatibleForLevel(widget.color, nextLevel)) {
60566
+ nextWidget = resetWidgetForegroundToDefault(widget, nextWidget);
60567
+ }
60568
+ if (isIncompatibleForLevel(widget.backgroundColor, nextLevel)) {
60569
+ nextWidget = {
60570
+ ...nextWidget,
60571
+ backgroundColor: undefined
60572
+ };
60573
+ }
60574
+ return nextWidget;
60575
+ }));
60576
+ }
60577
+
60578
+ // src/tui/components/TerminalOptionsMenu.tsx
60649
60579
  var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
60650
60580
  var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60651
60581
  const [showColorWarning, setShowColorWarning] = import_react44.useState(false);
@@ -60657,7 +60587,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60657
60587
  } else if (selectedIndex === 0) {
60658
60588
  onBack("width");
60659
60589
  } else if (selectedIndex === 1) {
60660
- 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:")))));
60590
+ const hasCustomColors = hasCustomWidgetColors(settings.lines);
60661
60591
  const currentLevel = settings.colorLevel;
60662
60592
  const nextLevel = (currentLevel + 1) % 4;
60663
60593
  if (hasCustomColors && (currentLevel === 2 && nextLevel !== 2 || currentLevel === 3 && nextLevel !== 3)) {
@@ -60665,47 +60595,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60665
60595
  setPendingColorLevel(nextLevel);
60666
60596
  } else {
60667
60597
  source_default.level = nextLevel;
60668
- const cleanedLines = settings.lines.map((line) => line.map((widget) => {
60669
- const newWidget = { ...widget };
60670
- if (nextLevel === 2) {
60671
- if (widget.color?.startsWith("hex:")) {
60672
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60673
- const widgetImpl = getWidget(widget.type);
60674
- if (widgetImpl) {
60675
- newWidget.color = widgetImpl.getDefaultColor();
60676
- }
60677
- }
60678
- }
60679
- if (widget.backgroundColor?.startsWith("hex:")) {
60680
- newWidget.backgroundColor = undefined;
60681
- }
60682
- } else if (nextLevel === 3) {
60683
- if (widget.color?.startsWith("ansi256:")) {
60684
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60685
- const widgetImpl = getWidget(widget.type);
60686
- if (widgetImpl) {
60687
- newWidget.color = widgetImpl.getDefaultColor();
60688
- }
60689
- }
60690
- }
60691
- if (widget.backgroundColor?.startsWith("ansi256:")) {
60692
- newWidget.backgroundColor = undefined;
60693
- }
60694
- } else {
60695
- if (widget.color?.startsWith("ansi256:") || widget.color?.startsWith("hex:")) {
60696
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60697
- const widgetImpl = getWidget(widget.type);
60698
- if (widgetImpl) {
60699
- newWidget.color = widgetImpl.getDefaultColor();
60700
- }
60701
- }
60702
- }
60703
- if (widget.backgroundColor?.startsWith("ansi256:") || widget.backgroundColor?.startsWith("hex:")) {
60704
- newWidget.backgroundColor = undefined;
60705
- }
60706
- }
60707
- return newWidget;
60708
- }));
60598
+ const cleanedLines = sanitizeLinesForColorLevel(settings.lines, nextLevel);
60709
60599
  onUpdate({
60710
60600
  ...settings,
60711
60601
  lines: cleanedLines,
@@ -60717,23 +60607,7 @@ var TerminalOptionsMenu = ({ settings, onUpdate, onBack }) => {
60717
60607
  const handleColorConfirm = () => {
60718
60608
  if (pendingColorLevel !== null) {
60719
60609
  source_default.level = pendingColorLevel;
60720
- const cleanedLines = settings.lines.map((line) => line.map((widget) => {
60721
- const newWidget = { ...widget };
60722
- 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:"))) {
60723
- if (widget.color?.startsWith("ansi256:") || widget.color?.startsWith("hex:")) {
60724
- if (widget.type !== "separator" && widget.type !== "flex-separator") {
60725
- const widgetImpl = getWidget(widget.type);
60726
- if (widgetImpl) {
60727
- newWidget.color = widgetImpl.getDefaultColor();
60728
- }
60729
- }
60730
- }
60731
- if (widget.backgroundColor?.startsWith("ansi256:") || widget.backgroundColor?.startsWith("hex:")) {
60732
- newWidget.backgroundColor = undefined;
60733
- }
60734
- }
60735
- return newWidget;
60736
- }));
60610
+ const cleanedLines = sanitizeLinesForColorLevel(settings.lines, pendingColorLevel);
60737
60611
  onUpdate({
60738
60612
  ...settings,
60739
60613
  lines: cleanedLines,
@@ -61095,7 +60969,7 @@ var App2 = () => {
61095
60969
  loadSettings().then((loadedSettings) => {
61096
60970
  source_default.level = loadedSettings.colorLevel;
61097
60971
  setSettings(loadedSettings);
61098
- setOriginalSettings(JSON.parse(JSON.stringify(loadedSettings)));
60972
+ setOriginalSettings(cloneSettings(loadedSettings));
61099
60973
  });
61100
60974
  isInstalled().then(setIsClaudeInstalled);
61101
60975
  const fontStatus = checkPowerlineFonts();
@@ -61134,7 +61008,7 @@ var App2 = () => {
61134
61008
  if (key.ctrl && input === "s" && settings) {
61135
61009
  (async () => {
61136
61010
  await saveSettings(settings);
61137
- setOriginalSettings(JSON.parse(JSON.stringify(settings)));
61011
+ setOriginalSettings(cloneSettings(settings));
61138
61012
  setHasChanges(false);
61139
61013
  setFlashMessage({
61140
61014
  text: "✓ Configuration saved",
@@ -61247,7 +61121,7 @@ ${GITHUB_REPO_URL}`,
61247
61121
  break;
61248
61122
  case "save":
61249
61123
  await saveSettings(settings);
61250
- setOriginalSettings(JSON.parse(JSON.stringify(settings)));
61124
+ setOriginalSettings(cloneSettings(settings));
61251
61125
  setHasChanges(false);
61252
61126
  exit();
61253
61127
  break;
@@ -61313,7 +61187,7 @@ ${GITHUB_REPO_URL}`,
61313
61187
  install: 5,
61314
61188
  starGithub: hasChanges ? 8 : 7
61315
61189
  };
61316
- setMenuSelections({ ...menuSelections, main: menuMap[value] ?? 0 });
61190
+ setMenuSelections((prev) => ({ ...prev, main: menuMap[value] ?? 0 }));
61317
61191
  }
61318
61192
  handleMainMenuSelect(value);
61319
61193
  },
@@ -61327,12 +61201,12 @@ ${GITHUB_REPO_URL}`,
61327
61201
  screen === "lines" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(LineSelector, {
61328
61202
  lines: settings.lines,
61329
61203
  onSelect: (line) => {
61330
- setMenuSelections({ ...menuSelections, lines: line });
61204
+ setMenuSelections((prev) => ({ ...prev, lines: line }));
61331
61205
  handleLineSelect(line);
61332
61206
  },
61333
61207
  onLinesUpdate: updateLines,
61334
61208
  onBack: () => {
61335
- setMenuSelections({ ...menuSelections, main: 0 });
61209
+ setMenuSelections((prev) => ({ ...prev, main: 0 }));
61336
61210
  setScreen("main");
61337
61211
  },
61338
61212
  initialSelection: menuSelections.lines,
@@ -61345,7 +61219,7 @@ ${GITHUB_REPO_URL}`,
61345
61219
  updateLine(selectedLine, widgets);
61346
61220
  },
61347
61221
  onBack: () => {
61348
- setMenuSelections({ ...menuSelections, lines: selectedLine });
61222
+ setMenuSelections((prev) => ({ ...prev, lines: selectedLine }));
61349
61223
  setScreen("lines");
61350
61224
  },
61351
61225
  lineNumber: selectedLine + 1,
@@ -61355,12 +61229,12 @@ ${GITHUB_REPO_URL}`,
61355
61229
  lines: settings.lines,
61356
61230
  onLinesUpdate: updateLines,
61357
61231
  onSelect: (line) => {
61358
- setMenuSelections({ ...menuSelections, lines: line });
61232
+ setMenuSelections((prev) => ({ ...prev, lines: line }));
61359
61233
  setSelectedLine(line);
61360
61234
  setScreen("colors");
61361
61235
  },
61362
61236
  onBack: () => {
61363
- setMenuSelections({ ...menuSelections, main: 1 });
61237
+ setMenuSelections((prev) => ({ ...prev, main: 1 }));
61364
61238
  setScreen("main");
61365
61239
  },
61366
61240
  initialSelection: menuSelections.lines,
@@ -61391,7 +61265,7 @@ ${GITHUB_REPO_URL}`,
61391
61265
  if (target === "width") {
61392
61266
  setScreen("terminalWidth");
61393
61267
  } else {
61394
- setMenuSelections({ ...menuSelections, main: 3 });
61268
+ setMenuSelections((prev) => ({ ...prev, main: 3 }));
61395
61269
  setScreen("main");
61396
61270
  }
61397
61271
  }
@@ -61411,7 +61285,7 @@ ${GITHUB_REPO_URL}`,
61411
61285
  setSettings(updatedSettings);
61412
61286
  },
61413
61287
  onBack: () => {
61414
- setMenuSelections({ ...menuSelections, main: 4 });
61288
+ setMenuSelections((prev) => ({ ...prev, main: 4 }));
61415
61289
  setScreen("main");
61416
61290
  }
61417
61291
  }, undefined, false, undefined, this),
@@ -61469,6 +61343,17 @@ function runTUI() {
61469
61343
  render_default(/* @__PURE__ */ jsx_dev_runtime18.jsxDEV(App2, {}, undefined, false, undefined, this));
61470
61344
  }
61471
61345
  // src/types/StatusJSON.ts
61346
+ var CoercedNumberSchema = exports_external.preprocess((value) => {
61347
+ if (typeof value !== "string") {
61348
+ return value;
61349
+ }
61350
+ const trimmed = value.trim();
61351
+ if (trimmed.length === 0) {
61352
+ return value;
61353
+ }
61354
+ const parsed = Number(trimmed);
61355
+ return Number.isFinite(parsed) ? parsed : value;
61356
+ }, exports_external.number());
61472
61357
  var StatusJSONSchema = exports_external.looseObject({
61473
61358
  hook_event_name: exports_external.string().optional(),
61474
61359
  session_id: exports_external.string().optional(),
@@ -61488,27 +61373,27 @@ var StatusJSONSchema = exports_external.looseObject({
61488
61373
  version: exports_external.string().optional(),
61489
61374
  output_style: exports_external.object({ name: exports_external.string().optional() }).optional(),
61490
61375
  cost: exports_external.object({
61491
- total_cost_usd: exports_external.number().optional(),
61492
- total_duration_ms: exports_external.number().optional(),
61493
- total_api_duration_ms: exports_external.number().optional(),
61494
- total_lines_added: exports_external.number().optional(),
61495
- total_lines_removed: exports_external.number().optional()
61376
+ total_cost_usd: CoercedNumberSchema.optional(),
61377
+ total_duration_ms: CoercedNumberSchema.optional(),
61378
+ total_api_duration_ms: CoercedNumberSchema.optional(),
61379
+ total_lines_added: CoercedNumberSchema.optional(),
61380
+ total_lines_removed: CoercedNumberSchema.optional()
61496
61381
  }).optional(),
61497
61382
  context_window: exports_external.object({
61498
- context_window_size: exports_external.number().nullable().optional(),
61499
- total_input_tokens: exports_external.number().nullable().optional(),
61500
- total_output_tokens: exports_external.number().nullable().optional(),
61383
+ context_window_size: CoercedNumberSchema.nullable().optional(),
61384
+ total_input_tokens: CoercedNumberSchema.nullable().optional(),
61385
+ total_output_tokens: CoercedNumberSchema.nullable().optional(),
61501
61386
  current_usage: exports_external.union([
61502
- exports_external.number(),
61387
+ CoercedNumberSchema,
61503
61388
  exports_external.object({
61504
- input_tokens: exports_external.number().optional(),
61505
- output_tokens: exports_external.number().optional(),
61506
- cache_creation_input_tokens: exports_external.number().optional(),
61507
- cache_read_input_tokens: exports_external.number().optional()
61389
+ input_tokens: CoercedNumberSchema.optional(),
61390
+ output_tokens: CoercedNumberSchema.optional(),
61391
+ cache_creation_input_tokens: CoercedNumberSchema.optional(),
61392
+ cache_read_input_tokens: CoercedNumberSchema.optional()
61508
61393
  })
61509
61394
  ]).nullable().optional(),
61510
- used_percentage: exports_external.number().nullable().optional(),
61511
- remaining_percentage: exports_external.number().nullable().optional()
61395
+ used_percentage: CoercedNumberSchema.nullable().optional(),
61396
+ remaining_percentage: CoercedNumberSchema.nullable().optional()
61512
61397
  }).nullable().optional()
61513
61398
  });
61514
61399
 
@@ -61579,12 +61464,10 @@ async function renderMultipleLines(data) {
61579
61464
  const line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
61580
61465
  const strippedLine = getVisibleText(line).trim();
61581
61466
  if (strippedLine.length > 0) {
61582
- const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
61583
- if (nonMergedWidgets.length > 1)
61584
- globalSeparatorIndex += nonMergedWidgets.length - 1;
61585
61467
  let outputLine = line.replace(/ /g, " ");
61586
61468
  outputLine = "\x1B[0m" + outputLine;
61587
61469
  console.log(outputLine);
61470
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
61588
61471
  }
61589
61472
  }
61590
61473
  }