cc-context-stats 1.12.1 → 1.13.0
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/package.json +1 -1
- package/scripts/statusline.js +62 -12
package/package.json
CHANGED
package/scripts/statusline.js
CHANGED
|
@@ -114,35 +114,49 @@ function getMIColor(mi, utilization, greenColor, yellowColor, redColor) {
|
|
|
114
114
|
/**
|
|
115
115
|
* Determine context zone indicator (P/C/D/X/Z) based on token usage.
|
|
116
116
|
* Returns { zone, colorName }.
|
|
117
|
+
* zoneConfig is an optional object of threshold overrides (0 = use default).
|
|
117
118
|
*/
|
|
118
|
-
function getContextZone(usedTokens, contextWindowSize) {
|
|
119
|
+
function getContextZone(usedTokens, contextWindowSize, zoneConfig) {
|
|
119
120
|
if (contextWindowSize === 0) {
|
|
120
121
|
return { zone: 'Plan', colorName: 'green' };
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
const
|
|
124
|
+
const zc = zoneConfig || {};
|
|
125
|
+
|
|
126
|
+
const lmt = zc.large_model_threshold || LARGE_MODEL_THRESHOLD;
|
|
127
|
+
const isLarge = contextWindowSize >= lmt;
|
|
124
128
|
|
|
125
129
|
if (isLarge) {
|
|
126
|
-
|
|
130
|
+
const pMax = zc.zone_1m_plan_max || ZONE_1M_P_MAX;
|
|
131
|
+
const cMax = zc.zone_1m_code_max || ZONE_1M_C_MAX;
|
|
132
|
+
const dMax = zc.zone_1m_dump_max || ZONE_1M_D_MAX;
|
|
133
|
+
const xMax = zc.zone_1m_xdump_max || ZONE_1M_X_MAX;
|
|
134
|
+
|
|
135
|
+
if (usedTokens < pMax) {
|
|
127
136
|
return { zone: 'Plan', colorName: 'green' };
|
|
128
137
|
}
|
|
129
|
-
if (usedTokens <
|
|
138
|
+
if (usedTokens < cMax) {
|
|
130
139
|
return { zone: 'Code', colorName: 'yellow' };
|
|
131
140
|
}
|
|
132
|
-
if (usedTokens <
|
|
141
|
+
if (usedTokens < dMax) {
|
|
133
142
|
return { zone: 'Dump', colorName: 'orange' };
|
|
134
143
|
}
|
|
135
|
-
if (usedTokens <
|
|
144
|
+
if (usedTokens < xMax) {
|
|
136
145
|
return { zone: 'ExDump', colorName: 'dark_red' };
|
|
137
146
|
}
|
|
138
147
|
return { zone: 'Dead', colorName: 'gray' };
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
// Standard models
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
const
|
|
150
|
+
// Standard models
|
|
151
|
+
const dumpRatio = zc.zone_std_dump_ratio || ZONE_STD_DUMP_ZONE;
|
|
152
|
+
const warnBuf = zc.zone_std_warn_buffer || ZONE_STD_WARN_BUFFER;
|
|
153
|
+
const hardLim = zc.zone_std_hard_limit || ZONE_STD_HARD_LIMIT;
|
|
154
|
+
const deadRat = zc.zone_std_dead_ratio || ZONE_STD_DEAD_ZONE;
|
|
155
|
+
|
|
156
|
+
const dumpZoneTokens = Math.floor(contextWindowSize * dumpRatio);
|
|
157
|
+
const warnStart = Math.max(0, dumpZoneTokens - warnBuf);
|
|
158
|
+
const hardLimitTokens = Math.floor(contextWindowSize * hardLim);
|
|
159
|
+
const deadZoneTokens = Math.floor(contextWindowSize * deadRat);
|
|
146
160
|
|
|
147
161
|
if (usedTokens < warnStart) {
|
|
148
162
|
return { zone: 'Plan', colorName: 'green' };
|
|
@@ -284,6 +298,23 @@ const COLOR_CONFIG_KEYS = {
|
|
|
284
298
|
color_separator: 'separator',
|
|
285
299
|
};
|
|
286
300
|
|
|
301
|
+
// Zone threshold config keys (integer token counts)
|
|
302
|
+
const ZONE_INT_KEYS = new Set([
|
|
303
|
+
'zone_1m_plan_max',
|
|
304
|
+
'zone_1m_code_max',
|
|
305
|
+
'zone_1m_dump_max',
|
|
306
|
+
'zone_1m_xdump_max',
|
|
307
|
+
'zone_std_warn_buffer',
|
|
308
|
+
'large_model_threshold',
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
// Zone threshold config keys (float ratios 0-1)
|
|
312
|
+
const ZONE_FLOAT_KEYS = new Set([
|
|
313
|
+
'zone_std_dump_ratio',
|
|
314
|
+
'zone_std_hard_limit',
|
|
315
|
+
'zone_std_dead_ratio',
|
|
316
|
+
]);
|
|
317
|
+
|
|
287
318
|
/**
|
|
288
319
|
* Return the visible width of a string after stripping ANSI escape sequences.
|
|
289
320
|
*/
|
|
@@ -393,6 +424,7 @@ function readConfig() {
|
|
|
393
424
|
showMI: false,
|
|
394
425
|
miCurveBeta: 0,
|
|
395
426
|
colors: {},
|
|
427
|
+
zoneConfig: {},
|
|
396
428
|
};
|
|
397
429
|
const configPath = path.join(os.homedir(), '.claude', 'statusline.conf');
|
|
398
430
|
|
|
@@ -464,6 +496,24 @@ show_session=true
|
|
|
464
496
|
if (ansi) {
|
|
465
497
|
config.colors[COLOR_CONFIG_KEYS[keyTrimmed]] = ansi;
|
|
466
498
|
}
|
|
499
|
+
} else if (ZONE_INT_KEYS.has(keyTrimmed)) {
|
|
500
|
+
const v = parseInt(rawValue, 10);
|
|
501
|
+
if (!isNaN(v) && v > 0) {
|
|
502
|
+
config.zoneConfig[keyTrimmed] = v;
|
|
503
|
+
} else {
|
|
504
|
+
process.stderr.write(
|
|
505
|
+
`[statusline] warning: ${keyTrimmed} must be a positive integer, ignoring '${rawValue}'\n`
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
} else if (ZONE_FLOAT_KEYS.has(keyTrimmed)) {
|
|
509
|
+
const v = parseFloat(rawValue);
|
|
510
|
+
if (!isNaN(v) && v > 0 && v < 1) {
|
|
511
|
+
config.zoneConfig[keyTrimmed] = v;
|
|
512
|
+
} else {
|
|
513
|
+
process.stderr.write(
|
|
514
|
+
`[statusline] warning: ${keyTrimmed} must be between 0 and 1, ignoring '${rawValue}'\n`
|
|
515
|
+
);
|
|
516
|
+
}
|
|
467
517
|
}
|
|
468
518
|
}
|
|
469
519
|
} catch (e) {
|
|
@@ -572,7 +622,7 @@ process.stdin.on('end', () => {
|
|
|
572
622
|
: `${(freeTokens / 1000).toFixed(1)}k`;
|
|
573
623
|
|
|
574
624
|
// Zone indicator — determines color for both context info and zone label
|
|
575
|
-
const zoneResult = getContextZone(usedTokens, totalSize);
|
|
625
|
+
const zoneResult = getContextZone(usedTokens, totalSize, config.zoneConfig);
|
|
576
626
|
const zoneAnsi = zoneAnsiColor(zoneResult.colorName);
|
|
577
627
|
|
|
578
628
|
// Context info uses zone color (traffic-light), with per-property override
|