ccstatusline-usage 2.1.2 → 2.1.3

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,12 @@
46
46
 
47
47
  ## 🆕 Recent Updates
48
48
 
49
+ ### [v2.1.3](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.3) - Mobile/compact mode and thinking effort bars
50
+
51
+ - [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
52
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Thinking effort bars** — Model widget shows `▌▌▌` bars indicating Claude Code's effort level (1=low, 2=medium, 3=high). Reads from `CLAUDE_CODE_EFFORT_LEVEL` env var or `~/.claude/settings.json`
53
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Tmux pane width detection** — correctly detects actual pane width via `tmux display-message` instead of falling back to default 80 columns
54
+
49
55
  ### [v2.1.2](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.2) - Token auth fallback and 401 handling
50
56
 
51
57
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): macOS file credential fallback — reads `~/.claude/.credentials.json` when Keychain entry is missing
@@ -355,7 +361,7 @@ Once configured, ccstatusline automatically formats your Claude Code status line
355
361
 
356
362
  ### 📊 Available Widgets
357
363
 
358
- - **Model Name** - Shows the current Claude model (e.g., "Claude 3.5 Sonnet")
364
+ - **Model Name** - Shows the current Claude model with thinking effort bars (`▌▌▌`) indicating low/medium/high effort
359
365
  - **Git Branch** - Displays current git branch name
360
366
  - **Git Changes** - Shows uncommitted insertions/deletions (e.g., "+42,-10")
361
367
  - **Git Worktree** - Shows the name of the current git worktree
@@ -32383,8 +32383,8 @@ var require_utils = __commonJS((exports) => {
32383
32383
  }
32384
32384
  return output;
32385
32385
  };
