ccstatusline 2.0.28 → 2.0.29

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,8 +46,9 @@
46
46
 
47
47
  ## 🆕 Recent Updates
48
48
 
49
- ### v2.0.26 - v2.0.28 - Performance, git internals, and workflow improvements
49
+ ### v2.0.26 - v2.0.29 - Performance, git internals, and workflow improvements
50
50
 
51
+ - **🧠 Memory Usage widget (v2.0.29)** - Added a new widget that shows current system memory usage (`Mem: used/total`).
51
52
  - **⚡ Block timer cache (v2.0.28)** - Cache block timer metrics to reduce JSONL parsing on every render, with per-config hashed cache files and automatic 5-hour block invalidation.
52
53
  - **🧱 Git widget command refactor (v2.0.28)** - Refactored git widgets to use shared git command helpers and expanded coverage for failure and edge-case tests.
53
54
  - **🪟 Windows UTF-8 piped output fix (v2.0.28)** - Sets the Windows UTF-8 code page for piped status line rendering.
@@ -381,6 +382,7 @@ Once configured, ccstatusline automatically formats your Claude Code status line
381
382
  - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for Sonnet 4.5 with `[1m]` suffix, 200k otherwise)
382
383
  - **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%)
383
384
  - **Terminal Width** - Shows detected terminal width (for debugging)
385
+ - **Memory Usage** - Shows system memory usage (used/total, e.g., "Mem: 12.4G/16.0G")
384
386
  - **Custom Text** - Add your own custom text to the status line
385
387
  - **Custom Command** - Execute shell commands and display their output (refreshes whenever the statusline is updated by Claude Code)
386
388
  - **Separator** - Visual divider between widgets (customizable: |, -, comma, space)
@@ -51405,7 +51405,7 @@ import { execSync as execSync3 } from "child_process";
51405
51405
  import * as fs5 from "fs";
51406
51406
  import * as path4 from "path";
51407
51407
  var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
51408
- var PACKAGE_VERSION = "2.0.28";
51408
+ var PACKAGE_VERSION = "2.0.29";
51409
51409
  function getPackageVersion() {
51410
51410
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51411
51411
  return PACKAGE_VERSION;
@@ -54568,6 +54568,89 @@ class ClaudeSessionIdWidget {
54568
54568
  return true;
54569
54569
  }
54570
54570
  }
54571
+ // src/widgets/FreeMemory.ts
54572
+ import { execSync as execSync6 } from "child_process";
54573
+ import os6 from "os";
54574
+ function formatBytes(bytes) {
54575
+ const GB = 1024 ** 3;
54576
+ const MB = 1024 ** 2;
54577
+ const KB = 1024;
54578
+ if (bytes >= GB)
54579
+ return `${(bytes / GB).toFixed(1)}G`;
54580
+ if (bytes >= MB)
54581
+ return `${(bytes / MB).toFixed(0)}M`;
54582
+ if (bytes >= KB)
54583
+ return `${(bytes / KB).toFixed(0)}K`;
54584
+ return `${bytes}B`;
54585
+ }
54586
+ function getUsedMemoryMacOS() {
54587
+ try {
54588
+ const output = execSync6("vm_stat", { encoding: "utf8" });
54589
+ const lines = output.split(`
54590
+ `);
54591
+ const firstLine = lines[0];
54592
+ if (!firstLine)
54593
+ return null;
54594
+ const pageSizeMatch = /page size of (\d+) bytes/.exec(firstLine);
54595
+ const pageSizeString = pageSizeMatch?.[1];
54596
+ if (!pageSizeString)
54597
+ return null;
54598
+ const pageSize = parseInt(pageSizeString, 10);
54599
+ let activePages = 0;
54600
+ let wiredPages = 0;
54601
+ for (const line of lines) {
54602
+ const activeMatch = /Pages active:\s+(\d+)/.exec(line);
54603
+ const activeValue = activeMatch?.[1];
54604
+ if (activeValue)
54605
+ activePages = parseInt(activeValue, 10);
54606
+ const wiredMatch = /Pages wired down:\s+(\d+)/.exec(line);
54607
+ const wiredValue = wiredMatch?.[1];
54608
+ if (wiredValue)
54609
+ wiredPages = parseInt(wiredValue, 10);
54610
+ }
54611
+ return (activePages + wiredPages) * pageSize;
54612
+ } catch {
54613
+ return null;
54614
+ }
54615
+ }
54616
+
54617
+ class FreeMemoryWidget {
54618
+ getDefaultColor() {
54619
+ return "cyan";
54620
+ }
54621
+ getDescription() {
54622
+ return "Shows system memory usage (used/total)";
54623
+ }
54624
+ getDisplayName() {
54625
+ return "Memory Usage";
54626
+ }
54627
+ getCategory() {
54628
+ return "Environment";
54629
+ }
54630
+ getEditorDisplay(item) {
54631
+ return { displayText: this.getDisplayName() };
54632
+ }
54633
+ render(item, context, settings) {
54634
+ if (context.isPreview) {
54635
+ return item.rawValue ? "12.4G/16.0G" : "Mem: 12.4G/16.0G";
54636
+ }
54637
+ const total = os6.totalmem();
54638
+ let used;
54639
+ if (os6.platform() === "darwin") {
54640
+ used = getUsedMemoryMacOS() ?? total - os6.freemem();
54641
+ } else {
54642
+ used = total - os6.freemem();
54643
+ }
54644
+ const value = `${formatBytes(used)}/${formatBytes(total)}`;
54645
+ return item.rawValue ? value : `Mem: ${value}`;
54646
+ }
54647
+ supportsRawValue() {
54648
+ return true;
54649
+ }
54650
+ supportsColors(item) {
54651
+ return true;
54652
+ }
54653
+ }
54571
54654
  // src/widgets/SessionName.ts
