@owloops/claude-powerline 1.25.2 → 1.27.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/README.md +124 -3
- package/dist/browser.d.ts +96 -9
- package/dist/browser.js +3 -3
- package/dist/index.mjs +13 -12
- package/package.json +1 -1
- package/src/browser.ts +5 -0
- package/src/config/defaults.ts +10 -2
- package/src/config/loader.ts +9 -0
- package/src/powerline.ts +148 -5
- package/src/segments/cacheTimer.ts +108 -0
- package/src/segments/index.ts +5 -0
- package/src/segments/renderer.ts +213 -60
- package/src/themes/dark.ts +9 -0
- package/src/themes/gruvbox.ts +9 -0
- package/src/themes/index.ts +27 -0
- package/src/themes/light.ts +9 -0
- package/src/themes/nord.ts +9 -0
- package/src/themes/rose-pine.ts +9 -0
- package/src/themes/tokyo-night.ts +9 -0
- package/src/tui/layouts.ts +56 -20
- package/src/tui/primitives.ts +12 -3
- package/src/tui/sections.ts +555 -124
- package/src/tui/types.ts +8 -0
- package/src/utils/budget.ts +69 -0
- package/src/utils/claude.ts +29 -0
- package/src/utils/constants.ts +6 -0
- package/src/utils/formatters.ts +15 -0
- package/src/utils/icon-visibility.ts +31 -0
package/src/segments/renderer.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ClaudeHookData } from "../utils/claude";
|
|
2
|
+
import { getEffortLevel, getThinkingEnabled } from "../utils/claude";
|
|
2
3
|
import type { PowerlineColors } from "../themes";
|
|
3
4
|
import type { PowerlineConfig } from "../config/loader";
|
|
4
5
|
import type { BlockInfo } from "./block";
|
|
6
|
+
import type { CacheTimerInfo } from "./cacheTimer";
|
|
5
7
|
import type {
|
|
6
8
|
UsageInfo,
|
|
7
9
|
TokenBreakdown,
|
|
@@ -16,17 +18,23 @@ import {
|
|
|
16
18
|
abbreviateFishStyle,
|
|
17
19
|
formatCost,
|
|
18
20
|
formatTokens,
|
|
21
|
+
formatTokenCount,
|
|
19
22
|
formatTokenBreakdown,
|
|
20
23
|
formatTimeSince,
|
|
21
24
|
formatDuration,
|
|
22
25
|
formatLongTimeRemaining,
|
|
26
|
+
formatCacheTimerElapsed,
|
|
27
|
+
formatCacheTimerRemaining,
|
|
23
28
|
collapseHome,
|
|
24
29
|
minutesUntilReset,
|
|
25
30
|
} from "../utils/formatters";
|
|
26
|
-
import {
|
|
31
|
+
import { resolveBudgetDisplay } from "../utils/budget";
|
|
32
|
+
import type { BudgetItemConfig } from "../config/loader";
|
|
33
|
+
import { shouldShowIcon } from "../utils/icon-visibility";
|
|
27
34
|
|
|
28
35
|
export interface SegmentConfig {
|
|
29
36
|
enabled: boolean;
|
|
37
|
+
showIcon?: boolean;
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
export interface DirectorySegmentConfig extends SegmentConfig {
|
|
@@ -49,6 +57,8 @@ export interface GitSegmentConfig extends SegmentConfig {
|
|
|
49
57
|
export interface UsageSegmentConfig extends SegmentConfig {
|
|
50
58
|
type: "cost" | "tokens" | "both" | "breakdown";
|
|
51
59
|
costSource?: "calculated" | "official";
|
|
60
|
+
/** Show the trailing "tokens" unit on token counts. Only affects `type: "tokens"` and `type: "both"` (default: true). Inert in the `tui` display style, which never renders the suffix. */
|
|
61
|
+
showUnits?: boolean;
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
export interface TmuxSegmentConfig extends SegmentConfig {}
|
|
@@ -90,6 +100,8 @@ export interface BlockSegmentConfig extends SegmentConfig {
|
|
|
90
100
|
|
|
91
101
|
export interface TodaySegmentConfig extends SegmentConfig {
|
|
92
102
|
type: "cost" | "tokens" | "both" | "breakdown";
|
|
103
|
+
/** Show the trailing "tokens" unit on token counts. Only affects `type: "tokens"` and `type: "both"` (default: true). Inert in the `tui` display style, which never renders the suffix. */
|
|
104
|
+
showUnits?: boolean;
|
|
93
105
|
}
|
|
94
106
|
|
|
95
107
|
export interface VersionSegmentConfig extends SegmentConfig {}
|
|
@@ -107,6 +119,20 @@ export interface WeeklySegmentConfig extends SegmentConfig {
|
|
|
107
119
|
displayStyle?: BarDisplayStyle;
|
|
108
120
|
}
|
|
109
121
|
|
|
122
|
+
export interface AgentSegmentConfig extends SegmentConfig {
|
|
123
|
+
showLabel?: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ThinkingSegmentConfig extends SegmentConfig {
|
|
127
|
+
showEnabled?: boolean;
|
|
128
|
+
showEffort?: boolean;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface CacheTimerSegmentConfig extends SegmentConfig {
|
|
132
|
+
displayMode?: "elapsed" | "remaining";
|
|
133
|
+
ttlSeconds?: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
110
136
|
export type AnySegmentConfig =
|
|
111
137
|
| SegmentConfig
|
|
112
138
|
| DirectorySegmentConfig
|
|
@@ -120,7 +146,10 @@ export type AnySegmentConfig =
|
|
|
120
146
|
| VersionSegmentConfig
|
|
121
147
|
| SessionIdSegmentConfig
|
|
122
148
|
| EnvSegmentConfig
|
|
123
|
-
| WeeklySegmentConfig
|
|
149
|
+
| WeeklySegmentConfig
|
|
150
|
+
| AgentSegmentConfig
|
|
151
|
+
| ThinkingSegmentConfig
|
|
152
|
+
| CacheTimerSegmentConfig;
|
|
124
153
|
|
|
125
154
|
export interface PowerlineSymbols {
|
|
126
155
|
right: string;
|
|
@@ -155,12 +184,16 @@ export interface PowerlineSymbols {
|
|
|
155
184
|
env: string;
|
|
156
185
|
session_id: string;
|
|
157
186
|
weekly_cost: string;
|
|
187
|
+
agent: string;
|
|
188
|
+
thinking: string;
|
|
189
|
+
cache_timer: string;
|
|
158
190
|
}
|
|
159
191
|
|
|
160
192
|
export interface SegmentData {
|
|
161
193
|
text: string;
|
|
162
194
|
bgColor: string;
|
|
163
195
|
fgColor: string;
|
|
196
|
+
bold?: boolean;
|
|
164
197
|
}
|
|
165
198
|
|
|
166
199
|
interface BarStyleDef {
|
|
@@ -188,13 +221,24 @@ export class SegmentRenderer {
|
|
|
188
221
|
private readonly symbols: PowerlineSymbols,
|
|
189
222
|
) {}
|
|
190
223
|
|
|
224
|
+
private leadingIcon(symbol: string, segConfig?: SegmentConfig): string {
|
|
225
|
+
const show = shouldShowIcon(
|
|
226
|
+
this.config.display?.showIcons,
|
|
227
|
+
segConfig?.showIcon,
|
|
228
|
+
);
|
|
229
|
+
return show ? `${symbol} ` : "";
|
|
230
|
+
}
|
|
231
|
+
|
|
191
232
|
renderDirectory(
|
|
192
233
|
hookData: ClaudeHookData,
|
|
193
234
|
colors: PowerlineColors,
|
|
194
235
|
config?: DirectorySegmentConfig,
|
|
195
236
|
): SegmentData {
|
|
196
|
-
const
|
|
197
|
-
const
|
|
237
|
+
const worktreeOriginalCwd = hookData.worktree?.original_cwd || undefined;
|
|
238
|
+
const currentDir =
|
|
239
|
+
worktreeOriginalCwd ??
|
|
240
|
+
(hookData.workspace?.current_dir || hookData.cwd || "/");
|
|
241
|
+
const projectDir = worktreeOriginalCwd ?? hookData.workspace?.project_dir;
|
|
198
242
|
|
|
199
243
|
const style = config?.style ?? (config?.showBasename ? "basename" : "full");
|
|
200
244
|
|
|
@@ -245,7 +289,15 @@ export class SegmentRenderer {
|
|
|
245
289
|
parts.push(`[${gitInfo.operation}]`);
|
|
246
290
|
}
|
|
247
291
|
|
|
248
|
-
|
|
292
|
+
const showBranchIcon = shouldShowIcon(
|
|
293
|
+
this.config.display?.showIcons,
|
|
294
|
+
config?.showIcon,
|
|
295
|
+
);
|
|
296
|
+
parts.push(
|
|
297
|
+
showBranchIcon
|
|
298
|
+
? `${this.symbols.branch} ${gitInfo.branch}`
|
|
299
|
+
: gitInfo.branch,
|
|
300
|
+
);
|
|
249
301
|
|
|
250
302
|
if (config?.showTag && gitInfo.tag) {
|
|
251
303
|
parts.push(`${this.symbols.git_tag} ${gitInfo.tag}`);
|
|
@@ -314,12 +366,16 @@ export class SegmentRenderer {
|
|
|
314
366
|
};
|
|
315
367
|
}
|
|
316
368
|
|
|
317
|
-
renderModel(
|
|
369
|
+
renderModel(
|
|
370
|
+
hookData: ClaudeHookData,
|
|
371
|
+
colors: PowerlineColors,
|
|
372
|
+
config?: SegmentConfig,
|
|
373
|
+
): SegmentData {
|
|
318
374
|
const rawName = hookData.model?.display_name || "Claude";
|
|
319
375
|
const modelName = formatModelName(rawName);
|
|
320
376
|
|
|
321
377
|
return {
|
|
322
|
-
text: `${this.symbols.model}
|
|
378
|
+
text: `${this.leadingIcon(this.symbols.model, config)}${modelName}`,
|
|
323
379
|
bgColor: colors.modelBg,
|
|
324
380
|
fgColor: colors.modelFg,
|
|
325
381
|
};
|
|
@@ -329,7 +385,7 @@ export class SegmentRenderer {
|
|
|
329
385
|
usageInfo: UsageInfo,
|
|
330
386
|
colors: PowerlineColors,
|
|
331
387
|
config?: UsageSegmentConfig,
|
|
332
|
-
): SegmentData {
|
|
388
|
+
): SegmentData | null {
|
|
333
389
|
const type = config?.type || "cost";
|
|
334
390
|
const costSource = config?.costSource;
|
|
335
391
|
const sessionBudget = this.config.budget?.session;
|
|
@@ -345,12 +401,13 @@ export class SegmentRenderer {
|
|
|
345
401
|
usageInfo.session.tokens,
|
|
346
402
|
usageInfo.session.tokenBreakdown,
|
|
347
403
|
type,
|
|
348
|
-
sessionBudget
|
|
349
|
-
|
|
350
|
-
sessionBudget?.type,
|
|
404
|
+
sessionBudget,
|
|
405
|
+
config?.showUnits ?? true,
|
|
351
406
|
);
|
|
352
407
|
|
|
353
|
-
|
|
408
|
+
if (formattedUsage === null) return null;
|
|
409
|
+
|
|
410
|
+
const text = `${this.leadingIcon(this.symbols.session_cost, config)}${formattedUsage}`;
|
|
354
411
|
|
|
355
412
|
return {
|
|
356
413
|
text,
|
|
@@ -366,7 +423,7 @@ export class SegmentRenderer {
|
|
|
366
423
|
): SegmentData {
|
|
367
424
|
const showLabel = config?.showIdLabel !== false;
|
|
368
425
|
const text = showLabel
|
|
369
|
-
? `${this.symbols.session_id}
|
|
426
|
+
? `${this.leadingIcon(this.symbols.session_id, config)}${sessionId}`
|
|
370
427
|
: sessionId;
|
|
371
428
|
|
|
372
429
|
return {
|
|
@@ -418,7 +475,7 @@ export class SegmentRenderer {
|
|
|
418
475
|
};
|
|
419
476
|
}
|
|
420
477
|
return {
|
|
421
|
-
text: `${this.symbols.context_time}
|
|
478
|
+
text: `${this.leadingIcon(this.symbols.context_time, config)}0 (${emptyPct})`,
|
|
422
479
|
bgColor: colors.contextBg,
|
|
423
480
|
fgColor: colors.contextFg,
|
|
424
481
|
};
|
|
@@ -426,13 +483,16 @@ export class SegmentRenderer {
|
|
|
426
483
|
|
|
427
484
|
let bgColor = colors.contextBg;
|
|
428
485
|
let fgColor = colors.contextFg;
|
|
486
|
+
let bold = colors.contextBold;
|
|
429
487
|
|
|
430
488
|
if (contextInfo.contextLeftPercentage <= 20) {
|
|
431
489
|
bgColor = colors.contextCriticalBg;
|
|
432
490
|
fgColor = colors.contextCriticalFg;
|
|
491
|
+
bold = colors.contextCriticalBold;
|
|
433
492
|
} else if (contextInfo.contextLeftPercentage <= 40) {
|
|
434
493
|
bgColor = colors.contextWarningBg;
|
|
435
494
|
fgColor = colors.contextWarningFg;
|
|
495
|
+
bold = colors.contextWarningBold;
|
|
436
496
|
}
|
|
437
497
|
|
|
438
498
|
const pct =
|
|
@@ -456,14 +516,15 @@ export class SegmentRenderer {
|
|
|
456
516
|
? `${bar} ${pct}%`
|
|
457
517
|
: `${bar} ${contextInfo.totalTokens.toLocaleString()} (${pct}%)`;
|
|
458
518
|
|
|
459
|
-
return { text, bgColor, fgColor };
|
|
519
|
+
return { text, bgColor, fgColor, bold };
|
|
460
520
|
}
|
|
461
521
|
|
|
522
|
+
const iconPrefix = this.leadingIcon(this.symbols.context_time, config);
|
|
462
523
|
const text = config?.showPercentageOnly
|
|
463
|
-
? `${
|
|
464
|
-
: `${
|
|
524
|
+
? `${iconPrefix}${pct}%`
|
|
525
|
+
: `${iconPrefix}${contextInfo.totalTokens.toLocaleString()} (${pct}%)`;
|
|
465
526
|
|
|
466
|
-
return { text, bgColor, fgColor };
|
|
527
|
+
return { text, bgColor, fgColor, bold };
|
|
467
528
|
}
|
|
468
529
|
|
|
469
530
|
private buildBar(
|
|
@@ -619,18 +680,22 @@ export class SegmentRenderer {
|
|
|
619
680
|
|
|
620
681
|
let bgColor = colors.blockBg;
|
|
621
682
|
let fgColor = colors.blockFg;
|
|
683
|
+
let bold = colors.blockBold;
|
|
622
684
|
if (pct >= warningThreshold) {
|
|
623
685
|
bgColor = colors.contextCriticalBg;
|
|
624
686
|
fgColor = colors.contextCriticalFg;
|
|
687
|
+
bold = colors.contextCriticalBold;
|
|
625
688
|
} else if (pct >= 50) {
|
|
626
689
|
bgColor = colors.contextWarningBg;
|
|
627
690
|
fgColor = colors.contextWarningFg;
|
|
691
|
+
bold = colors.contextWarningBold;
|
|
628
692
|
}
|
|
629
693
|
|
|
630
694
|
return {
|
|
631
|
-
text: `${this.symbols.block_cost}
|
|
695
|
+
text: `${this.leadingIcon(this.symbols.block_cost, config)}${this.formatPercentageWithBar(pct, config?.displayStyle, timeStr)}`,
|
|
632
696
|
bgColor,
|
|
633
697
|
fgColor,
|
|
698
|
+
bold,
|
|
634
699
|
};
|
|
635
700
|
}
|
|
636
701
|
|
|
@@ -649,36 +714,48 @@ export class SegmentRenderer {
|
|
|
649
714
|
|
|
650
715
|
let bgColor = colors.weeklyBg;
|
|
651
716
|
let fgColor = colors.weeklyFg;
|
|
717
|
+
let bold = colors.weeklyBold;
|
|
652
718
|
if (pct >= 80) {
|
|
653
719
|
bgColor = colors.contextCriticalBg;
|
|
654
720
|
fgColor = colors.contextCriticalFg;
|
|
721
|
+
bold = colors.contextCriticalBold;
|
|
655
722
|
} else if (pct >= 50) {
|
|
656
723
|
bgColor = colors.contextWarningBg;
|
|
657
724
|
fgColor = colors.contextWarningFg;
|
|
725
|
+
bold = colors.contextWarningBold;
|
|
658
726
|
}
|
|
659
727
|
|
|
660
728
|
return {
|
|
661
|
-
text: `${this.symbols.weekly_cost}
|
|
729
|
+
text: `${this.leadingIcon(this.symbols.weekly_cost, config)}${this.formatPercentageWithBar(pct, config?.displayStyle, timeStr)}`,
|
|
662
730
|
bgColor,
|
|
663
731
|
fgColor,
|
|
732
|
+
bold,
|
|
664
733
|
};
|
|
665
734
|
}
|
|
666
735
|
|
|
667
736
|
renderToday(
|
|
668
737
|
todayInfo: TodayInfo,
|
|
669
738
|
colors: PowerlineColors,
|
|
670
|
-
|
|
671
|
-
): SegmentData {
|
|
739
|
+
configOrType?: TodaySegmentConfig | string,
|
|
740
|
+
): SegmentData | null {
|
|
741
|
+
const config: TodaySegmentConfig | undefined =
|
|
742
|
+
typeof configOrType === "string"
|
|
743
|
+
? ({ enabled: true, type: configOrType } as TodaySegmentConfig)
|
|
744
|
+
: configOrType;
|
|
745
|
+
const type = config?.type ?? "cost";
|
|
672
746
|
const todayBudget = this.config.budget?.today;
|
|
673
|
-
const
|
|
747
|
+
const formattedUsage = this.formatUsageWithBudget(
|
|
674
748
|
todayInfo.cost,
|
|
675
749
|
todayInfo.tokens,
|
|
676
750
|
todayInfo.tokenBreakdown,
|
|
677
751
|
type,
|
|
678
|
-
todayBudget
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
752
|
+
todayBudget,
|
|
753
|
+
config?.showUnits ?? true,
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
if (formattedUsage === null) return null;
|
|
757
|
+
|
|
758
|
+
const text = `${this.leadingIcon(this.symbols.today_cost, config)}${formattedUsage}`;
|
|
682
759
|
|
|
683
760
|
return {
|
|
684
761
|
text,
|
|
@@ -710,14 +787,18 @@ export class SegmentRenderer {
|
|
|
710
787
|
tokens: number | null,
|
|
711
788
|
tokenBreakdown: TokenBreakdown | null,
|
|
712
789
|
type: string,
|
|
790
|
+
showUnits: boolean,
|
|
713
791
|
): string {
|
|
792
|
+
const tokenStr = showUnits
|
|
793
|
+
? formatTokens(tokens)
|
|
794
|
+
: formatTokenCount(tokens);
|
|
714
795
|
switch (type) {
|
|
715
796
|
case "cost":
|
|
716
797
|
return formatCost(cost);
|
|
717
798
|
case "tokens":
|
|
718
|
-
return
|
|
799
|
+
return tokenStr;
|
|
719
800
|
case "both":
|
|
720
|
-
return `${formatCost(cost)} (${
|
|
801
|
+
return `${formatCost(cost)} (${tokenStr})`;
|
|
721
802
|
case "breakdown":
|
|
722
803
|
return formatTokenBreakdown(tokenBreakdown);
|
|
723
804
|
default:
|
|
@@ -730,52 +811,36 @@ export class SegmentRenderer {
|
|
|
730
811
|
tokens: number | null,
|
|
731
812
|
tokenBreakdown: TokenBreakdown | null,
|
|
732
813
|
type: string,
|
|
733
|
-
budget:
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
814
|
+
budget: BudgetItemConfig | undefined,
|
|
815
|
+
showUnits: boolean,
|
|
816
|
+
): string | null {
|
|
817
|
+
const state = resolveBudgetDisplay(cost, tokens, budget);
|
|
818
|
+
if (state.suppressAll) return null;
|
|
819
|
+
if (!state.showBase) return state.percentText;
|
|
820
|
+
|
|
737
821
|
const baseDisplay = this.formatUsageDisplay(
|
|
738
822
|
cost,
|
|
739
823
|
tokens,
|
|
740
824
|
tokenBreakdown,
|
|
741
825
|
type,
|
|
826
|
+
showUnits,
|
|
742
827
|
);
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
if (budgetType === "tokens" && tokens !== null) {
|
|
748
|
-
budgetValue = tokens;
|
|
749
|
-
} else if (budgetType === "cost" && cost !== null) {
|
|
750
|
-
budgetValue = cost;
|
|
751
|
-
} else if (!budgetType && cost !== null) {
|
|
752
|
-
budgetValue = cost;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
if (budgetValue !== null) {
|
|
756
|
-
const budgetStatus = getBudgetStatus(
|
|
757
|
-
budgetValue,
|
|
758
|
-
budget,
|
|
759
|
-
warningThreshold,
|
|
760
|
-
);
|
|
761
|
-
return baseDisplay + budgetStatus.displayText;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
return baseDisplay;
|
|
828
|
+
return state.percentText
|
|
829
|
+
? `${baseDisplay} ${state.percentText}`
|
|
830
|
+
: baseDisplay;
|
|
766
831
|
}
|
|
767
832
|
|
|
768
833
|
renderVersion(
|
|
769
834
|
hookData: ClaudeHookData,
|
|
770
835
|
colors: PowerlineColors,
|
|
771
|
-
|
|
836
|
+
config?: VersionSegmentConfig,
|
|
772
837
|
): SegmentData | null {
|
|
773
838
|
if (!hookData.version) {
|
|
774
839
|
return null;
|
|
775
840
|
}
|
|
776
841
|
|
|
777
842
|
return {
|
|
778
|
-
text: `${this.symbols.version}
|
|
843
|
+
text: `${this.leadingIcon(this.symbols.version, config)}v${hookData.version}`,
|
|
779
844
|
bgColor: colors.versionBg,
|
|
780
845
|
fgColor: colors.versionFg,
|
|
781
846
|
};
|
|
@@ -788,9 +853,97 @@ export class SegmentRenderer {
|
|
|
788
853
|
const value = globalThis.process?.env?.[config.variable];
|
|
789
854
|
if (!value) return null;
|
|
790
855
|
const prefix = config.prefix ?? config.variable;
|
|
856
|
+
const iconPrefix = this.leadingIcon(this.symbols.env, config);
|
|
791
857
|
const text = prefix
|
|
792
|
-
? `${
|
|
793
|
-
: `${
|
|
858
|
+
? `${iconPrefix}${prefix}: ${value}`
|
|
859
|
+
: `${iconPrefix}${value}`;
|
|
794
860
|
return { text, bgColor: colors.envBg, fgColor: colors.envFg };
|
|
795
861
|
}
|
|
862
|
+
|
|
863
|
+
renderAgent(
|
|
864
|
+
hookData: ClaudeHookData,
|
|
865
|
+
colors: PowerlineColors,
|
|
866
|
+
config?: AgentSegmentConfig,
|
|
867
|
+
): SegmentData | null {
|
|
868
|
+
const rawName = hookData.agent?.name;
|
|
869
|
+
if (typeof rawName !== "string") return null;
|
|
870
|
+
const name = rawName.trim();
|
|
871
|
+
if (!name) return null;
|
|
872
|
+
|
|
873
|
+
const iconPrefix = this.leadingIcon(this.symbols.agent, config);
|
|
874
|
+
const body = config?.showLabel ? `agent: ${name}` : name;
|
|
875
|
+
|
|
876
|
+
return {
|
|
877
|
+
text: `${iconPrefix}${body}`,
|
|
878
|
+
bgColor: colors.agentBg,
|
|
879
|
+
fgColor: colors.agentFg,
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
renderThinking(
|
|
884
|
+
hookData: ClaudeHookData,
|
|
885
|
+
colors: PowerlineColors,
|
|
886
|
+
config?: ThinkingSegmentConfig,
|
|
887
|
+
): SegmentData | null {
|
|
888
|
+
const showEnabled = config?.showEnabled ?? true;
|
|
889
|
+
const showEffort = config?.showEffort ?? true;
|
|
890
|
+
if (!showEnabled && !showEffort) return null;
|
|
891
|
+
|
|
892
|
+
const enabled = showEnabled ? getThinkingEnabled(hookData) : null;
|
|
893
|
+
const level = showEffort ? getEffortLevel(hookData) : null;
|
|
894
|
+
|
|
895
|
+
const parts: string[] = [];
|
|
896
|
+
if (enabled !== null) parts.push(enabled ? "On" : "Off");
|
|
897
|
+
if (level) parts.push(level);
|
|
898
|
+
if (parts.length === 0) return null;
|
|
899
|
+
|
|
900
|
+
const iconPrefix = this.leadingIcon(this.symbols.thinking, config);
|
|
901
|
+
return {
|
|
902
|
+
text: `${iconPrefix}${parts.join(" · ")}`,
|
|
903
|
+
bgColor: colors.thinkingBg,
|
|
904
|
+
fgColor: colors.thinkingFg,
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
renderCacheTimer(
|
|
909
|
+
info: CacheTimerInfo,
|
|
910
|
+
colors: PowerlineColors,
|
|
911
|
+
config?: CacheTimerSegmentConfig,
|
|
912
|
+
): SegmentData {
|
|
913
|
+
const e = info.elapsedSeconds;
|
|
914
|
+
const iconPrefix = this.leadingIcon(this.symbols.cache_timer, config);
|
|
915
|
+
|
|
916
|
+
let bgColor = colors.cacheTimerBg;
|
|
917
|
+
let fgColor = colors.cacheTimerFg;
|
|
918
|
+
let bold = colors.cacheTimerBold;
|
|
919
|
+
|
|
920
|
+
if (config?.displayMode === "remaining") {
|
|
921
|
+
const ttl = config.ttlSeconds ?? info.detectedTtlSeconds ?? 3600;
|
|
922
|
+
const remaining = Math.max(0, ttl - e);
|
|
923
|
+
const text = `${iconPrefix}${formatCacheTimerRemaining(remaining)}`;
|
|
924
|
+
if (remaining < 60) {
|
|
925
|
+
bgColor = colors.contextCriticalBg;
|
|
926
|
+
fgColor = colors.contextCriticalFg;
|
|
927
|
+
bold = colors.contextCriticalBold;
|
|
928
|
+
} else if (remaining < 300) {
|
|
929
|
+
bgColor = colors.contextWarningBg;
|
|
930
|
+
fgColor = colors.contextWarningFg;
|
|
931
|
+
bold = colors.contextWarningBold;
|
|
932
|
+
}
|
|
933
|
+
return { text, bgColor, fgColor, bold };
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
const text = `${iconPrefix}${formatCacheTimerElapsed(e)}`;
|
|
937
|
+
if (e >= 300) {
|
|
938
|
+
bgColor = colors.contextCriticalBg;
|
|
939
|
+
fgColor = colors.contextCriticalFg;
|
|
940
|
+
bold = colors.contextCriticalBold;
|
|
941
|
+
} else if (e >= 180) {
|
|
942
|
+
bgColor = colors.contextWarningBg;
|
|
943
|
+
fgColor = colors.contextWarningFg;
|
|
944
|
+
bold = colors.contextWarningBold;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
return { text, bgColor, fgColor, bold };
|
|
948
|
+
}
|
|
796
949
|
}
|
package/src/themes/dark.ts
CHANGED
|
@@ -15,6 +15,9 @@ export const darkTheme: ColorTheme = {
|
|
|
15
15
|
version: { bg: "#3a3a4a", fg: "#b8b8d0" },
|
|
16
16
|
env: { bg: "#2d2d3d", fg: "#d0a0d0" },
|
|
17
17
|
weekly: { bg: "#2a2a3a", fg: "#a0c4e8" },
|
|
18
|
+
agent: { bg: "#2a2a4a", fg: "#b0a8e0" },
|
|
19
|
+
thinking: { bg: "#2a2a3a", fg: "#c792ea" },
|
|
20
|
+
cacheTimer: { bg: "#1f3a1f", fg: "#90ee90" },
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const darkAnsi256Theme: ColorTheme = {
|
|
@@ -32,6 +35,9 @@ export const darkAnsi256Theme: ColorTheme = {
|
|
|
32
35
|
version: { bg: "#444444", fg: "#d7afff" },
|
|
33
36
|
env: { bg: "#3a3a3a", fg: "#d787d7" },
|
|
34
37
|
weekly: { bg: "#303030", fg: "#87afd7" },
|
|
38
|
+
agent: { bg: "#3a3a5f", fg: "#afafd7" },
|
|
39
|
+
thinking: { bg: "#2a2a3a", fg: "#d787ff" },
|
|
40
|
+
cacheTimer: { bg: "#1c2e1c", fg: "#87ff87" },
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
export const darkAnsiTheme: ColorTheme = {
|
|
@@ -49,4 +55,7 @@ export const darkAnsiTheme: ColorTheme = {
|
|
|
49
55
|
version: { bg: "#585858", fg: "#af87ff" },
|
|
50
56
|
env: { bg: "#444444", fg: "#ff87ff" },
|
|
51
57
|
weekly: { bg: "#3a3a3a", fg: "#5fafff" },
|
|
58
|
+
agent: { bg: "#444444", fg: "#af87ff" },
|
|
59
|
+
thinking: { bg: "#444444", fg: "#ff87ff" },
|
|
60
|
+
cacheTimer: { bg: "#2f4f2f", fg: "#00ff00" },
|
|
52
61
|
};
|
package/src/themes/gruvbox.ts
CHANGED
|
@@ -15,6 +15,9 @@ export const gruvboxTheme: ColorTheme = {
|
|
|
15
15
|
version: { bg: "#504945", fg: "#8ec07c" },
|
|
16
16
|
env: { bg: "#3c3836", fg: "#d3869b" },
|
|
17
17
|
weekly: { bg: "#3c3836", fg: "#8ec07c" },
|
|
18
|
+
agent: { bg: "#504945", fg: "#d3869b" },
|
|
19
|
+
thinking: { bg: "#3c3046", fg: "#d3869b" },
|
|
20
|
+
cacheTimer: { bg: "#3c3836", fg: "#b8bb26" },
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const gruvboxAnsi256Theme: ColorTheme = {
|
|
@@ -32,6 +35,9 @@ export const gruvboxAnsi256Theme: ColorTheme = {
|
|
|
32
35
|
version: { bg: "#585858", fg: "#87af87" },
|
|
33
36
|
env: { bg: "#444444", fg: "#d787af" },
|
|
34
37
|
weekly: { bg: "#444444", fg: "#87af87" },
|
|
38
|
+
agent: { bg: "#6c6c6c", fg: "#d787af" },
|
|
39
|
+
thinking: { bg: "#444444", fg: "#d787af" },
|
|
40
|
+
cacheTimer: { bg: "#444444", fg: "#afaf00" },
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
export const gruvboxAnsiTheme: ColorTheme = {
|
|
@@ -49,4 +55,7 @@ export const gruvboxAnsiTheme: ColorTheme = {
|
|
|
49
55
|
version: { bg: "#808080", fg: "#00d787" },
|
|
50
56
|
env: { bg: "#585858", fg: "#ff87af" },
|
|
51
57
|
weekly: { bg: "#585858", fg: "#00d787" },
|
|
58
|
+
agent: { bg: "#808080", fg: "#ff87af" },
|
|
59
|
+
thinking: { bg: "#808080", fg: "#ff87af" },
|
|
60
|
+
cacheTimer: { bg: "#585858", fg: "#ffff00" },
|
|
52
61
|
};
|
package/src/themes/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { gruvboxTheme, gruvboxAnsi256Theme, gruvboxAnsiTheme } from "./gruvbox";
|
|
|
16
16
|
export interface SegmentColor {
|
|
17
17
|
bg: string;
|
|
18
18
|
fg: string;
|
|
19
|
+
bold?: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface ColorTheme {
|
|
@@ -33,38 +34,64 @@ export interface ColorTheme {
|
|
|
33
34
|
version: SegmentColor;
|
|
34
35
|
env: SegmentColor;
|
|
35
36
|
weekly: SegmentColor;
|
|
37
|
+
agent: SegmentColor;
|
|
38
|
+
thinking: SegmentColor;
|
|
39
|
+
cacheTimer: SegmentColor;
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
export interface PowerlineColors {
|
|
39
43
|
reset: string;
|
|
40
44
|
modeBg: string;
|
|
41
45
|
modeFg: string;
|
|
46
|
+
modeBold: boolean;
|
|
42
47
|
gitBg: string;
|
|
43
48
|
gitFg: string;
|
|
49
|
+
gitBold: boolean;
|
|
44
50
|
modelBg: string;
|
|
45
51
|
modelFg: string;
|
|
52
|
+
modelBold: boolean;
|
|
46
53
|
sessionBg: string;
|
|
47
54
|
sessionFg: string;
|
|
55
|
+
sessionBold: boolean;
|
|
48
56
|
blockBg: string;
|
|
49
57
|
blockFg: string;
|
|
58
|
+
blockBold: boolean;
|
|
50
59
|
todayBg: string;
|
|
51
60
|
todayFg: string;
|
|
61
|
+
todayBold: boolean;
|
|
52
62
|
tmuxBg: string;
|
|
53
63
|
tmuxFg: string;
|
|
64
|
+
tmuxBold: boolean;
|
|
54
65
|
contextBg: string;
|
|
55
66
|
contextFg: string;
|
|
67
|
+
contextBold: boolean;
|
|
56
68
|
contextWarningBg: string;
|
|
57
69
|
contextWarningFg: string;
|
|
70
|
+
contextWarningBold: boolean;
|
|
58
71
|
contextCriticalBg: string;
|
|
59
72
|
contextCriticalFg: string;
|
|
73
|
+
contextCriticalBold: boolean;
|
|
60
74
|
metricsBg: string;
|
|
61
75
|
metricsFg: string;
|
|
76
|
+
metricsBold: boolean;
|
|
62
77
|
versionBg: string;
|
|
63
78
|
versionFg: string;
|
|
79
|
+
versionBold: boolean;
|
|
64
80
|
envBg: string;
|
|
65
81
|
envFg: string;
|
|
82
|
+
envBold: boolean;
|
|
66
83
|
weeklyBg: string;
|
|
67
84
|
weeklyFg: string;
|
|
85
|
+
weeklyBold: boolean;
|
|
86
|
+
agentBg: string;
|
|
87
|
+
agentFg: string;
|
|
88
|
+
agentBold: boolean;
|
|
89
|
+
thinkingBg: string;
|
|
90
|
+
thinkingFg: string;
|
|
91
|
+
thinkingBold: boolean;
|
|
92
|
+
cacheTimerBg: string;
|
|
93
|
+
cacheTimerFg: string;
|
|
94
|
+
cacheTimerBold: boolean;
|
|
68
95
|
partFg: Record<string, string>;
|
|
69
96
|
}
|
|
70
97
|
|
package/src/themes/light.ts
CHANGED
|
@@ -15,6 +15,9 @@ export const lightTheme: ColorTheme = {
|
|
|
15
15
|
version: { bg: "#8b7dd8", fg: "#ffffff" },
|
|
16
16
|
env: { bg: "#d45dbf", fg: "#ffffff" },
|
|
17
17
|
weekly: { bg: "#4f46e5", fg: "#ffffff" },
|
|
18
|
+
agent: { bg: "#7c3aed", fg: "#ffffff" },
|
|
19
|
+
thinking: { bg: "#7c3aed", fg: "#ffffff" },
|
|
20
|
+
cacheTimer: { bg: "#059669", fg: "#ffffff" },
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const lightAnsi256Theme: ColorTheme = {
|
|
@@ -32,6 +35,9 @@ export const lightAnsi256Theme: ColorTheme = {
|
|
|
32
35
|
version: { bg: "#af87ff", fg: "#ffffff" },
|
|
33
36
|
env: { bg: "#d787af", fg: "#ffffff" },
|
|
34
37
|
weekly: { bg: "#5f5fff", fg: "#ffffff" },
|
|
38
|
+
agent: { bg: "#8787d7", fg: "#ffffff" },
|
|
39
|
+
thinking: { bg: "#8700d7", fg: "#ffffff" },
|
|
40
|
+
cacheTimer: { bg: "#00875f", fg: "#ffffff" },
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
export const lightAnsiTheme: ColorTheme = {
|
|
@@ -49,4 +55,7 @@ export const lightAnsiTheme: ColorTheme = {
|
|
|
49
55
|
version: { bg: "#af87ff", fg: "#ffffff" },
|
|
50
56
|
env: { bg: "#d787af", fg: "#ffffff" },
|
|
51
57
|
weekly: { bg: "#5f5fff", fg: "#ffffff" },
|
|
58
|
+
agent: { bg: "#5f5fff", fg: "#ffffff" },
|
|
59
|
+
thinking: { bg: "#8700d7", fg: "#ffffff" },
|
|
60
|
+
cacheTimer: { bg: "#00875f", fg: "#ffffff" },
|
|
52
61
|
};
|
package/src/themes/nord.ts
CHANGED
|
@@ -15,6 +15,9 @@ export const nordTheme: ColorTheme = {
|
|
|
15
15
|
version: { bg: "#434c5e", fg: "#88c0d0" },
|
|
16
16
|
env: { bg: "#3b4252", fg: "#b48ead" },
|
|
17
17
|
weekly: { bg: "#3b4252", fg: "#88c0d0" },
|
|
18
|
+
agent: { bg: "#4c566a", fg: "#b48ead" },
|
|
19
|
+
thinking: { bg: "#3b4252", fg: "#b48ead" },
|
|
20
|
+
cacheTimer: { bg: "#3b4252", fg: "#a3be8c" },
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const nordAnsi256Theme: ColorTheme = {
|
|
@@ -32,6 +35,9 @@ export const nordAnsi256Theme: ColorTheme = {
|
|
|
32
35
|
version: { bg: "#5f87af", fg: "#5fafaf" },
|
|
33
36
|
env: { bg: "#4e4e4e", fg: "#d787af" },
|
|
34
37
|
weekly: { bg: "#4e4e4e", fg: "#5fafaf" },
|
|
38
|
+
agent: { bg: "#6c6c6c", fg: "#d787af" },
|
|
39
|
+
thinking: { bg: "#4e4e4e", fg: "#d787af" },
|
|
40
|
+
cacheTimer: { bg: "#4e4e4e", fg: "#87af87" },
|
|
35
41
|
};
|
|
36
42
|
|
|
37
43
|
export const nordAnsiTheme: ColorTheme = {
|
|
@@ -49,4 +55,7 @@ export const nordAnsiTheme: ColorTheme = {
|
|
|
49
55
|
version: { bg: "#0087af", fg: "#00d7d7" },
|
|
50
56
|
env: { bg: "#585858", fg: "#ff87af" },
|
|
51
57
|
weekly: { bg: "#585858", fg: "#00d7d7" },
|
|
58
|
+
agent: { bg: "#808080", fg: "#ff87af" },
|
|
59
|
+
thinking: { bg: "#585858", fg: "#ff87d7" },
|
|
60
|
+
cacheTimer: { bg: "#585858", fg: "#87d787" },
|
|
52
61
|
};
|