@owloops/claude-powerline 1.1.5 → 1.1.7

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
@@ -1,101 +1,169 @@
1
+ <div align="center">
2
+
1
3
  # Claude Powerline
2
4
 
3
- A vim-style powerline statusline for Claude Code with real-time usage tracking, git integration, and custom themes.
5
+ **A vim-style powerline statusline for Claude Code with real-time usage tracking, git integration, and custom themes.**
4
6
 
5
7
  ![Language:TypeScript](https://img.shields.io/static/v1?label=Language&message=TypeScript&color=blue&style=flat-square)
6
8
  ![License:MIT](https://img.shields.io/static/v1?label=License&message=MIT&color=blue&style=flat-square)
7
9
  [![npm version](https://img.shields.io/npm/v/@owloops/claude-powerline?style=flat-square)](https://www.npmjs.com/package/@owloops/claude-powerline)
8
10
 
11
+ <table>
12
+ <tr>
13
+ <td align="center">
14
+ <img src="images/claude-powerline-dark.png" width="400" alt="Dark Theme"><br>
15
+ <strong>Dark</strong>
16
+ </td>
17
+ <td align="center">
18
+ <img src="images/claude-powerline-light.png" width="400" alt="Light Theme"><br>
19
+ <strong>Light</strong>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <td align="center">
24
+ <img src="images/claude-powerline-nord.png" width="400" alt="Nord Theme"><br>
25
+ <strong>Nord</strong>
26
+ </td>
27
+ <td align="center">
28
+ <img src="images/claude-powerline-tokyo-night.png" width="400" alt="Tokyo Night Theme"><br>
29
+ <strong>Tokyo Night</strong>
30
+ </td>
31
+ </tr>
32
+ <tr>
33
+ <td align="center">
34
+ <img src="images/claude-powerline-rose-pine.png" width="400" alt="Rose Pine Theme"><br>
35
+ <strong>Rose Pine</strong>
36
+ </td>
37
+ <td align="center">
38
+ <img src="images/claude-powerline-custom.png" width="400" alt="Custom Theme"><br>
39
+ <em>Create your own!</em>
40
+ </td>
41
+ </tr>
42
+ </table>
43
+ </div>
44
+
9
45
  ## Features
10
46
 
47
+ <table>
48
+ <tr>
49
+ <td width="50%" valign="top">
50
+
51
+ ### Core Features
52
+
11
53
  - **Vim-style powerline** with proper arrows and segments
12
54
  - **Real-time usage tracking** with costs, tokens, and session blocks
13
55
  - **Git integration** with branch, status, ahead/behind counts
56
+
57
+ </td>
58
+ <td width="50%" valign="top">
59
+
60
+ ### Customization
61
+
14
62
  - **Custom themes** with full color control
15
63
  - **Budget monitoring** with percentage warnings
16
64
  - **Flexible configuration** via JSON files and environment variables
17
65
 
66
+ </td>
67
+ </tr>
68
+ </table>
69
+
18
70
  ## Installation
19
71
 
72
+ ### Requirements
73
+
74
+ - **Node.js 18+**
75
+ - **Claude Code**
76
+
77
+ ### Setup
78
+
79
+ **Install powerline fonts:**
80
+
20
81
  ```bash
21
- npx -y @owloops/claude-powerline --install-fonts # Install powerline fonts
82
+ npx -y @owloops/claude-powerline --install-fonts
22
83
  ```
23
84
 
24
- Add to your Claude Code `settings.json`:
85
+ > [!WARNING]
86
+ > Without powerline fonts, arrow separators display as placeholder characters (�). The default `--style=minimal` mode resolves it by not using the powerline unicode.
87
+
88
+ **Add to your Claude Code `settings.json`:**
25
89
 
26
90
  ```json
27
91
  {
28
92
  "statusLine": {
29
- "type": "command",
30
- "command": "npx -y @owloops/claude-powerline",
93
+ "type": "command",
94
+ "command": "npx -y @owloops/claude-powerline --style=powerline",
31
95
  "padding": 0
32
96
  }
33
97
  }
34
98
  ```
35
99
 
36
- > **Note:** Using `npx` automatically downloads and runs the latest version, ensuring you always have the newest features and fixes without manual updates.
100
+ > [!NOTE]
101
+ > Using `npx` automatically downloads and runs the latest version, ensuring you always have the newest features and fixes without manual updates.
37
102
 
38
103
  ## Usage
39
104
 
40
105
  ```bash
41
- # Basic usage (single line with directory, git, model, session, today)
42
- claude-powerline
106
+ claude-powerline [OPTIONS]
107
+ ```
43
108
 
44
- # Dark theme
45
- claude-powerline --theme=dark
109
+ Options are specified by command line flags. Overall configuration can also use environment variables or configuration files.
46
110
 
47
- # Show tokens instead of costs
48
- claude-powerline --usage=tokens
111
+ ## Command Line Options
49
112
 
50
- # Show token breakdown (input/output)
51
- claude-powerline --usage=breakdown
113
+ | Option | Values | Description |
114
+ |--------|--------|-------------|
115
+ | `--theme` | `dark` (default), `light`, `nord`, `tokyo-night`, `rose-pine`, `custom` | Set color theme |
116
+ | `--style` | `minimal` (default), `powerline` | Set separator style |
117
+ | `--usage` | `cost`, `tokens`, `both`, `breakdown` | Set usage display format |
118
+ | `--daily-budget` | `AMOUNT` | Set daily budget limit in USD |
119
+ | `--session-budget` | `AMOUNT` | Set session budget limit in USD |
120
+ | `--config` | `PATH` | Use custom config file path |
121
+ | `--install-fonts` | - | Install powerline fonts to system |
122
+ | `-h, --help` | - | Show help message |
52
123
 
53
- # Set budgets with warnings
54
- claude-powerline --daily-budget=50 --session-budget=20
55
- ```
124
+ ### Usage Display Types
56
125
 
57
- ## Styles
126
+ - **cost**: Show dollar amounts (`$0.05`)
127
+ - **tokens**: Show token counts (`1.2K tokens`)
128
+ - **both**: Show both (`$0.05 (1.2K tokens)`)
129
+ - **breakdown**: Show detailed token breakdown (`1.2Kin + 0.8Kout + 1.5Kcached`)
58
130
 
59
- Set separator style:
131
+ ## Examples
60
132
 
61
- - **powerline** - Powerline arrows (requires Powerline fonts)
62
- - **minimal** - Rectangular segments, no separators (default)
133
+ ### Default Configuration
63
134
 
64
135
  ```bash
65
- claude-powerline --style=powerline
136
+ # Shows directory, git, model, session usage (tokens), today usage (both)
137
+ # Uses dark theme, minimal style, $50 daily budget
138
+ claude-powerline
66
139
  ```
67
140
 
68
- ## Screenshots
69
-
70
- ### Dark Theme (Default)
141
+ ### Theme and Style
71
142
 
72
- ![Dark Theme](images/powerline-dark.png)
73
-
74
- ### Light Theme
143
+ ```bash
144
+ # Nord theme with powerline arrows
145
+ claude-powerline --theme=nord --style=powerline
75
146
 
76
- ![Light theme](images/powerline-light.png)
147
+ # Tokyo Night theme, minimal style
148
+ claude-powerline --theme=tokyo-night --style=minimal
149
+ ```
77
150
 
78
- ## Default Segments
151
+ ### Usage Display
79
152
 
80
- By default displays: `Directory | Git Branch | Model | Session Usage | Today Usage`
153
+ ```bash
154
+ # Show token breakdown instead of costs
155
+ claude-powerline --usage=breakdown
81
156
 
82
- ### Usage Display Types
157
+ # Set daily budget limit
158
+ claude-powerline --daily-budget=50
159
+ ```
83
160
 
84
- - **cost**: Show dollar amounts (`$0.05`)
85
- - **tokens**: Show token counts (`1.2K tokens`)
86
- - **both**: Show both (`$0.05 (1.2K tokens)`)
87
161
  - **breakdown**: Show detailed token breakdown (`1.2Kin + 0.8Kout + 1.5Kcached`)
88
162
 
89
- ### Git Status Indicators
90
-
91
- - `✓` Clean, `●` Dirty, `⚠` Conflicts
92
- - `↑3` Ahead, `↓2` Behind remote
163
+ ### Status Indicators
93
164
 
94
- ### Budget Indicators
95
-
96
- - `25%` Normal (under 50%)
97
- - `+75%` Moderate (50-79%)
98
- - `!85%` Warning (80%+, configurable)
165
+ - **Git**: `✓` Clean, `●` Dirty, `⚠` Conflicts, `↑3` Ahead, `↓2` Behind remote
166
+ - **Budget**: `25%` Normal (under 50%), `+75%` Moderate (50-79%), `!85%` Warning (80%+)
99
167
 
100
168
  ## Configuration
101
169
 
@@ -106,13 +174,15 @@ Create config file:
106
174
  curl -o ~/.claude/claude-powerline.json https://raw.githubusercontent.com/Owloops/claude-powerline/main/.claude-powerline.json
107
175
  ```
108
176
 
109
- Config files loaded in priority order:
177
+ Configuration priority (top overrides bottom):
110
178
 
111
- 1. CLI arguments (`--theme`, `--usage`, `--config`)
112
- 2. Environment variables (`CLAUDE_POWERLINE_THEME`, `CLAUDE_POWERLINE_USAGE_TYPE`, `CLAUDE_POWERLINE_CONFIG`)
113
- 3. `./.claude-powerline.json` (project)
114
- 4. `~/.claude/claude-powerline.json` (user)
115
- 5. `~/.config/claude-powerline/config.json` (XDG)
179
+ 1. CLI arguments (`--theme`, `--style`, `--usage`, `--config`)
180
+ 2. Environment variables (`CLAUDE_POWERLINE_THEME`, `CLAUDE_POWERLINE_STYLE`, `CLAUDE_POWERLINE_USAGE_TYPE`, `CLAUDE_POWERLINE_CONFIG`)
181
+ 3. Config files (first found):
182
+ - `./.claude-powerline.json` (project)
183
+ - `~/.claude/claude-powerline.json` (user)
184
+ - `~/.config/claude-powerline/config.json` (XDG)
185
+ 4. Default values
116
186
 
117
187
  ### Enable Additional Segments
118
188
 
@@ -164,13 +234,8 @@ To prevent segment cutoff, configure multiple lines:
164
234
  }
165
235
  ```
166
236
 
167
- ### Built-in Themes
168
-
169
- Use `light` or `dark` themes with no configuration needed:
170
-
171
- ```bash
172
- claude-powerline --theme=light # or --theme=dark (default)
173
- ```
237
+ > [!NOTE]
238
+ > Claude Code system messages (e.g., Context left until auto-compact) may truncate the status line mid-sequence. Multi-line layouts help prevent segment cutoff.
174
239
 
175
240
  ### Custom Colors
176
241
 
@@ -197,16 +262,11 @@ To customize colors, copy dark or light theme colors from `src/themes/` in the r
197
262
 
198
263
  ```bash
199
264
  export CLAUDE_POWERLINE_THEME=dark
265
+ export CLAUDE_POWERLINE_STYLE=powerline
200
266
  export CLAUDE_POWERLINE_USAGE_TYPE=tokens
201
267
  export CLAUDE_POWERLINE_CONFIG=/path/to/config.json
202
268
  ```
203
269
 
204
- ## Requirements
205
-
206
- - Node.js ≥ 18.0.0
207
- - Terminal with powerline font support
208
- - Git (optional, for git integration)
209
-
210
270
  ## Troubleshooting
211
271
 
212
272
  **Arrows not displaying?** Run `claude-powerline --install-fonts` and set terminal font to a powerline-patched font.
package/dist/index.js CHANGED
@@ -45,10 +45,46 @@ var lightTheme = {
45
45
  tmux: { bg: "#32cd32", fg: "#ffffff" }
46
46
  };
47
47
 
48
+ // src/themes/nord.ts
49
+ var nordTheme = {
50
+ directory: { bg: "#434c5e", fg: "#d8dee9" },
51
+ git: { bg: "#3b4252", fg: "#a3be8c" },
52
+ model: { bg: "#4c566a", fg: "#81a1c1" },
53
+ session: { bg: "#2e3440", fg: "#88c0d0" },
54
+ today: { bg: "#434c5e", fg: "#ebcb8b" },
55
+ block: { bg: "#3b4252", fg: "#bf616a" },
56
+ tmux: { bg: "#2e3440", fg: "#8fbcbb" }
57
+ };
58
+
59
+ // src/themes/tokyo-night.ts
60
+ var tokyoNightTheme = {
61
+ directory: { bg: "#2f334d", fg: "#82aaff" },
62
+ git: { bg: "#1e2030", fg: "#c3e88d" },
63
+ model: { bg: "#191b29", fg: "#fca7ea" },
64
+ session: { bg: "#222436", fg: "#86e1fc" },
65
+ today: { bg: "#2f334d", fg: "#ffc777" },
66
+ block: { bg: "#1e2030", fg: "#ff966c" },
67
+ tmux: { bg: "#191b29", fg: "#4fd6be" }
68
+ };
69
+
70
+ // src/themes/rose-pine.ts
71
+ var rosePineTheme = {
72
+ directory: { bg: "#26233a", fg: "#c4a7e7" },
73
+ git: { bg: "#1f1d2e", fg: "#9ccfd8" },
74
+ model: { bg: "#191724", fg: "#ebbcba" },
75
+ session: { bg: "#26233a", fg: "#f6c177" },
76
+ today: { bg: "#1f1d2e", fg: "#eb6f92" },
77
+ block: { bg: "#191724", fg: "#31748f" },
78
+ tmux: { bg: "#26233a", fg: "#908caa" }
79
+ };
80
+
48
81
  // src/themes/index.ts
49
82
  var BUILT_IN_THEMES = {
50
83
  dark: darkTheme,
51
- light: lightTheme
84
+ light: lightTheme,
85
+ nord: nordTheme,
86
+ "tokyo-night": tokyoNightTheme,
87
+ "rose-pine": rosePineTheme
52
88
  };
53
89
  function getTheme(themeName) {
54
90
  return BUILT_IN_THEMES[themeName] || null;
@@ -644,12 +680,17 @@ var PowerlineRenderer = class {
644
680
  if (theme === "custom") {
645
681
  colorTheme = this.config.colors?.custom;
646
682
  if (!colorTheme) {
647
- throw new Error("Custom theme selected but no colors provided in configuration");
683
+ throw new Error(
684
+ "Custom theme selected but no colors provided in configuration"
685
+ );
648
686
  }
649
687
  } else {
650
688
  colorTheme = getTheme(theme);
651
689
  if (!colorTheme) {
652
- throw new Error(`Built-in theme '${theme}' not found`);
690
+ console.warn(
691
+ `Built-in theme '${theme}' not found, falling back to 'dark' theme`
692
+ );
693
+ colorTheme = getTheme("dark");
653
694
  }
654
695
  }
655
696
  return {
@@ -786,7 +827,15 @@ function loadEnvConfig() {
786
827
  }
787
828
  if (process.env.CLAUDE_POWERLINE_STYLE) {
788
829
  config.display = config.display || { lines: [] };
789
- config.display.style = process.env.CLAUDE_POWERLINE_STYLE;
830
+ const style = process.env.CLAUDE_POWERLINE_STYLE;
831
+ if (style === "minimal" || style === "powerline") {
832
+ config.display.style = style;
833
+ } else {
834
+ console.warn(
835
+ `Invalid display style '${style}' from environment variable, falling back to 'minimal'`
836
+ );
837
+ config.display.style = "minimal";
838
+ }
790
839
  }
791
840
  if (process.env.CLAUDE_POWERLINE_USAGE_TYPE) {
792
841
  const usageType = process.env.CLAUDE_POWERLINE_USAGE_TYPE;
@@ -825,7 +874,14 @@ function parseCLIOverrides(args) {
825
874
  const style = args[styleIndex]?.split("=")[1];
826
875
  if (style) {
827
876
  config.display = config.display || { lines: [] };
828
- config.display.style = style;
877
+ if (style === "minimal" || style === "powerline") {
878
+ config.display.style = style;
879
+ } else {
880
+ console.warn(
881
+ `Invalid display style '${style}' from CLI argument, falling back to 'minimal'`
882
+ );
883
+ config.display.style = "minimal";
884
+ }
829
885
  }
830
886
  }
831
887
  const dailyBudgetIndex = args.findIndex(
@@ -860,6 +916,27 @@ function parseCLIOverrides(args) {
860
916
  };
861
917
  }
862
918
  }
919
+ const usageIndex = args.findIndex((arg) => arg.startsWith("--usage="));
920
+ if (usageIndex !== -1) {
921
+ const usageType = args[usageIndex]?.split("=")[1];
922
+ if (usageType && ["cost", "tokens", "both", "breakdown"].includes(usageType)) {
923
+ config.display = config.display || { lines: [] };
924
+ if (config.display.lines.length === 0) {
925
+ config.display.lines = [{ segments: {} }];
926
+ }
927
+ config.display.lines.forEach((line) => {
928
+ if (line.segments.session) {
929
+ line.segments.session.type = usageType;
930
+ }
931
+ if (line.segments.today) {
932
+ line.segments.today.type = usageType;
933
+ }
934
+ if (line.segments.block) {
935
+ line.segments.block.type = usageType === "breakdown" || usageType === "both" ? "cost" : usageType;
936
+ }
937
+ });
938
+ }
939
+ }
863
940
  return config;
864
941
  }
865
942
  function loadConfig(options = {}) {
@@ -881,6 +958,12 @@ function loadConfig(options = {}) {
881
958
  );
882
959
  }
883
960
  }
961
+ if (config.display?.style && config.display.style !== "minimal" && config.display.style !== "powerline") {
962
+ console.warn(
963
+ `Invalid display style '${config.display.style}' in config file, falling back to 'minimal'`
964
+ );
965
+ config.display.style = "minimal";
966
+ }
884
967
  if (!ignoreEnvVars) {
885
968
  const envConfig = loadEnvConfig();
886
969
  config = deepMerge(config, envConfig);
@@ -982,7 +1065,8 @@ claude-powerline - Beautiful powerline statusline for Claude Code
982
1065
  Usage: claude-powerline [options]
983
1066
 
984
1067
  Options:
985
- --theme=THEME Set theme: light, dark, custom
1068
+ --theme=THEME Set theme: dark, light, nord, tokyo-night, rose-pine, custom
1069
+ --style=STYLE Set separator style: minimal, powerline
986
1070
  --usage=TYPE Usage display: cost, tokens, both, breakdown
987
1071
  --session-budget=AMOUNT Set session budget for percentage tracking
988
1072
  --daily-budget=AMOUNT Set daily budget for percentage tracking
@@ -992,8 +1076,8 @@ Options:
992
1076
 
993
1077
  Configuration:
994
1078
  Config files are loaded in this order (highest priority first):
995
- 1. CLI arguments (--theme, --usage, --config)
996
- 2. Environment variables (CLAUDE_POWERLINE_THEME, CLAUDE_POWERLINE_USAGE_TYPE, CLAUDE_POWERLINE_CONFIG)
1079
+ 1. CLI arguments (--theme, --style, --usage, --config)
1080
+ 2. Environment variables (CLAUDE_POWERLINE_THEME, CLAUDE_POWERLINE_STYLE, CLAUDE_POWERLINE_USAGE_TYPE, CLAUDE_POWERLINE_CONFIG)
997
1081
  3. ./.claude-powerline.json (project)
998
1082
  4. ~/.claude/claude-powerline.json (user)
999
1083
  5. ~/.config/claude-powerline/config.json (XDG)
@@ -1021,7 +1105,8 @@ claude-powerline - Beautiful powerline statusline for Claude Code
1021
1105
  Usage: claude-powerline [options]
1022
1106
 
1023
1107
  Options:
1024
- --theme=THEME Set theme: light, dark, custom
1108
+ --theme=THEME Set theme: dark, light, nord, tokyo-night, rose-pine, custom
1109
+ --style=STYLE Set separator style: minimal, powerline
1025
1110
  --usage=TYPE Usage display: cost, tokens, both, breakdown
1026
1111
  --session-budget=AMOUNT Set session budget for percentage tracking
1027
1112
  --daily-budget=AMOUNT Set daily budget for percentage tracking
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/colors.ts","../src/themes/dark.ts","../src/themes/light.ts","../src/themes/index.ts","../src/lib/usage-provider.ts","../src/lib/git-service.ts","../src/lib/tmux-service.ts","../src/lib/formatters.ts","../src/lib/budget.ts","../src/lib/segment-renderer.ts","../src/powerline.ts","../src/config/loader.ts","../src/config/defaults.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport process from \"node:process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport os from \"node:os\";\nimport getStdin from \"get-stdin\";\nimport { PowerlineRenderer } from \"./powerline\";\nimport { loadConfigFromCLI } from \"./config/loader\";\nimport type { ClaudeHookData } from \"./types\";\n\nasync function installFonts(): Promise<void> {\n try {\n const platform = os.platform();\n let fontDir: string;\n\n if (platform === \"darwin\") {\n fontDir = path.join(os.homedir(), \"Library\", \"Fonts\");\n } else if (platform === \"linux\") {\n fontDir = path.join(os.homedir(), \".local\", \"share\", \"fonts\");\n } else if (platform === \"win32\") {\n fontDir = path.join(\n os.homedir(),\n \"AppData\",\n \"Local\",\n \"Microsoft\",\n \"Windows\",\n \"Fonts\"\n );\n } else {\n console.log(\"Unsupported platform for font installation\");\n return;\n }\n\n if (!fs.existsSync(fontDir)) {\n fs.mkdirSync(fontDir, { recursive: true });\n }\n\n console.log(\"📦 Installing Powerline Fonts...\");\n console.log(\"Downloading from https://github.com/powerline/fonts\");\n\n const tempDir = path.join(os.tmpdir(), \"powerline-fonts\");\n\n try {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n\n console.log(\"Cloning powerline fonts repository...\");\n execSync(\n \"git clone --depth=1 https://github.com/powerline/fonts.git powerline-fonts\",\n {\n stdio: \"inherit\",\n cwd: os.tmpdir(),\n }\n );\n\n console.log(\"Installing fonts...\");\n const installScript = path.join(tempDir, \"install.sh\");\n\n if (fs.existsSync(installScript)) {\n fs.chmodSync(installScript, 0o755);\n execSync(\"./install.sh\", { stdio: \"inherit\", cwd: tempDir });\n } else {\n throw new Error(\n \"Install script not found in powerline fonts repository\"\n );\n }\n\n console.log(\"✅ Powerline fonts installation complete!\");\n console.log(\n \"Please restart your terminal and set your terminal font to a powerline font.\"\n );\n console.log(\n \"Popular choices: Source Code Pro Powerline, DejaVu Sans Mono Powerline, Ubuntu Mono Powerline\"\n );\n } finally {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n }\n } catch (error) {\n console.error(\n \"Error installing fonts:\",\n error instanceof Error ? error.message : String(error)\n );\n console.log(\n \"💡 You can manually install fonts from: https://github.com/powerline/fonts\"\n );\n }\n}\n\nasync function main(): Promise<void> {\n try {\n const showHelp =\n process.argv.includes(\"--help\") || process.argv.includes(\"-h\");\n const installFontsFlag = process.argv.includes(\"--install-fonts\");\n\n if (installFontsFlag) {\n await installFonts();\n process.exit(0);\n }\n\n\n if (showHelp) {\n console.log(`\nclaude-powerline - Beautiful powerline statusline for Claude Code\n\nUsage: claude-powerline [options]\n\nOptions:\n --theme=THEME Set theme: light, dark, custom\n --usage=TYPE Usage display: cost, tokens, both, breakdown\n --session-budget=AMOUNT Set session budget for percentage tracking\n --daily-budget=AMOUNT Set daily budget for percentage tracking\n --config=PATH Use custom config file path\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nConfiguration:\n Config files are loaded in this order (highest priority first):\n 1. CLI arguments (--theme, --usage, --config)\n 2. Environment variables (CLAUDE_POWERLINE_THEME, CLAUDE_POWERLINE_USAGE_TYPE, CLAUDE_POWERLINE_CONFIG)\n 3. ./.claude-powerline.json (project)\n 4. ~/.claude/claude-powerline.json (user)\n 5. ~/.config/claude-powerline/config.json (XDG)\n\nCreating a config file:\n Copy example from: https://github.com/Owloops/claude-powerline/blob/main/.claude-powerline.json\n\nUsage in Claude Code settings.json:\n{\n \"statusLine\": {\n \"type\": \"command\",\n \"command\": \"claude-powerline\",\n \"padding\": 0\n }\n}\n`);\n process.exit(0);\n }\n\n const stdin = await getStdin();\n if (stdin.length === 0) {\n console.error(\"Error: No input provided\");\n console.log(`\nclaude-powerline - Beautiful powerline statusline for Claude Code\n\nUsage: claude-powerline [options]\n\nOptions:\n --theme=THEME Set theme: light, dark, custom\n --usage=TYPE Usage display: cost, tokens, both, breakdown\n --session-budget=AMOUNT Set session budget for percentage tracking\n --daily-budget=AMOUNT Set daily budget for percentage tracking\n --config=PATH Use custom config file path\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nSee example config at: https://github.com/Owloops/claude-powerline/blob/main/.claude-powerline.json\n`);\n process.exit(1);\n }\n\n let hookData: ClaudeHookData;\n try {\n hookData = JSON.parse(stdin.trim());\n } catch (error) {\n console.error(\n \"Error: Invalid JSON input:\",\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n\n const projectDir = hookData.workspace?.project_dir;\n const config = loadConfigFromCLI(process.argv, projectDir);\n const renderer = new PowerlineRenderer(config);\n const statusline = await renderer.generateStatusline(hookData);\n\n console.log(statusline);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(\"Error generating statusline:\", errorMessage);\n process.exit(1);\n }\n}\n\nmain();\n","export function hexToAnsi(hex: string, isBackground: boolean): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return `\\x1b[${isBackground ? \"48\" : \"38\"};2;${r};${g};${b}m`;\n}\n\nexport function extractBgToFg(ansiCode: string): string {\n const match = ansiCode.match(/48;2;(\\d+);(\\d+);(\\d+)/);\n if (match) {\n return `\\x1b[38;2;${match[1]};${match[2]};${match[3]}m`;\n }\n return ansiCode.replace(\"48\", \"38\");\n}\n","import type { ColorTheme } from \"../types/config\";\n\nexport const darkTheme: ColorTheme = {\n directory: { bg: \"#8b4513\", fg: \"#ffffff\" },\n git: { bg: \"#404040\", fg: \"#ffffff\" },\n model: { bg: \"#2d2d2d\", fg: \"#ffffff\" },\n session: { bg: \"#202020\", fg: \"#00ffff\" },\n today: { bg: \"#a0520d\", fg: \"#ffffff\" },\n block: { bg: \"#8b4500\", fg: \"#ffffff\" },\n tmux: { bg: \"#2f4f2f\", fg: \"#90ee90\" },\n};\n","import type { ColorTheme } from \"../types/config\";\n\nexport const lightTheme: ColorTheme = {\n directory: { bg: \"#ff6b47\", fg: \"#ffffff\" },\n git: { bg: \"#4fb3d9\", fg: \"#ffffff\" },\n model: { bg: \"#87ceeb\", fg: \"#000000\" },\n session: { bg: \"#da70d6\", fg: \"#ffffff\" },\n today: { bg: \"#90ee90\", fg: \"#ffffff\" },\n block: { bg: \"#ff8c00\", fg: \"#ffffff\" },\n tmux: { bg: \"#32cd32\", fg: \"#ffffff\" },\n};\n","import type { ColorTheme } from \"../types/config\";\nimport { darkTheme } from \"./dark\";\nimport { lightTheme } from \"./light\";\n\nexport const BUILT_IN_THEMES: Record<string, ColorTheme> = {\n dark: darkTheme,\n light: lightTheme,\n};\n\nexport function getTheme(themeName: string): ColorTheme | null {\n return BUILT_IN_THEMES[themeName] || null;\n}\n\nexport { darkTheme, lightTheme };\n","import {\n loadSessionUsageById,\n loadDailyUsageData,\n loadSessionBlockData,\n getClaudePaths,\n} from \"ccusage/data-loader\";\nimport { calculateTotals, getTotalTokens } from \"ccusage/calculate-cost\";\nimport { logger } from \"ccusage/logger\";\n\nexport interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport interface SessionBlockInfo {\n cost: number;\n tokens: number;\n timeRemaining: number;\n burnRate: number | null;\n tokenBurnRate: number | null;\n isActive: boolean;\n}\n\nexport interface UsageInfo {\n session: {\n cost: number | null;\n tokens: number | null;\n tokenBreakdown: TokenBreakdown | null;\n };\n daily: {\n cost: number;\n tokens: number;\n tokenBreakdown: TokenBreakdown | null;\n };\n}\n\nexport class UsageProvider {\n async getSessionBlockInfo(): Promise<SessionBlockInfo | null> {\n const originalLevel = logger.level;\n logger.level = 0;\n\n try {\n const blocks = await loadSessionBlockData({\n mode: \"auto\",\n sessionDurationHours: 5,\n });\n\n const activeBlock = blocks.find((block) => block.isActive);\n\n if (!activeBlock) {\n return null;\n }\n\n const now = new Date();\n const timeRemaining = Math.round(\n (activeBlock.endTime.getTime() - now.getTime()) / (1000 * 60)\n );\n\n const elapsed = Math.round(\n (now.getTime() - activeBlock.startTime.getTime()) / (1000 * 60)\n );\n\n const totalTokens =\n (activeBlock.tokenCounts?.inputTokens || 0) +\n (activeBlock.tokenCounts?.outputTokens || 0) +\n (activeBlock.tokenCounts?.cacheCreationInputTokens || 0) +\n (activeBlock.tokenCounts?.cacheReadInputTokens || 0);\n\n const burnRate =\n elapsed > 0 ? (activeBlock.costUSD / elapsed) * 60 : null;\n const tokenBurnRate = elapsed > 0 ? (totalTokens / elapsed) * 60 : null;\n\n return {\n cost: activeBlock.costUSD,\n tokens: totalTokens,\n timeRemaining: Math.max(0, timeRemaining),\n burnRate,\n tokenBurnRate,\n isActive: true,\n };\n } catch {\n return null;\n } finally {\n logger.level = originalLevel;\n }\n }\n\n async getUsageInfo(sessionId: string): Promise<UsageInfo> {\n const originalLevel = logger.level;\n logger.level = 0;\n\n try {\n const claudePaths = getClaudePaths();\n if (claudePaths.length === 0) {\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n daily: { cost: 0, tokens: 0, tokenBreakdown: null },\n };\n }\n\n const [sessionData, dailyData] = await Promise.all([\n this.getSessionData(sessionId),\n this.getDailyData(),\n ]);\n\n return {\n session: sessionData,\n daily: dailyData,\n };\n } catch {\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n daily: { cost: 0, tokens: 0, tokenBreakdown: null },\n };\n } finally {\n logger.level = originalLevel;\n }\n }\n\n private async getSessionData(sessionId: string) {\n try {\n const sessionData = await loadSessionUsageById(sessionId, {\n mode: \"auto\",\n });\n\n if (!sessionData) {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n\n const breakdown = sessionData.entries.reduce(\n (acc, entry) => {\n const usage = entry.message.usage;\n return {\n input: acc.input + usage.input_tokens,\n output: acc.output + usage.output_tokens,\n cacheCreation:\n acc.cacheCreation + (usage.cache_creation_input_tokens || 0),\n cacheRead: acc.cacheRead + (usage.cache_read_input_tokens || 0),\n };\n },\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n\n const totalTokens =\n breakdown.input +\n breakdown.output +\n breakdown.cacheCreation +\n breakdown.cacheRead;\n\n return {\n cost: sessionData.totalCost,\n tokens: totalTokens,\n tokenBreakdown: breakdown,\n };\n } catch {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n }\n\n private async getDailyData() {\n try {\n const today = new Date();\n const todayStr =\n today.toISOString().split(\"T\")[0]?.replace(/-/g, \"\") ?? \"\";\n\n const dailyData = await loadDailyUsageData({\n since: todayStr,\n until: todayStr,\n mode: \"auto\",\n });\n\n if (dailyData.length === 0) {\n return { cost: 0, tokens: 0, tokenBreakdown: null };\n }\n\n const totals = calculateTotals(dailyData);\n const breakdown = dailyData.reduce(\n (acc, entry) => {\n return {\n input: acc.input + (entry.inputTokens || 0),\n output: acc.output + (entry.outputTokens || 0),\n cacheCreation: acc.cacheCreation + (entry.cacheCreationTokens || 0),\n cacheRead: acc.cacheRead + (entry.cacheReadTokens || 0),\n };\n },\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n\n return {\n cost: totals.totalCost,\n tokens: getTotalTokens(totals),\n tokenBreakdown: breakdown,\n };\n } catch {\n return { cost: 0, tokens: 0, tokenBreakdown: null };\n }\n }\n}\n","import { execSync } from \"node:child_process\";\n\nexport interface GitInfo {\n branch: string;\n status: \"clean\" | \"dirty\" | \"conflicts\";\n ahead: number;\n behind: number;\n sha?: string;\n}\n\nexport class GitService {\n getGitInfo(workingDir: string, showSha = false): GitInfo | null {\n try {\n const branch = this.getBranch(workingDir);\n const status = this.getStatus(workingDir);\n const { ahead, behind } = this.getAheadBehind(workingDir);\n const sha = showSha ? this.getSha(workingDir) || undefined : undefined;\n\n return {\n branch: branch || \"detached\",\n status,\n ahead,\n behind,\n sha,\n };\n } catch {\n return null;\n }\n }\n\n private getBranch(workingDir: string): string | null {\n try {\n return (\n execSync(\"git branch --show-current\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim() || null\n );\n } catch {\n return null;\n }\n }\n\n private getStatus(workingDir: string): \"clean\" | \"dirty\" | \"conflicts\" {\n try {\n const gitStatus = execSync(\"git status --porcelain\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n if (!gitStatus) return \"clean\";\n\n if (\n gitStatus.includes(\"UU\") ||\n gitStatus.includes(\"AA\") ||\n gitStatus.includes(\"DD\")\n ) {\n return \"conflicts\";\n }\n\n return \"dirty\";\n } catch {\n return \"clean\";\n }\n }\n\n private getAheadBehind(workingDir: string): {\n ahead: number;\n behind: number;\n } {\n try {\n const aheadResult = execSync(\"git rev-list --count @{u}..HEAD\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n const behindResult = execSync(\"git rev-list --count HEAD..@{u}\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return {\n ahead: parseInt(aheadResult) || 0,\n behind: parseInt(behindResult) || 0,\n };\n } catch {\n return { ahead: 0, behind: 0 };\n }\n }\n\n private getSha(workingDir: string): string | null {\n try {\n const sha = execSync(\"git rev-parse --short=7 HEAD\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return sha || null;\n } catch {\n return null;\n }\n }\n}\n","import { execSync } from \"node:child_process\";\n\nexport class TmuxService {\n getSessionId(): string | null {\n try {\n if (!process.env.TMUX_PANE) {\n return null;\n }\n\n const sessionId = execSync(\"tmux display-message -p '#S'\", {\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return sessionId || null;\n } catch {\n return null;\n }\n }\n\n isInTmux(): boolean {\n return !!process.env.TMUX_PANE;\n }\n}\n","interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport function formatCost(cost: number | null): string {\n if (cost === null) return \"N/A\";\n if (cost < 0.01) return \"<$0.01\";\n return `$${cost.toFixed(2)}`;\n}\n\nexport function formatTokens(tokens: number | null): string {\n if (tokens === null) return \"N/A\";\n if (tokens === 0) return \"0 tokens\";\n if (tokens >= 1_000_000) {\n return `${(tokens / 1_000_000).toFixed(1)}M tokens`;\n } else if (tokens >= 1_000) {\n return `${(tokens / 1_000).toFixed(1)}K tokens`;\n }\n return `${tokens} tokens`;\n}\n\nexport function formatTokenBreakdown(breakdown: TokenBreakdown | null): string {\n if (!breakdown) return \"N/A\";\n\n const parts: string[] = [];\n\n if (breakdown.input > 0) {\n parts.push(`${formatTokens(breakdown.input).replace(\" tokens\", \"\")}in`);\n }\n\n if (breakdown.output > 0) {\n parts.push(`${formatTokens(breakdown.output).replace(\" tokens\", \"\")}out`);\n }\n\n if (breakdown.cacheCreation > 0 || breakdown.cacheRead > 0) {\n const totalCached = breakdown.cacheCreation + breakdown.cacheRead;\n parts.push(`${formatTokens(totalCached).replace(\" tokens\", \"\")}cached`);\n }\n\n return parts.length > 0 ? parts.join(\" + \") : \"0 tokens\";\n}\n\nexport function formatTimeRemaining(minutes: number): string {\n if (minutes <= 0) return \"0m\";\n\n const hours = Math.floor(minutes / 60);\n const mins = minutes % 60;\n\n if (hours > 0) {\n return `${hours}h${mins > 0 ? ` ${mins}m` : \"\"}`;\n }\n\n return `${mins}m`;\n}\n","export interface BudgetStatus {\n percentage: number | null;\n isWarning: boolean;\n displayText: string;\n}\n\nexport function calculateBudgetPercentage(\n cost: number,\n budget: number | undefined\n): number | null {\n if (!budget || budget <= 0 || cost < 0) return null;\n return Math.min(100, (cost / budget) * 100);\n}\n\nexport function getBudgetStatus(\n cost: number,\n budget: number | undefined,\n warningThreshold = 80\n): BudgetStatus {\n const percentage = calculateBudgetPercentage(cost, budget);\n\n if (percentage === null) {\n return {\n percentage: null,\n isWarning: false,\n displayText: \"\",\n };\n }\n\n const percentStr = `${percentage.toFixed(0)}%`;\n const isWarning = percentage >= warningThreshold;\n\n let displayText = \"\";\n if (isWarning) {\n displayText = ` !${percentStr}`;\n } else if (percentage >= 50) {\n displayText = ` +${percentStr}`;\n } else {\n displayText = ` ${percentStr}`;\n }\n\n return {\n percentage,\n isWarning,\n displayText,\n };\n}\n","import type { PowerlineConfig } from \"../types/config\";\nimport type { ClaudeHookData } from \"../types\";\nimport {\n formatCost,\n formatTokens,\n formatTokenBreakdown,\n formatTimeRemaining,\n} from \"./formatters\";\nimport { getBudgetStatus } from \"./budget\";\nimport type { UsageInfo, SessionBlockInfo } from \"./usage-provider\";\nimport type { GitInfo } from \"./git-service\";\n\nexport interface PowerlineSymbols {\n right: string;\n branch: string;\n model: string;\n git_clean: string;\n git_dirty: string;\n git_conflicts: string;\n git_ahead: string;\n git_behind: string;\n session_cost: string;\n daily_cost: string;\n block_cost: string;\n}\n\nexport interface SegmentData {\n text: string;\n bgColor: string;\n fgColor: string;\n}\n\nexport class SegmentRenderer {\n constructor(\n private readonly config: PowerlineConfig,\n private readonly symbols: PowerlineSymbols\n ) {}\n\n renderDirectory(hookData: ClaudeHookData, colors: any): SegmentData {\n const currentDir = hookData.workspace?.current_dir || hookData.cwd || \"/\";\n const projectDir = hookData.workspace?.project_dir;\n const dirName = this.getDisplayDirectoryName(currentDir, projectDir);\n\n return {\n text: dirName,\n bgColor: colors.modeBg,\n fgColor: colors.modeFg,\n };\n }\n\n renderGit(\n gitInfo: GitInfo,\n colors: any,\n showSha = false\n ): SegmentData | null {\n if (!gitInfo) return null;\n\n let gitStatusIcon = this.symbols.git_clean;\n if (gitInfo.status === \"conflicts\") {\n gitStatusIcon = this.symbols.git_conflicts;\n } else if (gitInfo.status === \"dirty\") {\n gitStatusIcon = this.symbols.git_dirty;\n }\n\n let text = `${this.symbols.branch} ${gitInfo.branch} ${gitStatusIcon}`;\n\n if (gitInfo.sha && showSha) {\n text += ` ${gitInfo.sha}`;\n }\n\n if (gitInfo.ahead > 0 && gitInfo.behind > 0) {\n text += ` ${this.symbols.git_ahead}${gitInfo.ahead}${this.symbols.git_behind}${gitInfo.behind}`;\n } else if (gitInfo.ahead > 0) {\n text += ` ${this.symbols.git_ahead}${gitInfo.ahead}`;\n } else if (gitInfo.behind > 0) {\n text += ` ${this.symbols.git_behind}${gitInfo.behind}`;\n }\n\n return {\n text,\n bgColor: colors.gitBg,\n fgColor: colors.gitFg,\n };\n }\n\n renderModel(hookData: ClaudeHookData, colors: any): SegmentData {\n const modelName = hookData.model?.display_name || \"Claude\";\n\n return {\n text: `${this.symbols.model} ${modelName}`,\n bgColor: colors.modelBg,\n fgColor: colors.modelFg,\n };\n }\n\n renderSession(usageInfo: UsageInfo, colors: any, type = \"cost\"): SegmentData {\n const sessionBudget = this.config.budget?.session;\n const text = `${this.symbols.session_cost} ${this.formatUsageWithBudget(\n usageInfo.session.cost,\n usageInfo.session.tokens,\n usageInfo.session.tokenBreakdown,\n type,\n sessionBudget?.amount,\n sessionBudget?.warningThreshold || 80\n )}`;\n\n return {\n text,\n bgColor: colors.sessionBg,\n fgColor: colors.sessionFg,\n };\n }\n\n renderToday(usageInfo: UsageInfo, colors: any, type = \"cost\"): SegmentData {\n const todayBudget = this.config.budget?.today;\n const text = `Today ${this.formatUsageWithBudget(\n usageInfo.daily.cost,\n usageInfo.daily.tokens,\n usageInfo.daily.tokenBreakdown,\n type,\n todayBudget?.amount,\n todayBudget?.warningThreshold || 80\n )}`;\n\n return {\n text,\n bgColor: colors.burnLowBg,\n fgColor: colors.burnFg,\n };\n }\n\n renderBlock(\n blockInfo: SessionBlockInfo | null,\n colors: any,\n type = \"cost\"\n ): SegmentData | null {\n if (!blockInfo) return null;\n\n const text = `${this.symbols.block_cost} ${this.formatSessionBlockInfo(blockInfo, type)}`;\n\n return {\n text,\n bgColor: colors.blockBg,\n fgColor: colors.blockFg,\n };\n }\n\n renderTmux(sessionId: string | null, colors: any): SegmentData | null {\n if (!sessionId) return null;\n\n return {\n text: `tmux:${sessionId}`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n private getDisplayDirectoryName(\n currentDir: string,\n projectDir?: string\n ): string {\n if (projectDir && projectDir !== currentDir) {\n const projectName = projectDir.split(\"/\").pop() || \"project\";\n const currentDirName = currentDir.split(\"/\").pop() || \"root\";\n\n if (currentDir.includes(projectDir)) {\n return `${projectName}/${currentDirName}`;\n }\n\n return currentDirName;\n }\n\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n private formatUsageDisplay(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: any,\n type: string\n ): string {\n switch (type) {\n case \"cost\":\n return formatCost(cost);\n case \"tokens\":\n return formatTokens(tokens);\n case \"both\":\n return `${formatCost(cost)} (${formatTokens(tokens)})`;\n case \"breakdown\":\n return formatTokenBreakdown(tokenBreakdown);\n default:\n return formatCost(cost);\n }\n }\n\n private formatUsageWithBudget(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: any,\n type: string,\n budget: number | undefined,\n warningThreshold = 80\n ): string {\n const baseDisplay = this.formatUsageDisplay(\n cost,\n tokens,\n tokenBreakdown,\n type\n );\n\n if (budget && budget > 0 && cost !== null) {\n const budgetStatus = getBudgetStatus(cost, budget, warningThreshold);\n return baseDisplay + budgetStatus.displayText;\n }\n\n return baseDisplay;\n }\n\n private formatSessionBlockInfo(\n blockInfo: SessionBlockInfo,\n type = \"cost\"\n ): string {\n if (!blockInfo.isActive) {\n return \"No active block\";\n }\n\n const timeStr = formatTimeRemaining(blockInfo.timeRemaining);\n\n if (type === \"tokens\") {\n const tokensStr = formatTokens(blockInfo.tokens);\n let result = `${tokensStr} (${timeStr} left)`;\n\n if (blockInfo.tokenBurnRate !== null && blockInfo.tokenBurnRate > 0) {\n const burnRateStr = `${formatTokens(blockInfo.tokenBurnRate)}/hr`;\n result += ` ${burnRateStr}`;\n }\n\n return result;\n } else {\n const costStr = formatCost(blockInfo.cost);\n let result = `${costStr} (${timeStr} left)`;\n\n if (blockInfo.burnRate !== null && blockInfo.burnRate > 0) {\n const burnRateStr = `${formatCost(blockInfo.burnRate)}/hr`;\n result += ` ${burnRateStr}`;\n }\n\n return result;\n }\n }\n}\n","import type { ClaudeHookData, PowerlineColors } from \"./types\";\nimport type { PowerlineConfig, LineConfig } from \"./types/config\";\nimport { hexToAnsi, extractBgToFg } from \"./lib/colors\";\nimport { getTheme } from \"./themes\";\nimport { UsageProvider } from \"./lib/usage-provider\";\nimport { GitService } from \"./lib/git-service\";\nimport { TmuxService } from \"./lib/tmux-service\";\nimport { SegmentRenderer, PowerlineSymbols } from \"./lib/segment-renderer\";\n\nexport class PowerlineRenderer {\n private readonly symbols: PowerlineSymbols;\n private readonly usageProvider: UsageProvider;\n private readonly gitService: GitService;\n private readonly tmuxService: TmuxService;\n private readonly segmentRenderer: SegmentRenderer;\n\n constructor(private readonly config: PowerlineConfig) {\n this.symbols = this.initializeSymbols();\n this.usageProvider = new UsageProvider();\n this.gitService = new GitService();\n this.tmuxService = new TmuxService();\n this.segmentRenderer = new SegmentRenderer(config, this.symbols);\n }\n\n async generateStatusline(hookData: ClaudeHookData): Promise<string> {\n const usageInfo = await this.usageProvider.getUsageInfo(\n hookData.session_id\n );\n\n let sessionBlockInfo = null;\n if (this.needsSessionBlock()) {\n sessionBlockInfo = await this.usageProvider.getSessionBlockInfo();\n }\n\n const lines = this.config.display.lines\n .map((lineConfig) =>\n this.renderLine(lineConfig, hookData, usageInfo, sessionBlockInfo)\n )\n .filter((line) => line.length > 0);\n\n return lines.join(\"\\n\");\n }\n\n private needsSessionBlock(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.block?.enabled\n );\n }\n\n private renderLine(\n lineConfig: LineConfig,\n hookData: ClaudeHookData,\n usageInfo: any,\n sessionBlockInfo: any\n ): string {\n const colors = this.getThemeColors();\n const currentDir = hookData.workspace?.current_dir || hookData.cwd || \"/\";\n\n const segments = Object.entries(lineConfig.segments)\n .filter(([_, config]: [string, any]) => config?.enabled)\n .map(([type, config]: [string, any]) => ({ type, config }));\n\n let line = colors.reset;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (!segment) continue;\n\n const isLast = i === segments.length - 1;\n const nextSegment = !isLast ? segments[i + 1] : null;\n const nextBgColor = nextSegment\n ? this.getSegmentBgColor(nextSegment.type, colors)\n : \"\";\n\n const segmentData = this.renderSegment(\n segment,\n hookData,\n usageInfo,\n sessionBlockInfo,\n colors,\n currentDir\n );\n\n if (segmentData) {\n line += this.formatSegment(\n segmentData.bgColor,\n segmentData.fgColor,\n segmentData.text,\n isLast ? undefined : nextBgColor\n );\n }\n }\n\n return line;\n }\n\n private renderSegment(\n segment: any,\n hookData: ClaudeHookData,\n usageInfo: any,\n sessionBlockInfo: any,\n colors: any,\n currentDir: string\n ) {\n switch (segment.type) {\n case \"directory\":\n return this.segmentRenderer.renderDirectory(hookData, colors);\n\n case \"git\":\n const showSha = segment.config?.showSha || false;\n const gitInfo = this.gitService.getGitInfo(currentDir, showSha);\n return gitInfo\n ? this.segmentRenderer.renderGit(gitInfo, colors, showSha)\n : null;\n\n case \"model\":\n return this.segmentRenderer.renderModel(hookData, colors);\n\n case \"session\":\n const usageType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderSession(usageInfo, colors, usageType);\n\n case \"today\":\n const todayType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderToday(usageInfo, colors, todayType);\n\n case \"block\":\n const blockType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderBlock(\n sessionBlockInfo,\n colors,\n blockType\n );\n\n case \"tmux\":\n const tmuxSessionId = this.tmuxService.getSessionId();\n return this.segmentRenderer.renderTmux(tmuxSessionId, colors);\n\n default:\n return null;\n }\n }\n\n private initializeSymbols(): PowerlineSymbols {\n const isMinimalStyle = this.config.display.style === \"minimal\";\n \n return {\n right: isMinimalStyle ? \"\" : \"\\uE0B0\",\n branch: \"⑂\",\n model: \"⚡\",\n git_clean: \"✓\",\n git_dirty: \"●\",\n git_conflicts: \"⚠\",\n git_ahead: \"↑\",\n git_behind: \"↓\",\n session_cost: \"Session\",\n daily_cost: \"Today\",\n block_cost: \"Block\",\n };\n }\n\n private getThemeColors(): PowerlineColors {\n const theme = this.config.theme;\n let colorTheme;\n\n if (theme === \"custom\") {\n colorTheme = this.config.colors?.custom;\n if (!colorTheme) {\n throw new Error(\"Custom theme selected but no colors provided in configuration\");\n }\n } else {\n colorTheme = getTheme(theme);\n if (!colorTheme) {\n throw new Error(`Built-in theme '${theme}' not found`);\n }\n }\n\n return {\n reset: \"\\x1b[0m\",\n modeBg: hexToAnsi(colorTheme.directory.bg, true),\n modeFg: hexToAnsi(colorTheme.directory.fg, false),\n gitBg: hexToAnsi(colorTheme.git.bg, true),\n gitFg: hexToAnsi(colorTheme.git.fg, false),\n modelBg: hexToAnsi(colorTheme.model.bg, true),\n modelFg: hexToAnsi(colorTheme.model.fg, false),\n sessionBg: hexToAnsi(colorTheme.session.bg, true),\n sessionFg: hexToAnsi(colorTheme.session.fg, false),\n todayBg: hexToAnsi(colorTheme.today.bg, true),\n todayFg: hexToAnsi(colorTheme.today.fg, false),\n blockBg: hexToAnsi(colorTheme.block.bg, true),\n blockFg: hexToAnsi(colorTheme.block.fg, false),\n burnLowBg: hexToAnsi(colorTheme.today.bg, true),\n burnFg: hexToAnsi(colorTheme.today.fg, false),\n tmuxBg: hexToAnsi(colorTheme.tmux.bg, true),\n tmuxFg: hexToAnsi(colorTheme.tmux.fg, false),\n };\n }\n\n private getSegmentBgColor(\n segmentType: string,\n colors: PowerlineColors\n ): string {\n switch (segmentType) {\n case \"directory\":\n return colors.modeBg;\n case \"git\":\n return colors.gitBg;\n case \"model\":\n return colors.modelBg;\n case \"session\":\n return colors.sessionBg;\n case \"today\":\n return colors.burnLowBg;\n case \"block\":\n return colors.blockBg;\n case \"tmux\":\n return colors.tmuxBg;\n default:\n return colors.modeBg;\n }\n }\n\n private formatSegment(\n bgColor: string,\n fgColor: string,\n text: string,\n nextBgColor?: string\n ): string {\n let output = `${bgColor}${fgColor} ${text} `;\n\n const reset = \"\\x1b[0m\";\n\n if (nextBgColor) {\n const arrowFgColor = extractBgToFg(bgColor);\n output += `${reset}${nextBgColor}${arrowFgColor}${this.symbols.right}`;\n } else {\n output += `${reset}${extractBgToFg(bgColor)}${this.symbols.right}${reset}`;\n }\n\n return output;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport type { PowerlineConfig, ConfigLoadOptions } from \"../types/config\";\nimport { DEFAULT_CONFIG } from \"./defaults\";\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n if (\n typeof source[key] === \"object\" &&\n source[key] !== null &&\n !Array.isArray(source[key])\n ) {\n result[key] = deepMerge(result[key] || ({} as any), source[key] as any);\n } else {\n result[key] = source[key] as any;\n }\n }\n }\n\n return result;\n}\n\nfunction findConfigFile(\n customPath?: string,\n projectDir?: string\n): string | null {\n if (customPath) {\n return fs.existsSync(customPath) ? customPath : null;\n }\n\n const locations = [\n ...(projectDir ? [path.join(projectDir, \".claude-powerline.json\")] : []),\n path.join(process.cwd(), \".claude-powerline.json\"),\n path.join(os.homedir(), \".claude\", \"claude-powerline.json\"),\n path.join(os.homedir(), \".config\", \"claude-powerline\", \"config.json\"),\n ];\n\n return locations.find(fs.existsSync) || null;\n}\n\nfunction loadConfigFile(filePath: string): Partial<PowerlineConfig> {\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content);\n } catch (error) {\n throw new Error(\n `Failed to load config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nfunction loadEnvConfig(): Partial<PowerlineConfig> {\n const config: Partial<PowerlineConfig> = {};\n\n if (process.env.CLAUDE_POWERLINE_THEME) {\n config.theme = process.env.CLAUDE_POWERLINE_THEME as\n | \"light\"\n | \"dark\"\n | \"custom\";\n }\n\n if (process.env.CLAUDE_POWERLINE_STYLE) {\n config.display = config.display || { lines: [] };\n config.display.style = process.env.CLAUDE_POWERLINE_STYLE as\n | \"minimal\"\n | \"powerline\";\n }\n\n if (process.env.CLAUDE_POWERLINE_USAGE_TYPE) {\n const usageType = process.env.CLAUDE_POWERLINE_USAGE_TYPE as\n | \"cost\"\n | \"tokens\"\n | \"both\"\n | \"breakdown\";\n config.display = config.display || { lines: [] };\n\n if (config.display.lines.length === 0) {\n config.display.lines = [{ segments: {} }];\n }\n\n config.display.lines.forEach((line) => {\n if (line.segments.session) {\n line.segments.session.type = usageType;\n }\n if (line.segments.today) {\n line.segments.today.type = usageType;\n }\n if (line.segments.block) {\n line.segments.block.type =\n usageType === \"breakdown\" || usageType === \"both\"\n ? \"cost\"\n : usageType;\n }\n });\n }\n\n return config;\n}\n\nfunction getConfigPathFromEnv(): string | undefined {\n return process.env.CLAUDE_POWERLINE_CONFIG;\n}\n\nfunction parseCLIOverrides(args: string[]): Partial<PowerlineConfig> {\n const config: Partial<PowerlineConfig> = {};\n\n const themeIndex = args.findIndex((arg) => arg.startsWith(\"--theme=\"));\n if (themeIndex !== -1) {\n const theme = args[themeIndex]?.split(\"=\")[1];\n if (theme) {\n config.theme = theme as \"light\" | \"dark\" | \"custom\";\n }\n }\n\n const styleIndex = args.findIndex((arg) => arg.startsWith(\"--style=\"));\n if (styleIndex !== -1) {\n const style = args[styleIndex]?.split(\"=\")[1];\n if (style) {\n config.display = config.display || { lines: [] };\n config.display.style = style as \"minimal\" | \"powerline\";\n }\n }\n\n const dailyBudgetIndex = args.findIndex((arg) =>\n arg.startsWith(\"--daily-budget=\")\n );\n if (dailyBudgetIndex !== -1) {\n const dailyBudget = parseFloat(args[dailyBudgetIndex]?.split(\"=\")[1] || \"\");\n if (!isNaN(dailyBudget) && dailyBudget > 0) {\n config.budget = {\n ...config.budget,\n today: {\n ...DEFAULT_CONFIG.budget?.today,\n amount: dailyBudget,\n },\n };\n }\n }\n\n const sessionBudgetIndex = args.findIndex((arg) =>\n arg.startsWith(\"--session-budget=\")\n );\n if (sessionBudgetIndex !== -1) {\n const sessionBudget = parseFloat(\n args[sessionBudgetIndex]?.split(\"=\")[1] || \"\"\n );\n if (!isNaN(sessionBudget) && sessionBudget > 0) {\n config.budget = {\n ...config.budget,\n session: {\n ...DEFAULT_CONFIG.budget?.session,\n amount: sessionBudget,\n },\n };\n }\n }\n\n return config;\n}\n\nexport function loadConfig(options: ConfigLoadOptions = {}): PowerlineConfig {\n const {\n configPath,\n ignoreEnvVars = false,\n cliOverrides = {},\n projectDir,\n } = options;\n\n let config: PowerlineConfig = JSON.parse(JSON.stringify(DEFAULT_CONFIG));\n\n const configFile = findConfigFile(configPath, projectDir);\n if (configFile) {\n try {\n const fileConfig = loadConfigFile(configFile);\n config = deepMerge(config, fileConfig);\n } catch (err) {\n console.warn(\n `Warning: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n if (!ignoreEnvVars) {\n const envConfig = loadEnvConfig();\n config = deepMerge(config, envConfig);\n }\n\n config = deepMerge(config, cliOverrides);\n\n return config;\n}\n\nexport function loadConfigFromCLI(\n args: string[] = process.argv,\n projectDir?: string\n): PowerlineConfig {\n const configPathIndex = args.findIndex((arg) => arg.startsWith(\"--config=\"));\n const configPath =\n configPathIndex !== -1\n ? args[configPathIndex]?.split(\"=\")[1]\n : getConfigPathFromEnv();\n\n const cliOverrides = parseCLIOverrides(args);\n\n return loadConfig({ configPath, cliOverrides, projectDir });\n}\n\nexport function getConfigPath(\n customPath?: string,\n projectDir?: string\n): string | null {\n return findConfigFile(customPath, projectDir);\n}\n\n","import type { PowerlineConfig } from \"../types/config\";\n\nexport const DEFAULT_CONFIG: PowerlineConfig = {\n theme: \"dark\",\n display: {\n style: \"minimal\",\n lines: [\n {\n segments: {\n directory: { enabled: true },\n git: {\n enabled: true,\n showSha: false,\n },\n model: { enabled: true },\n session: { enabled: true, type: \"tokens\" },\n today: { enabled: true, type: \"both\" },\n block: { enabled: false, type: \"cost\" },\n tmux: { enabled: false },\n },\n },\n ],\n },\n budget: {\n session: {\n warningThreshold: 80,\n },\n today: {\n amount: 50,\n warningThreshold: 80,\n },\n },\n};\n"],"mappings":"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","names":["process","path","fs","execSync","os","execSync","os","path","fs","execSync","process"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/colors.ts","../src/themes/dark.ts","../src/themes/light.ts","../src/themes/nord.ts","../src/themes/tokyo-night.ts","../src/themes/rose-pine.ts","../src/themes/index.ts","../src/lib/usage-provider.ts","../src/lib/git-service.ts","../src/lib/tmux-service.ts","../src/lib/formatters.ts","../src/lib/budget.ts","../src/lib/segment-renderer.ts","../src/powerline.ts","../src/config/loader.ts","../src/config/defaults.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport process from \"node:process\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport os from \"node:os\";\nimport getStdin from \"get-stdin\";\nimport { PowerlineRenderer } from \"./powerline\";\nimport { loadConfigFromCLI } from \"./config/loader\";\nimport type { ClaudeHookData } from \"./types\";\n\nasync function installFonts(): Promise<void> {\n try {\n const platform = os.platform();\n let fontDir: string;\n\n if (platform === \"darwin\") {\n fontDir = path.join(os.homedir(), \"Library\", \"Fonts\");\n } else if (platform === \"linux\") {\n fontDir = path.join(os.homedir(), \".local\", \"share\", \"fonts\");\n } else if (platform === \"win32\") {\n fontDir = path.join(\n os.homedir(),\n \"AppData\",\n \"Local\",\n \"Microsoft\",\n \"Windows\",\n \"Fonts\"\n );\n } else {\n console.log(\"Unsupported platform for font installation\");\n return;\n }\n\n if (!fs.existsSync(fontDir)) {\n fs.mkdirSync(fontDir, { recursive: true });\n }\n\n console.log(\"📦 Installing Powerline Fonts...\");\n console.log(\"Downloading from https://github.com/powerline/fonts\");\n\n const tempDir = path.join(os.tmpdir(), \"powerline-fonts\");\n\n try {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n\n console.log(\"Cloning powerline fonts repository...\");\n execSync(\n \"git clone --depth=1 https://github.com/powerline/fonts.git powerline-fonts\",\n {\n stdio: \"inherit\",\n cwd: os.tmpdir(),\n }\n );\n\n console.log(\"Installing fonts...\");\n const installScript = path.join(tempDir, \"install.sh\");\n\n if (fs.existsSync(installScript)) {\n fs.chmodSync(installScript, 0o755);\n execSync(\"./install.sh\", { stdio: \"inherit\", cwd: tempDir });\n } else {\n throw new Error(\n \"Install script not found in powerline fonts repository\"\n );\n }\n\n console.log(\"✅ Powerline fonts installation complete!\");\n console.log(\n \"Please restart your terminal and set your terminal font to a powerline font.\"\n );\n console.log(\n \"Popular choices: Source Code Pro Powerline, DejaVu Sans Mono Powerline, Ubuntu Mono Powerline\"\n );\n } finally {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n }\n } catch (error) {\n console.error(\n \"Error installing fonts:\",\n error instanceof Error ? error.message : String(error)\n );\n console.log(\n \"💡 You can manually install fonts from: https://github.com/powerline/fonts\"\n );\n }\n}\n\nasync function main(): Promise<void> {\n try {\n const showHelp =\n process.argv.includes(\"--help\") || process.argv.includes(\"-h\");\n const installFontsFlag = process.argv.includes(\"--install-fonts\");\n\n if (installFontsFlag) {\n await installFonts();\n process.exit(0);\n }\n\n if (showHelp) {\n console.log(`\nclaude-powerline - Beautiful powerline statusline for Claude Code\n\nUsage: claude-powerline [options]\n\nOptions:\n --theme=THEME Set theme: dark, light, nord, tokyo-night, rose-pine, custom\n --style=STYLE Set separator style: minimal, powerline\n --usage=TYPE Usage display: cost, tokens, both, breakdown\n --session-budget=AMOUNT Set session budget for percentage tracking\n --daily-budget=AMOUNT Set daily budget for percentage tracking\n --config=PATH Use custom config file path\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nConfiguration:\n Config files are loaded in this order (highest priority first):\n 1. CLI arguments (--theme, --style, --usage, --config)\n 2. Environment variables (CLAUDE_POWERLINE_THEME, CLAUDE_POWERLINE_STYLE, CLAUDE_POWERLINE_USAGE_TYPE, CLAUDE_POWERLINE_CONFIG)\n 3. ./.claude-powerline.json (project)\n 4. ~/.claude/claude-powerline.json (user)\n 5. ~/.config/claude-powerline/config.json (XDG)\n\nCreating a config file:\n Copy example from: https://github.com/Owloops/claude-powerline/blob/main/.claude-powerline.json\n\nUsage in Claude Code settings.json:\n{\n \"statusLine\": {\n \"type\": \"command\",\n \"command\": \"claude-powerline\",\n \"padding\": 0\n }\n}\n`);\n process.exit(0);\n }\n\n const stdin = await getStdin();\n if (stdin.length === 0) {\n console.error(\"Error: No input provided\");\n console.log(`\nclaude-powerline - Beautiful powerline statusline for Claude Code\n\nUsage: claude-powerline [options]\n\nOptions:\n --theme=THEME Set theme: dark, light, nord, tokyo-night, rose-pine, custom\n --style=STYLE Set separator style: minimal, powerline\n --usage=TYPE Usage display: cost, tokens, both, breakdown\n --session-budget=AMOUNT Set session budget for percentage tracking\n --daily-budget=AMOUNT Set daily budget for percentage tracking\n --config=PATH Use custom config file path\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nSee example config at: https://github.com/Owloops/claude-powerline/blob/main/.claude-powerline.json\n`);\n process.exit(1);\n }\n\n let hookData: ClaudeHookData;\n try {\n hookData = JSON.parse(stdin.trim());\n } catch (error) {\n console.error(\n \"Error: Invalid JSON input:\",\n error instanceof Error ? error.message : String(error)\n );\n process.exit(1);\n }\n\n const projectDir = hookData.workspace?.project_dir;\n const config = loadConfigFromCLI(process.argv, projectDir);\n const renderer = new PowerlineRenderer(config);\n const statusline = await renderer.generateStatusline(hookData);\n\n console.log(statusline);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(\"Error generating statusline:\", errorMessage);\n process.exit(1);\n }\n}\n\nmain();\n","export function hexToAnsi(hex: string, isBackground: boolean): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n return `\\x1b[${isBackground ? \"48\" : \"38\"};2;${r};${g};${b}m`;\n}\n\nexport function extractBgToFg(ansiCode: string): string {\n const match = ansiCode.match(/48;2;(\\d+);(\\d+);(\\d+)/);\n if (match) {\n return `\\x1b[38;2;${match[1]};${match[2]};${match[3]}m`;\n }\n return ansiCode.replace(\"48\", \"38\");\n}\n","import type { ColorTheme } from \"../types/config\";\n\nexport const darkTheme: ColorTheme = {\n directory: { bg: \"#8b4513\", fg: \"#ffffff\" },\n git: { bg: \"#404040\", fg: \"#ffffff\" },\n model: { bg: \"#2d2d2d\", fg: \"#ffffff\" },\n session: { bg: \"#202020\", fg: \"#00ffff\" },\n today: { bg: \"#a0520d\", fg: \"#ffffff\" },\n block: { bg: \"#8b4500\", fg: \"#ffffff\" },\n tmux: { bg: \"#2f4f2f\", fg: \"#90ee90\" },\n};\n","import type { ColorTheme } from \"../types/config\";\n\nexport const lightTheme: ColorTheme = {\n directory: { bg: \"#ff6b47\", fg: \"#ffffff\" },\n git: { bg: \"#4fb3d9\", fg: \"#ffffff\" },\n model: { bg: \"#87ceeb\", fg: \"#000000\" },\n session: { bg: \"#da70d6\", fg: \"#ffffff\" },\n today: { bg: \"#90ee90\", fg: \"#ffffff\" },\n block: { bg: \"#ff8c00\", fg: \"#ffffff\" },\n tmux: { bg: \"#32cd32\", fg: \"#ffffff\" },\n};\n","import type { ColorTheme } from \"../types/config\";\n\nexport const nordTheme: ColorTheme = {\n directory: { bg: \"#434c5e\", fg: \"#d8dee9\" },\n git: { bg: \"#3b4252\", fg: \"#a3be8c\" },\n model: { bg: \"#4c566a\", fg: \"#81a1c1\" },\n session: { bg: \"#2e3440\", fg: \"#88c0d0\" },\n today: { bg: \"#434c5e\", fg: \"#ebcb8b\" },\n block: { bg: \"#3b4252\", fg: \"#bf616a\" },\n tmux: { bg: \"#2e3440\", fg: \"#8fbcbb\" },\n};\n","import type { ColorTheme } from \"../types/config\";\n\nexport const tokyoNightTheme: ColorTheme = {\n directory: { bg: \"#2f334d\", fg: \"#82aaff\" },\n git: { bg: \"#1e2030\", fg: \"#c3e88d\" },\n model: { bg: \"#191b29\", fg: \"#fca7ea\" },\n session: { bg: \"#222436\", fg: \"#86e1fc\" },\n today: { bg: \"#2f334d\", fg: \"#ffc777\" },\n block: { bg: \"#1e2030\", fg: \"#ff966c\" },\n tmux: { bg: \"#191b29\", fg: \"#4fd6be\" },\n};\n","import type { ColorTheme } from \"../types/config\";\n\nexport const rosePineTheme: ColorTheme = {\n directory: { bg: \"#26233a\", fg: \"#c4a7e7\" },\n git: { bg: \"#1f1d2e\", fg: \"#9ccfd8\" },\n model: { bg: \"#191724\", fg: \"#ebbcba\" },\n session: { bg: \"#26233a\", fg: \"#f6c177\" },\n today: { bg: \"#1f1d2e\", fg: \"#eb6f92\" },\n block: { bg: \"#191724\", fg: \"#31748f\" },\n tmux: { bg: \"#26233a\", fg: \"#908caa\" },\n};\n","import type { ColorTheme } from \"../types/config\";\nimport { darkTheme } from \"./dark\";\nimport { lightTheme } from \"./light\";\nimport { nordTheme } from \"./nord\";\nimport { tokyoNightTheme } from \"./tokyo-night\";\nimport { rosePineTheme } from \"./rose-pine\";\n\nexport const BUILT_IN_THEMES: Record<string, ColorTheme> = {\n dark: darkTheme,\n light: lightTheme,\n nord: nordTheme,\n \"tokyo-night\": tokyoNightTheme,\n \"rose-pine\": rosePineTheme,\n};\n\nexport function getTheme(themeName: string): ColorTheme | null {\n return BUILT_IN_THEMES[themeName] || null;\n}\n\nexport { darkTheme, lightTheme, nordTheme, tokyoNightTheme, rosePineTheme };\n","import {\n loadSessionUsageById,\n loadDailyUsageData,\n loadSessionBlockData,\n getClaudePaths,\n} from \"ccusage/data-loader\";\nimport { calculateTotals, getTotalTokens } from \"ccusage/calculate-cost\";\nimport { logger } from \"ccusage/logger\";\n\nexport interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport interface SessionBlockInfo {\n cost: number;\n tokens: number;\n timeRemaining: number;\n burnRate: number | null;\n tokenBurnRate: number | null;\n isActive: boolean;\n}\n\nexport interface UsageInfo {\n session: {\n cost: number | null;\n tokens: number | null;\n tokenBreakdown: TokenBreakdown | null;\n };\n daily: {\n cost: number;\n tokens: number;\n tokenBreakdown: TokenBreakdown | null;\n };\n}\n\nexport class UsageProvider {\n async getSessionBlockInfo(): Promise<SessionBlockInfo | null> {\n const originalLevel = logger.level;\n logger.level = 0;\n\n try {\n const blocks = await loadSessionBlockData({\n mode: \"auto\",\n sessionDurationHours: 5,\n });\n\n const activeBlock = blocks.find((block) => block.isActive);\n\n if (!activeBlock) {\n return null;\n }\n\n const now = new Date();\n const timeRemaining = Math.round(\n (activeBlock.endTime.getTime() - now.getTime()) / (1000 * 60)\n );\n\n const elapsed = Math.round(\n (now.getTime() - activeBlock.startTime.getTime()) / (1000 * 60)\n );\n\n const totalTokens =\n (activeBlock.tokenCounts?.inputTokens || 0) +\n (activeBlock.tokenCounts?.outputTokens || 0) +\n (activeBlock.tokenCounts?.cacheCreationInputTokens || 0) +\n (activeBlock.tokenCounts?.cacheReadInputTokens || 0);\n\n const burnRate =\n elapsed > 0 ? (activeBlock.costUSD / elapsed) * 60 : null;\n const tokenBurnRate = elapsed > 0 ? (totalTokens / elapsed) * 60 : null;\n\n return {\n cost: activeBlock.costUSD,\n tokens: totalTokens,\n timeRemaining: Math.max(0, timeRemaining),\n burnRate,\n tokenBurnRate,\n isActive: true,\n };\n } catch {\n return null;\n } finally {\n logger.level = originalLevel;\n }\n }\n\n async getUsageInfo(sessionId: string): Promise<UsageInfo> {\n const originalLevel = logger.level;\n logger.level = 0;\n\n try {\n const claudePaths = getClaudePaths();\n if (claudePaths.length === 0) {\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n daily: { cost: 0, tokens: 0, tokenBreakdown: null },\n };\n }\n\n const [sessionData, dailyData] = await Promise.all([\n this.getSessionData(sessionId),\n this.getDailyData(),\n ]);\n\n return {\n session: sessionData,\n daily: dailyData,\n };\n } catch {\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n daily: { cost: 0, tokens: 0, tokenBreakdown: null },\n };\n } finally {\n logger.level = originalLevel;\n }\n }\n\n private async getSessionData(sessionId: string) {\n try {\n const sessionData = await loadSessionUsageById(sessionId, {\n mode: \"auto\",\n });\n\n if (!sessionData) {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n\n const breakdown = sessionData.entries.reduce(\n (acc, entry) => {\n const usage = entry.message.usage;\n return {\n input: acc.input + usage.input_tokens,\n output: acc.output + usage.output_tokens,\n cacheCreation:\n acc.cacheCreation + (usage.cache_creation_input_tokens || 0),\n cacheRead: acc.cacheRead + (usage.cache_read_input_tokens || 0),\n };\n },\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n\n const totalTokens =\n breakdown.input +\n breakdown.output +\n breakdown.cacheCreation +\n breakdown.cacheRead;\n\n return {\n cost: sessionData.totalCost,\n tokens: totalTokens,\n tokenBreakdown: breakdown,\n };\n } catch {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n }\n\n private async getDailyData() {\n try {\n const today = new Date();\n const todayStr =\n today.toISOString().split(\"T\")[0]?.replace(/-/g, \"\") ?? \"\";\n\n const dailyData = await loadDailyUsageData({\n since: todayStr,\n until: todayStr,\n mode: \"auto\",\n });\n\n if (dailyData.length === 0) {\n return { cost: 0, tokens: 0, tokenBreakdown: null };\n }\n\n const totals = calculateTotals(dailyData);\n const breakdown = dailyData.reduce(\n (acc, entry) => {\n return {\n input: acc.input + (entry.inputTokens || 0),\n output: acc.output + (entry.outputTokens || 0),\n cacheCreation: acc.cacheCreation + (entry.cacheCreationTokens || 0),\n cacheRead: acc.cacheRead + (entry.cacheReadTokens || 0),\n };\n },\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n\n return {\n cost: totals.totalCost,\n tokens: getTotalTokens(totals),\n tokenBreakdown: breakdown,\n };\n } catch {\n return { cost: 0, tokens: 0, tokenBreakdown: null };\n }\n }\n}\n","import { execSync } from \"node:child_process\";\n\nexport interface GitInfo {\n branch: string;\n status: \"clean\" | \"dirty\" | \"conflicts\";\n ahead: number;\n behind: number;\n sha?: string;\n}\n\nexport class GitService {\n getGitInfo(workingDir: string, showSha = false): GitInfo | null {\n try {\n const branch = this.getBranch(workingDir);\n const status = this.getStatus(workingDir);\n const { ahead, behind } = this.getAheadBehind(workingDir);\n const sha = showSha ? this.getSha(workingDir) || undefined : undefined;\n\n return {\n branch: branch || \"detached\",\n status,\n ahead,\n behind,\n sha,\n };\n } catch {\n return null;\n }\n }\n\n private getBranch(workingDir: string): string | null {\n try {\n return (\n execSync(\"git branch --show-current\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim() || null\n );\n } catch {\n return null;\n }\n }\n\n private getStatus(workingDir: string): \"clean\" | \"dirty\" | \"conflicts\" {\n try {\n const gitStatus = execSync(\"git status --porcelain\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n if (!gitStatus) return \"clean\";\n\n if (\n gitStatus.includes(\"UU\") ||\n gitStatus.includes(\"AA\") ||\n gitStatus.includes(\"DD\")\n ) {\n return \"conflicts\";\n }\n\n return \"dirty\";\n } catch {\n return \"clean\";\n }\n }\n\n private getAheadBehind(workingDir: string): {\n ahead: number;\n behind: number;\n } {\n try {\n const aheadResult = execSync(\"git rev-list --count @{u}..HEAD\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n const behindResult = execSync(\"git rev-list --count HEAD..@{u}\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return {\n ahead: parseInt(aheadResult) || 0,\n behind: parseInt(behindResult) || 0,\n };\n } catch {\n return { ahead: 0, behind: 0 };\n }\n }\n\n private getSha(workingDir: string): string | null {\n try {\n const sha = execSync(\"git rev-parse --short=7 HEAD\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return sha || null;\n } catch {\n return null;\n }\n }\n}\n","import { execSync } from \"node:child_process\";\n\nexport class TmuxService {\n getSessionId(): string | null {\n try {\n if (!process.env.TMUX_PANE) {\n return null;\n }\n\n const sessionId = execSync(\"tmux display-message -p '#S'\", {\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n return sessionId || null;\n } catch {\n return null;\n }\n }\n\n isInTmux(): boolean {\n return !!process.env.TMUX_PANE;\n }\n}\n","interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport function formatCost(cost: number | null): string {\n if (cost === null) return \"N/A\";\n if (cost < 0.01) return \"<$0.01\";\n return `$${cost.toFixed(2)}`;\n}\n\nexport function formatTokens(tokens: number | null): string {\n if (tokens === null) return \"N/A\";\n if (tokens === 0) return \"0 tokens\";\n if (tokens >= 1_000_000) {\n return `${(tokens / 1_000_000).toFixed(1)}M tokens`;\n } else if (tokens >= 1_000) {\n return `${(tokens / 1_000).toFixed(1)}K tokens`;\n }\n return `${tokens} tokens`;\n}\n\nexport function formatTokenBreakdown(breakdown: TokenBreakdown | null): string {\n if (!breakdown) return \"N/A\";\n\n const parts: string[] = [];\n\n if (breakdown.input > 0) {\n parts.push(`${formatTokens(breakdown.input).replace(\" tokens\", \"\")}in`);\n }\n\n if (breakdown.output > 0) {\n parts.push(`${formatTokens(breakdown.output).replace(\" tokens\", \"\")}out`);\n }\n\n if (breakdown.cacheCreation > 0 || breakdown.cacheRead > 0) {\n const totalCached = breakdown.cacheCreation + breakdown.cacheRead;\n parts.push(`${formatTokens(totalCached).replace(\" tokens\", \"\")}cached`);\n }\n\n return parts.length > 0 ? parts.join(\" + \") : \"0 tokens\";\n}\n\nexport function formatTimeRemaining(minutes: number): string {\n if (minutes <= 0) return \"0m\";\n\n const hours = Math.floor(minutes / 60);\n const mins = minutes % 60;\n\n if (hours > 0) {\n return `${hours}h${mins > 0 ? ` ${mins}m` : \"\"}`;\n }\n\n return `${mins}m`;\n}\n","export interface BudgetStatus {\n percentage: number | null;\n isWarning: boolean;\n displayText: string;\n}\n\nexport function calculateBudgetPercentage(\n cost: number,\n budget: number | undefined\n): number | null {\n if (!budget || budget <= 0 || cost < 0) return null;\n return Math.min(100, (cost / budget) * 100);\n}\n\nexport function getBudgetStatus(\n cost: number,\n budget: number | undefined,\n warningThreshold = 80\n): BudgetStatus {\n const percentage = calculateBudgetPercentage(cost, budget);\n\n if (percentage === null) {\n return {\n percentage: null,\n isWarning: false,\n displayText: \"\",\n };\n }\n\n const percentStr = `${percentage.toFixed(0)}%`;\n const isWarning = percentage >= warningThreshold;\n\n let displayText = \"\";\n if (isWarning) {\n displayText = ` !${percentStr}`;\n } else if (percentage >= 50) {\n displayText = ` +${percentStr}`;\n } else {\n displayText = ` ${percentStr}`;\n }\n\n return {\n percentage,\n isWarning,\n displayText,\n };\n}\n","import type { PowerlineConfig } from \"../types/config\";\nimport type { ClaudeHookData } from \"../types\";\nimport {\n formatCost,\n formatTokens,\n formatTokenBreakdown,\n formatTimeRemaining,\n} from \"./formatters\";\nimport { getBudgetStatus } from \"./budget\";\nimport type { UsageInfo, SessionBlockInfo } from \"./usage-provider\";\nimport type { GitInfo } from \"./git-service\";\n\nexport interface PowerlineSymbols {\n right: string;\n branch: string;\n model: string;\n git_clean: string;\n git_dirty: string;\n git_conflicts: string;\n git_ahead: string;\n git_behind: string;\n session_cost: string;\n daily_cost: string;\n block_cost: string;\n}\n\nexport interface SegmentData {\n text: string;\n bgColor: string;\n fgColor: string;\n}\n\nexport class SegmentRenderer {\n constructor(\n private readonly config: PowerlineConfig,\n private readonly symbols: PowerlineSymbols\n ) {}\n\n renderDirectory(hookData: ClaudeHookData, colors: any): SegmentData {\n const currentDir = hookData.workspace?.current_dir || hookData.cwd || \"/\";\n const projectDir = hookData.workspace?.project_dir;\n const dirName = this.getDisplayDirectoryName(currentDir, projectDir);\n\n return {\n text: dirName,\n bgColor: colors.modeBg,\n fgColor: colors.modeFg,\n };\n }\n\n renderGit(\n gitInfo: GitInfo,\n colors: any,\n showSha = false\n ): SegmentData | null {\n if (!gitInfo) return null;\n\n let gitStatusIcon = this.symbols.git_clean;\n if (gitInfo.status === \"conflicts\") {\n gitStatusIcon = this.symbols.git_conflicts;\n } else if (gitInfo.status === \"dirty\") {\n gitStatusIcon = this.symbols.git_dirty;\n }\n\n let text = `${this.symbols.branch} ${gitInfo.branch} ${gitStatusIcon}`;\n\n if (gitInfo.sha && showSha) {\n text += ` ${gitInfo.sha}`;\n }\n\n if (gitInfo.ahead > 0 && gitInfo.behind > 0) {\n text += ` ${this.symbols.git_ahead}${gitInfo.ahead}${this.symbols.git_behind}${gitInfo.behind}`;\n } else if (gitInfo.ahead > 0) {\n text += ` ${this.symbols.git_ahead}${gitInfo.ahead}`;\n } else if (gitInfo.behind > 0) {\n text += ` ${this.symbols.git_behind}${gitInfo.behind}`;\n }\n\n return {\n text,\n bgColor: colors.gitBg,\n fgColor: colors.gitFg,\n };\n }\n\n renderModel(hookData: ClaudeHookData, colors: any): SegmentData {\n const modelName = hookData.model?.display_name || \"Claude\";\n\n return {\n text: `${this.symbols.model} ${modelName}`,\n bgColor: colors.modelBg,\n fgColor: colors.modelFg,\n };\n }\n\n renderSession(usageInfo: UsageInfo, colors: any, type = \"cost\"): SegmentData {\n const sessionBudget = this.config.budget?.session;\n const text = `${this.symbols.session_cost} ${this.formatUsageWithBudget(\n usageInfo.session.cost,\n usageInfo.session.tokens,\n usageInfo.session.tokenBreakdown,\n type,\n sessionBudget?.amount,\n sessionBudget?.warningThreshold || 80\n )}`;\n\n return {\n text,\n bgColor: colors.sessionBg,\n fgColor: colors.sessionFg,\n };\n }\n\n renderToday(usageInfo: UsageInfo, colors: any, type = \"cost\"): SegmentData {\n const todayBudget = this.config.budget?.today;\n const text = `Today ${this.formatUsageWithBudget(\n usageInfo.daily.cost,\n usageInfo.daily.tokens,\n usageInfo.daily.tokenBreakdown,\n type,\n todayBudget?.amount,\n todayBudget?.warningThreshold || 80\n )}`;\n\n return {\n text,\n bgColor: colors.burnLowBg,\n fgColor: colors.burnFg,\n };\n }\n\n renderBlock(\n blockInfo: SessionBlockInfo | null,\n colors: any,\n type = \"cost\"\n ): SegmentData | null {\n if (!blockInfo) return null;\n\n const text = `${this.symbols.block_cost} ${this.formatSessionBlockInfo(blockInfo, type)}`;\n\n return {\n text,\n bgColor: colors.blockBg,\n fgColor: colors.blockFg,\n };\n }\n\n renderTmux(sessionId: string | null, colors: any): SegmentData | null {\n if (!sessionId) return null;\n\n return {\n text: `tmux:${sessionId}`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n private getDisplayDirectoryName(\n currentDir: string,\n projectDir?: string\n ): string {\n if (projectDir && projectDir !== currentDir) {\n const projectName = projectDir.split(\"/\").pop() || \"project\";\n const currentDirName = currentDir.split(\"/\").pop() || \"root\";\n\n if (currentDir.includes(projectDir)) {\n return `${projectName}/${currentDirName}`;\n }\n\n return currentDirName;\n }\n\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n private formatUsageDisplay(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: any,\n type: string\n ): string {\n switch (type) {\n case \"cost\":\n return formatCost(cost);\n case \"tokens\":\n return formatTokens(tokens);\n case \"both\":\n return `${formatCost(cost)} (${formatTokens(tokens)})`;\n case \"breakdown\":\n return formatTokenBreakdown(tokenBreakdown);\n default:\n return formatCost(cost);\n }\n }\n\n private formatUsageWithBudget(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: any,\n type: string,\n budget: number | undefined,\n warningThreshold = 80\n ): string {\n const baseDisplay = this.formatUsageDisplay(\n cost,\n tokens,\n tokenBreakdown,\n type\n );\n\n if (budget && budget > 0 && cost !== null) {\n const budgetStatus = getBudgetStatus(cost, budget, warningThreshold);\n return baseDisplay + budgetStatus.displayText;\n }\n\n return baseDisplay;\n }\n\n private formatSessionBlockInfo(\n blockInfo: SessionBlockInfo,\n type = \"cost\"\n ): string {\n if (!blockInfo.isActive) {\n return \"No active block\";\n }\n\n const timeStr = formatTimeRemaining(blockInfo.timeRemaining);\n\n if (type === \"tokens\") {\n const tokensStr = formatTokens(blockInfo.tokens);\n let result = `${tokensStr} (${timeStr} left)`;\n\n if (blockInfo.tokenBurnRate !== null && blockInfo.tokenBurnRate > 0) {\n const burnRateStr = `${formatTokens(blockInfo.tokenBurnRate)}/hr`;\n result += ` ${burnRateStr}`;\n }\n\n return result;\n } else {\n const costStr = formatCost(blockInfo.cost);\n let result = `${costStr} (${timeStr} left)`;\n\n if (blockInfo.burnRate !== null && blockInfo.burnRate > 0) {\n const burnRateStr = `${formatCost(blockInfo.burnRate)}/hr`;\n result += ` ${burnRateStr}`;\n }\n\n return result;\n }\n }\n}\n","import type { ClaudeHookData, PowerlineColors } from \"./types\";\nimport type { PowerlineConfig, LineConfig } from \"./types/config\";\nimport { hexToAnsi, extractBgToFg } from \"./lib/colors\";\nimport { getTheme } from \"./themes\";\nimport { UsageProvider } from \"./lib/usage-provider\";\nimport { GitService } from \"./lib/git-service\";\nimport { TmuxService } from \"./lib/tmux-service\";\nimport { SegmentRenderer, PowerlineSymbols } from \"./lib/segment-renderer\";\n\nexport class PowerlineRenderer {\n private readonly symbols: PowerlineSymbols;\n private readonly usageProvider: UsageProvider;\n private readonly gitService: GitService;\n private readonly tmuxService: TmuxService;\n private readonly segmentRenderer: SegmentRenderer;\n\n constructor(private readonly config: PowerlineConfig) {\n this.symbols = this.initializeSymbols();\n this.usageProvider = new UsageProvider();\n this.gitService = new GitService();\n this.tmuxService = new TmuxService();\n this.segmentRenderer = new SegmentRenderer(config, this.symbols);\n }\n\n async generateStatusline(hookData: ClaudeHookData): Promise<string> {\n const usageInfo = await this.usageProvider.getUsageInfo(\n hookData.session_id\n );\n\n let sessionBlockInfo = null;\n if (this.needsSessionBlock()) {\n sessionBlockInfo = await this.usageProvider.getSessionBlockInfo();\n }\n\n const lines = this.config.display.lines\n .map((lineConfig) =>\n this.renderLine(lineConfig, hookData, usageInfo, sessionBlockInfo)\n )\n .filter((line) => line.length > 0);\n\n return lines.join(\"\\n\");\n }\n\n private needsSessionBlock(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.block?.enabled\n );\n }\n\n private renderLine(\n lineConfig: LineConfig,\n hookData: ClaudeHookData,\n usageInfo: any,\n sessionBlockInfo: any\n ): string {\n const colors = this.getThemeColors();\n const currentDir = hookData.workspace?.current_dir || hookData.cwd || \"/\";\n\n const segments = Object.entries(lineConfig.segments)\n .filter(([_, config]: [string, any]) => config?.enabled)\n .map(([type, config]: [string, any]) => ({ type, config }));\n\n let line = colors.reset;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (!segment) continue;\n\n const isLast = i === segments.length - 1;\n const nextSegment = !isLast ? segments[i + 1] : null;\n const nextBgColor = nextSegment\n ? this.getSegmentBgColor(nextSegment.type, colors)\n : \"\";\n\n const segmentData = this.renderSegment(\n segment,\n hookData,\n usageInfo,\n sessionBlockInfo,\n colors,\n currentDir\n );\n\n if (segmentData) {\n line += this.formatSegment(\n segmentData.bgColor,\n segmentData.fgColor,\n segmentData.text,\n isLast ? undefined : nextBgColor\n );\n }\n }\n\n return line;\n }\n\n private renderSegment(\n segment: any,\n hookData: ClaudeHookData,\n usageInfo: any,\n sessionBlockInfo: any,\n colors: any,\n currentDir: string\n ) {\n switch (segment.type) {\n case \"directory\":\n return this.segmentRenderer.renderDirectory(hookData, colors);\n\n case \"git\":\n const showSha = segment.config?.showSha || false;\n const gitInfo = this.gitService.getGitInfo(currentDir, showSha);\n return gitInfo\n ? this.segmentRenderer.renderGit(gitInfo, colors, showSha)\n : null;\n\n case \"model\":\n return this.segmentRenderer.renderModel(hookData, colors);\n\n case \"session\":\n const usageType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderSession(usageInfo, colors, usageType);\n\n case \"today\":\n const todayType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderToday(usageInfo, colors, todayType);\n\n case \"block\":\n const blockType = segment.config?.type || \"cost\";\n return this.segmentRenderer.renderBlock(\n sessionBlockInfo,\n colors,\n blockType\n );\n\n case \"tmux\":\n const tmuxSessionId = this.tmuxService.getSessionId();\n return this.segmentRenderer.renderTmux(tmuxSessionId, colors);\n\n default:\n return null;\n }\n }\n\n private initializeSymbols(): PowerlineSymbols {\n const isMinimalStyle = this.config.display.style === \"minimal\";\n\n return {\n right: isMinimalStyle ? \"\" : \"\\uE0B0\",\n branch: \"⑂\",\n model: \"⚡\",\n git_clean: \"✓\",\n git_dirty: \"●\",\n git_conflicts: \"⚠\",\n git_ahead: \"↑\",\n git_behind: \"↓\",\n session_cost: \"Session\",\n daily_cost: \"Today\",\n block_cost: \"Block\",\n };\n }\n\n private getThemeColors(): PowerlineColors {\n const theme = this.config.theme;\n let colorTheme;\n\n if (theme === \"custom\") {\n colorTheme = this.config.colors?.custom;\n if (!colorTheme) {\n throw new Error(\n \"Custom theme selected but no colors provided in configuration\"\n );\n }\n } else {\n colorTheme = getTheme(theme);\n if (!colorTheme) {\n console.warn(\n `Built-in theme '${theme}' not found, falling back to 'dark' theme`\n );\n colorTheme = getTheme(\"dark\")!;\n }\n }\n\n return {\n reset: \"\\x1b[0m\",\n modeBg: hexToAnsi(colorTheme.directory.bg, true),\n modeFg: hexToAnsi(colorTheme.directory.fg, false),\n gitBg: hexToAnsi(colorTheme.git.bg, true),\n gitFg: hexToAnsi(colorTheme.git.fg, false),\n modelBg: hexToAnsi(colorTheme.model.bg, true),\n modelFg: hexToAnsi(colorTheme.model.fg, false),\n sessionBg: hexToAnsi(colorTheme.session.bg, true),\n sessionFg: hexToAnsi(colorTheme.session.fg, false),\n todayBg: hexToAnsi(colorTheme.today.bg, true),\n todayFg: hexToAnsi(colorTheme.today.fg, false),\n blockBg: hexToAnsi(colorTheme.block.bg, true),\n blockFg: hexToAnsi(colorTheme.block.fg, false),\n burnLowBg: hexToAnsi(colorTheme.today.bg, true),\n burnFg: hexToAnsi(colorTheme.today.fg, false),\n tmuxBg: hexToAnsi(colorTheme.tmux.bg, true),\n tmuxFg: hexToAnsi(colorTheme.tmux.fg, false),\n };\n }\n\n private getSegmentBgColor(\n segmentType: string,\n colors: PowerlineColors\n ): string {\n switch (segmentType) {\n case \"directory\":\n return colors.modeBg;\n case \"git\":\n return colors.gitBg;\n case \"model\":\n return colors.modelBg;\n case \"session\":\n return colors.sessionBg;\n case \"today\":\n return colors.burnLowBg;\n case \"block\":\n return colors.blockBg;\n case \"tmux\":\n return colors.tmuxBg;\n default:\n return colors.modeBg;\n }\n }\n\n private formatSegment(\n bgColor: string,\n fgColor: string,\n text: string,\n nextBgColor?: string\n ): string {\n let output = `${bgColor}${fgColor} ${text} `;\n\n const reset = \"\\x1b[0m\";\n\n if (nextBgColor) {\n const arrowFgColor = extractBgToFg(bgColor);\n output += `${reset}${nextBgColor}${arrowFgColor}${this.symbols.right}`;\n } else {\n output += `${reset}${extractBgToFg(bgColor)}${this.symbols.right}${reset}`;\n }\n\n return output;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport type { PowerlineConfig, ConfigLoadOptions } from \"../types/config\";\nimport { DEFAULT_CONFIG } from \"./defaults\";\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n if (\n typeof source[key] === \"object\" &&\n source[key] !== null &&\n !Array.isArray(source[key])\n ) {\n result[key] = deepMerge(result[key] || ({} as any), source[key] as any);\n } else {\n result[key] = source[key] as any;\n }\n }\n }\n\n return result;\n}\n\nfunction findConfigFile(\n customPath?: string,\n projectDir?: string\n): string | null {\n if (customPath) {\n return fs.existsSync(customPath) ? customPath : null;\n }\n\n const locations = [\n ...(projectDir ? [path.join(projectDir, \".claude-powerline.json\")] : []),\n path.join(process.cwd(), \".claude-powerline.json\"),\n path.join(os.homedir(), \".claude\", \"claude-powerline.json\"),\n path.join(os.homedir(), \".config\", \"claude-powerline\", \"config.json\"),\n ];\n\n return locations.find(fs.existsSync) || null;\n}\n\nfunction loadConfigFile(filePath: string): Partial<PowerlineConfig> {\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content);\n } catch (error) {\n throw new Error(\n `Failed to load config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\nfunction loadEnvConfig(): Partial<PowerlineConfig> {\n const config: Partial<PowerlineConfig> = {};\n\n if (process.env.CLAUDE_POWERLINE_THEME) {\n config.theme = process.env.CLAUDE_POWERLINE_THEME as\n | \"light\"\n | \"dark\"\n | \"custom\";\n }\n\n if (process.env.CLAUDE_POWERLINE_STYLE) {\n config.display = config.display || { lines: [] };\n const style = process.env.CLAUDE_POWERLINE_STYLE;\n if (style === \"minimal\" || style === \"powerline\") {\n config.display.style = style;\n } else {\n console.warn(\n `Invalid display style '${style}' from environment variable, falling back to 'minimal'`\n );\n config.display.style = \"minimal\";\n }\n }\n\n if (process.env.CLAUDE_POWERLINE_USAGE_TYPE) {\n const usageType = process.env.CLAUDE_POWERLINE_USAGE_TYPE as\n | \"cost\"\n | \"tokens\"\n | \"both\"\n | \"breakdown\";\n config.display = config.display || { lines: [] };\n\n if (config.display.lines.length === 0) {\n config.display.lines = [{ segments: {} }];\n }\n\n config.display.lines.forEach((line) => {\n if (line.segments.session) {\n line.segments.session.type = usageType;\n }\n if (line.segments.today) {\n line.segments.today.type = usageType;\n }\n if (line.segments.block) {\n line.segments.block.type =\n usageType === \"breakdown\" || usageType === \"both\"\n ? \"cost\"\n : usageType;\n }\n });\n }\n\n return config;\n}\n\nfunction getConfigPathFromEnv(): string | undefined {\n return process.env.CLAUDE_POWERLINE_CONFIG;\n}\n\nfunction parseCLIOverrides(args: string[]): Partial<PowerlineConfig> {\n const config: Partial<PowerlineConfig> = {};\n\n const themeIndex = args.findIndex((arg) => arg.startsWith(\"--theme=\"));\n if (themeIndex !== -1) {\n const theme = args[themeIndex]?.split(\"=\")[1];\n if (theme) {\n config.theme = theme as \"light\" | \"dark\" | \"custom\";\n }\n }\n\n const styleIndex = args.findIndex((arg) => arg.startsWith(\"--style=\"));\n if (styleIndex !== -1) {\n const style = args[styleIndex]?.split(\"=\")[1];\n if (style) {\n config.display = config.display || { lines: [] };\n if (style === \"minimal\" || style === \"powerline\") {\n config.display.style = style;\n } else {\n console.warn(\n `Invalid display style '${style}' from CLI argument, falling back to 'minimal'`\n );\n config.display.style = \"minimal\";\n }\n }\n }\n\n const dailyBudgetIndex = args.findIndex((arg) =>\n arg.startsWith(\"--daily-budget=\")\n );\n if (dailyBudgetIndex !== -1) {\n const dailyBudget = parseFloat(args[dailyBudgetIndex]?.split(\"=\")[1] || \"\");\n if (!isNaN(dailyBudget) && dailyBudget > 0) {\n config.budget = {\n ...config.budget,\n today: {\n ...DEFAULT_CONFIG.budget?.today,\n amount: dailyBudget,\n },\n };\n }\n }\n\n const sessionBudgetIndex = args.findIndex((arg) =>\n arg.startsWith(\"--session-budget=\")\n );\n if (sessionBudgetIndex !== -1) {\n const sessionBudget = parseFloat(\n args[sessionBudgetIndex]?.split(\"=\")[1] || \"\"\n );\n if (!isNaN(sessionBudget) && sessionBudget > 0) {\n config.budget = {\n ...config.budget,\n session: {\n ...DEFAULT_CONFIG.budget?.session,\n amount: sessionBudget,\n },\n };\n }\n }\n\n const usageIndex = args.findIndex((arg) => arg.startsWith(\"--usage=\"));\n if (usageIndex !== -1) {\n const usageType = args[usageIndex]?.split(\"=\")[1] as\n | \"cost\"\n | \"tokens\"\n | \"both\"\n | \"breakdown\";\n if (\n usageType &&\n [\"cost\", \"tokens\", \"both\", \"breakdown\"].includes(usageType)\n ) {\n config.display = config.display || { lines: [] };\n\n if (config.display.lines.length === 0) {\n config.display.lines = [{ segments: {} }];\n }\n\n config.display.lines.forEach((line) => {\n if (line.segments.session) {\n line.segments.session.type = usageType;\n }\n if (line.segments.today) {\n line.segments.today.type = usageType;\n }\n if (line.segments.block) {\n line.segments.block.type =\n usageType === \"breakdown\" || usageType === \"both\"\n ? \"cost\"\n : usageType;\n }\n });\n }\n }\n\n return config;\n}\n\nexport function loadConfig(options: ConfigLoadOptions = {}): PowerlineConfig {\n const {\n configPath,\n ignoreEnvVars = false,\n cliOverrides = {},\n projectDir,\n } = options;\n\n let config: PowerlineConfig = JSON.parse(JSON.stringify(DEFAULT_CONFIG));\n\n const configFile = findConfigFile(configPath, projectDir);\n if (configFile) {\n try {\n const fileConfig = loadConfigFile(configFile);\n config = deepMerge(config, fileConfig);\n } catch (err) {\n console.warn(\n `Warning: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n if (\n config.display?.style &&\n config.display.style !== \"minimal\" &&\n config.display.style !== \"powerline\"\n ) {\n console.warn(\n `Invalid display style '${config.display.style}' in config file, falling back to 'minimal'`\n );\n config.display.style = \"minimal\";\n }\n\n if (!ignoreEnvVars) {\n const envConfig = loadEnvConfig();\n config = deepMerge(config, envConfig);\n }\n\n config = deepMerge(config, cliOverrides);\n\n return config;\n}\n\nexport function loadConfigFromCLI(\n args: string[] = process.argv,\n projectDir?: string\n): PowerlineConfig {\n const configPathIndex = args.findIndex((arg) => arg.startsWith(\"--config=\"));\n const configPath =\n configPathIndex !== -1\n ? args[configPathIndex]?.split(\"=\")[1]\n : getConfigPathFromEnv();\n\n const cliOverrides = parseCLIOverrides(args);\n\n return loadConfig({ configPath, cliOverrides, projectDir });\n}\n\nexport function getConfigPath(\n customPath?: string,\n projectDir?: string\n): string | null {\n return findConfigFile(customPath, projectDir);\n}\n","import type { PowerlineConfig } from \"../types/config\";\n\nexport const DEFAULT_CONFIG: PowerlineConfig = {\n theme: \"dark\",\n display: {\n style: \"minimal\",\n lines: [\n {\n segments: {\n directory: { enabled: true },\n git: {\n enabled: true,\n showSha: false,\n },\n model: { enabled: true },\n session: { enabled: true, type: \"tokens\" },\n today: { enabled: true, type: \"both\" },\n block: { enabled: false, type: \"cost\" },\n tmux: { enabled: false },\n },\n },\n ],\n },\n budget: {\n session: {\n warningThreshold: 80,\n },\n today: {\n amount: 50,\n warningThreshold: 80,\n },\n },\n};\n"],"mappings":"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","names":["process","path","fs","execSync","os","execSync","os","path","fs","execSync","process"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owloops/claude-powerline",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "Beautiful vim-style powerline statusline for Claude Code with real-time cost tracking, git integration, and custom themes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",