@bastra-recall/statusline 1.0.0 → 1.0.1
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/dist/.build-revision +1 -2
- package/dist/browser.d.ts +100 -102
- package/dist/browser.js +3 -3
- package/dist/index.mjs +14 -14
- package/package.json +3 -3
- package/src/config/defaults.ts +5 -1
- package/src/powerline-layout.ts +174 -0
- package/src/powerline-segments.ts +374 -0
- package/src/powerline-theme.ts +323 -0
- package/src/powerline.ts +53 -835
- package/src/segments/git.ts +3 -3
- package/src/segments/pricing.ts +78 -1
- package/src/segments/renderer-bars.ts +83 -0
- package/src/segments/renderer-format.ts +89 -0
- package/src/segments/renderer-types.ts +171 -0
- package/src/segments/renderer.ts +80 -328
- package/src/segments/session.ts +29 -5
- package/src/segments/today.ts +11 -13
- package/src/tui/sections-bars.ts +215 -0
- package/src/tui/sections-parts.ts +604 -0
- package/src/tui/sections-shared.ts +23 -0
- package/src/tui/sections.ts +67 -819
- package/src/utils/budget.ts +1 -1
- package/src/utils/claude.ts +55 -16
- package/src/utils/formatters.ts +12 -5
- package/src/utils/terminal.ts +5 -5
package/src/tui/sections.ts
CHANGED
|
@@ -3,280 +3,77 @@ import type { PowerlineColors } from "../themes";
|
|
|
3
3
|
import type {
|
|
4
4
|
TuiData,
|
|
5
5
|
SymbolSet,
|
|
6
|
-
BoxChars,
|
|
7
6
|
RenderCtx,
|
|
8
7
|
SegmentTemplate,
|
|
9
8
|
JustifyValue,
|
|
10
|
-
TuiTitleConfig,
|
|
11
9
|
} from "./types";
|
|
12
10
|
import { visibleLength } from "../utils/terminal";
|
|
13
11
|
|
|
14
12
|
import {
|
|
15
|
-
formatCost,
|
|
16
|
-
formatTokenCount,
|
|
17
|
-
collapseHome,
|
|
18
13
|
formatDuration,
|
|
19
14
|
formatModelName,
|
|
20
15
|
formatResponseTime,
|
|
21
|
-
formatTimeRemaining,
|
|
22
|
-
formatLongTimeRemaining,
|
|
23
|
-
minutesUntilReset,
|
|
24
16
|
abbreviateFishStyle,
|
|
25
|
-
formatCacheTimerElapsed,
|
|
26
17
|
} from "../utils/formatters";
|
|
27
|
-
import {
|
|
28
|
-
import { colorize, truncateAnsi } from "./primitives";
|
|
29
|
-
import { getEffortLevel, getThinkingEnabled } from "../utils/claude";
|
|
18
|
+
import { colorize } from "./primitives";
|
|
30
19
|
import { resolveIconVisibility } from "../utils/icon-visibility";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
if (finalLeftLen + finalRightLen > innerWidth) {
|
|
90
|
-
const maxRight = Math.max(0, innerWidth - finalLeftLen);
|
|
91
|
-
finalRight = truncateAnsi(finalRight, maxRight);
|
|
92
|
-
finalRightLen = visibleLength(finalRight);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const fillCount = innerWidth - finalLeftLen - finalRightLen;
|
|
97
|
-
|
|
98
|
-
if (fillCount < 2) {
|
|
99
|
-
const simpleFill = innerWidth - finalLeftLen;
|
|
100
|
-
return (
|
|
101
|
-
box.topLeft +
|
|
102
|
-
finalLeft +
|
|
103
|
-
box.horizontal.repeat(Math.max(0, simpleFill)) +
|
|
104
|
-
box.topRight
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
box.topLeft +
|
|
110
|
-
finalLeft +
|
|
111
|
-
box.horizontal.repeat(fillCount) +
|
|
112
|
-
finalRight +
|
|
113
|
-
box.topRight
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function resolveThresholdStyle(
|
|
118
|
-
pct: number,
|
|
119
|
-
defaultFg: string,
|
|
120
|
-
defaultBold: boolean,
|
|
121
|
-
colors: PowerlineColors,
|
|
122
|
-
warningAt = 60,
|
|
123
|
-
criticalAt = 80,
|
|
124
|
-
): { fg: string; bold: boolean } {
|
|
125
|
-
if (pct >= criticalAt)
|
|
126
|
-
return { fg: colors.contextCriticalFg, bold: colors.contextCriticalBold };
|
|
127
|
-
if (pct >= warningAt)
|
|
128
|
-
return { fg: colors.contextWarningFg, bold: colors.contextWarningBold };
|
|
129
|
-
return { fg: defaultFg, bold: defaultBold };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function buildBarString(
|
|
133
|
-
pct: number,
|
|
134
|
-
barWidth: number,
|
|
135
|
-
sym: SymbolSet,
|
|
136
|
-
reset: string,
|
|
137
|
-
fgColor: string,
|
|
138
|
-
bold = false,
|
|
139
|
-
): string {
|
|
140
|
-
barWidth = Math.max(5, barWidth);
|
|
141
|
-
const filledCount = Math.max(
|
|
142
|
-
0,
|
|
143
|
-
Math.min(barWidth, Math.round((pct / 100) * barWidth)),
|
|
144
|
-
);
|
|
145
|
-
const emptyCount = barWidth - filledCount;
|
|
146
|
-
const bar =
|
|
147
|
-
sym.bar_filled.repeat(filledCount) + sym.bar_empty.repeat(emptyCount);
|
|
148
|
-
return colorize(bar, fgColor, reset, bold);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function formatContextParts(
|
|
152
|
-
data: TuiData,
|
|
153
|
-
sym: SymbolSet,
|
|
154
|
-
iconVisible = true,
|
|
155
|
-
): Record<string, string> {
|
|
156
|
-
if (!data.contextInfo)
|
|
157
|
-
return { icon: "", label: "context", bar: "", pct: "", tokens: "" };
|
|
158
|
-
|
|
159
|
-
const usedPct = data.contextInfo.usablePercentage;
|
|
160
|
-
const tokenStr = formatTokenCount(data.contextInfo.totalTokens);
|
|
161
|
-
const maxStr = formatTokenCount(data.contextInfo.maxTokens);
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
icon: iconVisible ? sym.context_time : "",
|
|
165
|
-
label: "context",
|
|
166
|
-
bar: " ",
|
|
167
|
-
pct: `${usedPct}%`,
|
|
168
|
-
tokens: `${tokenStr}/${maxStr}`,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function buildContextBar(
|
|
173
|
-
data: TuiData,
|
|
174
|
-
barWidth: number,
|
|
175
|
-
sym: SymbolSet,
|
|
176
|
-
reset: string,
|
|
177
|
-
colors: PowerlineColors,
|
|
178
|
-
partFg?: Record<string, string>,
|
|
179
|
-
): string {
|
|
180
|
-
if (!data.contextInfo) return "";
|
|
181
|
-
const usedPct = data.contextInfo.usablePercentage;
|
|
182
|
-
const defaultFg =
|
|
183
|
-
partFg?.["context.bar"] ?? partFg?.["context"] ?? colors.contextFg;
|
|
184
|
-
const { fg, bold } = resolveThresholdStyle(
|
|
185
|
-
usedPct,
|
|
186
|
-
defaultFg,
|
|
187
|
-
colors.contextBold,
|
|
188
|
-
colors,
|
|
189
|
-
);
|
|
190
|
-
return buildBarString(usedPct, barWidth, sym, reset, fg, bold);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export function buildBlockBar(
|
|
194
|
-
data: TuiData,
|
|
195
|
-
barWidth: number,
|
|
196
|
-
sym: SymbolSet,
|
|
197
|
-
reset: string,
|
|
198
|
-
colors: PowerlineColors,
|
|
199
|
-
config: PowerlineConfig,
|
|
200
|
-
partFg?: Record<string, string>,
|
|
201
|
-
): string {
|
|
202
|
-
if (!data.blockInfo) return "";
|
|
203
|
-
|
|
204
|
-
const pct = data.blockInfo.nativeUtilization;
|
|
205
|
-
const warningThreshold = config.budget?.block?.warningThreshold ?? 80;
|
|
206
|
-
const defaultFg =
|
|
207
|
-
partFg?.["block.bar"] ?? partFg?.["block"] ?? colors.blockFg;
|
|
208
|
-
const { fg, bold } = resolveThresholdStyle(
|
|
209
|
-
pct,
|
|
210
|
-
defaultFg,
|
|
211
|
-
colors.blockBold,
|
|
212
|
-
colors,
|
|
213
|
-
50,
|
|
214
|
-
warningThreshold,
|
|
215
|
-
);
|
|
216
|
-
return buildBarString(pct, barWidth, sym, reset, fg, bold);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export function buildWeeklyBar(
|
|
220
|
-
data: TuiData,
|
|
221
|
-
barWidth: number,
|
|
222
|
-
sym: SymbolSet,
|
|
223
|
-
reset: string,
|
|
224
|
-
colors: PowerlineColors,
|
|
225
|
-
partFg?: Record<string, string>,
|
|
226
|
-
): string {
|
|
227
|
-
const sevenDay = data.hookData.rate_limits?.seven_day;
|
|
228
|
-
if (!sevenDay) return "";
|
|
229
|
-
|
|
230
|
-
const pct = sevenDay.used_percentage;
|
|
231
|
-
const defaultFg =
|
|
232
|
-
partFg?.["weekly.bar"] ?? partFg?.["weekly"] ?? colors.weeklyFg;
|
|
233
|
-
const { fg, bold } = resolveThresholdStyle(
|
|
234
|
-
pct,
|
|
235
|
-
defaultFg,
|
|
236
|
-
colors.weeklyBold,
|
|
237
|
-
colors,
|
|
238
|
-
);
|
|
239
|
-
return buildBarString(pct, barWidth, sym, reset, fg, bold);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export function buildContextLine(
|
|
243
|
-
data: TuiData,
|
|
244
|
-
contentWidth: number,
|
|
245
|
-
sym: SymbolSet,
|
|
246
|
-
reset: string,
|
|
247
|
-
colors: PowerlineColors,
|
|
248
|
-
): string | null {
|
|
249
|
-
if (!data.contextInfo) {
|
|
250
|
-
return null;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const usedPct = data.contextInfo.usablePercentage;
|
|
254
|
-
const tokenStr = formatTokenCount(data.contextInfo.totalTokens);
|
|
255
|
-
const maxStr = formatTokenCount(data.contextInfo.maxTokens);
|
|
256
|
-
const suffix = ` ${usedPct}% ${tokenStr}/${maxStr}`;
|
|
257
|
-
const barLen = Math.max(5, contentWidth - suffix.length);
|
|
258
|
-
const filledCount = Math.max(
|
|
259
|
-
0,
|
|
260
|
-
Math.min(barLen, Math.round((usedPct / 100) * barLen)),
|
|
261
|
-
);
|
|
262
|
-
const emptyCount = barLen - filledCount;
|
|
263
|
-
const bar =
|
|
264
|
-
sym.bar_filled.repeat(filledCount) + sym.bar_empty.repeat(emptyCount);
|
|
265
|
-
|
|
266
|
-
const { fg, bold } = resolveThresholdStyle(
|
|
267
|
-
usedPct,
|
|
268
|
-
colors.contextFg,
|
|
269
|
-
colors.contextBold,
|
|
270
|
-
colors,
|
|
271
|
-
);
|
|
272
|
-
|
|
273
|
-
return colorize(`${bar}${suffix}`, fg, reset, bold);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function getDirectoryDisplay(hookData: TuiData["hookData"]): string {
|
|
277
|
-
const currentDir = hookData.workspace?.current_dir || hookData.cwd || "/";
|
|
278
|
-
return collapseHome(currentDir);
|
|
279
|
-
}
|
|
20
|
+
import { resolveThresholdStyle, getDirectoryDisplay } from "./sections-shared";
|
|
21
|
+
import { buildContextLine } from "./sections-bars";
|
|
22
|
+
import {
|
|
23
|
+
formatContextParts,
|
|
24
|
+
formatBlockParts,
|
|
25
|
+
formatBlockSegment,
|
|
26
|
+
formatWeeklyParts,
|
|
27
|
+
formatWeeklySegment,
|
|
28
|
+
formatSessionParts,
|
|
29
|
+
formatSessionSegment,
|
|
30
|
+
formatTodayParts,
|
|
31
|
+
formatTodaySegment,
|
|
32
|
+
formatMetricsParts,
|
|
33
|
+
formatMetricsSegment,
|
|
34
|
+
formatActivityParts,
|
|
35
|
+
formatActivitySegment,
|
|
36
|
+
formatGitParts,
|
|
37
|
+
formatGitSegment,
|
|
38
|
+
formatDirParts,
|
|
39
|
+
formatDirValue,
|
|
40
|
+
formatVersionParts,
|
|
41
|
+
formatVersionSegment,
|
|
42
|
+
formatAgentParts,
|
|
43
|
+
formatAgentSegment,
|
|
44
|
+
formatThinkingParts,
|
|
45
|
+
formatThinkingSegment,
|
|
46
|
+
formatCacheTimerParts,
|
|
47
|
+
formatCacheTimerSegment,
|
|
48
|
+
cacheTimerTtl,
|
|
49
|
+
cacheTimerStyle,
|
|
50
|
+
formatTmuxParts,
|
|
51
|
+
formatTmuxSegment,
|
|
52
|
+
formatEnvParts,
|
|
53
|
+
formatEnvSegment,
|
|
54
|
+
} from "./sections-parts";
|
|
55
|
+
|
|
56
|
+
// #680: bar renderers live in sections-bars.ts, part formatters in
|
|
57
|
+
// sections-parts.ts; this module keeps the public surface and re-exports them.
|
|
58
|
+
export {
|
|
59
|
+
resolveTitleToken,
|
|
60
|
+
buildTitleBar,
|
|
61
|
+
buildContextBar,
|
|
62
|
+
buildBlockBar,
|
|
63
|
+
buildWeeklyBar,
|
|
64
|
+
buildContextLine,
|
|
65
|
+
} from "./sections-bars";
|
|
66
|
+
export {
|
|
67
|
+
formatContextParts,
|
|
68
|
+
formatBlockParts,
|
|
69
|
+
formatBlockSegment,
|
|
70
|
+
formatWeeklyParts,
|
|
71
|
+
formatWeeklySegment,
|
|
72
|
+
formatSessionParts,
|
|
73
|
+
formatSessionSegment,
|
|
74
|
+
formatTodayParts,
|
|
75
|
+
formatTodaySegment,
|
|
76
|
+
} from "./sections-parts";
|
|
280
77
|
|
|
281
78
|
export function collectMetricSegments(
|
|
282
79
|
data: TuiData,
|
|
@@ -450,6 +247,7 @@ export function collectFooterParts(
|
|
|
450
247
|
const { fg, bold } = cacheTimerStyle(
|
|
451
248
|
data.cacheTimerInfo.elapsedSeconds,
|
|
452
249
|
colors,
|
|
250
|
+
cacheTimerTtl(config, data),
|
|
453
251
|
);
|
|
454
252
|
parts.push(colorize(cacheTimerText, fg, reset, bold));
|
|
455
253
|
}
|
|
@@ -547,565 +345,11 @@ function formatBastraText(data: TuiData): string | null {
|
|
|
547
345
|
info.currentRecallStartedAt !== null
|
|
548
346
|
? info.totalMs + Math.max(0, Date.now() - info.currentRecallStartedAt)
|
|
549
347
|
: info.totalMs;
|
|
550
|
-
return `bastra · ${info.recallCount} calls · ${info.totalHits} hits · ${live}ms · ${info.currentStage}`;
|
|
348
|
+
return `bastra · ${info.recallCount} ${info.recallCount === 1 ? "call" : "calls"} · ${info.totalHits} ${info.totalHits === 1 ? "hit" : "hits"} · ${live}ms · ${info.currentStage}`;
|
|
551
349
|
}
|
|
552
|
-
const hits = info.totalHits > 0 ? ` · ${info.totalHits} hits` : "";
|
|
350
|
+
const hits = info.totalHits > 0 ? ` · ${info.totalHits} ${info.totalHits === 1 ? "hit" : "hits"}` : "";
|
|
553
351
|
const ms = info.totalMs > 0 ? ` · ${info.totalMs}ms` : "";
|
|
554
|
-
return `✓ bastra · ${info.recallCount} calls${hits}${ms}`;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
export function formatBlockParts(
|
|
558
|
-
blockInfo: TuiData["blockInfo"] & {},
|
|
559
|
-
sym: SymbolSet,
|
|
560
|
-
_config: PowerlineConfig,
|
|
561
|
-
iconVisible = true,
|
|
562
|
-
): Record<string, string> {
|
|
563
|
-
const value = `${Math.round(blockInfo.nativeUtilization)}%`;
|
|
564
|
-
const time = formatTimeRemaining(blockInfo.timeRemaining);
|
|
565
|
-
|
|
566
|
-
return {
|
|
567
|
-
icon: iconVisible ? sym.block_cost : "",
|
|
568
|
-
label: "block",
|
|
569
|
-
value,
|
|
570
|
-
time,
|
|
571
|
-
budget: "",
|
|
572
|
-
bar: " ",
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
export function formatBlockSegment(
|
|
577
|
-
blockInfo: TuiData["blockInfo"] & {},
|
|
578
|
-
sym: SymbolSet,
|
|
579
|
-
config: PowerlineConfig,
|
|
580
|
-
iconVisible = true,
|
|
581
|
-
): string {
|
|
582
|
-
const parts = formatBlockParts(blockInfo, sym, config, iconVisible);
|
|
583
|
-
let text = parts.icon ? `${parts.icon} ${parts.value}` : (parts.value ?? "");
|
|
584
|
-
if (parts.time) text += ` · ${parts.time}`;
|
|
585
|
-
if (parts.budget) text += parts.budget;
|
|
586
|
-
return text;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
export function formatWeeklyParts(
|
|
590
|
-
sevenDay: { used_percentage: number; resets_at: number },
|
|
591
|
-
sym: SymbolSet,
|
|
592
|
-
iconVisible = true,
|
|
593
|
-
): Record<string, string> {
|
|
594
|
-
const pct = `${Math.round(sevenDay.used_percentage)}%`;
|
|
595
|
-
const time = formatLongTimeRemaining(minutesUntilReset(sevenDay.resets_at));
|
|
596
|
-
return {
|
|
597
|
-
icon: iconVisible ? sym.weekly_cost : "",
|
|
598
|
-
label: "weekly",
|
|
599
|
-
pct,
|
|
600
|
-
time,
|
|
601
|
-
bar: " ",
|
|
602
|
-
};
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
export function formatWeeklySegment(
|
|
606
|
-
sevenDay: { used_percentage: number; resets_at: number },
|
|
607
|
-
sym: SymbolSet,
|
|
608
|
-
iconVisible = true,
|
|
609
|
-
): string {
|
|
610
|
-
const parts = formatWeeklyParts(sevenDay, sym, iconVisible);
|
|
611
|
-
let text = parts.icon ? `${parts.icon} ${parts.pct}` : (parts.pct ?? "");
|
|
612
|
-
if (parts.time) text += ` · ${parts.time}`;
|
|
613
|
-
return text;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
export function formatSessionParts(
|
|
617
|
-
usageInfo: TuiData["usageInfo"] & {},
|
|
618
|
-
sym: SymbolSet,
|
|
619
|
-
config: PowerlineConfig,
|
|
620
|
-
iconVisible = true,
|
|
621
|
-
): Record<string, string> {
|
|
622
|
-
const state = resolveBudgetDisplay(
|
|
623
|
-
usageInfo.session.cost,
|
|
624
|
-
usageInfo.session.tokens,
|
|
625
|
-
config.budget?.session,
|
|
626
|
-
);
|
|
627
|
-
|
|
628
|
-
if (state.suppressAll) {
|
|
629
|
-
return { icon: "", label: "", cost: "", tokens: "", budget: "" };
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
const sessionTokens = usageInfo.session.tokens;
|
|
633
|
-
const tokenStr =
|
|
634
|
-
state.showBase && sessionTokens !== null && sessionTokens > 0
|
|
635
|
-
? formatTokenCount(sessionTokens)
|
|
636
|
-
: "";
|
|
637
|
-
|
|
638
|
-
return {
|
|
639
|
-
icon: iconVisible ? sym.session_cost : "",
|
|
640
|
-
label: state.percentageOnly ? "" : "session",
|
|
641
|
-
cost: state.showBase ? formatCost(usageInfo.session.cost) : "",
|
|
642
|
-
tokens: tokenStr,
|
|
643
|
-
budget: state.percentText ? ` ${state.percentText}` : "",
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
export function formatSessionSegment(
|
|
648
|
-
usageInfo: TuiData["usageInfo"] & {},
|
|
649
|
-
sym: SymbolSet,
|
|
650
|
-
config: PowerlineConfig,
|
|
651
|
-
iconVisible = true,
|
|
652
|
-
): string {
|
|
653
|
-
const state = resolveBudgetDisplay(
|
|
654
|
-
usageInfo.session.cost,
|
|
655
|
-
usageInfo.session.tokens,
|
|
656
|
-
config.budget?.session,
|
|
657
|
-
);
|
|
658
|
-
if (state.suppressAll) return "";
|
|
659
|
-
|
|
660
|
-
const icon = iconVisible ? sym.session_cost : "";
|
|
661
|
-
|
|
662
|
-
if (!state.showBase) {
|
|
663
|
-
return icon ? `${icon} ${state.percentText}` : state.percentText;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
const costStr = formatCost(usageInfo.session.cost);
|
|
667
|
-
const sessionTokens = usageInfo.session.tokens;
|
|
668
|
-
let text = icon ? `${icon} ${costStr}` : costStr;
|
|
669
|
-
if (sessionTokens !== null && sessionTokens > 0) {
|
|
670
|
-
text += ` · ${formatTokenCount(sessionTokens)}`;
|
|
671
|
-
}
|
|
672
|
-
if (state.percentText) text += ` ${state.percentText}`;
|
|
673
|
-
return text;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
export function formatTodayParts(
|
|
677
|
-
todayInfo: TuiData["todayInfo"] & {},
|
|
678
|
-
sym: SymbolSet,
|
|
679
|
-
config: PowerlineConfig,
|
|
680
|
-
iconVisible = true,
|
|
681
|
-
): Record<string, string> {
|
|
682
|
-
const state = resolveBudgetDisplay(
|
|
683
|
-
todayInfo.cost,
|
|
684
|
-
todayInfo.tokens,
|
|
685
|
-
config.budget?.today,
|
|
686
|
-
);
|
|
687
|
-
|
|
688
|
-
if (state.suppressAll) {
|
|
689
|
-
return { icon: "", label: "", cost: "", budget: "" };
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
return {
|
|
693
|
-
icon: iconVisible ? sym.today_cost : "",
|
|
694
|
-
cost: state.showBase ? formatCost(todayInfo.cost) : "",
|
|
695
|
-
label: state.percentageOnly ? "" : "today",
|
|
696
|
-
budget: state.percentText ? ` ${state.percentText}` : "",
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
export function formatTodaySegment(
|
|
701
|
-
todayInfo: TuiData["todayInfo"] & {},
|
|
702
|
-
sym: SymbolSet,
|
|
703
|
-
config: PowerlineConfig,
|
|
704
|
-
iconVisible = true,
|
|
705
|
-
): string {
|
|
706
|
-
const state = resolveBudgetDisplay(
|
|
707
|
-
todayInfo.cost,
|
|
708
|
-
todayInfo.tokens,
|
|
709
|
-
config.budget?.today,
|
|
710
|
-
);
|
|
711
|
-
if (state.suppressAll) return "";
|
|
712
|
-
|
|
713
|
-
const icon = iconVisible ? sym.today_cost : "";
|
|
714
|
-
|
|
715
|
-
if (!state.showBase) {
|
|
716
|
-
return icon ? `${icon} ${state.percentText}` : state.percentText;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
const costStr = formatCost(todayInfo.cost);
|
|
720
|
-
let text = icon ? `${icon} ${costStr} today` : `${costStr} today`;
|
|
721
|
-
if (state.percentText) text += ` ${state.percentText}`;
|
|
722
|
-
return text;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
function formatMetricsParts(
|
|
726
|
-
data: TuiData,
|
|
727
|
-
sym: SymbolSet,
|
|
728
|
-
): Record<string, string> {
|
|
729
|
-
const empty = {
|
|
730
|
-
response: "",
|
|
731
|
-
responseIcon: "",
|
|
732
|
-
responseVal: "",
|
|
733
|
-
lastResponse: "",
|
|
734
|
-
lastResponseIcon: "",
|
|
735
|
-
lastResponseVal: "",
|
|
736
|
-
added: "",
|
|
737
|
-
addedIcon: "",
|
|
738
|
-
addedVal: "",
|
|
739
|
-
removed: "",
|
|
740
|
-
removedIcon: "",
|
|
741
|
-
removedVal: "",
|
|
742
|
-
};
|
|
743
|
-
if (!data.metricsInfo) return empty;
|
|
744
|
-
|
|
745
|
-
const hasResponse =
|
|
746
|
-
data.metricsInfo.responseTime !== null &&
|
|
747
|
-
!isNaN(data.metricsInfo.responseTime) &&
|
|
748
|
-
data.metricsInfo.responseTime > 0;
|
|
749
|
-
const responseValStr = hasResponse
|
|
750
|
-
? formatResponseTime(data.metricsInfo.responseTime!)
|
|
751
|
-
: "";
|
|
752
|
-
|
|
753
|
-
const hasLast =
|
|
754
|
-
data.metricsInfo.lastResponseTime !== null &&
|
|
755
|
-
!isNaN(data.metricsInfo.lastResponseTime) &&
|
|
756
|
-
data.metricsInfo.lastResponseTime > 0;
|
|
757
|
-
const lastValStr = hasLast
|
|
758
|
-
? formatResponseTime(data.metricsInfo.lastResponseTime!)
|
|
759
|
-
: "";
|
|
760
|
-
|
|
761
|
-
const hasAdded =
|
|
762
|
-
data.metricsInfo.linesAdded !== null && data.metricsInfo.linesAdded > 0;
|
|
763
|
-
const addedValStr = hasAdded ? `${data.metricsInfo.linesAdded}` : "";
|
|
764
|
-
|
|
765
|
-
const hasRemoved =
|
|
766
|
-
data.metricsInfo.linesRemoved !== null && data.metricsInfo.linesRemoved > 0;
|
|
767
|
-
const removedValStr = hasRemoved ? `${data.metricsInfo.linesRemoved}` : "";
|
|
768
|
-
|
|
769
|
-
return {
|
|
770
|
-
response: hasResponse ? `${sym.metrics_response} ${responseValStr}` : "",
|
|
771
|
-
responseIcon: hasResponse ? sym.metrics_response : "",
|
|
772
|
-
responseVal: responseValStr,
|
|
773
|
-
lastResponse: hasLast
|
|
774
|
-
? `${sym.metrics_last_response} ${lastValStr}`
|
|
775
|
-
: `${sym.metrics_last_response} --`,
|
|
776
|
-
lastResponseIcon: sym.metrics_last_response,
|
|
777
|
-
lastResponseVal: hasLast ? lastValStr : "--",
|
|
778
|
-
added: hasAdded ? `${sym.metrics_lines_added}${addedValStr}` : "",
|
|
779
|
-
addedIcon: hasAdded ? sym.metrics_lines_added : "",
|
|
780
|
-
addedVal: addedValStr,
|
|
781
|
-
removed: hasRemoved ? `${sym.metrics_lines_removed}${removedValStr}` : "",
|
|
782
|
-
removedIcon: hasRemoved ? sym.metrics_lines_removed : "",
|
|
783
|
-
removedVal: removedValStr,
|
|
784
|
-
};
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
function formatMetricsSegment(data: TuiData, sym: SymbolSet): string {
|
|
788
|
-
const parts = formatMetricsParts(data, sym);
|
|
789
|
-
const filled = [
|
|
790
|
-
parts.response,
|
|
791
|
-
parts.lastResponse,
|
|
792
|
-
parts.added,
|
|
793
|
-
parts.removed,
|
|
794
|
-
].filter(Boolean);
|
|
795
|
-
return filled.length > 0 ? filled.join(" · ") : "";
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
function formatActivityParts(
|
|
799
|
-
data: TuiData,
|
|
800
|
-
sym: SymbolSet,
|
|
801
|
-
): Record<string, string> {
|
|
802
|
-
const empty = {
|
|
803
|
-
icon: "",
|
|
804
|
-
duration: "",
|
|
805
|
-
durationIcon: "",
|
|
806
|
-
durationVal: "",
|
|
807
|
-
messages: "",
|
|
808
|
-
messagesIcon: "",
|
|
809
|
-
messagesVal: "",
|
|
810
|
-
};
|
|
811
|
-
if (!data.metricsInfo) return empty;
|
|
812
|
-
|
|
813
|
-
const hasDuration =
|
|
814
|
-
data.metricsInfo.sessionDuration !== null &&
|
|
815
|
-
data.metricsInfo.sessionDuration > 0;
|
|
816
|
-
const durationValStr = hasDuration
|
|
817
|
-
? formatDuration(data.metricsInfo.sessionDuration!)
|
|
818
|
-
: "";
|
|
819
|
-
|
|
820
|
-
const hasMessages =
|
|
821
|
-
data.metricsInfo.messageCount !== null && data.metricsInfo.messageCount > 0;
|
|
822
|
-
const messagesValStr = hasMessages ? `${data.metricsInfo.messageCount}` : "";
|
|
823
|
-
|
|
824
|
-
return {
|
|
825
|
-
icon: sym.activity,
|
|
826
|
-
duration: hasDuration ? `${sym.metrics_duration} ${durationValStr}` : "",
|
|
827
|
-
durationIcon: hasDuration ? sym.metrics_duration : "",
|
|
828
|
-
durationVal: durationValStr,
|
|
829
|
-
messages: hasMessages ? `${sym.metrics_messages} ${messagesValStr}` : "",
|
|
830
|
-
messagesIcon: hasMessages ? sym.metrics_messages : "",
|
|
831
|
-
messagesVal: messagesValStr,
|
|
832
|
-
};
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
function formatActivitySegment(data: TuiData, sym: SymbolSet): string {
|
|
836
|
-
const parts = formatActivityParts(data, sym);
|
|
837
|
-
const filled = [parts.duration, parts.messages].filter(Boolean);
|
|
838
|
-
return filled.length > 0 ? filled.join(" · ") : "";
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
function formatGitParts(
|
|
842
|
-
data: TuiData,
|
|
843
|
-
sym: SymbolSet,
|
|
844
|
-
iconVisible = true,
|
|
845
|
-
): Record<string, string> {
|
|
846
|
-
if (!data.gitInfo)
|
|
847
|
-
return {
|
|
848
|
-
icon: "",
|
|
849
|
-
headVal: "",
|
|
850
|
-
branch: "",
|
|
851
|
-
status: "",
|
|
852
|
-
ahead: "",
|
|
853
|
-
behind: "",
|
|
854
|
-
working: "",
|
|
855
|
-
head: "",
|
|
856
|
-
};
|
|
857
|
-
|
|
858
|
-
let statusIcon: string;
|
|
859
|
-
if (data.gitInfo.status === "conflicts") {
|
|
860
|
-
statusIcon = sym.git_conflicts;
|
|
861
|
-
} else if (data.gitInfo.status === "dirty") {
|
|
862
|
-
statusIcon = sym.git_dirty;
|
|
863
|
-
} else {
|
|
864
|
-
statusIcon = sym.git_clean;
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
const ahead =
|
|
868
|
-
data.gitInfo.ahead > 0 ? `${sym.git_ahead}${data.gitInfo.ahead}` : "";
|
|
869
|
-
const behind =
|
|
870
|
-
data.gitInfo.behind > 0 ? `${sym.git_behind}${data.gitInfo.behind}` : "";
|
|
871
|
-
|
|
872
|
-
const counts: string[] = [];
|
|
873
|
-
if (data.gitInfo.staged && data.gitInfo.staged > 0)
|
|
874
|
-
counts.push(`+${data.gitInfo.staged}`);
|
|
875
|
-
if (data.gitInfo.unstaged && data.gitInfo.unstaged > 0)
|
|
876
|
-
counts.push(`~${data.gitInfo.unstaged}`);
|
|
877
|
-
if (data.gitInfo.untracked && data.gitInfo.untracked > 0)
|
|
878
|
-
counts.push(`?${data.gitInfo.untracked}`);
|
|
879
|
-
const working = counts.length > 0 ? `(${counts.join(" ")})` : "";
|
|
880
|
-
|
|
881
|
-
const headParts: string[] = [];
|
|
882
|
-
if (iconVisible) headParts.push(sym.branch);
|
|
883
|
-
headParts.push(data.gitInfo.branch, statusIcon);
|
|
884
|
-
if (ahead) headParts.push(ahead);
|
|
885
|
-
if (behind) headParts.push(behind);
|
|
886
|
-
|
|
887
|
-
const infoParts = [data.gitInfo.branch, statusIcon];
|
|
888
|
-
if (ahead) infoParts.push(ahead);
|
|
889
|
-
if (behind) infoParts.push(behind);
|
|
890
|
-
|
|
891
|
-
return {
|
|
892
|
-
icon: iconVisible ? sym.branch : "",
|
|
893
|
-
headVal: infoParts.join(" "),
|
|
894
|
-
branch: data.gitInfo.branch,
|
|
895
|
-
status: statusIcon,
|
|
896
|
-
ahead,
|
|
897
|
-
behind,
|
|
898
|
-
working,
|
|
899
|
-
head: headParts.join(" "),
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
function formatGitSegment(
|
|
904
|
-
data: TuiData,
|
|
905
|
-
sym: SymbolSet,
|
|
906
|
-
iconVisible = true,
|
|
907
|
-
): string {
|
|
908
|
-
const parts = formatGitParts(data, sym, iconVisible);
|
|
909
|
-
if (!parts.branch) return "";
|
|
910
|
-
let text = parts.icon
|
|
911
|
-
? `${parts.icon} ${parts.branch} ${parts.status}`
|
|
912
|
-
: `${parts.branch} ${parts.status}`;
|
|
913
|
-
if (parts.ahead) text += ` ${parts.ahead}`;
|
|
914
|
-
if (parts.behind) text += `${parts.behind}`;
|
|
915
|
-
if (parts.working) text += ` ${parts.working}`;
|
|
916
|
-
return text;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
function formatDirParts(
|
|
920
|
-
data: TuiData,
|
|
921
|
-
config: PowerlineConfig,
|
|
922
|
-
sym: SymbolSet,
|
|
923
|
-
iconVisible = true,
|
|
924
|
-
): Record<string, string> {
|
|
925
|
-
return {
|
|
926
|
-
icon: iconVisible ? sym.dir : "",
|
|
927
|
-
value: formatDirValue(data, config),
|
|
928
|
-
};
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
function formatDirValue(data: TuiData, config: PowerlineConfig): string {
|
|
932
|
-
const raw = getDirectoryDisplay(data.hookData);
|
|
933
|
-
const dirConfig = config.display.lines
|
|
934
|
-
.map((line) => line.segments.directory)
|
|
935
|
-
.find((d) => d?.enabled);
|
|
936
|
-
const style =
|
|
937
|
-
dirConfig?.style ?? (dirConfig?.showBasename ? "basename" : "fish");
|
|
938
|
-
if (style === "basename") {
|
|
939
|
-
const sep = raw.includes("/") ? "/" : "\\";
|
|
940
|
-
return raw.split(sep).pop() || raw;
|
|
941
|
-
}
|
|
942
|
-
if (style === "full") return raw;
|
|
943
|
-
return abbreviateFishStyle(raw);
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
function formatVersionParts(
|
|
947
|
-
data: TuiData,
|
|
948
|
-
sym: SymbolSet,
|
|
949
|
-
iconVisible = true,
|
|
950
|
-
): Record<string, string> {
|
|
951
|
-
if (!data.hookData.version) return { icon: "", value: "" };
|
|
952
|
-
return {
|
|
953
|
-
icon: iconVisible ? sym.version : "",
|
|
954
|
-
value: `v${data.hookData.version}`,
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
function formatVersionSegment(
|
|
959
|
-
data: TuiData,
|
|
960
|
-
sym: SymbolSet,
|
|
961
|
-
iconVisible = true,
|
|
962
|
-
): string {
|
|
963
|
-
const parts = formatVersionParts(data, sym, iconVisible);
|
|
964
|
-
if (!parts.value) return "";
|
|
965
|
-
return parts.icon ? `${parts.icon} ${parts.value}` : parts.value;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
function formatAgentParts(
|
|
969
|
-
data: TuiData,
|
|
970
|
-
sym: SymbolSet,
|
|
971
|
-
iconVisible = true,
|
|
972
|
-
): Record<string, string> {
|
|
973
|
-
const raw = data.hookData.agent?.name;
|
|
974
|
-
if (typeof raw !== "string") return { icon: "", name: "" };
|
|
975
|
-
const name = raw.trim();
|
|
976
|
-
if (!name) return { icon: "", name: "" };
|
|
977
|
-
return {
|
|
978
|
-
icon: iconVisible ? sym.agent : "",
|
|
979
|
-
name,
|
|
980
|
-
};
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
function formatAgentSegment(
|
|
984
|
-
data: TuiData,
|
|
985
|
-
sym: SymbolSet,
|
|
986
|
-
config: PowerlineConfig,
|
|
987
|
-
iconVisible = true,
|
|
988
|
-
): string {
|
|
989
|
-
const parts = formatAgentParts(data, sym, iconVisible);
|
|
990
|
-
if (!parts.name) return "";
|
|
991
|
-
const agentConfig = config.display.lines
|
|
992
|
-
.map((line) => line.segments.agent)
|
|
993
|
-
.find((a) => a?.enabled);
|
|
994
|
-
const body = agentConfig?.showLabel ? `agent: ${parts.name}` : parts.name;
|
|
995
|
-
return parts.icon ? `${parts.icon} ${body}` : body;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
function buildThinkingBody(
|
|
999
|
-
data: TuiData,
|
|
1000
|
-
thinkingConfig: { showEnabled?: boolean; showEffort?: boolean } | undefined,
|
|
1001
|
-
): string {
|
|
1002
|
-
const showEnabled = thinkingConfig?.showEnabled ?? true;
|
|
1003
|
-
const showEffort = thinkingConfig?.showEffort ?? true;
|
|
1004
|
-
if (!showEnabled && !showEffort) return "";
|
|
1005
|
-
|
|
1006
|
-
const enabled = showEnabled ? getThinkingEnabled(data.hookData) : null;
|
|
1007
|
-
const level = showEffort ? getEffortLevel(data.hookData) : null;
|
|
1008
|
-
|
|
1009
|
-
const segments: string[] = [];
|
|
1010
|
-
if (enabled !== null) segments.push(enabled ? "On" : "Off");
|
|
1011
|
-
if (level) segments.push(level);
|
|
1012
|
-
return segments.join(" · ");
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
function formatThinkingParts(
|
|
1016
|
-
data: TuiData,
|
|
1017
|
-
sym: SymbolSet,
|
|
1018
|
-
thinkingConfig: { showEnabled?: boolean; showEffort?: boolean } | undefined,
|
|
1019
|
-
iconVisible = true,
|
|
1020
|
-
): Record<string, string> {
|
|
1021
|
-
const showEnabled = thinkingConfig?.showEnabled ?? true;
|
|
1022
|
-
const showEffort = thinkingConfig?.showEffort ?? true;
|
|
1023
|
-
const enabled = showEnabled ? getThinkingEnabled(data.hookData) : null;
|
|
1024
|
-
const level = showEffort ? getEffortLevel(data.hookData) : null;
|
|
1025
|
-
|
|
1026
|
-
const enabledText = enabled === null ? "" : enabled ? "On" : "Off";
|
|
1027
|
-
const effortText = level ?? "";
|
|
1028
|
-
const hasAny = enabledText !== "" || effortText !== "";
|
|
1029
|
-
return {
|
|
1030
|
-
icon: hasAny && iconVisible ? sym.thinking : "",
|
|
1031
|
-
enabled: enabledText,
|
|
1032
|
-
effort: effortText,
|
|
1033
|
-
};
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
function formatThinkingSegment(
|
|
1037
|
-
data: TuiData,
|
|
1038
|
-
sym: SymbolSet,
|
|
1039
|
-
thinkingConfig: { showEnabled?: boolean; showEffort?: boolean } | undefined,
|
|
1040
|
-
iconVisible = true,
|
|
1041
|
-
): string {
|
|
1042
|
-
const body = buildThinkingBody(data, thinkingConfig);
|
|
1043
|
-
if (!body) return "";
|
|
1044
|
-
return iconVisible ? `${sym.thinking} ${body}` : body;
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
function formatCacheTimerParts(
|
|
1048
|
-
data: TuiData,
|
|
1049
|
-
sym: SymbolSet,
|
|
1050
|
-
iconVisible = true,
|
|
1051
|
-
): Record<string, string> {
|
|
1052
|
-
if (!data.cacheTimerInfo) return { icon: "", value: "" };
|
|
1053
|
-
return {
|
|
1054
|
-
icon: iconVisible ? sym.cache_timer : "",
|
|
1055
|
-
value: formatCacheTimerElapsed(data.cacheTimerInfo.elapsedSeconds),
|
|
1056
|
-
};
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
function formatCacheTimerSegment(
|
|
1060
|
-
data: TuiData,
|
|
1061
|
-
sym: SymbolSet,
|
|
1062
|
-
iconVisible = true,
|
|
1063
|
-
): string {
|
|
1064
|
-
const parts = formatCacheTimerParts(data, sym, iconVisible);
|
|
1065
|
-
if (!parts.value) return "";
|
|
1066
|
-
return parts.icon ? `${parts.icon} ${parts.value}` : parts.value;
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
function cacheTimerStyle(
|
|
1070
|
-
elapsed: number,
|
|
1071
|
-
colors: PowerlineColors,
|
|
1072
|
-
): { fg: string; bold: boolean } {
|
|
1073
|
-
if (elapsed >= 300) {
|
|
1074
|
-
return { fg: colors.contextCriticalFg, bold: colors.contextCriticalBold };
|
|
1075
|
-
}
|
|
1076
|
-
if (elapsed >= 180) {
|
|
1077
|
-
return { fg: colors.contextWarningFg, bold: colors.contextWarningBold };
|
|
1078
|
-
}
|
|
1079
|
-
return { fg: colors.cacheTimerFg, bold: colors.cacheTimerBold };
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
function formatTmuxParts(data: TuiData): Record<string, string> {
|
|
1083
|
-
if (!data.tmuxSessionId) return { label: "", value: "" };
|
|
1084
|
-
return { label: "tmux", value: data.tmuxSessionId };
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
function formatTmuxSegment(data: TuiData): string {
|
|
1088
|
-
const parts = formatTmuxParts(data);
|
|
1089
|
-
if (!parts.label) return "";
|
|
1090
|
-
return `${parts.label}:${parts.value}`;
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
function formatEnvParts(config: PowerlineConfig): Record<string, string> {
|
|
1094
|
-
const envConfig = config.display.lines
|
|
1095
|
-
.map((line) => line.segments.env)
|
|
1096
|
-
.find((env) => env?.enabled);
|
|
1097
|
-
|
|
1098
|
-
if (!envConfig || !envConfig.variable) return { prefix: "", value: "" };
|
|
1099
|
-
const envVal = globalThis.process?.env?.[envConfig.variable];
|
|
1100
|
-
if (!envVal) return { prefix: "", value: "" };
|
|
1101
|
-
const prefix = envConfig.prefix ?? envConfig.variable;
|
|
1102
|
-
return { prefix: prefix || "", value: envVal };
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
function formatEnvSegment(config: PowerlineConfig): string {
|
|
1106
|
-
const parts = formatEnvParts(config);
|
|
1107
|
-
if (!parts.value) return "";
|
|
1108
|
-
return parts.prefix ? `${parts.prefix}:${parts.value}` : parts.value;
|
|
352
|
+
return `✓ bastra · ${info.recallCount} ${info.recallCount === 1 ? "call" : "calls"}${hits}${ms}`;
|
|
1109
353
|
}
|
|
1110
354
|
|
|
1111
355
|
function addParts(
|
|
@@ -1499,7 +743,11 @@ export function resolveSegments(
|
|
|
1499
743
|
|
|
1500
744
|
// CacheTimer
|
|
1501
745
|
const cacheTimerElapsed = data.cacheTimerInfo?.elapsedSeconds ?? 0;
|
|
1502
|
-
const cacheTimerStyleResolved = cacheTimerStyle(
|
|
746
|
+
const cacheTimerStyleResolved = cacheTimerStyle(
|
|
747
|
+
cacheTimerElapsed,
|
|
748
|
+
colors,
|
|
749
|
+
cacheTimerTtl(config, data),
|
|
750
|
+
);
|
|
1503
751
|
const cacheTimerColor = pf?.["cacheTimer"] ?? cacheTimerStyleResolved.fg;
|
|
1504
752
|
result.cacheTimer = colorizeOrEmpty(
|
|
1505
753
|
formatCacheTimerSegment(data, sym, iconVisible.cacheTimer),
|