ccstatusline 2.0.21 → 2.0.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
@@ -364,8 +364,8 @@ Once configured, ccstatusline automatically formats your Claude Code status line
364
364
  - **Tokens Cached** - Shows cached tokens used
365
365
  - **Tokens Total** - Shows total tokens used
366
366
  - **Context Length** - Shows current context length in tokens
367
- - **Context Percentage** - Shows percentage of context limit used (out of 200k)
368
- - **Context Percentage (usable)** - Shows percentage of usable context (out of 160k, accounting for auto-compact at 80%)
367
+ - **Context Percentage** - Shows percentage of context limit used (dynamic: 1M for Sonnet 4.5 with `[1m]` suffix, 200k otherwise)
368
+ - **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%)
369
369
  - **Terminal Width** - Shows detected terminal width (for debugging)
370
370
  - **Custom Text** - Add your own custom text to the status line
371
371
  - **Custom Command** - Execute shell commands and display their output (refreshes whenever the statusline is updated by Claude Code)
@@ -818,7 +818,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
818
818
 
819
819
  // node_modules/react/index.js
820
820
  var require_react = __commonJS((exports, module) => {
821
- var react_development = __toESM(require_react_development(), 1);
821
+ var react_development = __toESM(require_react_development());
822
822
  if (false) {} else {
823
823
  module.exports = react_development;
824
824
  }
@@ -1263,7 +1263,7 @@ var require_scheduler_development = __commonJS((exports) => {
1263
1263
 
1264
1264
  // node_modules/react-reconciler/node_modules/scheduler/index.js
1265
1265
  var require_scheduler = __commonJS((exports, module) => {
1266
- var scheduler_development = __toESM(require_scheduler_development(), 1);
1266
+ var scheduler_development = __toESM(require_scheduler_development());
1267
1267
  if (false) {} else {
1268
1268
  module.exports = scheduler_development;
1269
1269
  }
@@ -1271,8 +1271,8 @@ var require_scheduler = __commonJS((exports, module) => {
1271
1271
 
1272
1272
  // node_modules/react-reconciler/cjs/react-reconciler.development.js
1273
1273
  var require_react_reconciler_development = __commonJS((exports, module) => {
1274
- var React = __toESM(require_react(), 1);
1275
- var Scheduler = __toESM(require_scheduler(), 1);
1274
+ var React = __toESM(require_react());
1275
+ var Scheduler = __toESM(require_scheduler());
1276
1276
  module.exports = function($$$config) {
1277
1277
  function findHook(fiber, id) {
1278
1278
  for (fiber = fiber.memoizedState;fiber !== null && 0 < id; )
@@ -28235,7 +28235,7 @@ var require_react_is_development = __commonJS((exports) => {
28235
28235
 
28236
28236
  // node_modules/react-is/index.js
28237
28237
  var require_react_is = __commonJS((exports, module) => {
28238
- var react_is_development = __toESM(require_react_is_development(), 1);
28238
+ var react_is_development = __toESM(require_react_is_development());
28239
28239
  if (false) {} else {
28240
28240
  module.exports = react_is_development;
28241
28241
  }
@@ -28376,7 +28376,7 @@ var require_checkPropTypes = __commonJS((exports, module) => {
28376
28376
 
28377
28377
  // node_modules/prop-types/factoryWithTypeCheckers.js
28378
28378
  var require_factoryWithTypeCheckers = __commonJS((exports, module) => {
28379
- var ReactIs = __toESM(require_react_is(), 1);
28379
+ var ReactIs = __toESM(require_react_is());
28380
28380
  var assign = require_object_assign();
28381
28381
  var ReactPropTypesSecret = require_ReactPropTypesSecret();
28382
28382
  var has = require_has();
@@ -28800,7 +28800,7 @@ Valid keys: ` + JSON.stringify(Object.keys(shapeTypes), null, " "));
28800
28800
 
28801
28801
  // node_modules/prop-types/index.js
28802
28802
  var require_prop_types = __commonJS((exports, module) => {
28803
- var ReactIs = __toESM(require_react_is(), 1);
28803
+ var ReactIs = __toESM(require_react_is());
28804
28804
  if (true) {
28805
28805
  throwOnDirectAccess = true;
28806
28806
  module.exports = require_factoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
@@ -31641,7 +31641,7 @@ var require_gradient_string = __commonJS((exports, module) => {
31641
31641
 
31642
31642
  // node_modules/react/cjs/react-jsx-dev-runtime.development.js
31643
31643
  var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
31644
- var React14 = __toESM(require_react(), 1);
31644
+ var React14 = __toESM(require_react());
31645
31645
  (function() {
31646
31646
  function getComponentNameFromType(type) {
31647
31647
  if (type == null)
@@ -31855,7 +31855,7 @@ React keys must be passed directly to JSX without using spread:
31855
31855
 
31856
31856
  // node_modules/react/jsx-dev-runtime.js
31857
31857
  var require_jsx_dev_runtime = __commonJS((exports, module) => {
31858
- var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development(), 1);
31858
+ var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development());
31859
31859
  if (false) {} else {
31860
31860
  module.exports = react_jsx_dev_runtime_development;
31861
31861
  }
@@ -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.21";
51408
+ var PACKAGE_VERSION = "2.0.22";
51409
51409
  function getPackageVersion() {
51410
51410
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51411
51411
  return PACKAGE_VERSION;
@@ -52523,6 +52523,33 @@ class GitWorktreeWidget {
52523
52523
  return true;
52524
52524
  }
52525
52525
  }
52526
+ // src/utils/model-context.ts
52527
+ function getContextConfig(modelId) {
52528
+ const defaultConfig = {
52529
+ maxTokens: 200000,
52530
+ usableTokens: 160000
52531
+ };
52532
+ if (!modelId)
52533
+ return defaultConfig;
52534
+ if (modelId.includes("claude-sonnet-4-5") && modelId.toLowerCase().includes("[1m]")) {
52535
+ return {
52536
+ maxTokens: 1e6,
52537
+ usableTokens: 800000
52538
+ };
52539
+ }
52540
+ return defaultConfig;
52541
+ }
52542
+
52543
+ // src/utils/context-percentage.ts
52544
+ function calculateContextPercentage(context) {
52545
+ if (!context.tokenMetrics) {
52546
+ return 0;
52547
+ }
52548
+ const modelId = context.data?.model?.id;
52549
+ const contextConfig = getContextConfig(modelId);
52550
+ return Math.min(100, context.tokenMetrics.contextLength / contextConfig.maxTokens * 100);
52551
+ }
52552
+
52526
52553
  // src/utils/renderer.ts
52527
52554
  var ANSI_REGEX = new RegExp(`\\x1b\\[[0-9;]*m`, "g");
52528
52555
  function formatTokens(count) {
@@ -52575,7 +52602,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
52575
52602
  terminalWidth = detectedWidth - 40;
52576
52603
  } else if (flexMode === "full-until-compact") {
52577
52604
  const threshold = settings.compactThreshold;
52578
- const contextPercentage = context.tokenMetrics ? Math.min(100, context.tokenMetrics.contextLength / 200000 * 100) : 0;
52605
+ const contextPercentage = calculateContextPercentage(context);
52579
52606
  if (contextPercentage >= threshold) {
52580
52607
  terminalWidth = detectedWidth - 40;
52581
52608
  } else {
@@ -52949,7 +52976,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
52949
52976
  terminalWidth = detectedWidth - 40;
52950
52977
  } else if (flexMode === "full-until-compact") {
52951
52978
  const threshold = settings.compactThreshold;
52952
- const contextPercentage = context.tokenMetrics ? Math.min(100, context.tokenMetrics.contextLength / 200000 * 100) : 0;
52979
+ const contextPercentage = calculateContextPercentage(context);
52953
52980
  if (contextPercentage >= threshold) {
52954
52981
  terminalWidth = detectedWidth - 40;
52955
52982
  } else {
@@ -53339,7 +53366,7 @@ class ContextPercentageWidget {
53339
53366
  return "blue";
53340
53367
  }
53341
53368
  getDescription() {
53342
- return "Shows percentage of context window used or remaining (of 200k tokens)";
53369
+ return "Shows percentage of context window used or remaining";
53343
53370
  }
53344
53371
  getDisplayName() {
53345
53372
  return "Context %";
@@ -53374,7 +53401,9 @@ class ContextPercentageWidget {
53374
53401
  const previewValue = isInverse ? "90.7%" : "9.3%";
53375
53402
  return item.rawValue ? previewValue : `Ctx: ${previewValue}`;
53376
53403
  } else if (context.tokenMetrics) {
53377
- const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / 200000 * 100);
53404
+ const modelId = context.data?.model?.id;
53405
+ const contextConfig = getContextConfig(modelId);
53406
+ const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.maxTokens * 100);
53378
53407
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53379
53408
  return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx: ${displayPercentage.toFixed(1)}%`;
53380
53409
  }
@@ -53398,7 +53427,7 @@ class ContextPercentageUsableWidget {
53398
53427
  return "green";
53399
53428
  }
53400
53429
  getDescription() {
53401
- return "Shows percentage of usable context window used or remaining (of 160k tokens before auto-compact)";
53430
+ return "Shows percentage of usable context window used or remaining (80% of max before auto-compact)";
53402
53431
  }
53403
53432
  getDisplayName() {
53404
53433
  return "Context % (usable)";
@@ -53433,7 +53462,9 @@ class ContextPercentageUsableWidget {
53433
53462
  const previewValue = isInverse ? "88.4%" : "11.6%";
53434
53463
  return item.rawValue ? previewValue : `Ctx(u): ${previewValue}`;
53435
53464
  } else if (context.tokenMetrics) {
53436
- const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / 160000 * 100);
53465
+ const modelId = context.data?.model?.id;
53466
+ const contextConfig = getContextConfig(modelId);
53467
+ const usedPercentage = Math.min(100, context.tokenMetrics.contextLength / contextConfig.usableTokens * 100);
53437
53468
  const displayPercentage = isInverse ? 100 - usedPercentage : usedPercentage;
53438
53469
  return item.rawValue ? `${displayPercentage.toFixed(1)}%` : `Ctx(u): ${displayPercentage.toFixed(1)}%`;
53439
53470
  }
@@ -58987,40 +59018,12 @@ async function getTokenMetrics(transcriptPath) {
58987
59018
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
58988
59019
  }
58989
59020
  }
58990
- function getBlockMetrics(transcriptPath) {
58991
- if (!transcriptPath || typeof transcriptPath !== "string") {
58992
- return null;
58993
- }
58994
- let claudePath = null;
58995
- if (process.platform === "win32") {
58996
- const homeDir = process.env.USERPROFILE ?? process.env.HOME;
58997
- if (homeDir) {
58998
- claudePath = path6.join(homeDir, ".claude");
58999
- if (!fs6.existsSync(claudePath)) {
59000
- return null;
59001
- }
59002
- }
59003
- } else {
59004
- let currentPath = path6.dirname(transcriptPath);
59005
- const visitedPaths = new Set;
59006
- while (currentPath && !visitedPaths.has(currentPath)) {
59007
- visitedPaths.add(currentPath);
59008
- const baseName = path6.basename(currentPath);
59009
- if (baseName === ".claude") {
59010
- claudePath = currentPath;
59011
- break;
59012
- }
59013
- const parentPath = path6.dirname(currentPath);
59014
- if (parentPath === currentPath) {
59015
- break;
59016
- }
59017
- currentPath = parentPath;
59018
- }
59019
- }
59020
- if (!claudePath)
59021
+ function getBlockMetrics() {
59022
+ const claudeDir = getClaudeConfigDir();
59023
+ if (!claudeDir)
59021
59024
  return null;
59022
59025
  try {
59023
- return findMostRecentBlockStartTime(claudePath);
59026
+ return findMostRecentBlockStartTime(claudeDir);
59024
59027
  } catch {
59025
59028
  return null;
59026
59029
  }
@@ -59190,14 +59193,17 @@ async function renderMultipleLines(data) {
59190
59193
  const hasSessionClock = lines.some((line) => line.some((item) => item.type === "session-clock"));
59191
59194
  const hasBlockTimer = lines.some((line) => line.some((item) => item.type === "block-timer"));
59192
59195
  let tokenMetrics = null;
59193
- if (hasTokenItems && data.transcript_path)
59196
+ if (hasTokenItems && data.transcript_path) {
59194
59197
  tokenMetrics = await getTokenMetrics(data.transcript_path);
59198
+ }
59195
59199
  let sessionDuration = null;
59196
- if (hasSessionClock && data.transcript_path)
59200
+ if (hasSessionClock && data.transcript_path) {
59197
59201
  sessionDuration = await getSessionDuration(data.transcript_path);
59202
+ }
59198
59203
  let blockMetrics = null;
59199
- if (hasBlockTimer && data.transcript_path)
59200
- blockMetrics = getBlockMetrics(data.transcript_path);
59204
+ if (hasBlockTimer) {
59205
+ blockMetrics = getBlockMetrics();
59206
+ }
59201
59207
  const context = {
59202
59208
  data,
59203
59209
  tokenMetrics,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.0.21",
3
+ "version": "2.0.22",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",