54572
54655
  import * as fs6 from "fs";
54573
54656
 
@@ -54644,7 +54727,8 @@ var widgetRegistry = new Map([
54644
54727
  ["custom-text", new CustomTextWidget],
54645
54728
  ["custom-command", new CustomCommandWidget],
54646
54729
  ["claude-session-id", new ClaudeSessionIdWidget],
54647
- ["session-name", new SessionNameWidget]
54730
+ ["session-name", new SessionNameWidget],
54731
+ ["free-memory", new FreeMemoryWidget]
54648
54732
  ]);
54649
54733
  function getWidget(type) {
54650
54734
  return widgetRegistry.get(type) ?? null;
@@ -57004,7 +57088,7 @@ var MainMenu = ({ onSelect, isClaudeInstalled, hasChanges, initialSelection = 0,
57004
57088
  };
57005
57089
  // src/tui/components/PowerlineSetup.tsx
57006
57090
  var import_react41 = __toESM(require_react(), 1);
57007
- import * as os6 from "os";
57091
+ import * as os7 from "os";
57008
57092
 
57009
57093
  // src/tui/components/PowerlineSeparatorEditor.tsx
57010
57094
  var import_react39 = __toESM(require_react(), 1);
@@ -57721,7 +57805,7 @@ var PowerlineSetup = ({
57721
57805
  }, undefined, false, undefined, this)
57722
57806
  ]
57723
57807
  }, undefined, true, undefined, this),
57724
- os6.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57808
+ os7.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57725
57809
  children: [
57726
57810
  /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
57727
57811
  dimColor: true,
@@ -57737,7 +57821,7 @@ var PowerlineSetup = ({
57737
57821
  }, undefined, false, undefined, this)
57738
57822
  ]
57739
57823
  }, undefined, true, undefined, this),
57740
- os6.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57824
+ os7.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57741
57825
  children: [
57742
57826
  /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
57743
57827
  dimColor: true,
@@ -57753,7 +57837,7 @@ var PowerlineSetup = ({
57753
57837
  }, undefined, false, undefined, this)
57754
57838
  ]
57755
57839
  }, undefined, true, undefined, this),
57756
- os6.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57840
+ os7.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(jsx_dev_runtime13.Fragment, {
57757
57841
  children: [
57758
57842
  /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
57759
57843
  dimColor: true,
@@ -58936,7 +59020,7 @@ var StatusJSONSchema = exports_external.looseObject({
58936
59020
  // src/utils/jsonl.ts
58937
59021
  import * as fs7 from "fs";
58938
59022
  import { createHash } from "node:crypto";
58939
- import os7 from "node:os";
59023
+ import os8 from "node:os";
58940
59024
  import path6 from "node:path";
58941
59025
 
58942
59026
  // node_modules/tinyglobby/dist/index.mjs
@@ -59737,7 +59821,7 @@ function normalizeConfigDir(configDir) {
59737
59821
  function getBlockCachePath(configDir = getClaudeConfigDir()) {
59738
59822
  const normalizedConfigDir = normalizeConfigDir(configDir);
59739
59823
  const configHash = createHash("sha256").update(normalizedConfigDir).digest("hex").slice(0, 16);
59740
- return path6.join(os7.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
59824
+ return path6.join(os8.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
59741
59825
  }
59742
59826
  function readBlockCache(expectedConfigDir) {
59743
59827
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.0.28",
3
+ "version": "2.0.29",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",