32386
- exports.basename = (path6, { windows } = {}) => {
32387
- const segs = path6.split(windows ? /[\\/]/ : "/");
32386
+ exports.basename = (path7, { windows } = {}) => {
32387
+ const segs = path7.split(windows ? /[\\/]/ : "/");
32388
32388
  const last = segs[segs.length - 1];
32389
32389
  if (last === "") {
32390
32390
  return segs[segs.length - 2];
@@ -50988,7 +50988,7 @@ var SettingsSchema = exports_external.object({
50988
50988
  { id: "sep2", type: "separator" },
50989
50989
  { id: "reset-timer", type: "reset-timer", color: "brightBlue" },
50990
50990
  { id: "sep3", type: "separator" },
50991
- { id: "model", type: "model", color: "magenta" },
50991
+ { id: "model", type: "model", color: "ansi256:124" },
50992
50992
  { id: "sep4", type: "separator" },
50993
50993
  { id: "session-id", type: "claude-session-id", color: "cyan" }
50994
50994
  ],
@@ -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.2";
51453
+ var PACKAGE_VERSION = "2.1.3";
51454
51454
  function getPackageVersion() {
51455
51455
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51456
51456
  return PACKAGE_VERSION;
@@ -51470,6 +51470,14 @@ function getPackageVersion() {
51470
51470
  return "";
51471
51471
  }
51472
51472
  function getTerminalWidth() {
51473
+ if (process.env.TMUX) {
51474
+ try {
51475
+ const output = execSync3("tmux display-message -p '#{pane_width}'", { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"], timeout: 2000 }).trim();
51476
+ const parsed = parseInt(output, 10);
51477
+ if (!isNaN(parsed) && parsed > 0)
51478
+ return parsed;
51479
+ } catch {}
51480
+ }
51473
51481
  try {
51474
51482
  const tty2 = execSync3("ps -o tty= -p $(ps -o ppid= -p $$)", {
51475
51483
  encoding: "utf8",
@@ -52280,9 +52288,61 @@ function getDefaultPowerlineTheme() {
52280
52288
  }
52281
52289
 
52282
52290
  // src/widgets/Model.ts
52291
+ import * as fs6 from "fs";
52292
+ import { homedir as homedir4 } from "os";
52293
+ import * as path5 from "path";
52294
+ var MOBILE_THRESHOLD = 80;
52295
+ function compactModelName(name) {
52296
+ const stripped = name.replace(/^claude-/, "");
52297
+ const match = /^([a-z]+)-(\d+)-(\d+)/.exec(stripped);
52298
+ if (match) {
52299
+ const letter = match[1]?.charAt(0) ?? "";
52300
+ return `${letter}${match[2]}.${match[3]}`;
52301
+ }
52302
+ return stripped;
52303
+ }
52304
+ function getEffortLevel() {
52305
+ const envLevel = process.env.CLAUDE_CODE_EFFORT_LEVEL;
52306
+ if (envLevel)
52307
+ return envLevel.toLowerCase();
52308
+ try {
52309
+ const configDir = process.env.CLAUDE_CONFIG_DIR ?? path5.join(homedir4(), ".claude");
52310
+ const settingsPath = path5.join(configDir, "settings.json");
52311
+ const content = fs6.readFileSync(settingsPath, "utf-8");
52312
+ const settings = JSON.parse(content);
52313
+ if (settings.effortLevel)
52314
+ return settings.effortLevel.toLowerCase();
52315
+ } catch {}
52316
+ return "high";
52317
+ }
52318
+ function effortToLevel(effort) {
52319
+ switch (effort) {
52320
+ case "low":
52321
+ return 1;
52322
+ case "medium":
52323
+ return 2;
52324
+ default:
52325
+ return 3;
52326
+ }
52327
+ }
52328
+ function renderThinkingBars(level, settings) {
52329
+ if (level <= 0)
52330
+ return "";
52331
+ const colorLevel = getColorLevelString(settings.colorLevel);
52332
+ const activeChalk = getChalkColor("red", colorLevel);
52333
+ const dimChalk = getChalkColor("brightBlack", colorLevel);
52334
+ const bars = ["▌", "▌", "▌"];
52335
+ return " " + bars.map((bar, i) => {
52336
+ if (i < level) {
52337
+ return activeChalk ? activeChalk(bar) : bar;
52338
+ }
52339
+ return dimChalk ? dimChalk(bar) : bar;
52340
+ }).join("");
52341
+ }
52342
+
52283
52343
  class ModelWidget {
52284
52344
  getDefaultColor() {
52285
- return "cyan";
52345
+ return "ansi256:124";
52286
52346
  }
52287
52347
  getDescription() {
52288
52348
  return "Displays the Claude model name (e.g., Claude 3.5 Sonnet)";
@@ -52295,14 +52355,21 @@ class ModelWidget {
52295
52355
  }
52296
52356
  render(item, context, settings) {
52297
52357
  if (context.isPreview) {
52298
- return item.rawValue ? "Claude" : "Model: Claude";
52358
+ const bars2 = renderThinkingBars(3, settings);
52359
+ return item.rawValue ? `Claude${bars2}` : `Model: Claude${bars2}`;
52299
52360
  }
52300
52361
  const model = context.data?.model;
52362
+ const modelId = typeof model === "string" ? model : model?.id;
52301
52363
  const modelDisplayName = typeof model === "string" ? model : model?.display_name ?? model?.id;
52302
- if (modelDisplayName) {
52303
- return item.rawValue ? modelDisplayName : `Model: ${modelDisplayName}`;
52364
+ if (!modelDisplayName)
52365
+ return null;
52366
+ const level = effortToLevel(getEffortLevel());
52367
+ const bars = renderThinkingBars(level, settings);
52368
+ const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD;
52369
+ if (mobile && modelId) {
52370
+ return `M: ${compactModelName(modelId)}${bars}`;
52304
52371
  }
52305
- return null;
52372
+ return item.rawValue ? `${modelDisplayName}${bars}` : `Model: ${modelDisplayName}${bars}`;
52306
52373
  }
52307
52374
  supportsRawValue() {
52308
52375
  return true;
@@ -54272,13 +54339,13 @@ class CurrentWorkingDirWidget {
54272
54339
  supportsColors(item) {
54273
54340
  return true;
54274
54341
  }
54275
- abbreviatePath(path5) {
54342
+ abbreviatePath(path6) {
54276
54343
  const homeDir = os5.homedir();
54277
- const useBackslash = path5.includes("\\") && !path5.includes("/");
54344
+ const useBackslash = path6.includes("\\") && !path6.includes("/");
54278
54345
  const sep = useBackslash ? "\\" : "/";
54279
- let normalizedPath = path5;
54280
- if (path5.startsWith(homeDir)) {
54281
- normalizedPath = "~" + path5.slice(homeDir.length);
54346
+ let normalizedPath = path6;
54347
+ if (path6.startsWith(homeDir)) {
54348
+ normalizedPath = "~" + path6.slice(homeDir.length);
54282
54349
  }
54283
54350
  const parts = normalizedPath.split(/[\\/]+/).filter((part) => part !== "");
54284
54351
  const abbreviated = parts.map((part, index) => {
@@ -54376,13 +54443,16 @@ class ClaudeSessionIdWidget {
54376
54443
  render(item, context, settings) {
54377
54444
  if (context.isPreview) {
54378
54445
  return item.rawValue ? "preview-session-id" : "Session ID: preview-session-id";
54379
- } else {
54380
- const sessionId = context.data?.session_id;
54381
- if (!sessionId) {
54382
- return null;
54383
- }
54384
- return item.rawValue ? sessionId : `Session ID: ${sessionId}`;
54385
54446
  }
54447
+ const sessionId = context.data?.session_id;
54448
+ if (!sessionId) {
54449
+ return null;
54450
+ }
54451
+ const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < 80;
54452
+ if (mobile) {
54453
+ return `S: ${sessionId.slice(0, 8)}`;
54454
+ }
54455
+ return item.rawValue ? sessionId : `Session ID: ${sessionId}`;
54386
54456
  }
54387
54457
  supportsRawValue() {
54388
54458
  return true;
@@ -54396,10 +54466,10 @@ import {
54396
54466
  execSync as execSync8,
54397
54467
  spawnSync
54398
54468
  } from "child_process";
54399
- import * as fs6 from "fs";
54400
- import * as path5 from "path";
54401
- var CACHE_FILE = path5.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.json");
54402
- var LOCK_FILE = path5.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.lock");
54469
+ import * as fs7 from "fs";
54470
+ import * as path6 from "path";
54471
+ var CACHE_FILE = path6.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.json");
54472
+ var LOCK_FILE = path6.join(process.env.HOME ?? "", ".cache", "ccstatusline-api.lock");
54403
54473
  var CACHE_MAX_AGE = 180;
54404
54474
  var LOCK_MAX_AGE = 30;
54405
54475
  var TOKEN_CACHE_MAX_AGE = 3600;
@@ -54407,10 +54477,10 @@ var cachedData = null;
54407
54477
  var cacheTime = 0;
54408
54478
  var cachedToken = null;
54409
54479
  var tokenCacheTime = 0;
54410
- var CRED_FILE = path5.join(process.env.HOME ?? "", ".claude", ".credentials.json");
54480
+ var CRED_FILE = path6.join(process.env.HOME ?? "", ".claude", ".credentials.json");
54411
54481
  function readTokenFromFile() {
54412
54482
  try {
54413
- const creds = JSON.parse(fs6.readFileSync(CRED_FILE, "utf8"));
54483
+ const creds = JSON.parse(fs7.readFileSync(CRED_FILE, "utf8"));
54414
54484
  return creds?.claudeAiOauth?.accessToken ?? null;
54415
54485
  } catch {
54416
54486
  return null;
@@ -54447,7 +54517,7 @@ function getToken() {
54447
54517
  }
54448
54518
  function readStaleCache() {
54449
54519
  try {
54450
- return JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54520
+ return JSON.parse(fs7.readFileSync(CACHE_FILE, "utf8"));
54451
54521
  } catch {
54452
54522
  return null;
54453
54523
  }
@@ -54505,10 +54575,10 @@ function fetchApiData() {
54505
54575
  return cachedData;
54506
54576
  }
54507
54577
  try {
54508
- const stat = fs6.statSync(CACHE_FILE);
54578
+ const stat = fs7.statSync(CACHE_FILE);
54509
54579
  const fileAge = now - Math.floor(stat.mtimeMs / 1000);
54510
54580
  if (fileAge < CACHE_MAX_AGE) {
54511
- const fileData = JSON.parse(fs6.readFileSync(CACHE_FILE, "utf8"));
54581
+ const fileData = JSON.parse(fs7.readFileSync(CACHE_FILE, "utf8"));
54512
54582
  if (!fileData.error) {
54513
54583
  cachedData = fileData;
54514
54584
  cacheTime = now;
@@ -54517,7 +54587,7 @@ function fetchApiData() {
54517
54587
  }
54518
54588
  } catch {}
54519
54589
  try {
54520
- const lockStat = fs6.statSync(LOCK_FILE);
54590
+ const lockStat = fs7.statSync(LOCK_FILE);
54521
54591
  const lockAge = now - Math.floor(lockStat.mtimeMs / 1000);
54522
54592
  if (lockAge < LOCK_MAX_AGE) {
54523
54593
  const stale = readStaleCache();
@@ -54527,11 +54597,11 @@ function fetchApiData() {
54527
54597
  }
54528
54598
  } catch {}
54529
54599
  try {
54530
- const lockDir = path5.dirname(LOCK_FILE);
54531
- if (!fs6.existsSync(lockDir)) {
54532
- fs6.mkdirSync(lockDir, { recursive: true });
54600
+ const lockDir = path6.dirname(LOCK_FILE);
54601
+ if (!fs7.existsSync(lockDir)) {
54602
+ fs7.mkdirSync(lockDir, { recursive: true });
54533
54603
  }
54534
- fs6.writeFileSync(LOCK_FILE, "");
54604
+ fs7.writeFileSync(LOCK_FILE, "");
54535
54605
  } catch {}
54536
54606
  const token = getToken();
54537
54607
  if (!token) {
@@ -54577,11 +54647,11 @@ function fetchApiData() {
54577
54647
  return { error: "parse-error" };
54578
54648
  }
54579
54649
  try {
54580
- const cacheDir = path5.dirname(CACHE_FILE);
54581
- if (!fs6.existsSync(cacheDir)) {
54582
- fs6.mkdirSync(cacheDir, { recursive: true });
54650
+ const cacheDir = path6.dirname(CACHE_FILE);
54651
+ if (!fs7.existsSync(cacheDir)) {
54652
+ fs7.mkdirSync(cacheDir, { recursive: true });
54583
54653
  }
54584
- fs6.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54654
+ fs7.writeFileSync(CACHE_FILE, JSON.stringify(apiData));
54585
54655
  } catch {}
54586
54656
  cachedData = apiData;
54587
54657
  cacheTime = now;
@@ -54605,11 +54675,11 @@ function getErrorMessage(error43) {
54605
54675
  return "[Parse Error]";
54606
54676
  }
54607
54677
  }
54608
- var MOBILE_THRESHOLD = 80;
54678
+ var MOBILE_THRESHOLD2 = 80;
54609
54679
  var MOBILE_BAR_WIDTH = 4;
54610
54680
  var DEFAULT_BAR_WIDTH = 15;
54611
54681
  function isMobileWidth(context) {
54612
- return (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD;
54682
+ return (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MOBILE_THRESHOLD2;
54613
54683
  }
54614
54684
  function makeProgressBar(percent, width = DEFAULT_BAR_WIDTH) {
54615
54685
  const filled = Math.round(percent / 100 * width);
@@ -58681,42 +58751,42 @@ var StatusJSONSchema = exports_external.looseObject({
58681
58751
  });
58682
58752
 
58683
58753
  // src/utils/jsonl.ts
58684
- import * as fs7 from "fs";
58685
- import path7 from "node:path";
58754
+ import * as fs8 from "fs";
58755
+ import path8 from "node:path";
58686
58756
 
58687
58757
  // node_modules/tinyglobby/dist/index.mjs
58688
- import path6, { posix } from "path";
58758
+ import path7, { posix } from "path";
58689
58759
 
58690
58760
  // node_modules/fdir/dist/index.mjs
58691
58761
  import { createRequire as createRequire2 } from "module";
58692
58762
  import { basename as basename2, dirname as dirname3, normalize, relative, resolve as resolve2, sep } from "path";
58693
58763
  import * as nativeFs from "fs";
58694
58764
  var __require2 = /* @__PURE__ */ createRequire2(import.meta.url);
58695
- function cleanPath(path6) {
58696
- let normalized = normalize(path6);
58765
+ function cleanPath(path7) {
58766
+ let normalized = normalize(path7);
58697
58767
  if (normalized.length > 1 && normalized[normalized.length - 1] === sep)
58698
58768
  normalized = normalized.substring(0, normalized.length - 1);
58699
58769
  return normalized;
58700
58770
  }
58701
58771
  var SLASHES_REGEX = /[\\/]/g;
58702
- function convertSlashes(path6, separator) {
58703
- return path6.replace(SLASHES_REGEX, separator);
58772
+ function convertSlashes(path7, separator) {
58773
+ return path7.replace(SLASHES_REGEX, separator);
58704
58774
  }
58705
58775
  var WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
58706
- function isRootDirectory(path6) {
58707
- return path6 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path6);
58776
+ function isRootDirectory(path7) {
58777
+ return path7 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path7);
58708
58778
  }
58709
- function normalizePath(path6, options) {
58779
+ function normalizePath(path7, options) {
58710
58780
  const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
58711
- const pathNeedsCleaning = process.platform === "win32" && path6.includes("/") || path6.startsWith(".");
58781
+ const pathNeedsCleaning = process.platform === "win32" && path7.includes("/") || path7.startsWith(".");
58712
58782
  if (resolvePaths)
58713
- path6 = resolve2(path6);
58783
+ path7 = resolve2(path7);
58714
58784
  if (normalizePath$1 || pathNeedsCleaning)
58715
- path6 = cleanPath(path6);
58716
- if (path6 === ".")
58785
+ path7 = cleanPath(path7);
58786
+ if (path7 === ".")
58717
58787
  return "";
58718
- const needsSeperator = path6[path6.length - 1] !== pathSeparator;
58719
- return convertSlashes(needsSeperator ? path6 + pathSeparator : path6, pathSeparator);
58788
+ const needsSeperator = path7[path7.length - 1] !== pathSeparator;
58789
+ return convertSlashes(needsSeperator ? path7 + pathSeparator : path7, pathSeparator);
58720
58790
  }
58721
58791
  function joinPathWithBasePath(filename, directoryPath) {
58722
58792
  return directoryPath + filename;
@@ -58756,9 +58826,9 @@ var pushDirectory = (directoryPath, paths) => {
58756
58826
  paths.push(directoryPath || ".");
58757
58827
  };
58758
58828
  var pushDirectoryFilter = (directoryPath, paths, filters) => {
58759
- const path6 = directoryPath || ".";
58760
- if (filters.every((filter) => filter(path6, true)))
58761
- paths.push(path6);
58829
+ const path7 = directoryPath || ".";
58830
+ if (filters.every((filter) => filter(path7, true)))
58831
+ paths.push(path7);
58762
58832
  };
58763
58833
  var empty$2 = () => {};
58764
58834
  function build$6(root, options) {
@@ -58815,29 +58885,29 @@ var empty = () => {};
58815
58885
  function build$3(options) {
58816
58886
  return options.group ? groupFiles : empty;
58817
58887
  }
58818
- var resolveSymlinksAsync = function(path6, state, callback$1) {
58819
- const { queue, fs: fs7, options: { suppressErrors } } = state;
58888
+ var resolveSymlinksAsync = function(path7, state, callback$1) {
58889
+ const { queue, fs: fs8, options: { suppressErrors } } = state;
58820
58890
  queue.enqueue();
58821
- fs7.realpath(path6, (error43, resolvedPath) => {
58891
+ fs8.realpath(path7, (error43, resolvedPath) => {
58822
58892
  if (error43)
58823
58893
  return queue.dequeue(suppressErrors ? null : error43, state);
58824
- fs7.stat(resolvedPath, (error$1, stat) => {
58894
+ fs8.stat(resolvedPath, (error$1, stat) => {
58825
58895
  if (error$1)
58826
58896
  return queue.dequeue(suppressErrors ? null : error$1, state);
58827
- if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
58897
+ if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
58828
58898
  return queue.dequeue(null, state);
58829
58899
  callback$1(stat, resolvedPath);
58830
58900
  queue.dequeue(null, state);
58831
58901
  });
58832
58902
  });
58833
58903
  };
58834
- var resolveSymlinks = function(path6, state, callback$1) {
58835
- const { queue, fs: fs7, options: { suppressErrors } } = state;
58904
+ var resolveSymlinks = function(path7, state, callback$1) {
58905
+ const { queue, fs: fs8, options: { suppressErrors } } = state;
58836
58906
  queue.enqueue();
58837
58907
  try {
58838
- const resolvedPath = fs7.realpathSync(path6);
58839
- const stat = fs7.statSync(resolvedPath);
58840
- if (stat.isDirectory() && isRecursive(path6, resolvedPath, state))
58908
+ const resolvedPath = fs8.realpathSync(path7);
58909
+ const stat = fs8.statSync(resolvedPath);
58910
+ if (stat.isDirectory() && isRecursive(path7, resolvedPath, state))
58841
58911
  return;
58842
58912
  callback$1(stat, resolvedPath);
58843
58913
  } catch (e) {
@@ -58850,10 +58920,10 @@ function build$2(options, isSynchronous) {
58850
58920
  return null;
58851
58921
  return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
58852
58922
  }
58853
- function isRecursive(path6, resolved, state) {
58923
+ function isRecursive(path7, resolved, state) {
58854
58924
  if (state.options.useRealPaths)
58855
58925
  return isRecursiveUsingRealPaths(resolved, state);
58856
- let parent = dirname3(path6);
58926
+ let parent = dirname3(path7);
58857
58927
  let depth = 1;
58858
58928
  while (parent !== state.root && depth < 2) {
58859
58929
  const resolvedPath = state.symlinks.get(parent);
@@ -58863,7 +58933,7 @@ function isRecursive(path6, resolved, state) {
58863
58933
  else
58864
58934
  parent = dirname3(parent);
58865
58935
  }
58866
- state.symlinks.set(path6, resolved);
58936
+ state.symlinks.set(path7, resolved);
58867
58937
  return depth > 1;
58868
58938
  }
58869
58939
  function isRecursiveUsingRealPaths(resolved, state) {
@@ -58919,23 +58989,23 @@ var walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58919
58989
  state.queue.enqueue();
58920
58990
  if (currentDepth < 0)
58921
58991
  return state.queue.dequeue(null, state);
58922
- const { fs: fs7 } = state;
58992
+ const { fs: fs8 } = state;
58923
58993
  state.visited.push(crawlPath);
58924
58994
  state.counts.directories++;
58925
- fs7.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
58995
+ fs8.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
58926
58996
  callback$1(entries, directoryPath, currentDepth);
58927
58997
  state.queue.dequeue(state.options.suppressErrors ? null : error43, state);
58928
58998
  });
58929
58999
  };
58930
59000
  var walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58931
- const { fs: fs7 } = state;
59001
+ const { fs: fs8 } = state;
58932
59002
  if (currentDepth < 0)
58933
59003
  return;
58934
59004
  state.visited.push(crawlPath);
58935
59005
  state.counts.directories++;
58936
59006
  let entries = [];
58937
59007
  try {
58938
- entries = fs7.readdirSync(crawlPath || ".", readdirOpts);
59008
+ entries = fs8.readdirSync(crawlPath || ".", readdirOpts);
58939
59009
  } catch (e) {
58940
59010
  if (!state.options.suppressErrors)
58941
59011
  throw e;
@@ -59041,21 +59111,21 @@ var Walker = class {
59041
59111
  const filename = this.joinPath(entry.name, directoryPath);
59042
59112
  this.pushFile(filename, files, this.state.counts, filters);
59043
59113
  } else if (entry.isDirectory()) {
59044
- let path6 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
59045
- if (exclude && exclude(entry.name, path6))
59114
+ let path7 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
59115
+ if (exclude && exclude(entry.name, path7))
59046
59116
  continue;
59047
- this.pushDirectory(path6, paths, filters);
59048
- this.walkDirectory(this.state, path6, path6, depth - 1, this.walk);
59117
+ this.pushDirectory(path7, paths, filters);
59118
+ this.walkDirectory(this.state, path7, path7, depth - 1, this.walk);
59049
59119
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
59050
- let path6 = joinPathWithBasePath(entry.name, directoryPath);
59051
- this.resolveSymlink(path6, this.state, (stat, resolvedPath) => {
59120
+ let path7 = joinPathWithBasePath(entry.name, directoryPath);
59121
+ this.resolveSymlink(path7, this.state, (stat, resolvedPath) => {
59052
59122
  if (stat.isDirectory()) {
59053
59123
  resolvedPath = normalizePath(resolvedPath, this.state.options);
59054
- if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path6 + pathSeparator))
59124
+ if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path7 + pathSeparator))
59055
59125
  return;
59056
- this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path6 + pathSeparator, depth - 1, this.walk);
59126
+ this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path7 + pathSeparator, depth - 1, this.walk);
59057
59127
  } else {
59058
- resolvedPath = useRealPaths ? resolvedPath : path6;
59128
+ resolvedPath = useRealPaths ? resolvedPath : path7;
59059
59129
  const filename = basename2(resolvedPath);
59060
59130
  const directoryPath$1 = normalizePath(dirname3(resolvedPath), this.state.options);
59061
59131
  resolvedPath = this.joinPath(filename, directoryPath$1);
@@ -59215,7 +59285,7 @@ var Builder = class {
59215
59285
  isMatch = globFn(patterns, ...options);
59216
59286
  this.globCache[patterns.join("\x00")] = isMatch;
59217
59287
  }
59218
- this.options.filters.push((path6) => isMatch(path6));
59288
+ this.options.filters.push((path7) => isMatch(path7));
59219
59289
  return this;
59220
59290
  }
59221
59291
  };
@@ -59294,7 +59364,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
59294
59364
  if (!result.endsWith("*") && expandDirectories)
59295
59365
  result += "/**";
59296
59366
  const escapedCwd = escapePath(cwd2);
59297
- if (path6.isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")))
59367
+ if (path7.isAbsolute(result.replace(ESCAPING_BACKSLASHES, "")))
59298
59368
  result = posix.relative(escapedCwd, result);
59299
59369
  else
59300
59370
  result = posix.normalize(result);
@@ -59331,7 +59401,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
59331
59401
  }
59332
59402
  props.depthOffset = newCommonPath.length;
59333
59403
  props.commonPath = newCommonPath;
59334
- props.root = newCommonPath.length > 0 ? path6.posix.join(cwd2, ...newCommonPath) : cwd2;
59404
+ props.root = newCommonPath.length > 0 ? path7.posix.join(cwd2, ...newCommonPath) : cwd2;
59335
59405
  }
59336
59406
  return result;
59337
59407
  }
@@ -59464,18 +59534,18 @@ function globSync(patternsOrOptions, options) {
59464
59534
  ...options,
59465
59535
  patterns: patternsOrOptions
59466
59536
  } : patternsOrOptions;
59467
- const cwd2 = opts.cwd ? path6.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
59537
+ const cwd2 = opts.cwd ? path7.resolve(opts.cwd).replace(BACKSLASHES, "/") : process.cwd().replace(BACKSLASHES, "/");
59468
59538
  return crawl(opts, cwd2, true);
59469
59539
  }
59470
59540
 
59471
59541
  // src/utils/jsonl.ts
59472
59542
  import { promisify } from "util";
59473
- var readFile4 = promisify(fs7.readFile);
59474
- var readFileSync5 = fs7.readFileSync;
59475
- var statSync5 = fs7.statSync;
59543
+ var readFile4 = promisify(fs8.readFile);
59544
+ var readFileSync6 = fs8.readFileSync;
59545
+ var statSync5 = fs8.statSync;
59476
59546
  async function getSessionDuration(transcriptPath) {
59477
59547
  try {
59478
- if (!fs7.existsSync(transcriptPath)) {
59548
+ if (!fs8.existsSync(transcriptPath)) {
59479
59549
  return null;
59480
59550
  }
59481
59551
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59527,7 +59597,7 @@ async function getSessionDuration(transcriptPath) {
59527
59597
  }
59528
59598
  async function getTokenMetrics(transcriptPath) {
59529
59599
  try {
59530
- if (!fs7.existsSync(transcriptPath)) {
59600
+ if (!fs8.existsSync(transcriptPath)) {
59531
59601
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
59532
59602
  }
59533
59603
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59580,7 +59650,7 @@ function getBlockMetrics() {
59580
59650
  function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
59581
59651
  const sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
59582
59652
  const now = new Date;
59583
- const pattern = path7.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
59653
+ const pattern = path8.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
59584
59654
  const files = globSync([pattern], {
59585
59655
  absolute: true,
59586
59656
  cwd: rootDir
@@ -59674,7 +59744,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
59674
59744
  function getAllTimestampsFromFile(filePath) {
59675
59745
  const timestamps = [];
59676
59746
  try {
59677
- const content = readFileSync5(filePath, "utf-8");
59747
+ const content = readFileSync6(filePath, "utf-8");
59678
59748
  const lines = content.trim().split(`
59679
59749
  `).filter((line) => line.length > 0);
59680
59750
  for (const line of lines) {
@@ -59753,15 +59823,21 @@ async function renderMultipleLines(data) {
59753
59823
  if (hasBlockTimer) {
59754
59824
  blockMetrics = getBlockMetrics();
59755
59825
  }
59826
+ const rawWidth = getTerminalWidth();
59827
+ const deduction = settings.flexMode === "full-minus-40" ? 40 : 6;
59828
+ const effectiveWidth = rawWidth ? rawWidth - deduction : null;
59756
59829
  const context = {
59757
59830
  data,
59758
59831
  tokenMetrics,
59759
59832
  sessionDuration,
59760
59833
  blockMetrics,
59834
+ terminalWidth: effectiveWidth,
59761
59835
  isPreview: false
59762
59836
  };
59763
59837
  const preRenderedLines = preRenderAllWidgets(lines, settings, context);
59764
59838
  const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
59839
+ const mobile = effectiveWidth !== null && effectiveWidth > 0 && effectiveWidth < 80;
59840
+ const renderedLines = [];
59765
59841
  let globalSeparatorIndex = 0;
59766
59842
  for (let i = 0;i < lines.length; i++) {
59767
59843
  const lineItems = lines[i];
@@ -59774,12 +59850,24 @@ async function renderMultipleLines(data) {
59774
59850
  const nonMergedWidgets = lineItems.filter((_, idx) => idx === lineItems.length - 1 || !lineItems[idx]?.merge);
59775
59851
  if (nonMergedWidgets.length > 1)
59776
59852
  globalSeparatorIndex += nonMergedWidgets.length - 1;
59777
- let outputLine = line.replace(/ /g, " ");
59778
- outputLine = "\x1B[0m" + outputLine;
59779
- console.log(outputLine);
59853
+ renderedLines.push(line);
59780
59854
  }
59781
59855
  }
59782
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);
59864
+ } else {
59865
+ for (const line of renderedLines) {
59866
+ let outputLine = line.replace(/ /g, " ");
59867
+ outputLine = "\x1B[0m" + outputLine;
59868
+ console.log(outputLine);
59869
+ }
59870
+ }
59783
59871
  if (settings.updatemessage?.message && settings.updatemessage.message.trim() !== "" && settings.updatemessage.remaining && settings.updatemessage.remaining > 0) {
59784
59872
  console.log(settings.updatemessage.message);
59785
59873
  const newRemaining = settings.updatemessage.remaining - 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",