ccstatusline 2.0.21 → 2.0.23
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 +2 -2
- package/dist/ccstatusline.js +92 -53
- package/package.json +1 -1
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 (
|
|
368
|
-
- **Context Percentage (usable)** - Shows percentage of usable context (
|
|
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)
|
package/dist/ccstatusline.js
CHANGED
|
@@ -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()
|
|
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()
|
|
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()
|
|
1275
|
-
var Scheduler = __toESM(require_scheduler()
|
|
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()
|
|
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()
|
|
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()
|
|
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()
|
|
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()
|
|
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.
|
|
51408
|
+
var PACKAGE_VERSION = "2.0.23";
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
}
|
|
@@ -54277,6 +54308,38 @@ var CurrentWorkingDirEditor = ({ widget, onComplete, onCancel, action }) => {
|
|
|
54277
54308
|
children: "Unknown editor mode"
|
|
54278
54309
|
}, undefined, false, undefined, this);
|
|
54279
54310
|
};
|
|
54311
|
+
// src/widgets/ClaudeSessionId.ts
|
|
54312
|
+
class ClaudeSessionIdWidget {
|
|
54313
|
+
getDefaultColor() {
|
|
54314
|
+
return "cyan";
|
|
54315
|
+
}
|
|
54316
|
+
getDescription() {
|
|
54317
|
+
return "Shows the current Claude Code session ID reported in status JSON";
|
|
54318
|
+
}
|
|
54319
|
+
getDisplayName() {
|
|
54320
|
+
return "Claude Session ID";
|
|
54321
|
+
}
|
|
54322
|
+
getEditorDisplay(item) {
|
|
54323
|
+
return { displayText: this.getDisplayName() };
|
|
54324
|
+
}
|
|
54325
|
+
render(item, context, settings) {
|
|
54326
|
+
if (context.isPreview) {
|
|
54327
|
+
return item.rawValue ? "preview-session-id" : "Session ID: preview-session-id";
|
|
54328
|
+
} else {
|
|
54329
|
+
const sessionId = context.data?.session_id;
|
|
54330
|
+
if (!sessionId) {
|
|
54331
|
+
return null;
|
|
54332
|
+
}
|
|
54333
|
+
return item.rawValue ? sessionId : `Session ID: ${sessionId}`;
|
|
54334
|
+
}
|
|
54335
|
+
}
|
|
54336
|
+
supportsRawValue() {
|
|
54337
|
+
return true;
|
|
54338
|
+
}
|
|
54339
|
+
supportsColors(item) {
|
|
54340
|
+
return true;
|
|
54341
|
+
}
|
|
54342
|
+
}
|
|
54280
54343
|
// src/utils/widgets.ts
|
|
54281
54344
|
var widgetRegistry = new Map([
|
|
54282
54345
|
["model", new ModelWidget],
|
|
@@ -54298,7 +54361,8 @@ var widgetRegistry = new Map([
|
|
|
54298
54361
|
["terminal-width", new TerminalWidthWidget],
|
|
54299
54362
|
["version", new VersionWidget],
|
|
54300
54363
|
["custom-text", new CustomTextWidget],
|
|
54301
|
-
["custom-command", new CustomCommandWidget]
|
|
54364
|
+
["custom-command", new CustomCommandWidget],
|
|
54365
|
+
["claude-session-id", new ClaudeSessionIdWidget]
|
|
54302
54366
|
]);
|
|
54303
54367
|
function getWidget(type) {
|
|
54304
54368
|
return widgetRegistry.get(type) ?? null;
|
|
@@ -58987,40 +59051,12 @@ async function getTokenMetrics(transcriptPath) {
|
|
|
58987
59051
|
return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
|
|
58988
59052
|
}
|
|
58989
59053
|
}
|
|
58990
|
-
function getBlockMetrics(
|
|
58991
|
-
|
|
58992
|
-
|
|
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)
|
|
59054
|
+
function getBlockMetrics() {
|
|
59055
|
+
const claudeDir = getClaudeConfigDir();
|
|
59056
|
+
if (!claudeDir)
|
|
59021
59057
|
return null;
|
|
59022
59058
|
try {
|
|
59023
|
-
return findMostRecentBlockStartTime(
|
|
59059
|
+
return findMostRecentBlockStartTime(claudeDir);
|
|
59024
59060
|
} catch {
|
|
59025
59061
|
return null;
|
|
59026
59062
|
}
|
|
@@ -59190,14 +59226,17 @@ async function renderMultipleLines(data) {
|
|
|
59190
59226
|
const hasSessionClock = lines.some((line) => line.some((item) => item.type === "session-clock"));
|
|
59191
59227
|
const hasBlockTimer = lines.some((line) => line.some((item) => item.type === "block-timer"));
|
|
59192
59228
|
let tokenMetrics = null;
|
|
59193
|
-
if (hasTokenItems && data.transcript_path)
|
|
59229
|
+
if (hasTokenItems && data.transcript_path) {
|
|
59194
59230
|
tokenMetrics = await getTokenMetrics(data.transcript_path);
|
|
59231
|
+
}
|
|
59195
59232
|
let sessionDuration = null;
|
|
59196
|
-
if (hasSessionClock && data.transcript_path)
|
|
59233
|
+
if (hasSessionClock && data.transcript_path) {
|
|
59197
59234
|
sessionDuration = await getSessionDuration(data.transcript_path);
|
|
59235
|
+
}
|
|
59198
59236
|
let blockMetrics = null;
|
|
59199
|
-
if (hasBlockTimer
|
|
59200
|
-
blockMetrics = getBlockMetrics(
|
|
59237
|
+
if (hasBlockTimer) {
|
|
59238
|
+
blockMetrics = getBlockMetrics();
|
|
59239
|
+
}
|
|
59201
59240
|
const context = {
|
|
59202
59241
|
data,
|
|
59203
59242
|
tokenMetrics,
|