ccstatusline 2.2.21 → 2.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,14 @@
47
47
 
48
48
  ## 🆕 Recent Updates
49
49
 
50
+ ### v2.2.22 - Powerline flex mode, dim styling, safer config, and polish
51
+
52
+ ![Powerline Flex Mode](https://raw.githubusercontent.com/sirmalloc/ccstatusline/main/screenshots/powerline-flex.png)
53
+
54
+ - **⚡ Powerline flex mode** - Flex separators now work in Powerline mode, letting Powerline status lines right-align content or absorb available width.
55
+ - **🌗 Per-widget dim styling** - The color editor can dim an entire widget or only parenthesized text, with reset and clear-all actions covering dim state.
56
+ - **🧯 Safer settings recovery** - Invalid `settings.json` files are left untouched, defaults render in memory, and the status line shows an invalid-config warning.
57
+
50
58
  ### v2.2.21 - Cache widgets, compaction details, extra usage currency, and package fixes
51
59
 
52
60
  - **🔣 Custom widget glyphs** - Git and JJ symbol widgets can override or suppress their built-in glyphs from the TUI.
@@ -100,7 +108,7 @@
100
108
  - **🧮 Git file status widgets** - Added `Git Staged Files`, `Git Unstaged Files`, `Git Untracked Files`, and `Git Clean Status` for file counts and clean/dirty state.
101
109
  - **🏷️ Clear context percentage labels** - `Context %` and `Context % (usable)` now label rendered values as used or left when toggling used/remaining mode.
102
110
  - **⚡ More Powerline caps** - The Powerline separator editor now supports more than three start/end caps.
103
- - **🧠 Thinking Effort updates** - Added `xhigh`, show `default` when no effort is set, mark unknown future effort levels with `?`, and track live status JSON plus `/effort` command changes.
111
+ - **🧠 Thinking Effort updates** - Added `xhigh`, show `default` when no effort is set, mark unknown future effort levels with `?`, and track live status JSON plus `/effort` command changes. Claude Code reports Ultracode as `xhigh` in status line data.
104
112
  - **🧮 More accurate token counts** - Streaming duplicate JSONL entries are deduped so token widgets do not overcount live Claude Code output.
105
113
  - **🏷️ Cleaner model display** - The Model widget strips trailing context suffixes like `(1M context)`; use `Context Window` when you want the total window size shown.
106
114
  - **🧹 Cleaner empty-widget separators** - Manual separators now collapse around widgets that render empty, avoiding dangling separators when hide-when-empty widgets disappear.
@@ -52986,6 +52986,7 @@ var init_Widget = __esm(() => {
52986
52986
  color: exports_external.string().optional(),
52987
52987
  backgroundColor: exports_external.string().optional(),
52988
52988
  bold: exports_external.boolean().optional(),
52989
+ dim: exports_external.union([exports_external.boolean(), exports_external.literal("parens")]).optional(),
52989
52990
  character: exports_external.string().optional(),
52990
52991
  rawValue: exports_external.boolean().optional(),
52991
52992
  customText: exports_external.string().optional(),
@@ -57351,14 +57352,24 @@ function getChalkColor(colorName, colorLevel = "ansi16", isBackground = false) {
57351
57352
  return colorEntry.ansi16;
57352
57353
  }
57353
57354
  }
57354
- function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel = "ansi16") {
57355
- if (!foregroundColor && !backgroundColor && !bold) {
57356
- return text;
57355
+ function applyParensDim(text, bold) {
57356
+ const intensityReset = bold ? "\x1B[22;1m" : "\x1B[22m";
57357
+ return text.replace(/\([^()]*\)/g, (span) => `\x1B[2m${span}${intensityReset}`);
57358
+ }
57359
+ function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel = "ansi16", dim) {
57360
+ const styledText = dim === "parens" ? applyParensDim(text, bold) : text;
57361
+ if (!foregroundColor && !backgroundColor && !bold && dim !== true) {
57362
+ return styledText;
57357
57363
  }
57358
57364
  let prefix = "";
57359
57365
  let suffix = "";
57360
57366
  if (bold) {
57361
57367
  prefix += "\x1B[1m";
57368
+ }
57369
+ if (dim === true) {
57370
+ prefix += "\x1B[2m";
57371
+ }
57372
+ if (bold || dim === true) {
57362
57373
  suffix = "\x1B[22m" + suffix;
57363
57374
  }
57364
57375
  if (backgroundColor) {
@@ -57371,7 +57382,7 @@ function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel =
57371
57382
  if (foregroundColor) {
57372
57383
  const gradientStops = parseGradientSpec(foregroundColor);
57373
57384
  if (gradientStops && colorLevel !== "ansi16") {
57374
- return prefix + applyGradientToText(text, gradientStops, colorLevel) + "\x1B[39m" + suffix;
57385
+ return prefix + applyGradientToText(styledText, gradientStops, colorLevel) + "\x1B[39m" + suffix;
57375
57386
  }
57376
57387
  const fgCode = getColorAnsiCode(foregroundColor, colorLevel, false);
57377
57388
  if (fgCode) {
@@ -57379,7 +57390,7 @@ function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel =
57379
57390
  suffix = "\x1B[39m" + suffix;
57380
57391
  }
57381
57392
  }
57382
- return prefix + text + suffix;
57393
+ return prefix + styledText + suffix;
57383
57394
  }
57384
57395
  function getColorAnsiCode(colorName, colorLevel = "ansi16", isBackground = false) {
57385
57396
  if (!colorName)
@@ -57861,19 +57872,22 @@ function getTerminalWidth() {
57861
57872
  function canDetectTerminalWidth() {
57862
57873
  return probeTerminalWidth() !== null;
57863
57874
  }
57864
- var __dirname = "/home/runner/work/ccstatusline/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.21";
57875
+ var __dirname = "/home/runner/work/ccstatusline/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.22";
57865
57876
  var init_terminal = () => {};
57866
57877
 
57867
57878
  // src/utils/format-tokens.ts
57868
- function formatTokens(count) {
57869
- if (count >= 999950)
57879
+ function formatTokens(count, decimals = 1) {
57880
+ if (count >= 1e6 - 500 / 10 ** decimals)
57870
57881
  return `${(count / 1e6).toFixed(1)}M`;
57871
57882
  if (count >= 1000)
57872
- return `${(count / 1000).toFixed(1)}k`;
57883
+ return `${(count / 1000).toFixed(decimals)}k`;
57873
57884
  return count.toString();
57874
57885
  }
57875
57886
 
57876
57887
  // src/utils/renderer.ts
57888
+ function buildConfigWarningBadge(colorLevel) {
57889
+ return applyColors("⚠ invalid config", "red", undefined, false, getColorLevelString(colorLevel));
57890
+ }
57877
57891
  function maybeApplyForegroundGradient(line, settings, colorLevel) {
57878
57892
  const stops = parseGradientSpec(settings.overrideForegroundColor);
57879
57893
  return stops ? applyLineGradient(line, stops, colorLevel) : line;
@@ -57917,8 +57931,9 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57917
57931
  const startCaps = config2.startCaps ?? [];
57918
57932
  const endCaps = config2.endCaps ?? [];
57919
57933
  const capLineIndex = context.lineIndex ?? lineIndex;
57920
- const startCap = startCaps.length > 0 ? startCaps[capLineIndex % startCaps.length] : "";
57921
- const endCap = endCaps.length > 0 ? endCaps[capLineIndex % endCaps.length] : "";
57934
+ const startCapIndex = context.globalPowerlineStartCapIndex ?? capLineIndex;
57935
+ const getStartCap = (segmentOffset2) => startCaps.length > 0 ? startCaps[(startCapIndex + segmentOffset2) % startCaps.length] ?? "" : "";
57936
+ const getEndCap = (segmentOffset2) => endCaps.length > 0 ? endCaps[(startCapIndex + segmentOffset2) % endCaps.length] ?? "" : "";
57922
57937
  const themeName = config2.theme;
57923
57938
  let themeColors;
57924
57939
  if (themeName && themeName !== "custom") {
@@ -57931,13 +57946,45 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57931
57946
  }
57932
57947
  const colorLevel = getColorLevelString(settings.colorLevel);
57933
57948
  const overrideForegroundGradientStops = parseGradientSpec(settings.overrideForegroundColor);
57949
+ const isSeparatorBoundary = (widget) => widget?.type === "separator" || widget?.type === "flex-separator";
57934
57950
  const filteredWidgets = widgets.filter((widget) => widget.type !== "separator" && widget.type !== "flex-separator");
57951
+ const FLEX_SENTINEL = "\x01FLEX_SEP\x01";
57935
57952
  if (filteredWidgets.length === 0)
57936
57953
  return "";
57937
57954
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
57938
57955
  const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
57939
57956
  const widgetElements = [];
57940
57957
  let widgetColorIndex = continueThemeAcrossLines ? globalThemeColorOffset : 0;
57958
+ const hasNextRenderedWidgetBeforeSeparator = (originalIndex) => {
57959
+ for (let j = originalIndex + 1;j < widgets.length; j++) {
57960
+ const nextWidget = widgets[j];
57961
+ if (!nextWidget)
57962
+ continue;
57963
+ if (isSeparatorBoundary(nextWidget))
57964
+ return false;
57965
+ if (preRenderedWidgets[j]?.content)
57966
+ return true;
57967
+ }
57968
+ return false;
57969
+ };
57970
+ const canMergeWithNextRenderedWidget = (originalIndex) => {
57971
+ if (originalIndex === undefined)
57972
+ return false;
57973
+ const widget = widgets[originalIndex];
57974
+ return Boolean(widget?.merge && hasNextRenderedWidgetBeforeSeparator(originalIndex));
57975
+ };
57976
+ const findPreviousRenderedWidgetIndexBeforeSeparator = (originalIndex) => {
57977
+ for (let j = originalIndex - 1;j >= 0; j--) {
57978
+ const previousWidget = widgets[j];
57979
+ if (!previousWidget)
57980
+ continue;
57981
+ if (isSeparatorBoundary(previousWidget))
57982
+ return null;
57983
+ if (preRenderedWidgets[j]?.content)
57984
+ return j;
57985
+ }
57986
+ return null;
57987
+ };
57941
57988
  const preRenderedIndices = [];
57942
57989
  for (let i = 0;i < widgets.length; i++) {
57943
57990
  const widget = widgets[i];
@@ -57968,10 +58015,11 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57968
58015
  if (settings.overrideForegroundColor && settings.overrideForegroundColor !== "none" && widget.type === "custom-command" && widget.preserveColors) {
57969
58016
  widgetText = stripSgrCodes(widgetText);
57970
58017
  }
57971
- const prevItem = i > 0 ? filteredWidgets[i - 1] : null;
57972
- const nextItem = i < filteredWidgets.length - 1 ? filteredWidgets[i + 1] : null;
57973
- const omitLeadingPadding = prevItem?.merge === "no-padding";
57974
- const omitTrailingPadding = widget.merge === "no-padding" && nextItem;
58018
+ const previousRenderedIndex = actualPreRenderedIndex !== undefined ? findPreviousRenderedWidgetIndexBeforeSeparator(actualPreRenderedIndex) : null;
58019
+ const previousRenderedWidget = previousRenderedIndex !== null ? widgets[previousRenderedIndex] : undefined;
58020
+ const mergesWithNext = canMergeWithNextRenderedWidget(actualPreRenderedIndex);
58021
+ const omitLeadingPadding = previousRenderedWidget?.merge === "no-padding" && canMergeWithNextRenderedWidget(previousRenderedIndex ?? undefined);
58022
+ const omitTrailingPadding = widget.merge === "no-padding" && mergesWithNext;
57975
58023
  const leadingPadding = omitLeadingPadding ? "" : padding;
57976
58024
  const trailingPadding = omitTrailingPadding ? "" : padding;
57977
58025
  const paddedText = `${leadingPadding}${widgetText}${trailingPadding}`;
@@ -57983,7 +58031,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57983
58031
  fgColor = themeColors.fg[widgetColorIndex % themeColors.fg.length] ?? fgColor;
57984
58032
  }
57985
58033
  bgColor = themeColors.bg[widgetColorIndex % themeColors.bg.length] ?? bgColor;
57986
- if (!widget.merge) {
58034
+ if (!mergesWithNext) {
57987
58035
  widgetColorIndex++;
57988
58036
  }
57989
58037
  }
@@ -57994,12 +58042,56 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57994
58042
  content: paddedText,
57995
58043
  bgColor: bgColor ?? undefined,
57996
58044
  fgColor,
58045
+ mergesWithNext,
58046
+ originalIndex: actualPreRenderedIndex ?? -1,
57997
58047
  widget
57998
58048
  });
57999
58049
  }
58000
58050
  }
58001
58051
  if (widgetElements.length === 0)
58002
58052
  return "";
58053
+ const renderedElementIndexByOriginalIndex = new Map;
58054
+ widgetElements.forEach((element, index) => {
58055
+ renderedElementIndexByOriginalIndex.set(element.originalIndex, index);
58056
+ });
58057
+ const flexAfterIndex = new Map;
58058
+ const startCapBeforeIndex = new Map;
58059
+ const segmentOffsetByRenderedIndex = new Map;
58060
+ let leadingFlexCount = 0;
58061
+ let totalFlexCount = 0;
58062
+ let lastRenderedIndex = null;
58063
+ let pendingFlexCount = 0;
58064
+ let segmentOffset = 0;
58065
+ let hasRenderedSegment = false;
58066
+ for (let i = 0;i < widgets.length; i++) {
58067
+ const widget = widgets[i];
58068
+ if (!widget || widget.type === "separator")
58069
+ continue;
58070
+ if (widget.type === "flex-separator") {
58071
+ totalFlexCount++;
58072
+ if (lastRenderedIndex === null) {
58073
+ leadingFlexCount++;
58074
+ } else {
58075
+ pendingFlexCount++;
58076
+ flexAfterIndex.set(lastRenderedIndex, (flexAfterIndex.get(lastRenderedIndex) ?? 0) + 1);
58077
+ }
58078
+ continue;
58079
+ }
58080
+ const renderedIndex = renderedElementIndexByOriginalIndex.get(i);
58081
+ if (renderedIndex !== undefined) {
58082
+ if (!hasRenderedSegment) {
58083
+ startCapBeforeIndex.set(renderedIndex, segmentOffset);
58084
+ pendingFlexCount = 0;
58085
+ hasRenderedSegment = true;
58086
+ } else if (pendingFlexCount > 0) {
58087
+ segmentOffset++;
58088
+ startCapBeforeIndex.set(renderedIndex, segmentOffset);
58089
+ pendingFlexCount = 0;
58090
+ }
58091
+ segmentOffsetByRenderedIndex.set(renderedIndex, segmentOffset);
58092
+ lastRenderedIndex = renderedIndex;
58093
+ }
58094
+ }
58003
58095
  const autoAlign = config2.autoAlign;
58004
58096
  if (autoAlign) {
58005
58097
  let alignmentPos = 0;
@@ -58008,13 +58100,13 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
58008
58100
  if (!element)
58009
58101
  continue;
58010
58102
  const prevWidget = i > 0 ? widgetElements[i - 1] : null;
58011
- const isPreviousMerged = prevWidget?.widget.merge;
58103
+ const isPreviousMerged = prevWidget?.mergesWithNext;
58012
58104
  if (!isPreviousMerged) {
58013
58105
  const maxWidth = preCalculatedMaxWidths[alignmentPos];
58014
58106
  if (maxWidth !== undefined) {
58015
58107
  let combinedLength = getVisibleWidth(element.content);
58016
58108
  let j = i;
58017
- while (j < widgetElements.length - 1 && widgetElements[j]?.widget.merge) {
58109
+ while (j < widgetElements.length - 1 && widgetElements[j]?.mergesWithNext) {
58018
58110
  j++;
58019
58111
  const nextElement = widgetElements[j];
58020
58112
  if (nextElement) {
@@ -58040,29 +58132,45 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
58040
58132
  }, 0) : 0;
58041
58133
  let powerlineGradientColumn = 0;
58042
58134
  let result2 = "";
58043
- if (startCap && widgetElements.length > 0) {
58044
- const firstWidget = widgetElements[0];
58045
- if (firstWidget?.bgColor) {
58046
- const capFg = bgToFg(firstWidget.bgColor);
58047
- const fgCode = getColorAnsiCode(capFg, colorLevel, false);
58048
- result2 += fgCode + startCap + "\x1B[39m";
58049
- } else {
58050
- result2 += startCap;
58051
- }
58135
+ if (leadingFlexCount > 0) {
58136
+ result2 += FLEX_SENTINEL.repeat(leadingFlexCount);
58052
58137
  }
58138
+ let localSeparatorIndex = 0;
58053
58139
  for (let i = 0;i < widgetElements.length; i++) {
58054
58140
  const widget = widgetElements[i];
58055
58141
  const nextWidget = widgetElements[i + 1];
58056
58142
  if (!widget)
58057
58143
  continue;
58058
58144
  const shouldBold = settings.globalBold || widget.widget.bold;
58059
- const needsSeparator = i < widgetElements.length - 1 && separators.length > 0 && nextWidget && !widget.widget.merge;
58145
+ const shouldDim = widget.widget.dim === true;
58146
+ const needsSeparator = i < widgetElements.length - 1 && separators.length > 0 && nextWidget !== undefined && !widget.mergesWithNext;
58147
+ const flexCountAfter = flexAfterIndex.get(i) ?? 0;
58148
+ const currentSegmentOffset = segmentOffsetByRenderedIndex.get(i) ?? 0;
58149
+ const isLastWidget = i === widgetElements.length - 1;
58150
+ const hasEndCapAfterWidget = Boolean(getEndCap(currentSegmentOffset)) && (flexCountAfter > 0 || isLastWidget);
58151
+ const startCapSegmentOffset = startCapBeforeIndex.get(i);
58152
+ if (startCapSegmentOffset !== undefined) {
58153
+ const segmentStartCap = getStartCap(startCapSegmentOffset);
58154
+ if (segmentStartCap) {
58155
+ if (widget.bgColor) {
58156
+ const capFg = bgToFg(widget.bgColor);
58157
+ const fgCode = getColorAnsiCode(capFg, colorLevel, false);
58158
+ result2 += fgCode + segmentStartCap + "\x1B[39m";
58159
+ } else {
58160
+ result2 += segmentStartCap;
58161
+ }
58162
+ }
58163
+ }
58060
58164
  let widgetContent = "";
58061
58165
  const isPreserveColors = widget.widget.type === "custom-command" && widget.widget.preserveColors;
58062
58166
  if (shouldBold && !isPreserveColors) {
58063
58167
  widgetContent += "\x1B[1m";
58064
58168
  }
58169
+ if (shouldDim && !isPreserveColors) {
58170
+ widgetContent += "\x1B[2m";
58171
+ }
58065
58172
  const textGradientStops = !isPreserveColors && powerlineGradientWidth > 1 ? overrideForegroundGradientStops : null;
58173
+ const styledContent = widget.widget.dim === "parens" && !isPreserveColors ? applyParensDim(widget.content, shouldBold) : widget.content;
58066
58174
  if (widget.fgColor && !isPreserveColors && !textGradientStops) {
58067
58175
  widgetContent += getColorAnsiCode(widget.fgColor, colorLevel, false);
58068
58176
  }
@@ -58070,26 +58178,44 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
58070
58178
  widgetContent += getColorAnsiCode(widget.bgColor, colorLevel, true);
58071
58179
  }
58072
58180
  if (textGradientStops) {
58073
- const gradientResult = applyLineGradientSegment(widget.content, textGradientStops, colorLevel, powerlineGradientColumn, powerlineGradientWidth);
58181
+ const gradientResult = applyLineGradientSegment(styledContent, textGradientStops, colorLevel, powerlineGradientColumn, powerlineGradientWidth);
58074
58182
  widgetContent += gradientResult.text;
58075
58183
  powerlineGradientColumn = gradientResult.nextColumn;
58076
58184
  } else {
58077
- widgetContent += widget.content;
58185
+ widgetContent += styledContent;
58078
58186
  }
58079
58187
  if (isPreserveColors) {
58080
58188
  widgetContent += "\x1B[0m";
58081
58189
  } else {
58082
58190
  widgetContent += "\x1B[49m\x1B[39m";
58083
- const isLastWidget = i === widgetElements.length - 1;
58084
- const hasEndCap = endCaps.length > 0 && endCaps[capLineIndex % endCaps.length];
58085
- if (shouldBold && !needsSeparator && !(isLastWidget && hasEndCap)) {
58191
+ const shouldRestoreBoldForBoundary = shouldDim && shouldBold && (needsSeparator || hasEndCapAfterWidget);
58192
+ if (shouldRestoreBoldForBoundary) {
58193
+ widgetContent += "\x1B[22;1m";
58194
+ } else if (shouldDim || shouldBold && !needsSeparator && !hasEndCapAfterWidget) {
58086
58195
  widgetContent += "\x1B[22m";
58087
58196
  }
58088
58197
  }
58089
58198
  result2 += widgetContent;
58199
+ if (flexCountAfter > 0) {
58200
+ const segmentEndCap = getEndCap(currentSegmentOffset);
58201
+ if (segmentEndCap) {
58202
+ if (widget.bgColor) {
58203
+ const capFg = bgToFg(widget.bgColor);
58204
+ const fgCode = getColorAnsiCode(capFg, colorLevel, false);
58205
+ result2 += fgCode + segmentEndCap + "\x1B[39m";
58206
+ } else {
58207
+ result2 += segmentEndCap;
58208
+ }
58209
+ }
58210
+ if (shouldBold) {
58211
+ result2 += "\x1B[22m";
58212
+ }
58213
+ result2 += FLEX_SENTINEL.repeat(flexCountAfter);
58214
+ continue;
58215
+ }
58090
58216
  if (needsSeparator) {
58091
- const globalIndex = globalSeparatorOffset + i;
58092
- const separatorIndex = Math.min(globalIndex, separators.length - 1);
58217
+ const globalIndex = globalSeparatorOffset + localSeparatorIndex;
58218
+ const separatorIndex = globalIndex % separators.length;
58093
58219
  const separator = separators[separatorIndex] ?? "";
58094
58220
  const shouldInvert = invertBgs[separatorIndex] ?? false;
58095
58221
  let separatorOutput;
@@ -58144,23 +58270,49 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
58144
58270
  }
58145
58271
  }
58146
58272
  result2 += separatorOutput;
58147
- if (shouldBold) {
58273
+ if (shouldBold || shouldDim) {
58148
58274
  result2 += "\x1B[22m";
58149
58275
  }
58276
+ localSeparatorIndex++;
58150
58277
  }
58151
58278
  }
58152
- if (endCap && widgetElements.length > 0) {
58153
- const lastWidget = widgetElements[widgetElements.length - 1];
58154
- if (lastWidget?.bgColor) {
58155
- const capFg = bgToFg(lastWidget.bgColor);
58156
- const fgCode = getColorAnsiCode(capFg, colorLevel, false);
58157
- result2 += fgCode + endCap + "\x1B[39m";
58158
- } else {
58159
- result2 += endCap;
58160
- }
58279
+ if (widgetElements.length > 0) {
58280
+ const lastWidgetIndex = widgetElements.length - 1;
58281
+ const lastWidget = widgetElements[lastWidgetIndex];
58161
58282
  const lastWidgetBold = settings.globalBold || lastWidget?.widget.bold;
58162
- if (lastWidgetBold) {
58163
- result2 += "\x1B[22m";
58283
+ const lastWidgetDim = lastWidget?.widget.dim === true;
58284
+ const lastSegmentOffset = segmentOffsetByRenderedIndex.get(lastWidgetIndex) ?? 0;
58285
+ const lastWidgetHasFlexAfter = (flexAfterIndex.get(lastWidgetIndex) ?? 0) > 0;
58286
+ const segmentEndCap = getEndCap(lastSegmentOffset);
58287
+ if (segmentEndCap && !lastWidgetHasFlexAfter) {
58288
+ if (lastWidget?.bgColor) {
58289
+ const capFg = bgToFg(lastWidget.bgColor);
58290
+ const fgCode = getColorAnsiCode(capFg, colorLevel, false);
58291
+ result2 += fgCode + segmentEndCap + "\x1B[39m";
58292
+ } else {
58293
+ result2 += segmentEndCap;
58294
+ }
58295
+ if (lastWidgetBold || lastWidgetDim) {
58296
+ result2 += "\x1B[22m";
58297
+ }
58298
+ }
58299
+ }
58300
+ if (totalFlexCount > 0) {
58301
+ if (terminalWidth && terminalWidth > 0) {
58302
+ const parts = result2.split(FLEX_SENTINEL);
58303
+ const totalContentWidth = parts.reduce((sum2, p) => sum2 + getVisibleWidth(p), 0);
58304
+ const flexCount = parts.length - 1;
58305
+ const totalSpace = Math.max(0, terminalWidth - totalContentWidth);
58306
+ const spacePerFlex = flexCount > 0 ? Math.floor(totalSpace / flexCount) : 0;
58307
+ const extraSpace = flexCount > 0 ? totalSpace % flexCount : 0;
58308
+ let newResult = parts[0] ?? "";
58309
+ for (let i = 1;i < parts.length; i++) {
58310
+ const flexSize = spacePerFlex + (i - 1 < extraSpace ? 1 : 0);
58311
+ newResult += " ".repeat(flexSize) + (parts[i] ?? "");
58312
+ }
58313
+ result2 = newResult;
58314
+ } else {
58315
+ result2 = result2.split(FLEX_SENTINEL).join(" ");
58164
58316
  }
58165
58317
  }
58166
58318
  result2 += source_default.reset("");
@@ -58184,6 +58336,32 @@ function formatSeparator(sep) {
58184
58336
  }
58185
58337
  return sep;
58186
58338
  }
58339
+ function countPowerlineStartCapSlots(widgets, preRenderedWidgets) {
58340
+ let pendingFlexAfterRenderedSegment = false;
58341
+ let hasRenderedSegment = false;
58342
+ let renderedSegmentCount = 0;
58343
+ for (let i = 0;i < widgets.length; i++) {
58344
+ const widget = widgets[i];
58345
+ if (!widget || widget.type === "separator")
58346
+ continue;
58347
+ if (widget.type === "flex-separator") {
58348
+ if (hasRenderedSegment) {
58349
+ pendingFlexAfterRenderedSegment = true;
58350
+ }
58351
+ continue;
58352
+ }
58353
+ if (!preRenderedWidgets[i]?.content)
58354
+ continue;
58355
+ if (!hasRenderedSegment) {
58356
+ hasRenderedSegment = true;
58357
+ renderedSegmentCount = 1;
58358
+ } else if (pendingFlexAfterRenderedSegment) {
58359
+ renderedSegmentCount++;
58360
+ pendingFlexAfterRenderedSegment = false;
58361
+ }
58362
+ }
58363
+ return renderedSegmentCount;
58364
+ }
58187
58365
  function preRenderAllWidgets(allLinesWidgets, settings, context) {
58188
58366
  const preRenderedLines = [];
58189
58367
  for (const lineWidgets of allLinesWidgets) {
@@ -58199,6 +58377,11 @@ function preRenderAllWidgets(allLinesWidgets, settings, context) {
58199
58377
  }
58200
58378
  const widgetImpl = getWidget(widget.type);
58201
58379
  if (!widgetImpl) {
58380
+ preRenderedLine.push({
58381
+ content: "",
58382
+ plainLength: 0,
58383
+ widget
58384
+ });
58202
58385
  continue;
58203
58386
  }
58204
58387
  const effectiveWidget = context.minimalist ? { ...widget, rawValue: true } : widget;
@@ -58219,19 +58402,35 @@ function calculateMaxWidthsFromPreRendered(preRenderedLines, settings) {
58219
58402
  const defaultPadding = settings.defaultPadding ?? "";
58220
58403
  const paddingLength = defaultPadding.length;
58221
58404
  for (const preRenderedLine of preRenderedLines) {
58222
- const filteredWidgets = preRenderedLine.filter((w) => w.widget.type !== "separator" && w.widget.type !== "flex-separator" && w.content);
58405
+ const isSeparatorBoundary = (entry) => entry?.widget.type === "separator" || entry?.widget.type === "flex-separator";
58406
+ const hasNextRenderedWidgetBeforeSeparator = (originalIndex) => {
58407
+ for (let j = originalIndex + 1;j < preRenderedLine.length; j++) {
58408
+ const nextEntry = preRenderedLine[j];
58409
+ if (!nextEntry)
58410
+ continue;
58411
+ if (isSeparatorBoundary(nextEntry))
58412
+ return false;
58413
+ if (nextEntry.content)
58414
+ return true;
58415
+ }
58416
+ return false;
58417
+ };
58418
+ const renderedWidgets = preRenderedLine.map((entry, originalIndex) => ({
58419
+ ...entry,
58420
+ mergesWithNext: Boolean(entry.widget.merge && hasNextRenderedWidgetBeforeSeparator(originalIndex))
58421
+ })).filter((entry) => !isSeparatorBoundary(entry) && entry.content);
58223
58422
  let alignmentPos = 0;
58224
- for (let i = 0;i < filteredWidgets.length; i++) {
58225
- const widget = filteredWidgets[i];
58423
+ for (let i = 0;i < renderedWidgets.length; i++) {
58424
+ const widget = renderedWidgets[i];
58226
58425
  if (!widget)
58227
58426
  continue;
58228
58427
  let totalWidth = widget.plainLength + paddingLength * 2;
58229
58428
  let j = i;
58230
- while (j < filteredWidgets.length - 1 && filteredWidgets[j]?.widget.merge) {
58429
+ while (j < renderedWidgets.length - 1 && renderedWidgets[j]?.mergesWithNext) {
58231
58430
  j++;
58232
- const nextWidget = filteredWidgets[j];
58431
+ const nextWidget = renderedWidgets[j];
58233
58432
  if (nextWidget) {
58234
- if (filteredWidgets[j - 1]?.widget.merge === "no-padding") {
58433
+ if (renderedWidgets[j - 1]?.widget.merge === "no-padding") {
58235
58434
  totalWidth += nextWidget.plainLength;
58236
58435
  } else {
58237
58436
  totalWidth += nextWidget.plainLength + paddingLength * 2;
@@ -58261,7 +58460,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58261
58460
  const isPowerlineMode = Boolean(powerlineSettings?.enabled);
58262
58461
  if (isPowerlineMode)
58263
58462
  return renderPowerlineStatusLine(widgets, settings, context, context.lineIndex ?? 0, context.globalSeparatorIndex ?? 0, context.globalPowerlineThemeIndex ?? 0, preRenderedWidgets, preCalculatedMaxWidths);
58264
- const applyColorsWithOverride = (text, foregroundColor, backgroundColor, bold) => {
58463
+ const applyColorsWithOverride = (text, foregroundColor, backgroundColor, bold, dim) => {
58265
58464
  let fgColor = foregroundColor;
58266
58465
  const fgOverride = settings.overrideForegroundColor;
58267
58466
  if (fgOverride && fgOverride !== "none") {
@@ -58276,7 +58475,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58276
58475
  bgColor = settings.overrideBackgroundColor;
58277
58476
  }
58278
58477
  const shouldBold = settings.globalBold || bold;
58279
- return applyColors(text, fgColor, bgColor, shouldBold, colorLevel);
58478
+ return applyColors(text, fgColor, bgColor, shouldBold, colorLevel, dim);
58280
58479
  };
58281
58480
  const detectedWidth = context.terminalWidth ?? getTerminalWidth();
58282
58481
  const terminalWidth = resolveEffectiveTerminalWidth(detectedWidth, settings, context);
@@ -58304,6 +58503,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58304
58503
  let separatorColor = widget.color ?? "gray";
58305
58504
  let separatorBg = widget.backgroundColor;
58306
58505
  let separatorBold = widget.bold;
58506
+ let separatorDim = widget.dim;
58307
58507
  if (settings.inheritSeparatorColors && i > 0 && !widget.color && !widget.backgroundColor) {
58308
58508
  const prevWidget = widgets[i - 1];
58309
58509
  if (prevWidget && prevWidget.type !== "separator" && prevWidget.type !== "flex-separator") {
@@ -58315,9 +58515,10 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58315
58515
  separatorColor = widgetColor;
58316
58516
  separatorBg = prevWidget.backgroundColor;
58317
58517
  separatorBold = prevWidget.bold;
58518
+ separatorDim = prevWidget.dim;
58318
58519
  }
58319
58520
  }
58320
- elements.push({ content: applyColorsWithOverride(formattedSep, separatorColor, separatorBg, separatorBold), type: "separator", widget });
58521
+ elements.push({ content: applyColorsWithOverride(formattedSep, separatorColor, separatorBg, separatorBold, separatorDim), type: "separator", widget });
58321
58522
  continue;
58322
58523
  }
58323
58524
  if (widget.type === "flex-separator") {
@@ -58348,7 +58549,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58348
58549
  elements.push({ content: finalOutput, type: widget.type, widget });
58349
58550
  } else {
58350
58551
  elements.push({
58351
- content: applyColorsWithOverride(widgetText, widget.color ?? defaultColor, widget.backgroundColor, widget.bold),
58552
+ content: applyColorsWithOverride(widgetText, widget.color ?? defaultColor, widget.backgroundColor, widget.bold, widget.dim),
58352
58553
  type: widget.type,
58353
58554
  widget
58354
58555
  });
@@ -58378,7 +58579,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58378
58579
  const widgetImpl = getWidget(prevElem2.widget.type);
58379
58580
  widgetColor = widgetImpl ? widgetImpl.getDefaultColor() : "white";
58380
58581
  }
58381
- const coloredSep = applyColorsWithOverride(defaultSep, widgetColor, prevElem2.widget.backgroundColor, prevElem2.widget.bold);
58582
+ const coloredSep = applyColorsWithOverride(defaultSep, widgetColor, prevElem2.widget.backgroundColor, prevElem2.widget.bold, prevElem2.widget.dim);
58382
58583
  finalElements.push(coloredSep);
58383
58584
  } else {
58384
58585
  finalElements.push(defaultSep);
@@ -58395,7 +58596,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
58395
58596
  } else {
58396
58597
  const nextElem = index < elements.length - 1 ? elements[index + 1] : null;
58397
58598
  const omitLeadingPadding = prevElem?.widget?.merge === "no-padding";
58398
- const omitTrailingPadding = elem.widget?.merge === "no-padding" && nextElem;
58599
+ const omitTrailingPadding = elem.widget?.merge === "no-padding" && nextElem && nextElem.type !== "separator" && nextElem.type !== "flex-separator";
58399
58600
  const hasColorOverride = Boolean(settings.overrideBackgroundColor && settings.overrideBackgroundColor !== "none") || Boolean(settings.overrideForegroundColor && settings.overrideForegroundColor !== "none");
58400
58601
  if (padding && (elem.widget?.backgroundColor || hasColorOverride)) {
58401
58602
  const leadingPadding = omitLeadingPadding ? "" : applyColorsWithOverride(padding, undefined, elem.widget?.backgroundColor);
@@ -68227,15 +68428,15 @@ class ContextBarWidget {
68227
68428
  }
68228
68429
  const percent = used / total * 100;
68229
68430
  const clampedPercent = Math.max(0, Math.min(100, percent));
68230
- const usedK = Math.round(used / 1000);
68231
- const totalK = Math.round(total / 1000);
68431
+ const usedDisplay = formatTokens(used, 0);
68432
+ const totalDisplay = formatTokens(total, 0);
68232
68433
  if (isBarSliderMode(displayMode)) {
68233
68434
  const slider = makeSliderBar(clampedPercent);
68234
- const sliderDisplay = displayMode === "slider" ? `${slider} ${usedK}k/${totalK}k (${Math.round(clampedPercent)}%)` : slider;
68435
+ const sliderDisplay = displayMode === "slider" ? `${slider} ${usedDisplay}/${totalDisplay} (${Math.round(clampedPercent)}%)` : slider;
68235
68436
  return item.rawValue ? sliderDisplay : `Context: ${sliderDisplay}`;
68236
68437
  }
68237
68438
  const barWidth = displayMode === "progress" ? 32 : 16;
68238
- const display = `${makeUsageProgressBar(clampedPercent, barWidth)} ${usedK}k/${totalK}k (${Math.round(clampedPercent)}%)`;
68439
+ const display = `${makeUsageProgressBar(clampedPercent, barWidth)} ${usedDisplay}/${totalDisplay} (${Math.round(clampedPercent)}%)`;
68239
68440
  return item.rawValue ? display : `Context: ${display}`;
68240
68441
  }
68241
68442
  getCustomKeybinds() {
@@ -68252,7 +68453,10 @@ class ContextBarWidget {
68252
68453
  }
68253
68454
  var init_ContextBar = __esm(async () => {
68254
68455
  init_usage_display();
68255
- await init_usage();
68456
+ await __promiseAll([
68457
+ init_renderer2(),
68458
+ init_usage()
68459
+ ]);
68256
68460
  });
68257
68461
 
68258
68462
  // src/widgets/Link.tsx
@@ -68683,6 +68887,7 @@ class ThinkingEffortWidget {
68683
68887
  }
68684
68888
  getDescription() {
68685
68889
  return `Displays the current thinking effort level (low, medium, high, xhigh, max).
68890
+ Claude Code reports Ultracode as xhigh in status line data; Ultracode is not exposed as a separate effort level.
68686
68891
  Unknown levels are shown with a trailing "?" (e.g. "super-max?").
68687
68892
  May be incorrect when multiple Claude Code sessions are running due to current Claude Code limitations.`;
68688
68893
  }
@@ -69084,8 +69289,12 @@ function toggleHideZero(item) {
69084
69289
  }
69085
69290
  };
69086
69291
  }
69087
- function formatReclaimedSuffix(tokensReclaimed) {
69088
- return tokensReclaimed > 0 ? ` ↓${formatTokens(tokensReclaimed)}` : "";
69292
+ function formatReclaimedSuffix(tokensReclaimed, item) {
69293
+ if (tokensReclaimed <= 0) {
69294
+ return "";
69295
+ }
69296
+ const symbol2 = getSlotSymbol(item, RECLAIMED_SLOT);
69297
+ return symbol2.length > 0 ? ` ${symbol2}${formatTokens(tokensReclaimed)}` : ` ${formatTokens(tokensReclaimed)}`;
69089
69298
  }
69090
69299
  function formatTriggerSuffix(byTrigger) {
69091
69300
  const parts = [];
@@ -69106,7 +69315,7 @@ function formatStats(data, item, icon) {
69106
69315
  out += formatTriggerSuffix(data.byTrigger);
69107
69316
  }
69108
69317
  if (isMetadataFlagEnabled(item, SHOW_RECLAIMED_METADATA_KEY)) {
69109
- out += formatReclaimedSuffix(data.tokensReclaimed);
69318
+ out += formatReclaimedSuffix(data.tokensReclaimed, item);
69110
69319
  }
69111
69320
  return out;
69112
69321
  }
@@ -69208,8 +69417,12 @@ class CompactionCounterWidget {
69208
69417
  keybinds.push({ key: "s", label: "(s)plit by trigger", action: TOGGLE_TRIGGERS_ACTION });
69209
69418
  keybinds.push({ key: "t", label: "(t)okens reclaimed", action: TOGGLE_RECLAIMED_ACTION });
69210
69419
  keybinds.push({ key: "h", label: "(h)ide when zero", action: TOGGLE_HIDE_ZERO_ACTION });
69420
+ keybinds.push(getSymbolKeybind());
69211
69421
  return keybinds;
69212
69422
  }
69423
+ renderEditor(props) {
69424
+ return renderSymbolSlotsEditor(props, [RECLAIMED_SLOT]);
69425
+ }
69213
69426
  supportsRawValue() {
69214
69427
  return false;
69215
69428
  }
@@ -69217,10 +69430,12 @@ class CompactionCounterWidget {
69217
69430
  return true;
69218
69431
  }
69219
69432
  }
69220
- var COMPACTION_ICON = "↻", COMPACTION_NERD_FONT_ICON = "", FORMATS2, DEFAULT_FORMAT2 = "icon-space-number", CYCLE_FORMAT_ACTION2 = "cycle-format", TOGGLE_HIDE_ZERO_ACTION = "toggle-hide-zero", TOGGLE_NERD_FONT_ACTION2 = "toggle-nerd-font", HIDE_ZERO_METADATA_KEY = "hideZero", NERD_FONT_METADATA_KEY2 = "nerdFont", TOGGLE_TRIGGERS_ACTION = "toggle-triggers", SHOW_TRIGGERS_METADATA_KEY = "showTriggers", TOGGLE_RECLAIMED_ACTION = "toggle-reclaimed", SHOW_RECLAIMED_METADATA_KEY = "showReclaimed", SAMPLE_STATS;
69221
- var init_CompactionCounter = __esm(() => {
69433
+ var COMPACTION_ICON = "↻", COMPACTION_NERD_FONT_ICON = "", FORMATS2, DEFAULT_FORMAT2 = "icon-space-number", CYCLE_FORMAT_ACTION2 = "cycle-format", TOGGLE_HIDE_ZERO_ACTION = "toggle-hide-zero", TOGGLE_NERD_FONT_ACTION2 = "toggle-nerd-font", HIDE_ZERO_METADATA_KEY = "hideZero", NERD_FONT_METADATA_KEY2 = "nerdFont", TOGGLE_TRIGGERS_ACTION = "toggle-triggers", SHOW_TRIGGERS_METADATA_KEY = "showTriggers", TOGGLE_RECLAIMED_ACTION = "toggle-reclaimed", SHOW_RECLAIMED_METADATA_KEY = "showReclaimed", RECLAIMED_SLOT, SAMPLE_STATS;
69434
+ var init_CompactionCounter = __esm(async () => {
69222
69435
  init_compaction();
69436
+ await init_symbol_override();
69223
69437
  FORMATS2 = ["icon-space-number", "text-and-number", "number"];
69438
+ RECLAIMED_SLOT = { id: "symbolReclaimed", label: "Reclaimed", defaultSymbol: "↓" };
69224
69439
  SAMPLE_STATS = Object.freeze({
69225
69440
  count: 2,
69226
69441
  byTrigger: Object.freeze({ auto: 1, manual: 1, unknown: 0 }),
@@ -69525,7 +69740,6 @@ var init_widgets = __esm(async () => {
69525
69740
  init_FreeMemory();
69526
69741
  init_SessionName();
69527
69742
  init_VimMode();
69528
- init_CompactionCounter();
69529
69743
  await __promiseAll([
69530
69744
  init_GitBranch(),
69531
69745
  init_GitWorktree(),
@@ -69569,6 +69783,7 @@ var init_widgets = __esm(async () => {
69569
69783
  init_Skills(),
69570
69784
  init_ThinkingEffort(),
69571
69785
  init_GitWorktreeMode(),
69786
+ init_CompactionCounter(),
69572
69787
  init_VoiceStatus(),
69573
69788
  init_RemoteControlStatus()
69574
69789
  ]);
@@ -69694,12 +69909,10 @@ function getWidget(type) {
69694
69909
  }
69695
69910
  function getAllWidgetTypes(settings) {
69696
69911
  const allTypes = WIDGET_MANIFEST.map((entry) => entry.type);
69697
- if (!settings.powerline.enabled) {
69698
- if (!settings.defaultSeparator) {
69699
- allTypes.push("separator");
69700
- }
69701
- allTypes.push("flex-separator");
69912
+ if (!settings.powerline.enabled && !settings.defaultSeparator) {
69913
+ allTypes.push("separator");
69702
69914
  }
69915
+ allTypes.push("flex-separator");
69703
69916
  return allTypes;
69704
69917
  }
69705
69918
  function getLayoutCatalogEntry(type) {
@@ -69844,6 +70057,9 @@ var init_hooks = __esm(async () => {
69844
70057
  import * as fs12 from "fs";
69845
70058
  import * as os9 from "os";
69846
70059
  import * as path8 from "path";
70060
+ function getConfigLoadError() {
70061
+ return lastLoadError;
70062
+ }
69847
70063
  function initConfigPath(filePath) {
69848
70064
  settingsPath = filePath ? path8.resolve(filePath) : DEFAULT_SETTINGS_PATH;
69849
70065
  }
@@ -69854,49 +70070,78 @@ function isCustomConfigPath() {
69854
70070
  return settingsPath !== DEFAULT_SETTINGS_PATH;
69855
70071
  }
69856
70072
  function getSettingsPaths() {
69857
- const configDir = path8.dirname(settingsPath);
69858
- const parsedPath = path8.parse(settingsPath);
69859
- const backupBaseName = parsedPath.ext ? `${parsedPath.name}.bak` : `${parsedPath.base}.bak`;
69860
70073
  return {
69861
- configDir,
69862
- settingsPath,
69863
- settingsBackupPath: path8.join(configDir, backupBaseName)
70074
+ configDir: path8.dirname(settingsPath),
70075
+ settingsPath
69864
70076
  };
69865
70077
  }
69866
- async function writeSettingsJson(settings, paths) {
69867
- await mkdir(paths.configDir, { recursive: true });
69868
- await writeFile(paths.settingsPath, JSON.stringify(settings, null, 2), "utf-8");
70078
+ function getErrorCode(error51) {
70079
+ return typeof error51 === "object" && error51 !== null && "code" in error51 ? String(error51.code) : undefined;
69869
70080
  }
69870
- async function backupBadSettings(paths) {
70081
+ async function resolveSymlinkTarget(linkPath) {
69871
70082
  try {
69872
- if (fs12.existsSync(paths.settingsPath)) {
69873
- const content = await readFile3(paths.settingsPath, "utf-8");
69874
- await writeFile(paths.settingsBackupPath, content, "utf-8");
69875
- console.error(`Bad settings backed up to ${paths.settingsBackupPath}`);
70083
+ return await realpath2(linkPath);
70084
+ } catch (error51) {
70085
+ if (getErrorCode(error51) !== "ENOENT") {
70086
+ throw error51;
69876
70087
  }
70088
+ const linkTarget = await readlink(linkPath);
70089
+ return path8.resolve(path8.dirname(linkPath), linkTarget);
70090
+ }
70091
+ }
70092
+ async function resolveAtomicWriteTarget(paths) {
70093
+ try {
70094
+ const stats = await lstat(paths.settingsPath);
70095
+ if (!stats.isSymbolicLink()) {
70096
+ return {
70097
+ targetPath: paths.settingsPath,
70098
+ tempDir: paths.configDir
70099
+ };
70100
+ }
70101
+ const targetPath = await resolveSymlinkTarget(paths.settingsPath);
70102
+ return {
70103
+ targetPath,
70104
+ tempDir: path8.dirname(targetPath)
70105
+ };
69877
70106
  } catch (error51) {
69878
- console.error("Failed to backup bad settings:", error51);
70107
+ if (getErrorCode(error51) === "ENOENT") {
70108
+ return {
70109
+ targetPath: paths.settingsPath,
70110
+ tempDir: paths.configDir
70111
+ };
70112
+ }
70113
+ throw error51;
70114
+ }
70115
+ }
70116
+ async function writeSettingsJson(settings, paths) {
70117
+ await mkdir(paths.configDir, { recursive: true });
70118
+ const writeTarget = await resolveAtomicWriteTarget(paths);
70119
+ const tempPath = path8.join(writeTarget.tempDir, `${path8.basename(writeTarget.targetPath)}.${process.pid}.${Date.now()}.tmp`);
70120
+ try {
70121
+ await writeFile(tempPath, JSON.stringify(settings, null, 2), "utf-8");
70122
+ await rename(tempPath, writeTarget.targetPath);
70123
+ } catch (error51) {
70124
+ try {
70125
+ await unlink(tempPath);
70126
+ } catch {}
70127
+ throw error51;
69879
70128
  }
69880
70129
  }
70130
+ function inMemoryDefaults() {
70131
+ return SettingsSchema.parse({});
70132
+ }
69881
70133
  async function writeDefaultSettings(paths) {
69882
- const defaults2 = SettingsSchema.parse({});
69883
- const settingsWithVersion = {
69884
- ...defaults2,
69885
- version: CURRENT_VERSION
69886
- };
70134
+ const defaults2 = inMemoryDefaults();
69887
70135
  try {
69888
- await writeSettingsJson(settingsWithVersion, paths);
70136
+ await writeSettingsJson(defaults2, paths);
69889
70137
  console.error(`Default settings written to ${paths.settingsPath}`);
69890
70138
  } catch (error51) {
69891
70139
  console.error("Failed to write default settings:", error51);
69892
70140
  }
69893
70141
  return defaults2;
69894
70142
  }
69895
- async function recoverWithDefaults(paths) {
69896
- await backupBadSettings(paths);
69897
- return await writeDefaultSettings(paths);
69898
- }
69899
70143
  async function loadSettings() {
70144
+ lastLoadError = null;
69900
70145
  const paths = getSettingsPaths();
69901
70146
  try {
69902
70147
  if (!fs12.existsSync(paths.settingsPath))
@@ -69906,34 +70151,42 @@ async function loadSettings() {
69906
70151
  try {
69907
70152
  rawData = JSON.parse(content);
69908
70153
  } catch {
69909
- console.error("Failed to parse settings.json, backing up and using defaults");
69910
- return await recoverWithDefaults(paths);
70154
+ console.error("Failed to parse settings.json, using defaults (file left unchanged)");
70155
+ lastLoadError = "settings.json is not valid JSON";
70156
+ return inMemoryDefaults();
69911
70157
  }
69912
70158
  const hasVersion = typeof rawData === "object" && rawData !== null && "version" in rawData;
70159
+ let migrated = false;
69913
70160
  if (!hasVersion) {
69914
70161
  const v1Result = SettingsSchema_v1.safeParse(rawData);
69915
70162
  if (!v1Result.success) {
69916
- console.error("Invalid v1 settings format:", v1Result.error);
69917
- return await recoverWithDefaults(paths);
70163
+ console.error("Invalid v1 settings format, using defaults (file left unchanged):", v1Result.error);
70164
+ lastLoadError = "settings.json is not in a valid format";
70165
+ return inMemoryDefaults();
69918
70166
  }
69919
70167
  rawData = migrateConfig(rawData, CURRENT_VERSION);
69920
- await writeSettingsJson(rawData, paths);
70168
+ migrated = true;
69921
70169
  } else if (needsMigration(rawData, CURRENT_VERSION)) {
69922
70170
  rawData = migrateConfig(rawData, CURRENT_VERSION);
69923
- await writeSettingsJson(rawData, paths);
70171
+ migrated = true;
69924
70172
  }
69925
70173
  const result2 = SettingsSchema.safeParse(rawData);
69926
70174
  if (!result2.success) {
69927
- console.error("Failed to parse settings:", result2.error);
69928
- return await recoverWithDefaults(paths);
70175
+ console.error("Failed to parse settings, using defaults (file left unchanged):", result2.error);
70176
+ lastLoadError = "settings.json is not in a valid format";
70177
+ return inMemoryDefaults();
70178
+ }
70179
+ if (migrated) {
70180
+ await writeSettingsJson(rawData, paths);
69929
70181
  }
69930
70182
  return {
69931
70183
  ...result2.data,
69932
70184
  lines: upgradeLegacyWidgetTypes(result2.data.lines)
69933
70185
  };
69934
70186
  } catch (error51) {
69935
- console.error("Error loading settings:", error51);
69936
- return await recoverWithDefaults(paths);
70187
+ console.error("Error loading settings, using defaults:", error51);
70188
+ lastLoadError = "settings.json could not be read";
70189
+ return inMemoryDefaults();
69937
70190
  }
69938
70191
  }
69939
70192
  async function saveSettings(settings) {
@@ -69954,6 +70207,10 @@ async function saveInstallationMetadata(metadata) {
69954
70207
  return;
69955
70208
  }
69956
70209
  const settings = await loadSettings();
70210
+ if (getConfigLoadError() !== null) {
70211
+ console.error("Skipping installation-metadata write: settings.json is unreadable (left unchanged).");
70212
+ return;
70213
+ }
69957
70214
  const settingsWithVersion = {
69958
70215
  ...settings,
69959
70216
  version: CURRENT_VERSION
@@ -69965,7 +70222,7 @@ async function saveInstallationMetadata(metadata) {
69965
70222
  }
69966
70223
  await writeSettingsJson(settingsWithVersion, paths);
69967
70224
  }
69968
- var readFile3, writeFile, mkdir, DEFAULT_SETTINGS_PATH, settingsPath;
70225
+ var readFile3, writeFile, mkdir, rename, unlink, lstat, readlink, realpath2, DEFAULT_SETTINGS_PATH, settingsPath, lastLoadError = null;
69969
70226
  var init_config = __esm(async () => {
69970
70227
  init_Settings();
69971
70228
  init_migrations();
@@ -69973,6 +70230,11 @@ var init_config = __esm(async () => {
69973
70230
  readFile3 = fs12.promises.readFile;
69974
70231
  writeFile = fs12.promises.writeFile;
69975
70232
  mkdir = fs12.promises.mkdir;
70233
+ rename = fs12.promises.rename;
70234
+ unlink = fs12.promises.unlink;
70235
+ lstat = fs12.promises.lstat;
70236
+ readlink = fs12.promises.readlink;
70237
+ realpath2 = fs12.promises.realpath;
69976
70238
  DEFAULT_SETTINGS_PATH = path8.join(os9.homedir(), ".config", "ccstatusline", "settings.json");
69977
70239
  settingsPath = DEFAULT_SETTINGS_PATH;
69978
70240
  });
@@ -72558,12 +72820,31 @@ function toggleWidgetBold(widgets, widgetId) {
72558
72820
  bold: !widget.bold
72559
72821
  }));
72560
72822
  }
72823
+ function cycleWidgetDim(widgets, widgetId) {
72824
+ return updateWidgetById(widgets, widgetId, (widget) => {
72825
+ if (widget.dim === true) {
72826
+ return {
72827
+ ...widget,
72828
+ dim: "parens"
72829
+ };
72830
+ }
72831
+ if (widget.dim === "parens") {
72832
+ const { dim, ...restWidget } = widget;
72833
+ return restWidget;
72834
+ }
72835
+ return {
72836
+ ...widget,
72837
+ dim: true
72838
+ };
72839
+ });
72840
+ }
72561
72841
  function resetWidgetStyling(widgets, widgetId) {
72562
72842
  return updateWidgetById(widgets, widgetId, (widget) => {
72563
72843
  const {
72564
72844
  color,
72565
72845
  backgroundColor,
72566
72846
  bold,
72847
+ dim,
72567
72848
  ...restWidget
72568
72849
  } = widget;
72569
72850
  return restWidget;
@@ -72575,6 +72856,7 @@ function clearAllWidgetStyling(widgets) {
72575
72856
  color,
72576
72857
  backgroundColor,
72577
72858
  bold,
72859
+ dim,
72578
72860
  ...restWidget
72579
72861
  } = widget;
72580
72862
  return restWidget;
@@ -72831,6 +73113,14 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
72831
73113
  onUpdate(newItems);
72832
73114
  }
72833
73115
  }
73116
+ } else if (input === "d" || input === "D") {
73117
+ if (highlightedItemId && highlightedItemId !== "back") {
73118
+ const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
73119
+ if (selectedWidget2) {
73120
+ const newItems = cycleWidgetDim(widgets, selectedWidget2.id);
73121
+ onUpdate(newItems);
73122
+ }
73123
+ }
72834
73124
  } else if (input === "r" || input === "R") {
72835
73125
  if (highlightedItemId && highlightedItemId !== "back") {
72836
73126
  const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
@@ -72914,7 +73204,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
72914
73204
  defaultColor = widgetImpl.getDefaultColor();
72915
73205
  }
72916
73206
  }
72917
- const styledLabel = applyColors(label, widget.color ?? defaultColor, widget.backgroundColor, widget.bold, level);
73207
+ const styledLabel = applyColors(label, widget.color ?? defaultColor, widget.backgroundColor, widget.bold, level, widget.dim);
72918
73208
  return {
72919
73209
  label: styledLabel,
72920
73210
  value: widget.id
@@ -72981,6 +73271,11 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
72981
73271
  colorDisplay = applyColors(displayName, currentColor, undefined, false, level);
72982
73272
  }
72983
73273
  }
73274
+ const styleIndicators = [
73275
+ selectedWidget?.bold ? "[BOLD]" : null,
73276
+ selectedWidget?.dim === true ? "[DIM]" : null,
73277
+ selectedWidget?.dim === "parens" ? "[DIM ()]" : null
73278
+ ].filter((indicator) => indicator !== null).join(" ");
72984
73279
  if (gradientMode) {
72985
73280
  const level = getColorLevelString(settings.colorLevel);
72986
73281
  const widgetName = selectedWidget ? getItemLabel(selectedWidget) : "";
@@ -73195,7 +73490,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
73195
73490
  "↑↓ to select, ←→ to cycle",
73196
73491
  " ",
73197
73492
  editingBackground ? "background" : "foreground",
73198
- ", (f) to toggle bg/fg, (b)old,",
73493
+ ", (f) to toggle bg/fg, (b)old, (d)im,",
73199
73494
  settings.colorLevel === 3 ? " (h)ex," : settings.colorLevel === 2 ? " (a)nsi256," : "",
73200
73495
  !editingBackground && settings.colorLevel >= 2 ? " (g)radient," : "",
73201
73496
  " ",
@@ -73222,7 +73517,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
73222
73517
  "):",
73223
73518
  " ",
73224
73519
  colorDisplay,
73225
- selectedWidget.bold && source_default.bold(" [BOLD]")
73520
+ styleIndicators && ` ${styleIndicators}`
73226
73521
  ]
73227
73522
  }, undefined, true, undefined, this)
73228
73523
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
@@ -74664,7 +74959,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
74664
74959
  children: [
74665
74960
  "⚠",
74666
74961
  " ",
74667
- settings.powerline.enabled ? "Powerline mode active: separators controlled by powerline settings" : "Default separator active: manual separators disabled"
74962
+ settings.powerline.enabled ? "Powerline mode active: manual separators disabled" : "Default separator active: manual separators disabled"
74668
74963
  ]
74669
74964
  }, undefined, true, undefined, this)
74670
74965
  }, undefined, false, undefined, this)
@@ -75583,7 +75878,7 @@ function resolveEnabledPowerlineTheme(theme) {
75583
75878
  }
75584
75879
  function buildEnabledPowerlineSettings(settings, removeManualSeparators) {
75585
75880
  const powerlineConfig = settings.powerline;
75586
- const lines = removeManualSeparators ? settings.lines.map((line) => line.filter((item) => item.type !== "separator" && item.type !== "flex-separator")) : settings.lines;
75881
+ const lines = removeManualSeparators ? settings.lines.map((line) => line.filter((item) => item.type !== "separator")) : settings.lines;
75587
75882
  return {
75588
75883
  ...settings,
75589
75884
  powerline: {
@@ -76208,7 +76503,7 @@ var PowerlineSetup = ({
76208
76503
  const [selectedMenuItem, setSelectedMenuItem] = import_react47.useState(0);
76209
76504
  const [confirmingEnable, setConfirmingEnable] = import_react47.useState(false);
76210
76505
  const [confirmingFontInstall, setConfirmingFontInstall] = import_react47.useState(false);
76211
- const hasSeparatorItems = settings.lines.some((line) => line.some((item) => item.type === "separator" || item.type === "flex-separator"));
76506
+ const hasManualSeparatorItems = settings.lines.some((line) => line.some((item) => item.type === "separator"));
76212
76507
  const hasGlobalFgOverride = Boolean(settings.overrideForegroundColor && settings.overrideForegroundColor !== "none");
76213
76508
  const globalOverrideMessage = hasGlobalFgOverride ? "⚠ Global override for FG active" : null;
76214
76509
  use_input_default((input, key) => {
@@ -76226,7 +76521,7 @@ var PowerlineSetup = ({
76226
76521
  onBack();
76227
76522
  } else if (input === "t" || input === "T") {
76228
76523
  if (!powerlineConfig.enabled) {
76229
- if (hasSeparatorItems) {
76524
+ if (hasManualSeparatorItems) {
76230
76525
  setConfirmingEnable(true);
76231
76526
  } else {
76232
76527
  onUpdate(buildEnabledPowerlineSettings(settings, false));
@@ -76461,12 +76756,12 @@ var PowerlineSetup = ({
76461
76756
  flexDirection: "column",
76462
76757
  marginTop: 1,
76463
76758
  children: [
76464
- hasSeparatorItems && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(jsx_dev_runtime22.Fragment, {
76759
+ hasManualSeparatorItems && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(jsx_dev_runtime22.Fragment, {
76465
76760
  children: [
76466
76761
  /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
76467
76762
  children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76468
76763
  color: "yellow",
76469
- children: "⚠ Warning: Enabling Powerline mode will remove all existing separators and flex-separators from your status lines."
76764
+ children: "⚠ Warning: Enabling Powerline mode will remove all existing manual separators from your status lines."
76470
76765
  }, undefined, false, undefined, this)
76471
76766
  }, undefined, false, undefined, this),
76472
76767
  /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
@@ -76479,7 +76774,7 @@ var PowerlineSetup = ({
76479
76774
  ]
76480
76775
  }, undefined, true, undefined, this),
76481
76776
  /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
76482
- marginTop: hasSeparatorItems ? 1 : 0,
76777
+ marginTop: hasManualSeparatorItems ? 1 : 0,
76483
76778
  children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76484
76779
  children: "Do you want to continue? "
76485
76780
  }, undefined, false, undefined, this)
@@ -76882,7 +77177,11 @@ function countPowerlineThemeSlots(entries) {
76882
77177
  let previousVisibleWidget = null;
76883
77178
  let slotCount = 0;
76884
77179
  for (const entry of entries) {
76885
- if (!entry.content || entry.widget.type === "separator" || entry.widget.type === "flex-separator") {
77180
+ if (entry.widget.type === "separator" || entry.widget.type === "flex-separator") {
77181
+ previousVisibleWidget = null;
77182
+ continue;
77183
+ }
77184
+ if (!entry.content) {
76886
77185
  continue;
76887
77186
  }
76888
77187
  if (!previousVisibleWidget?.merge) {
@@ -76900,17 +77199,47 @@ function advanceGlobalPowerlineThemeIndex(currentIndex, entries) {
76900
77199
  await init_renderer2();
76901
77200
 
76902
77201
  // src/utils/separator-index.ts
76903
- function countSeparatorSlots(widgets) {
76904
- const nonMergedWidgets = widgets.filter((_, idx) => idx === widgets.length - 1 || !widgets[idx]?.merge);
76905
- return Math.max(0, nonMergedWidgets.length - 1);
77202
+ function hasRenderedContent(widgetIndex, preRenderedWidgets) {
77203
+ return preRenderedWidgets ? Boolean(preRenderedWidgets[widgetIndex]?.content) : true;
76906
77204
  }
76907
- function advanceGlobalSeparatorIndex(currentIndex, widgets) {
76908
- return currentIndex + countSeparatorSlots(widgets);
77205
+ function countSeparatorSlots(widgets, preRenderedWidgets) {
77206
+ let count = 0;
77207
+ let hasPreviousRenderableWidget = false;
77208
+ let previousRenderableWidgetMergesWithNext = false;
77209
+ for (let i = 0;i < widgets.length; i++) {
77210
+ const widget = widgets[i];
77211
+ if (!widget) {
77212
+ continue;
77213
+ }
77214
+ if (widget.type === "separator") {
77215
+ if (hasPreviousRenderableWidget) {
77216
+ previousRenderableWidgetMergesWithNext = false;
77217
+ }
77218
+ continue;
77219
+ }
77220
+ if (widget.type === "flex-separator") {
77221
+ hasPreviousRenderableWidget = false;
77222
+ previousRenderableWidgetMergesWithNext = false;
77223
+ continue;
77224
+ }
77225
+ if (!hasRenderedContent(i, preRenderedWidgets)) {
77226
+ continue;
77227
+ }
77228
+ if (hasPreviousRenderableWidget && !previousRenderableWidgetMergesWithNext) {
77229
+ count++;
77230
+ }
77231
+ hasPreviousRenderableWidget = true;
77232
+ previousRenderableWidgetMergesWithNext = Boolean(widget.merge);
77233
+ }
77234
+ return count;
77235
+ }
77236
+ function advanceGlobalSeparatorIndex(currentIndex, widgets, preRenderedWidgets) {
77237
+ return currentIndex + countSeparatorSlots(widgets, preRenderedWidgets);
76909
77238
  }
76910
77239
 
76911
77240
  // src/tui/components/StatusLinePreview.tsx
76912
77241
  var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
76913
- var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, globalPowerlineThemeIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
77242
+ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, globalPowerlineThemeIndex, globalPowerlineStartCapIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
76914
77243
  const context = {
76915
77244
  terminalWidth,
76916
77245
  isPreview: true,
@@ -76918,7 +77247,8 @@ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSepar
76918
77247
  gitCacheTtlSeconds: settings.gitCacheTtlSeconds,
76919
77248
  lineIndex,
76920
77249
  globalSeparatorIndex,
76921
- globalPowerlineThemeIndex
77250
+ globalPowerlineThemeIndex,
77251
+ globalPowerlineStartCapIndex
76922
77252
  };
76923
77253
  return renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
76924
77254
  };
@@ -76941,18 +77271,22 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
76941
77271
  const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
76942
77272
  let globalSeparatorIndex = 0;
76943
77273
  let globalPowerlineThemeIndex = 0;
77274
+ let globalPowerlineStartCapIndex = 0;
76944
77275
  const result2 = [];
76945
77276
  let truncated = false;
76946
77277
  for (let i = 0;i < lines.length; i++) {
76947
77278
  const lineItems = lines[i];
76948
77279
  if (lineItems && lineItems.length > 0) {
76949
77280
  const preRenderedWidgets = preRenderedLines[i] ?? [];
76950
- const renderResult = renderSingleLine(lineItems, terminalWidth, settings, i, globalSeparatorIndex, globalPowerlineThemeIndex, preRenderedWidgets, preCalculatedMaxWidths);
77281
+ const renderResult = renderSingleLine(lineItems, terminalWidth, settings, i, globalSeparatorIndex, globalPowerlineThemeIndex, globalPowerlineStartCapIndex, preRenderedWidgets, preCalculatedMaxWidths);
76951
77282
  result2.push(renderResult.line);
76952
77283
  if (renderResult.wasTruncated) {
76953
77284
  truncated = true;
76954
77285
  }
76955
- globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
77286
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems, preRenderedWidgets);
77287
+ if (settings.powerline.enabled) {
77288
+ globalPowerlineStartCapIndex += countPowerlineStartCapSlots(lineItems, preRenderedWidgets);
77289
+ }
76956
77290
  if (settings.powerline.enabled && settings.powerline.continueThemeAcrossLines) {
76957
77291
  globalPowerlineThemeIndex = advanceGlobalPowerlineThemeIndex(globalPowerlineThemeIndex, preRenderedWidgets);
76958
77292
  }
@@ -78917,6 +79251,7 @@ async function ensureWindowsUtf8CodePage() {
78917
79251
  }
78918
79252
  async function renderMultipleLines(data) {
78919
79253
  const settings = await loadSettings();
79254
+ const configError = getConfigLoadError();
78920
79255
  source_default.level = settings.colorLevel;
78921
79256
  updateColorMap();
78922
79257
  const lines = settings.lines;
@@ -78974,6 +79309,8 @@ async function renderMultipleLines(data) {
78974
79309
  const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
78975
79310
  let globalSeparatorIndex = 0;
78976
79311
  let globalPowerlineThemeIndex = 0;
79312
+ let globalPowerlineStartCapIndex = 0;
79313
+ let configBadgePrepended = false;
78977
79314
  for (let i = 0;i < lines.length; i++) {
78978
79315
  const lineItems = lines[i];
78979
79316
  if (lineItems && lineItems.length > 0) {
@@ -78982,21 +79319,32 @@ async function renderMultipleLines(data) {
78982
79319
  ...context,
78983
79320
  lineIndex: i,
78984
79321
  globalSeparatorIndex,
78985
- globalPowerlineThemeIndex
79322
+ globalPowerlineThemeIndex,
79323
+ globalPowerlineStartCapIndex
78986
79324
  };
78987
- const line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
79325
+ let line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
78988
79326
  const strippedLine = getVisibleText(line).trim();
78989
79327
  if (strippedLine.length > 0) {
79328
+ if (configError && !configBadgePrepended) {
79329
+ line = `${buildConfigWarningBadge(settings.colorLevel)} | ${line}`;
79330
+ configBadgePrepended = true;
79331
+ }
78990
79332
  let outputLine = line.replace(/ /g, " ");
78991
79333
  outputLine = "\x1B[0m" + outputLine;
78992
79334
  console.log(outputLine);
78993
- globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems);
79335
+ globalSeparatorIndex = advanceGlobalSeparatorIndex(globalSeparatorIndex, lineItems, preRenderedWidgets);
79336
+ if (settings.powerline.enabled) {
79337
+ globalPowerlineStartCapIndex += countPowerlineStartCapSlots(lineItems, preRenderedWidgets);
79338
+ }
78994
79339
  if (settings.powerline.enabled && settings.powerline.continueThemeAcrossLines) {
78995
79340
  globalPowerlineThemeIndex = advanceGlobalPowerlineThemeIndex(globalPowerlineThemeIndex, preRenderedWidgets);
78996
79341
  }
78997
79342
  }
78998
79343
  }
78999
79344
  }
79345
+ if (configError && !configBadgePrepended) {
79346
+ console.log("\x1B[0m" + buildConfigWarningBadge(settings.colorLevel).replace(/ /g, " "));
79347
+ }
79000
79348
  if (settings.updatemessage?.message && settings.updatemessage.message.trim() !== "" && settings.updatemessage.remaining && settings.updatemessage.remaining > 0) {
79001
79349
  console.log(settings.updatemessage.message);
79002
79350
  const newRemaining = settings.updatemessage.remaining - 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.2.21",
3
+ "version": "2.2.22",
4
4
  "bugs": {
5
5
  "url": "https://github.com/sirmalloc/ccstatusline/issues"
6
6
  },