ccstatusline-usage 2.1.3 โ†’ 2.1.4

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
@@ -46,6 +46,15 @@
46
46
 
47
47
  ## ๐Ÿ†• Recent Updates
48
48
 
49
+ ### [v2.1.4](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.4) - Compact mode widget-boundary wrapping
50
+
51
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Widget-boundary wrapping** โ€” compact mode now wraps at widget boundaries instead of mid-widget, using a dedicated compact renderer (`compact-renderer.ts`). Widgets that don't fit on the current line cleanly wrap to the next:
52
+ ```
53
+ S: [โ–‘โ–‘โ–‘โ–‘] 2.0% | W: [โ–ˆโ–ˆโ–‘โ–‘] 43.0% | 4:36 hr
54
+ M: o4.6 โ–Œโ–Œโ–Œ | S: 5647528d | C: [โ–ˆโ–ˆโ–‘โ–‘] 119k/200k
55
+ ```
56
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Terminal-agnostic compact detection** โ€” compact mode now triggers on any narrow terminal (< 80 columns), not just tmux
57
+
49
58
  ### [v2.1.3](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.3) - Mobile/compact mode and thinking effort bars
50
59
 
51
60
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Mobile/compact mode** โ€” in narrow terminals (< 80 effective columns, e.g. tmux panes), widgets auto-switch to compact rendering: `M: o4.6` instead of `Model: claude-opus-4-6`, session ID truncated to 8 chars, and multiple status lines merge into one
@@ -376,8 +385,8 @@ Once configured, ccstatusline automatically formats your Claude Code status line
376
385
  - **Tokens Cached** - Shows cached tokens used
377
386
  - **Tokens Total** - Shows total tokens used
378
387
  - **Context Length** - Shows current context length in tokens
379
- - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for Sonnet 4.5 with `[1m]` suffix, 200k otherwise)
380
- - **Context Percentage (usable)** - Shows percentage of usable context (dynamic: 800k for Sonnet 4.5 with `[1m]` suffix, 160k otherwise, accounting for auto-compact at 80%)
388
+ - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for Sonnet 4.5/Opus 4.6 with `[1m]` suffix, 200k otherwise)
389
+ - **Context Percentage (usable)** - Shows percentage of usable context (dynamic: 800k for Sonnet 4.5/Opus 4.6 with `[1m]` suffix, 160k otherwise, accounting for auto-compact at 80%)
381
390
  - **Terminal Width** - Shows detected terminal width (for debugging)
382
391
  - **Custom Text** - Add your own custom text to the status line
383
392
  - **Custom Command** - Execute shell commands and display their output (refreshes whenever the statusline is updated by Claude Code)
@@ -447,7 +456,7 @@ The Block Timer widget helps you track your progress through Claude Code's 5-hou
447
456
  ### ๐Ÿ”ค Raw Value Mode
448
457
 
449
458
  Some widgets support "raw value" mode which displays just the value without a label:
450
- - Normal: `Model: Claude 3.5 Sonnet` โ†’ Raw: `Claude 3.5 Sonnet`
459
+ - Normal: `Model: Claude Opus 4.6` โ†’ Raw: `Claude Opus 4.6`
451
460
  - Normal: `Session: 2hr 15m` โ†’ Raw: `2hr 15m`
452
461
  - Normal: `Block: 3hr 45m` โ†’ Raw: `3hr 45m`
453
462
  - Normal: `Ctx: 18.6k` โ†’ Raw: `18.6k`
@@ -624,6 +633,11 @@ Contributions are welcome! Please feel free to submit a Pull Request.
624
633
 
625
634
  - GitHub: [@sirmalloc](https://github.com/sirmalloc)
626
635
 
636
+ **Fork maintained by Peter van Velzen**
637
+
638
+ - GitHub: [@pcvelz](https://github.com/pcvelz)
639
+ - Fork: [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage)
640
+
627
641
  ---
628
642
 
629
643
  ## ๐Ÿ”— Related Projects
@@ -643,11 +657,11 @@ Contributions are welcome! Please feel free to submit a Pull Request.
643
657
 
644
658
  ## Star History
645
659
 
646
- <a href="https://www.star-history.com/#sirmalloc/ccstatusline&Timeline">
660
+ <a href="https://www.star-history.com/#pcvelz/ccstatusline-usage&Timeline">
647
661
  <picture>
648
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=sirmalloc/ccstatusline&type=Timeline&theme=dark" />
649
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=sirmalloc/ccstatusline&type=Timeline" />
650
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=sirmalloc/ccstatusline&type=Timeline" />
662
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=pcvelz/ccstatusline-usage&type=Timeline&theme=dark" />
663
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=pcvelz/ccstatusline-usage&type=Timeline" />
664
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=pcvelz/ccstatusline-usage&type=Timeline" />
651
665
  </picture>
652
666
  </a>
653
667
 
@@ -657,21 +671,21 @@ Contributions are welcome! Please feel free to submit a Pull Request.
657
671
 
658
672
  Give a โญ if this project helped you!
659
673
 
660
- [![GitHub stars](https://img.shields.io/github/stars/sirmalloc/ccstatusline?style=social)](https://github.com/sirmalloc/ccstatusline/stargazers)
661
- [![GitHub forks](https://img.shields.io/github/forks/sirmalloc/ccstatusline?style=social)](https://github.com/sirmalloc/ccstatusline/network/members)
662
- [![GitHub watchers](https://img.shields.io/github/watchers/sirmalloc/ccstatusline?style=social)](https://github.com/sirmalloc/ccstatusline/watchers)
674
+ [![GitHub stars](https://img.shields.io/github/stars/pcvelz/ccstatusline-usage?style=social)](https://github.com/pcvelz/ccstatusline-usage/stargazers)
675
+ [![GitHub forks](https://img.shields.io/github/forks/pcvelz/ccstatusline-usage?style=social)](https://github.com/pcvelz/ccstatusline-usage/network/members)
676
+ [![GitHub watchers](https://img.shields.io/github/watchers/pcvelz/ccstatusline-usage?style=social)](https://github.com/pcvelz/ccstatusline-usage/watchers)
663
677
 
664
- [![npm version](https://img.shields.io/npm/v/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
665
- [![npm downloads](https://img.shields.io/npm/dm/ccstatusline.svg)](https://www.npmjs.com/package/ccstatusline)
666
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sirmalloc/ccstatusline/blob/main/LICENSE)
678
+ [![npm version](https://img.shields.io/npm/v/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
679
+ [![npm downloads](https://img.shields.io/npm/dm/ccstatusline-usage.svg)](https://www.npmjs.com/package/ccstatusline-usage)
680
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/pcvelz/ccstatusline-usage/blob/main/LICENSE)
667
681
  [![Made with Bun](https://img.shields.io/badge/Made%20with-Bun-000000.svg?logo=bun)](https://bun.sh)
668
682
 
669
- [![Issues](https://img.shields.io/github/issues/sirmalloc/ccstatusline)](https://github.com/sirmalloc/ccstatusline/issues)
670
- [![Pull Requests](https://img.shields.io/github/issues-pr/sirmalloc/ccstatusline)](https://github.com/sirmalloc/ccstatusline/pulls)
671
- [![Contributors](https://img.shields.io/github/contributors/sirmalloc/ccstatusline)](https://github.com/sirmalloc/ccstatusline/graphs/contributors)
683
+ [![Issues](https://img.shields.io/github/issues/pcvelz/ccstatusline-usage)](https://github.com/pcvelz/ccstatusline-usage/issues)
684
+ [![Pull Requests](https://img.shields.io/github/issues-pr/pcvelz/ccstatusline-usage)](https://github.com/pcvelz/ccstatusline-usage/pulls)
685
+ [![Contributors](https://img.shields.io/github/contributors/pcvelz/ccstatusline-usage)](https://github.com/pcvelz/ccstatusline-usage/graphs/contributors)
672
686
 
673
687
  ### ๐Ÿ’ฌ Connect
674
688
 
675
- [Report Bug](https://github.com/sirmalloc/ccstatusline/issues) ยท [Request Feature](https://github.com/sirmalloc/ccstatusline/issues) ยท [Discussions](https://github.com/sirmalloc/ccstatusline/discussions)
689
+ [Report Bug](https://github.com/pcvelz/ccstatusline-usage/issues) ยท [Request Feature](https://github.com/pcvelz/ccstatusline-usage/issues) ยท [Discussions](https://github.com/pcvelz/ccstatusline-usage/discussions)
676
690
 
677
691
  </div>
@@ -51450,7 +51450,7 @@ import { execSync as execSync3 } from "child_process";
51450
51450
  import * as fs5 from "fs";
51451
51451
  import * as path4 from "path";
51452
51452
  var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils";
51453
- var PACKAGE_VERSION = "2.1.3";
51453
+ var PACKAGE_VERSION = "2.1.4";
51454
51454
  function getPackageVersion() {
51455
51455
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51456
51456
  return PACKAGE_VERSION;
@@ -58750,6 +58750,63 @@ var StatusJSONSchema = exports_external.looseObject({
58750
58750
  }).nullable().optional()
58751
58751
  });
58752
58752
 
58753
+ // src/utils/compact-renderer.ts
58754
+ function renderCompactOutput(preRenderedLines, settings, maxWidth) {
58755
+ const colorLevel = getColorLevelString(settings.colorLevel);
58756
+ const sep = settings.defaultSeparator ?? "|";
58757
+ const separatorText = sep === "|" ? " | " : ` ${sep} `;
58758
+ const separatorWidth = separatorText.length;
58759
+ const coloredWidgets = [];
58760
+ for (const line of preRenderedLines) {
58761
+ for (const pw of line) {
58762
+ if (pw.widget.type === "separator" || pw.widget.type === "flex-separator")
58763
+ continue;
58764
+ if (pw.plainLength === 0)
58765
+ continue;
58766
+ let fgColor = pw.widget.color;
58767
+ if (!fgColor) {
58768
+ const impl = getWidget(pw.widget.type);
58769
+ fgColor = impl ? impl.getDefaultColor() : "white";
58770
+ }
58771
+ let bgColor = pw.widget.backgroundColor;
58772
+ if (settings.overrideForegroundColor && settings.overrideForegroundColor !== "none")
58773
+ fgColor = settings.overrideForegroundColor;
58774
+ if (settings.overrideBackgroundColor && settings.overrideBackgroundColor !== "none")
58775
+ bgColor = settings.overrideBackgroundColor;
58776
+ const bold = settings.globalBold || pw.widget.bold;
58777
+ const colored = applyColors(pw.content, fgColor, bgColor, bold, colorLevel);
58778
+ coloredWidgets.push({ colored, width: pw.plainLength });
58779
+ }
58780
+ }
58781
+ if (coloredWidgets.length === 0)
58782
+ return;
58783
+ const outputLines = [];
58784
+ let currentLine = "";
58785
+ let currentWidth = 0;
58786
+ for (const cw of coloredWidgets) {
58787
+ const needed = currentWidth === 0 ? cw.width : separatorWidth + cw.width;
58788
+ if (currentWidth > 0 && currentWidth + needed > maxWidth) {
58789
+ outputLines.push(currentLine);
58790
+ currentLine = cw.colored;
58791
+ currentWidth = cw.width;
58792
+ } else {
58793
+ if (currentWidth > 0) {
58794
+ currentLine += source_default.gray(separatorText);
58795
+ currentWidth += separatorWidth;
58796
+ }
58797
+ currentLine += cw.colored;
58798
+ currentWidth += cw.width;
58799
+ }
58800
+ }
58801
+ if (currentLine)
58802
+ outputLines.push(currentLine);
58803
+ for (const line of outputLines) {
58804
+ let outputLine = line.replace(/ /g, "ย ");
58805
+ outputLine = "\x1B[0m" + outputLine;
58806
+ console.log(outputLine);
58807
+ }
58808
+ }
58809
+
58753
58810
  // src/utils/jsonl.ts
58754
58811
  import * as fs8 from "fs";
58755
58812
  import path8 from "node:path";
@@ -59781,6 +59838,10 @@ function floorToHour(timestamp) {
59781
59838
  }
59782
59839
 
59783
59840
  // src/ccstatusline.ts
59841
+ var COMPACT_THRESHOLD = 80;
59842
+ function isCompactWidth(width) {
59843
+ return width !== null && width > 0 && width < COMPACT_THRESHOLD;
59844
+ }
59784
59845
  async function readStdin() {
59785
59846
  if (process.stdin.isTTY) {
59786
59847
  return null;
@@ -59823,49 +59884,38 @@ async function renderMultipleLines(data) {
59823
59884
  if (hasBlockTimer) {
59824
59885
  blockMetrics = getBlockMetrics();
59825
59886
  }
59826
- const rawWidth = getTerminalWidth();
59827
- const deduction = settings.flexMode === "full-minus-40" ? 40 : 6;
59828
- const effectiveWidth = rawWidth ? rawWidth - deduction : null;
59887
+ const terminalWidth = getTerminalWidth();
59829
59888
  const context = {
59830
59889
  data,
59831
59890
  tokenMetrics,
59832
59891
  sessionDuration,
59833
59892
  blockMetrics,
59834
- terminalWidth: effectiveWidth,
59893
+ terminalWidth,
59835
59894
  isPreview: false
59836
59895
  };
59837
59896
  const preRenderedLines = preRenderAllWidgets(lines, settings, context);
59838
- const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
59839
- const mobile = effectiveWidth !== null && effectiveWidth > 0 && effectiveWidth < 80;
59840
- const renderedLines = [];
59841
- let globalSeparatorIndex = 0;
59842
- for (let i = 0;i < lines.length; i++) {
59843
- const lineItems = lines[i];
59844
- if (lineItems && lineItems.length > 0) {
59845
- const lineContext = { ...context, lineIndex: i, globalSeparatorIndex };
59846
- const preRenderedWidgets = preRenderedLines[i] ?? [];
59847
- const line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
59848
- const strippedLine = line.replace(/\x1b\[[0-9;]*m/g, "").trim();
59849
- if (strippedLine.length > 0) {
59850
- const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
59851
- if (nonMergedWidgets.length > 1)
59852
- globalSeparatorIndex += nonMergedWidgets.length - 1;
59853
- renderedLines.push(line);
59854
- }
59855
- }
59856
- }
59857
- if (mobile && renderedLines.length > 1) {
59858
- const sep2 = settings.defaultSeparator ?? "|";
59859
- const separator = sep2 === "|" ? " | " : ` ${sep2} `;
59860
- const merged = renderedLines.join(separator);
59861
- let outputLine = merged.replace(/ /g, "ย ");
59862
- outputLine = "\x1B[0m" + outputLine;
59863
- console.log(outputLine);
59897
+ const compact = isCompactWidth(terminalWidth);
59898
+ if (compact && terminalWidth) {
59899
+ renderCompactOutput(preRenderedLines, settings, terminalWidth - 6);
59864
59900
  } else {
59865
- for (const line of renderedLines) {
59866
- let outputLine = line.replace(/ /g, "ย ");
59867
- outputLine = "\x1B[0m" + outputLine;
59868
- console.log(outputLine);
59901
+ const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
59902
+ let globalSeparatorIndex = 0;
59903
+ for (let i = 0;i < lines.length; i++) {
59904
+ const lineItems = lines[i];
59905
+ if (lineItems && lineItems.length > 0) {
59906
+ const lineContext = { ...context, lineIndex: i, globalSeparatorIndex };
59907
+ const preRenderedWidgets = preRenderedLines[i] ?? [];
59908
+ const line = renderStatusLine(lineItems, settings, lineContext, preRenderedWidgets, preCalculatedMaxWidths);
59909
+ const strippedLine = line.replace(/\x1b\[[0-9;]*m/g, "").trim();
59910
+ if (strippedLine.length > 0) {
59911
+ const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
59912
+ if (nonMergedWidgets.length > 1)
59913
+ globalSeparatorIndex += nonMergedWidgets.length - 1;
59914
+ let outputLine = line.replace(/ /g, "ย ");
59915
+ outputLine = "\x1B[0m" + outputLine;
59916
+ console.log(outputLine);
59917
+ }
59918
+ }
59869
59919
  }
59870
59920
  }
59871
59921
  if (settings.updatemessage?.message && settings.updatemessage.message.trim() !== "" && settings.updatemessage.remaining && settings.updatemessage.remaining > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",