@owloops/claude-powerline 1.4.1 → 1.4.3
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 +3 -1
- package/dist/index.js +75 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -172,7 +172,7 @@ claude-powerline --session-budget=50
|
|
|
172
172
|
### Status Indicators
|
|
173
173
|
|
|
174
174
|
- **Git**: `✓` Clean, `●` Dirty, `⚠` Conflicts, `↑3` Ahead, `↓2` Behind remote
|
|
175
|
-
- **Context**: `⊡ 34,040 (79%)` - Token count and percentage remaining until auto-compact
|
|
175
|
+
- **Context**: `⊡ 34,040 (79%)` - Token count and percentage remaining until auto-compact (uses 75% of 200k limit)
|
|
176
176
|
- **Budget**: `25%` Normal (under 50%), `+75%` Moderate (50-79%), `!85%` Warning (80%+)
|
|
177
177
|
|
|
178
178
|
## Configuration
|
|
@@ -398,6 +398,8 @@ export CLAUDE_POWERLINE_DEBUG=1
|
|
|
398
398
|
|
|
399
399
|
Contributions are welcome! Please feel free to submit issues or pull requests.
|
|
400
400
|
|
|
401
|
+
See [CONTRIBUTORS.md](CONTRIBUTORS.md) for people who have contributed outside of GitHub PRs.
|
|
402
|
+
|
|
401
403
|
## License
|
|
402
404
|
|
|
403
405
|
This project is licensed under the [MIT License](LICENSE).
|
package/dist/index.js
CHANGED
|
@@ -110,6 +110,8 @@ var debug = (message, ...args) => {
|
|
|
110
110
|
|
|
111
111
|
// src/segments/git.ts
|
|
112
112
|
var GitService = class {
|
|
113
|
+
cache = /* @__PURE__ */ new Map();
|
|
114
|
+
CACHE_TTL = 1e3;
|
|
113
115
|
isGitRepo(workingDir) {
|
|
114
116
|
try {
|
|
115
117
|
return fs.existsSync(path.join(workingDir, ".git"));
|
|
@@ -119,28 +121,39 @@ var GitService = class {
|
|
|
119
121
|
}
|
|
120
122
|
getGitInfo(workingDir, showSha = false, projectDir) {
|
|
121
123
|
const gitDir = projectDir && this.isGitRepo(projectDir) ? projectDir : workingDir;
|
|
124
|
+
const cacheKey = `${gitDir}:${showSha}`;
|
|
125
|
+
const cached = this.cache.get(cacheKey);
|
|
126
|
+
const now = Date.now();
|
|
127
|
+
if (cached && now - cached.timestamp < this.CACHE_TTL) {
|
|
128
|
+
return cached.data;
|
|
129
|
+
}
|
|
122
130
|
if (!this.isGitRepo(gitDir)) {
|
|
123
|
-
|
|
131
|
+
const result = {
|
|
124
132
|
branch: "detached",
|
|
125
133
|
status: "clean",
|
|
126
134
|
ahead: 0,
|
|
127
135
|
behind: 0,
|
|
128
136
|
sha: void 0
|
|
129
137
|
};
|
|
138
|
+
this.cache.set(cacheKey, { data: result, timestamp: now });
|
|
139
|
+
return result;
|
|
130
140
|
}
|
|
131
141
|
try {
|
|
132
142
|
const branch = this.getBranch(gitDir);
|
|
133
143
|
const status = this.getStatus(gitDir);
|
|
134
144
|
const { ahead, behind } = this.getAheadBehind(gitDir);
|
|
135
145
|
const sha = showSha ? this.getSha(gitDir) || void 0 : void 0;
|
|
136
|
-
|
|
146
|
+
const result = {
|
|
137
147
|
branch: branch || "detached",
|
|
138
148
|
status,
|
|
139
149
|
ahead,
|
|
140
150
|
behind,
|
|
141
151
|
sha
|
|
142
152
|
};
|
|
153
|
+
this.cache.set(cacheKey, { data: result, timestamp: now });
|
|
154
|
+
return result;
|
|
143
155
|
} catch {
|
|
156
|
+
this.cache.set(cacheKey, { data: null, timestamp: now });
|
|
144
157
|
return null;
|
|
145
158
|
}
|
|
146
159
|
}
|
|
@@ -149,7 +162,7 @@ var GitService = class {
|
|
|
149
162
|
return execSync("git branch --show-current", {
|
|
150
163
|
cwd: workingDir,
|
|
151
164
|
encoding: "utf8",
|
|
152
|
-
timeout:
|
|
165
|
+
timeout: 5e3
|
|
153
166
|
}).trim() || null;
|
|
154
167
|
} catch (error) {
|
|
155
168
|
debug(`Git branch command failed in ${workingDir}:`, error);
|
|
@@ -161,7 +174,7 @@ var GitService = class {
|
|
|
161
174
|
const gitStatus = execSync("git status --porcelain", {
|
|
162
175
|
cwd: workingDir,
|
|
163
176
|
encoding: "utf8",
|
|
164
|
-
timeout:
|
|
177
|
+
timeout: 5e3
|
|
165
178
|
}).trim();
|
|
166
179
|
if (!gitStatus) return "clean";
|
|
167
180
|
if (gitStatus.includes("UU") || gitStatus.includes("AA") || gitStatus.includes("DD")) {
|
|
@@ -178,12 +191,12 @@ var GitService = class {
|
|
|
178
191
|
const aheadResult = execSync("git rev-list --count @{u}..HEAD", {
|
|
179
192
|
cwd: workingDir,
|
|
180
193
|
encoding: "utf8",
|
|
181
|
-
timeout:
|
|
194
|
+
timeout: 5e3
|
|
182
195
|
}).trim();
|
|
183
196
|
const behindResult = execSync("git rev-list --count HEAD..@{u}", {
|
|
184
197
|
cwd: workingDir,
|
|
185
198
|
encoding: "utf8",
|
|
186
|
-
timeout:
|
|
199
|
+
timeout: 5e3
|
|
187
200
|
}).trim();
|
|
188
201
|
return {
|
|
189
202
|
ahead: parseInt(aheadResult) || 0,
|
|
@@ -199,7 +212,7 @@ var GitService = class {
|
|
|
199
212
|
const sha = execSync("git rev-parse --short=7 HEAD", {
|
|
200
213
|
cwd: workingDir,
|
|
201
214
|
encoding: "utf8",
|
|
202
|
-
timeout:
|
|
215
|
+
timeout: 5e3
|
|
203
216
|
}).trim();
|
|
204
217
|
return sha || null;
|
|
205
218
|
} catch {
|
|
@@ -410,13 +423,18 @@ var PricingService = class {
|
|
|
410
423
|
const now = Date.now();
|
|
411
424
|
const memCached = this.memoryCache.get("pricing");
|
|
412
425
|
if (memCached && now - memCached.timestamp < this.CACHE_TTL) {
|
|
413
|
-
debug(
|
|
426
|
+
debug(
|
|
427
|
+
`Using memory cached pricing data for ${Object.keys(memCached.data).length} models`
|
|
428
|
+
);
|
|
414
429
|
return memCached.data;
|
|
415
430
|
}
|
|
416
431
|
const diskCached = this.loadDiskCache();
|
|
417
432
|
if (diskCached && now - diskCached.timestamp < this.CACHE_TTL) {
|
|
433
|
+
this.memoryCache.clear();
|
|
418
434
|
this.memoryCache.set("pricing", diskCached);
|
|
419
|
-
debug(
|
|
435
|
+
debug(
|
|
436
|
+
`Using disk cached pricing data for ${Object.keys(diskCached.data).length} models`
|
|
437
|
+
);
|
|
420
438
|
return diskCached.data;
|
|
421
439
|
}
|
|
422
440
|
try {
|
|
@@ -437,9 +455,15 @@ var PricingService = class {
|
|
|
437
455
|
}
|
|
438
456
|
}
|
|
439
457
|
if (this.validatePricingData(pricingData)) {
|
|
440
|
-
this.memoryCache.
|
|
458
|
+
this.memoryCache.clear();
|
|
459
|
+
this.memoryCache.set("pricing", {
|
|
460
|
+
data: pricingData,
|
|
461
|
+
timestamp: now
|
|
462
|
+
});
|
|
441
463
|
this.saveDiskCache(pricingData);
|
|
442
|
-
debug(
|
|
464
|
+
debug(
|
|
465
|
+
`Fetched fresh pricing from GitHub for ${Object.keys(pricingData).length} models`
|
|
466
|
+
);
|
|
443
467
|
debug(`Pricing last updated: ${meta?.updated || "unknown"}`);
|
|
444
468
|
return pricingData;
|
|
445
469
|
}
|
|
@@ -449,10 +473,14 @@ var PricingService = class {
|
|
|
449
473
|
}
|
|
450
474
|
if (diskCached) {
|
|
451
475
|
this.memoryCache.set("pricing", diskCached);
|
|
452
|
-
debug(
|
|
476
|
+
debug(
|
|
477
|
+
`Using stale cached pricing data for ${Object.keys(diskCached.data).length} models`
|
|
478
|
+
);
|
|
453
479
|
return diskCached.data;
|
|
454
480
|
}
|
|
455
|
-
debug(
|
|
481
|
+
debug(
|
|
482
|
+
`Using offline pricing data for ${Object.keys(OFFLINE_PRICING_DATA).length} models`
|
|
483
|
+
);
|
|
456
484
|
return OFFLINE_PRICING_DATA;
|
|
457
485
|
}
|
|
458
486
|
static validatePricingData(data) {
|
|
@@ -481,12 +509,30 @@ var PricingService = class {
|
|
|
481
509
|
}
|
|
482
510
|
}
|
|
483
511
|
const patterns = [
|
|
484
|
-
{
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
{
|
|
489
|
-
|
|
512
|
+
{
|
|
513
|
+
pattern: ["opus-4-1", "claude-opus-4-1"],
|
|
514
|
+
fallback: "claude-opus-4-1-20250805"
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
pattern: ["opus-4", "claude-opus-4"],
|
|
518
|
+
fallback: "claude-opus-4-20250514"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
pattern: ["sonnet-4", "claude-sonnet-4"],
|
|
522
|
+
fallback: "claude-sonnet-4-20250514"
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
pattern: ["sonnet-3.7", "3-7-sonnet"],
|
|
526
|
+
fallback: "claude-3-7-sonnet-20250219"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
pattern: ["3-5-sonnet", "sonnet-3.5"],
|
|
530
|
+
fallback: "claude-3-5-sonnet-20241022"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
pattern: ["3-5-haiku", "haiku-3.5"],
|
|
534
|
+
fallback: "claude-3-5-haiku-20241022"
|
|
535
|
+
},
|
|
490
536
|
{ pattern: ["haiku", "3-haiku"], fallback: "claude-3-haiku-20240307" },
|
|
491
537
|
{ pattern: ["opus"], fallback: "claude-opus-4-20250514" },
|
|
492
538
|
{ pattern: ["sonnet"], fallback: "claude-3-5-sonnet-20241022" }
|
|
@@ -1717,6 +1763,13 @@ async function installFonts() {
|
|
|
1717
1763
|
console.log("\u{1F4E6} Installing Powerline Fonts...");
|
|
1718
1764
|
console.log("Downloading from https://github.com/powerline/fonts");
|
|
1719
1765
|
const tempDir = path3.join(os2.tmpdir(), "powerline-fonts");
|
|
1766
|
+
const cleanup = () => {
|
|
1767
|
+
if (fs3.existsSync(tempDir)) {
|
|
1768
|
+
fs3.rmSync(tempDir, { recursive: true, force: true });
|
|
1769
|
+
}
|
|
1770
|
+
};
|
|
1771
|
+
process2.on("SIGINT", cleanup);
|
|
1772
|
+
process2.on("SIGTERM", cleanup);
|
|
1720
1773
|
try {
|
|
1721
1774
|
if (fs3.existsSync(tempDir)) {
|
|
1722
1775
|
fs3.rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -1747,9 +1800,9 @@ async function installFonts() {
|
|
|
1747
1800
|
"Popular choices: Source Code Pro Powerline, DejaVu Sans Mono Powerline, Ubuntu Mono Powerline"
|
|
1748
1801
|
);
|
|
1749
1802
|
} finally {
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1803
|
+
cleanup();
|
|
1804
|
+
process2.removeListener("SIGINT", cleanup);
|
|
1805
|
+
process2.removeListener("SIGTERM", cleanup);
|
|
1753
1806
|
}
|
|
1754
1807
|
} catch (error) {
|
|
1755
1808
|
console.error(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/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/segments/git.ts","../src/utils/logger.ts","../src/segments/tmux.ts","../src/segments/session.ts","../src/segments/pricing.ts","../src/utils/claude.ts","../src/segments/context.ts","../src/segments/metrics.ts","../src/utils/formatters.ts","../src/utils/budget.ts","../src/segments/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 { json } from \"node:stream/consumers\";\nimport { PowerlineRenderer } from \"./powerline\";\nimport { loadConfigFromCLI } from \"./config/loader\";\nimport { debug } from \"./utils/logger\";\nexport interface ClaudeHookData {\n hook_event_name: string;\n session_id: string;\n transcript_path: string;\n cwd: string;\n model: {\n id: string;\n display_name: string;\n };\n workspace: {\n current_dir: string;\n project_dir: string;\n };\n}\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\nStandalone Commands:\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nDebugging:\n CLAUDE_POWERLINE_DEBUG=1 Enable debug logging for troubleshooting\n\nClaude Code Options (for settings.json):\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 --config=PATH Use custom config file path\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 if (process.stdin.isTTY === true) {\n console.error(`Error: This tool requires input from Claude Code\n\nclaude-powerline is designed to be used as a Claude Code statusLine command.\nIt reads hook data from stdin and outputs formatted statusline.\n\nAdd to ~/.claude/settings.json:\n{\n \"statusLine\": {\n \"type\": \"command\",\n \"command\": \"claude-powerline --style=powerline\"\n }\n}\n\nRun with --help for more options.\n\nTo test output manually:\necho '{\"session_id\":\"test-session\",\"workspace\":{\"project_dir\":\"/path/to/project\"},\"model\":{\"id\":\"claude-3-5-sonnet\",\"display_name\":\"Claude\"}}' | claude-powerline --style=powerline`);\n process.exit(1);\n }\n\n debug(`Working directory: ${process.cwd()}`);\n debug(`Process args:`, process.argv);\n\n const hookData = (await json(process.stdin)) as ClaudeHookData;\n debug(`Received hook data:`, JSON.stringify(hookData, null, 2));\n\n if (!hookData) {\n console.error(\"Error: No input data received from stdin\");\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 --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 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 \"./index\";\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 tmux: { bg: \"#2f4f2f\", fg: \"#90ee90\" },\n context: { bg: \"#4a5568\", fg: \"#cbd5e0\" },\n metrics: { bg: \"#374151\", fg: \"#d1d5db\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#32cd32\", fg: \"#ffffff\" },\n context: { bg: \"#718096\", fg: \"#ffffff\" },\n metrics: { bg: \"#6b7280\", fg: \"#ffffff\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#2e3440\", fg: \"#8fbcbb\" },\n context: { bg: \"#5e81ac\", fg: \"#eceff4\" },\n metrics: { bg: \"#b48ead\", fg: \"#2e3440\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#191b29\", fg: \"#4fd6be\" },\n context: { bg: \"#414868\", fg: \"#c0caf5\" },\n metrics: { bg: \"#3d59a1\", fg: \"#c0caf5\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#26233a\", fg: \"#908caa\" },\n context: { bg: \"#393552\", fg: \"#e0def4\" },\n metrics: { bg: \"#524f67\", fg: \"#e0def4\" },\n};\n","import { darkTheme } from \"./dark\";\nimport { lightTheme } from \"./light\";\nimport { nordTheme } from \"./nord\";\nimport { tokyoNightTheme } from \"./tokyo-night\";\nimport { rosePineTheme } from \"./rose-pine\";\n\nexport interface SegmentColor {\n bg: string;\n fg: string;\n}\n\nexport interface ColorTheme {\n directory: SegmentColor;\n git: SegmentColor;\n model: SegmentColor;\n session: SegmentColor;\n tmux: SegmentColor;\n context: SegmentColor;\n metrics: SegmentColor;\n}\n\nexport interface PowerlineColors {\n reset: string;\n modeBg: string;\n modeFg: string;\n gitBg: string;\n gitFg: string;\n modelBg: string;\n modelFg: string;\n sessionBg: string;\n sessionFg: string;\n tmuxBg: string;\n tmuxFg: string;\n contextBg: string;\n contextFg: string;\n metricsBg: string;\n metricsFg: string;\n}\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 { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { debug } from \"../utils/logger\";\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 private isGitRepo(workingDir: string): boolean {\n try {\n return fs.existsSync(path.join(workingDir, \".git\"));\n } catch {\n return false;\n }\n }\n\n getGitInfo(\n workingDir: string,\n showSha = false,\n projectDir?: string\n ): GitInfo | null {\n const gitDir =\n projectDir && this.isGitRepo(projectDir) ? projectDir : workingDir;\n\n if (!this.isGitRepo(gitDir)) {\n return {\n branch: \"detached\",\n status: \"clean\",\n ahead: 0,\n behind: 0,\n sha: undefined,\n };\n }\n\n try {\n const branch = this.getBranch(gitDir);\n const status = this.getStatus(gitDir);\n const { ahead, behind } = this.getAheadBehind(gitDir);\n const sha = showSha ? this.getSha(gitDir) || 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 (error) {\n debug(`Git branch command failed in ${workingDir}:`, error);\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 (error) {\n debug(`Git status command failed in ${workingDir}:`, error);\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 (error) {\n debug(`Git ahead/behind command failed in ${workingDir}:`, error);\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","const debug = (message: string, ...args: any[]): void => {\n if (process.env.CLAUDE_POWERLINE_DEBUG) {\n console.error(`[DEBUG] ${message}`, ...args);\n }\n};\n\nexport { debug };\n","import { execSync } from \"node:child_process\";\nimport { debug } from \"../utils/logger\";\n\nexport class TmuxService {\n getSessionId(): string | null {\n try {\n if (!process.env.TMUX_PANE) {\n debug(`TMUX_PANE not set, not in tmux session`);\n return null;\n }\n\n debug(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);\n\n const sessionId = execSync(\"tmux display-message -p '#S'\", {\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n debug(`Tmux session ID: ${sessionId || \"empty\"}`);\n\n return sessionId || null;\n } catch (error) {\n debug(`Error getting tmux session ID:`, error);\n return null;\n }\n }\n\n isInTmux(): boolean {\n return !!process.env.TMUX_PANE;\n }\n}","import { readFile } from \"node:fs/promises\";\nimport { debug } from \"../utils/logger\";\nimport { PricingService } from \"./pricing\";\nimport { findTranscriptFile } from \"../utils/claude\";\n\nexport interface SessionUsageEntry {\n timestamp: string;\n message: {\n usage: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n costUSD?: number;\n}\n\nexport interface SessionUsage {\n totalCost: number;\n entries: SessionUsageEntry[];\n}\n\nexport interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport interface SessionInfo {\n cost: number | null;\n tokens: number | null;\n tokenBreakdown: TokenBreakdown | null;\n}\n\nexport interface UsageInfo {\n session: SessionInfo;\n}\n\nexport class SessionProvider {\n\n async getSessionUsage(sessionId: string): Promise<SessionUsage | null> {\n try {\n const transcriptPath = await findTranscriptFile(sessionId);\n if (!transcriptPath) {\n debug(`No transcript found for session: ${sessionId}`);\n return null;\n }\n\n debug(`Found transcript at: ${transcriptPath}`);\n \n const content = await readFile(transcriptPath, 'utf-8');\n const lines = content.trim().split('\\n').filter(line => line.trim());\n \n if (lines.length === 0) {\n return { totalCost: 0, entries: [] };\n }\n\n const entries: SessionUsageEntry[] = [];\n let totalCost = 0;\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as Record<string, unknown>;\n \n if (entry.message && typeof entry.message === 'object') {\n const message = entry.message as Record<string, unknown>;\n if (message.usage && typeof message.usage === 'object') {\n const sessionEntry: SessionUsageEntry = {\n timestamp: (entry.timestamp as string) || new Date().toISOString(),\n message: {\n usage: message.usage as SessionUsageEntry['message']['usage']\n }\n };\n\n if (typeof entry.costUSD === 'number') {\n sessionEntry.costUSD = entry.costUSD;\n totalCost += entry.costUSD;\n } else {\n const cost = await PricingService.calculateCostForEntry(entry);\n sessionEntry.costUSD = cost;\n totalCost += cost;\n }\n\n entries.push(sessionEntry);\n }\n }\n } catch (parseError) {\n debug(`Failed to parse JSONL line: ${parseError}`);\n continue;\n }\n }\n\n debug(`Parsed ${entries.length} usage entries, total cost: $${totalCost.toFixed(4)}`);\n return { totalCost, entries };\n\n } catch (error) {\n debug(`Error reading session usage for ${sessionId}:`, error);\n return null;\n }\n }\n\n calculateTokenBreakdown(entries: SessionUsageEntry[]): TokenBreakdown {\n return entries.reduce(\n (breakdown, entry) => ({\n input: breakdown.input + (entry.message.usage.input_tokens || 0),\n output: breakdown.output + (entry.message.usage.output_tokens || 0),\n cacheCreation: breakdown.cacheCreation + (entry.message.usage.cache_creation_input_tokens || 0),\n cacheRead: breakdown.cacheRead + (entry.message.usage.cache_read_input_tokens || 0),\n }),\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n }\n\n async getSessionInfo(sessionId: string): Promise<SessionInfo> {\n const sessionUsage = await this.getSessionUsage(sessionId);\n \n if (!sessionUsage || sessionUsage.entries.length === 0) {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n\n const tokenBreakdown = this.calculateTokenBreakdown(sessionUsage.entries);\n const totalTokens = tokenBreakdown.input + tokenBreakdown.output + \n tokenBreakdown.cacheCreation + tokenBreakdown.cacheRead;\n\n return {\n cost: sessionUsage.totalCost,\n tokens: totalTokens,\n tokenBreakdown,\n };\n }\n}\n\nexport class UsageProvider {\n private sessionProvider = new SessionProvider();\n\n async getUsageInfo(sessionId: string): Promise<UsageInfo> {\n try {\n debug(`Starting usage info retrieval for session: ${sessionId}`);\n \n const sessionInfo = await this.sessionProvider.getSessionInfo(sessionId);\n \n return {\n session: sessionInfo,\n };\n } catch (error) {\n debug(`Error getting usage info for session ${sessionId}:`, error);\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n };\n }\n }\n}","import { debug } from \"../utils/logger\";\n\n\nexport interface ModelPricing {\n name: string;\n input: number;\n cache_write_5m: number;\n cache_write_1h: number;\n cache_read: number;\n output: number;\n}\nconst OFFLINE_PRICING_DATA: Record<string, ModelPricing> = {\n \"claude-3-haiku-20240307\": {\n name: \"Claude 3 Haiku\",\n input: 0.25,\n output: 1.25,\n cache_write_5m: 0.30,\n cache_write_1h: 0.50,\n cache_read: 0.03\n },\n \"claude-3-5-haiku-20241022\": {\n name: \"Claude 3.5 Haiku\",\n input: 0.80,\n output: 4.00,\n cache_write_5m: 1.00,\n cache_write_1h: 1.60,\n cache_read: 0.08\n },\n \"claude-3-5-haiku-latest\": {\n name: \"Claude 3.5 Haiku Latest\",\n input: 1.00,\n output: 5.00,\n cache_write_5m: 1.25,\n cache_write_1h: 2.00,\n cache_read: 0.10\n },\n \"claude-3-opus-latest\": {\n name: \"Claude 3 Opus Latest\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-3-opus-20240229\": {\n name: \"Claude 3 Opus\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-3-5-sonnet-latest\": {\n name: \"Claude 3.5 Sonnet Latest\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-3-5-sonnet-20240620\": {\n name: \"Claude 3.5 Sonnet\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-3-5-sonnet-20241022\": {\n name: \"Claude 3.5 Sonnet\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-opus-4-20250514\": {\n name: \"Claude Opus 4\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-opus-4-1\": {\n name: \"Claude Opus 4.1\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-opus-4-1-20250805\": {\n name: \"Claude Opus 4.1\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-sonnet-4-20250514\": {\n name: \"Claude Sonnet 4\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-4-opus-20250514\": {\n name: \"Claude 4 Opus\",\n input: 15.00,\n output: 75.00,\n cache_write_5m: 18.75,\n cache_write_1h: 30.00,\n cache_read: 1.50\n },\n \"claude-4-sonnet-20250514\": {\n name: \"Claude 4 Sonnet\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-3-7-sonnet-latest\": {\n name: \"Claude 3.7 Sonnet Latest\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n },\n \"claude-3-7-sonnet-20250219\": {\n name: \"Claude 3.7 Sonnet\",\n input: 3.00,\n output: 15.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30\n }\n};\n\nexport class PricingService {\n private static memoryCache: Map<string, { data: Record<string, ModelPricing>; timestamp: number }> = new Map();\n private static readonly CACHE_TTL = 24 * 60 * 60 * 1000;\n private static readonly GITHUB_PRICING_URL = \"https://raw.githubusercontent.com/Owloops/claude-powerline/main/pricing.json\";\n\n private static getCacheFilePath(): string {\n const { homedir } = require('os');\n const { join } = require('path');\n const { mkdirSync } = require('fs');\n \n const cacheDir = join(homedir(), '.claude', 'cache');\n try {\n mkdirSync(cacheDir, { recursive: true });\n } catch {}\n \n return join(cacheDir, 'pricing.json');\n }\n\n private static loadDiskCache(): { data: Record<string, ModelPricing>; timestamp: number } | null {\n try {\n const { readFileSync } = require('fs');\n const cacheFile = this.getCacheFilePath();\n const content = readFileSync(cacheFile, 'utf-8');\n const cached = JSON.parse(content);\n \n if (cached && cached.data && cached.timestamp) {\n return cached;\n }\n } catch {}\n return null;\n }\n\n private static saveDiskCache(data: Record<string, ModelPricing>): void {\n try {\n const { writeFileSync } = require('fs');\n const cacheFile = this.getCacheFilePath();\n const cacheData = { data, timestamp: Date.now() };\n writeFileSync(cacheFile, JSON.stringify(cacheData));\n } catch (error) {\n debug('Failed to save pricing cache to disk:', error);\n }\n }\n\n static async getCurrentPricing(): Promise<Record<string, ModelPricing>> {\n const now = Date.now();\n\n const memCached = this.memoryCache.get('pricing');\n if (memCached && now - memCached.timestamp < this.CACHE_TTL) {\n debug(`Using memory cached pricing data for ${Object.keys(memCached.data).length} models`);\n return memCached.data;\n }\n\n const diskCached = this.loadDiskCache();\n if (diskCached && now - diskCached.timestamp < this.CACHE_TTL) {\n this.memoryCache.set('pricing', diskCached);\n debug(`Using disk cached pricing data for ${Object.keys(diskCached.data).length} models`);\n return diskCached.data;\n }\n\n try {\n const response = await globalThis.fetch(this.GITHUB_PRICING_URL, {\n headers: {\n 'User-Agent': 'claude-powerline',\n 'Cache-Control': 'no-cache'\n }\n });\n\n if (response.ok) {\n const data = await response.json();\n \n const dataObj = data as Record<string, unknown>;\n const meta = dataObj._meta as { updated?: string } | undefined;\n \n const pricingData: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(dataObj)) {\n if (key !== '_meta') {\n pricingData[key] = value;\n }\n }\n \n if (this.validatePricingData(pricingData)) {\n this.memoryCache.set('pricing', { data: pricingData, timestamp: now });\n this.saveDiskCache(pricingData);\n debug(`Fetched fresh pricing from GitHub for ${Object.keys(pricingData).length} models`);\n debug(`Pricing last updated: ${meta?.updated || 'unknown'}`);\n return pricingData;\n }\n }\n } catch (error) {\n debug('Failed to fetch pricing from GitHub, using fallback:', error);\n }\n\n if (diskCached) {\n this.memoryCache.set('pricing', diskCached);\n debug(`Using stale cached pricing data for ${Object.keys(diskCached.data).length} models`);\n return diskCached.data;\n }\n\n debug(`Using offline pricing data for ${Object.keys(OFFLINE_PRICING_DATA).length} models`);\n return OFFLINE_PRICING_DATA;\n }\n\n private static validatePricingData(data: unknown): data is Record<string, ModelPricing> {\n if (!data || typeof data !== 'object') return false;\n \n for (const [, value] of Object.entries(data)) {\n if (!value || typeof value !== 'object') return false;\n const pricing = value as Record<string, unknown>;\n \n if (typeof pricing.input !== 'number' || \n typeof pricing.output !== 'number' ||\n typeof pricing.cache_read !== 'number') {\n return false;\n }\n }\n \n return true;\n }\n\n static async getModelPricing(modelId: string): Promise<ModelPricing> {\n const allPricing = await this.getCurrentPricing();\n \n if (allPricing[modelId]) {\n return allPricing[modelId];\n }\n\n return this.fuzzyMatchModel(modelId, allPricing);\n }\n\n\n private static fuzzyMatchModel(modelId: string, allPricing: Record<string, ModelPricing>): ModelPricing {\n const lowerModelId = modelId.toLowerCase();\n \n for (const [key, pricing] of Object.entries(allPricing)) {\n if (key.toLowerCase() === lowerModelId) {\n return pricing;\n }\n }\n const patterns = [\n { pattern: ['opus-4-1', 'claude-opus-4-1'], fallback: 'claude-opus-4-1-20250805' },\n { pattern: ['opus-4', 'claude-opus-4'], fallback: 'claude-opus-4-20250514' },\n { pattern: ['sonnet-4', 'claude-sonnet-4'], fallback: 'claude-sonnet-4-20250514' },\n { pattern: ['sonnet-3.7', '3-7-sonnet'], fallback: 'claude-3-7-sonnet-20250219' },\n { pattern: ['3-5-sonnet', 'sonnet-3.5'], fallback: 'claude-3-5-sonnet-20241022' },\n { pattern: ['3-5-haiku', 'haiku-3.5'], fallback: 'claude-3-5-haiku-20241022' },\n { pattern: ['haiku', '3-haiku'], fallback: 'claude-3-haiku-20240307' },\n { pattern: ['opus'], fallback: 'claude-opus-4-20250514' },\n { pattern: ['sonnet'], fallback: 'claude-3-5-sonnet-20241022' },\n ];\n\n for (const { pattern, fallback } of patterns) {\n if (pattern.some(p => lowerModelId.includes(p))) {\n if (allPricing[fallback]) {\n return allPricing[fallback];\n }\n }\n }\n\n return allPricing['claude-3-5-sonnet-20241022'] || {\n name: `${modelId} (Unknown Model)`,\n input: 3.00,\n cache_write_5m: 3.75,\n cache_write_1h: 6.00,\n cache_read: 0.30,\n output: 15.00\n };\n }\n\n static async calculateCostForEntry(entry: any): Promise<number> {\n const message = entry.message;\n const usage = message?.usage;\n if (!usage) return 0;\n\n const modelId = this.extractModelId(entry);\n const pricing = await this.getModelPricing(modelId);\n \n const inputTokens = usage.input_tokens || 0;\n const outputTokens = usage.output_tokens || 0;\n const cacheCreationTokens = usage.cache_creation_input_tokens || 0;\n const cacheReadTokens = usage.cache_read_input_tokens || 0;\n \n const inputCost = (inputTokens / 1_000_000) * pricing.input;\n const outputCost = (outputTokens / 1_000_000) * pricing.output;\n const cacheReadCost = (cacheReadTokens / 1_000_000) * pricing.cache_read;\n const cacheCreationCost = (cacheCreationTokens / 1_000_000) * pricing.cache_write_5m;\n \n return inputCost + outputCost + cacheCreationCost + cacheReadCost;\n }\n\n private static extractModelId(entry: any): string {\n if (entry.model && typeof entry.model === 'string') {\n return entry.model;\n }\n \n const message = entry.message;\n if (message?.model) {\n const model = message.model;\n if (typeof model === 'string') {\n return model;\n }\n return model?.id || 'claude-3-5-sonnet-20241022';\n }\n \n if (entry.model_id && typeof entry.model_id === 'string') {\n return entry.model_id;\n }\n \n return 'claude-3-5-sonnet-20241022';\n }\n}","import { readdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { debug } from \"./logger\";\n\nexport function getClaudePaths(): string[] {\n const paths: string[] = [];\n \n const homeDir = homedir();\n const defaultPath = join(homeDir, \".claude\");\n \n if (existsSync(defaultPath)) {\n paths.push(defaultPath);\n }\n \n return paths;\n}\n\nexport async function findProjectPaths(claudePaths: string[]): Promise<string[]> {\n const projectPaths: string[] = [];\n \n for (const claudePath of claudePaths) {\n const projectsDir = join(claudePath, \"projects\");\n \n if (existsSync(projectsDir)) {\n try {\n const entries = await readdir(projectsDir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isDirectory()) {\n const projectPath = join(projectsDir, entry.name);\n projectPaths.push(projectPath);\n }\n }\n } catch (error) {\n debug(`Failed to read projects directory ${projectsDir}:`, error);\n }\n }\n }\n \n return projectPaths;\n}\n\nexport async function findTranscriptFile(sessionId: string): Promise<string | null> {\n const claudePaths = getClaudePaths();\n const projectPaths = await findProjectPaths(claudePaths);\n \n for (const projectPath of projectPaths) {\n const transcriptPath = join(projectPath, `${sessionId}.jsonl`);\n if (existsSync(transcriptPath)) {\n return transcriptPath;\n }\n }\n \n return null;\n}","import { readFileSync } from \"node:fs\";\nimport { debug } from \"../utils/logger\";\n\nexport interface ContextInfo {\n inputTokens: number;\n percentage: number;\n usablePercentage: number;\n contextLeftPercentage: number;\n maxTokens: number;\n usableTokens: number;\n}\n\ninterface ContextUsageThresholds {\n LOW: number;\n MEDIUM: number;\n}\n\ninterface TranscriptEntry {\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n isSidechain?: boolean;\n timestamp?: string;\n}\n\nexport class ContextProvider {\n private readonly thresholds: ContextUsageThresholds = {\n LOW: 50,\n MEDIUM: 80,\n };\n\n getContextUsageThresholds(): ContextUsageThresholds {\n return this.thresholds;\n }\n\n private getContextLimit(_modelId: string): number {\n return 200000;\n }\n\n calculateContextTokens(\n transcriptPath: string,\n modelId?: string\n ): ContextInfo | null {\n try {\n debug(`Calculating context tokens from transcript: ${transcriptPath}`);\n\n const content = readFileSync(transcriptPath, \"utf-8\");\n if (!content) {\n debug(\"Transcript file is empty\");\n return null;\n }\n\n const lines = content.trim().split(\"\\n\");\n if (lines.length === 0) {\n debug(\"No lines in transcript\");\n return null;\n }\n\n let mostRecentEntry: TranscriptEntry | null = null;\n let mostRecentTime = 0;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n try {\n const entry: TranscriptEntry = JSON.parse(line);\n\n if (!entry.message?.usage?.input_tokens) continue;\n\n if (entry.isSidechain === true) continue;\n\n if (!entry.timestamp) continue;\n\n const entryTime = new Date(entry.timestamp).getTime();\n if (entryTime > mostRecentTime) {\n mostRecentTime = entryTime;\n mostRecentEntry = entry;\n }\n } catch {}\n }\n\n if (mostRecentEntry?.message?.usage) {\n const usage = mostRecentEntry.message.usage;\n const contextLength =\n (usage.input_tokens || 0) +\n (usage.cache_read_input_tokens || 0) +\n (usage.cache_creation_input_tokens || 0);\n\n const contextLimit = modelId ? this.getContextLimit(modelId) : 200000;\n\n debug(\n `Most recent main chain context: ${contextLength} tokens (limit: ${contextLimit})`\n );\n\n const percentage = Math.min(\n 100,\n Math.max(0, Math.round((contextLength / contextLimit) * 100))\n );\n\n const usableLimit = Math.round(contextLimit * 0.75);\n const usablePercentage = Math.min(\n 100,\n Math.max(0, Math.round((contextLength / usableLimit) * 100))\n );\n\n const contextLeftPercentage = Math.max(0, 100 - usablePercentage);\n\n return {\n inputTokens: contextLength,\n percentage,\n usablePercentage,\n contextLeftPercentage,\n maxTokens: contextLimit,\n usableTokens: usableLimit,\n };\n }\n\n debug(\"No main chain entries with usage data found\");\n return null;\n } catch (error) {\n debug(\n `Error reading transcript: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { debug } from \"../utils/logger\";\nimport { PricingService } from \"./pricing\";\nimport { findTranscriptFile } from \"../utils/claude\";\n\nexport interface MetricsInfo {\n responseTime: number | null;\n sessionDuration: number | null;\n messageCount: number | null;\n costBurnRate: number | null;\n tokenBurnRate: number | null;\n}\n\ninterface TranscriptEntry {\n timestamp: string;\n type?: string;\n message?: {\n role?: string;\n type?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n costUSD?: number;\n isSidechain?: boolean;\n}\n\nexport class MetricsProvider {\n private async loadTranscriptEntries(\n sessionId: string\n ): Promise<TranscriptEntry[]> {\n try {\n const transcriptPath = await findTranscriptFile(sessionId);\n if (!transcriptPath) {\n debug(`No transcript found for session: ${sessionId}`);\n return [];\n }\n\n debug(`Loading transcript from: ${transcriptPath}`);\n\n const content = await readFile(transcriptPath, \"utf-8\");\n const lines = content\n .trim()\n .split(\"\\n\")\n .filter((line) => line.trim());\n\n const entries: TranscriptEntry[] = [];\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n\n if (entry.isSidechain === true) {\n continue;\n }\n\n entries.push(entry);\n } catch (parseError) {\n debug(`Failed to parse JSONL line: ${parseError}`);\n continue;\n }\n }\n\n debug(`Loaded ${entries.length} transcript entries`);\n return entries;\n } catch (error) {\n debug(`Error loading transcript for ${sessionId}:`, error);\n return [];\n }\n }\n\n private calculateResponseTimes(entries: TranscriptEntry[]): number | null {\n const userMessages: Date[] = [];\n const assistantMessages: Date[] = [];\n\n for (const entry of entries) {\n if (!entry.timestamp) continue;\n\n try {\n const timestamp = new Date(entry.timestamp);\n\n const messageType =\n entry.type || entry.message?.role || entry.message?.type;\n\n if (messageType === \"user\" || messageType === \"human\") {\n userMessages.push(timestamp);\n debug(`Found user message at ${timestamp.toISOString()}`);\n } else if (messageType === \"assistant\" || messageType === \"ai\") {\n assistantMessages.push(timestamp);\n debug(`Found assistant message at ${timestamp.toISOString()}`);\n } else if (entry.message?.usage) {\n assistantMessages.push(timestamp);\n debug(\n `Found assistant message with usage at ${timestamp.toISOString()}`\n );\n } else {\n debug(\n `Unknown message type: ${messageType}, has usage: ${!!entry.message?.usage}`\n );\n }\n } catch {\n continue;\n }\n }\n\n if (userMessages.length === 0 || assistantMessages.length === 0) {\n return null;\n }\n\n const responseTimes: number[] = [];\n\n for (const assistantTime of assistantMessages) {\n const priorUsers = userMessages.filter(\n (userTime) => userTime < assistantTime\n );\n\n if (priorUsers.length > 0) {\n const userTime = new Date(\n Math.max(...priorUsers.map((d) => d.getTime()))\n );\n const responseTime =\n (assistantTime.getTime() - userTime.getTime()) / 1000;\n\n if (responseTime > 0.1 && responseTime < 300) {\n responseTimes.push(responseTime);\n debug(`Valid response time: ${responseTime.toFixed(1)}s`);\n } else {\n debug(\n `Rejected response time: ${responseTime.toFixed(1)}s (outside 0.1s-5m range)`\n );\n }\n }\n }\n\n if (responseTimes.length === 0) {\n return null;\n }\n\n const avgResponseTime =\n responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length;\n debug(\n `Calculated average response time: ${avgResponseTime.toFixed(2)}s from ${responseTimes.length} measurements`\n );\n debug(\n `Response times: [${responseTimes.map((t) => t.toFixed(1)).join(\", \")}]`\n );\n return avgResponseTime;\n }\n\n private calculateSessionDuration(entries: TranscriptEntry[]): number | null {\n const timestamps: Date[] = [];\n\n for (const entry of entries) {\n if (!entry.timestamp) continue;\n\n try {\n timestamps.push(new Date(entry.timestamp));\n } catch {\n continue;\n }\n }\n\n if (timestamps.length < 2) {\n return null;\n }\n\n timestamps.sort((a, b) => a.getTime() - b.getTime());\n\n const lastTimestamp = timestamps[timestamps.length - 1];\n const firstTimestamp = timestamps[0];\n\n if (!lastTimestamp || !firstTimestamp) {\n return null;\n }\n\n const duration =\n (lastTimestamp.getTime() - firstTimestamp.getTime()) / 1000;\n return duration > 0 ? duration : null;\n }\n\n private calculateBurnRateDuration(entries: TranscriptEntry[]): number | null {\n if (entries.length === 0) return null;\n\n const now = new Date();\n const timestamps = entries\n .map((entry) => entry.timestamp)\n .filter(Boolean)\n .map((ts) => new Date(ts))\n .filter((ts) => now.getTime() - ts.getTime() < 2 * 60 * 60 * 1000)\n .sort((a, b) => a.getTime() - b.getTime());\n\n if (timestamps.length === 0) return null;\n\n const sessionStart = timestamps[0];\n if (!sessionStart) return null;\n\n const durationFromStart = Math.max(\n (now.getTime() - sessionStart.getTime()) / 1000,\n 30 * 60\n );\n\n return durationFromStart;\n }\n\n private calculateMessageCount(entries: TranscriptEntry[]): number {\n return entries.filter((entry) => {\n const messageType =\n entry.type || entry.message?.role || entry.message?.type;\n return messageType === \"user\" || messageType === \"human\";\n }).length;\n }\n\n private async calculateTotalCost(\n entries: TranscriptEntry[]\n ): Promise<number> {\n let total = 0;\n const processedEntries = new Set<string>();\n\n for (const entry of entries) {\n const entryKey = `${entry.timestamp}-${JSON.stringify(entry.message?.usage || {})}`;\n\n if (processedEntries.has(entryKey)) {\n debug(`Skipping duplicate entry at ${entry.timestamp}`);\n continue;\n }\n processedEntries.add(entryKey);\n\n if (typeof entry.costUSD === \"number\") {\n total += entry.costUSD;\n } else if (entry.message?.usage) {\n const cost = await PricingService.calculateCostForEntry(entry);\n total += cost;\n }\n }\n\n return Math.round(total * 10000) / 10000;\n }\n\n private calculateTotalTokens(entries: TranscriptEntry[]): number {\n const processedEntries = new Set<string>();\n\n return entries.reduce((total, entry) => {\n const usage = entry.message?.usage;\n if (!usage) return total;\n\n const entryKey = `${entry.timestamp}-${JSON.stringify(usage)}`;\n\n if (processedEntries.has(entryKey)) {\n debug(`Skipping duplicate token entry at ${entry.timestamp}`);\n return total;\n }\n processedEntries.add(entryKey);\n\n return (\n total +\n (usage.input_tokens || 0) +\n (usage.output_tokens || 0) +\n (usage.cache_creation_input_tokens || 0) +\n (usage.cache_read_input_tokens || 0)\n );\n }, 0);\n }\n\n async getMetricsInfo(sessionId: string): Promise<MetricsInfo> {\n try {\n debug(`Starting metrics calculation for session: ${sessionId}`);\n\n const entries = await this.loadTranscriptEntries(sessionId);\n\n if (entries.length === 0) {\n return {\n responseTime: null,\n sessionDuration: null,\n messageCount: null,\n costBurnRate: null,\n tokenBurnRate: null,\n };\n }\n\n const responseTime = this.calculateResponseTimes(entries);\n const sessionDuration = this.calculateSessionDuration(entries);\n const messageCount = this.calculateMessageCount(entries);\n\n let costBurnRate: number | null = null;\n let tokenBurnRate: number | null = null;\n\n const burnRateDuration = this.calculateBurnRateDuration(entries);\n if (burnRateDuration && burnRateDuration > 60) {\n const hoursElapsed = burnRateDuration / 3600;\n\n if (hoursElapsed <= 0) {\n debug(`Invalid hours elapsed: ${hoursElapsed}`);\n } else {\n const totalCost = await this.calculateTotalCost(entries);\n const totalTokens = this.calculateTotalTokens(entries);\n\n if (totalCost > 0) {\n costBurnRate = Math.round((totalCost / hoursElapsed) * 100) / 100;\n debug(\n `Cost burn rate: $${costBurnRate}/h (total: $${totalCost}, duration: ${hoursElapsed}h)`\n );\n }\n\n if (totalTokens > 0) {\n tokenBurnRate = Math.round(totalTokens / hoursElapsed);\n debug(\n `Token burn rate: ${tokenBurnRate}/h (total: ${totalTokens}, duration: ${hoursElapsed}h)`\n );\n }\n }\n }\n\n debug(\n `Metrics calculated: responseTime=${responseTime?.toFixed(2) || \"null\"}s, sessionDuration=${sessionDuration?.toFixed(0) || \"null\"}s, messageCount=${messageCount}`\n );\n\n return {\n responseTime,\n sessionDuration,\n messageCount,\n costBurnRate,\n tokenBurnRate,\n };\n } catch (error) {\n debug(`Error calculating metrics for session ${sessionId}:`, error);\n return {\n responseTime: null,\n sessionDuration: null,\n messageCount: null,\n costBurnRate: null,\n tokenBurnRate: null,\n };\n }\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 \"$0.00\";\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 \"0 tokens\";\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 \"0 tokens\";\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","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 { ClaudeHookData } from \"../index\";\nimport type { PowerlineColors } from \"../themes\";\nimport type { PowerlineConfig } from \"../config/loader\";\n\nexport interface SegmentConfig {\n enabled: boolean;\n}\n\nexport interface GitSegmentConfig extends SegmentConfig {\n showSha: boolean;\n}\n\nexport interface UsageSegmentConfig extends SegmentConfig {\n type: \"cost\" | \"tokens\" | \"both\" | \"breakdown\";\n}\n\nexport interface TmuxSegmentConfig extends SegmentConfig {}\n\nexport interface ContextSegmentConfig extends SegmentConfig {}\n\nexport interface MetricsSegmentConfig extends SegmentConfig {\n showResponseTime?: boolean;\n showDuration?: boolean;\n showMessageCount?: boolean;\n showCostBurnRate?: boolean;\n showTokenBurnRate?: boolean;\n}\n\nexport type AnySegmentConfig =\n | SegmentConfig\n | GitSegmentConfig\n | UsageSegmentConfig\n | TmuxSegmentConfig\n | ContextSegmentConfig\n | MetricsSegmentConfig;\n\nimport {\n formatCost,\n formatTokens,\n formatTokenBreakdown,\n} from \"../utils/formatters\";\nimport { getBudgetStatus } from \"../utils/budget\";\nimport type {\n UsageInfo,\n TokenBreakdown,\n GitInfo,\n ContextInfo,\n MetricsInfo,\n} from \".\";\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 context_time: string;\n metrics_response: string;\n metrics_duration: string;\n metrics_messages: string;\n metrics_burn: 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(\n hookData: ClaudeHookData,\n colors: PowerlineColors\n ): 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: PowerlineColors,\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: PowerlineColors): 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(\n usageInfo: UsageInfo,\n colors: PowerlineColors,\n type = \"cost\"\n ): 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 renderTmux(\n sessionId: string | null,\n colors: PowerlineColors\n ): SegmentData | null {\n if (!sessionId) {\n return {\n text: `tmux:none`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n return {\n text: `tmux:${sessionId}`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n renderContext(\n contextInfo: ContextInfo | null,\n colors: PowerlineColors\n ): SegmentData | null {\n if (!contextInfo) {\n return {\n text: `${this.symbols.context_time} 0 (100%)`,\n bgColor: colors.contextBg,\n fgColor: colors.contextFg,\n };\n }\n\n const tokenDisplay = contextInfo.inputTokens.toLocaleString();\n\n const contextLeft = `${contextInfo.contextLeftPercentage}%`;\n\n return {\n text: `${this.symbols.context_time} ${tokenDisplay} (${contextLeft})`,\n bgColor: colors.contextBg,\n fgColor: colors.contextFg,\n };\n }\n\n renderMetrics(\n metricsInfo: MetricsInfo | null,\n colors: PowerlineColors,\n config?: MetricsSegmentConfig\n ): SegmentData | null {\n if (!metricsInfo) {\n return {\n text: `${this.symbols.metrics_response} new`,\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n const parts: string[] = [];\n\n if (\n config?.showResponseTime !== false &&\n metricsInfo.responseTime !== null\n ) {\n const responseTime =\n metricsInfo.responseTime < 60\n ? `${metricsInfo.responseTime.toFixed(1)}s`\n : `${(metricsInfo.responseTime / 60).toFixed(1)}m`;\n parts.push(`${this.symbols.metrics_response} ${responseTime}`);\n }\n\n if (\n config?.showDuration !== false &&\n metricsInfo.sessionDuration !== null\n ) {\n const duration = this.formatDuration(metricsInfo.sessionDuration);\n parts.push(`${this.symbols.metrics_duration} ${duration}`);\n }\n\n if (\n config?.showMessageCount !== false &&\n metricsInfo.messageCount !== null\n ) {\n parts.push(\n `${this.symbols.metrics_messages} ${metricsInfo.messageCount}`\n );\n }\n\n if (config?.showCostBurnRate && metricsInfo.costBurnRate !== null) {\n const burnRate =\n metricsInfo.costBurnRate < 1\n ? `${(metricsInfo.costBurnRate * 100).toFixed(0)}¢/h`\n : `$${metricsInfo.costBurnRate.toFixed(2)}/h`;\n parts.push(`${this.symbols.metrics_burn} ${burnRate}`);\n }\n\n if (config?.showTokenBurnRate && metricsInfo.tokenBurnRate !== null) {\n const tokenRate = formatTokens(Math.round(metricsInfo.tokenBurnRate));\n parts.push(`${this.symbols.metrics_burn} ${tokenRate}/h`);\n }\n\n if (parts.length === 0) {\n return {\n text: `${this.symbols.metrics_response} active`,\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n return {\n text: parts.join(\" \"),\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n private formatDuration(seconds: number): string {\n if (seconds < 60) {\n return `${seconds.toFixed(0)}s`;\n } else if (seconds < 3600) {\n return `${(seconds / 60).toFixed(0)}m`;\n } else if (seconds < 86400) {\n return `${(seconds / 3600).toFixed(1)}h`;\n } else {\n return `${(seconds / 86400).toFixed(1)}d`;\n }\n }\n\n private getDisplayDirectoryName(\n currentDir: string,\n projectDir?: string\n ): string {\n if (projectDir && projectDir !== currentDir) {\n if (currentDir.startsWith(projectDir)) {\n const relativePath = currentDir.slice(projectDir.length + 1);\n return relativePath || projectDir.split(\"/\").pop() || \"project\";\n }\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n private formatUsageDisplay(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: TokenBreakdown | null,\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: TokenBreakdown | null,\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","import type { ClaudeHookData } from \"./index\";\nimport type { PowerlineColors } from \"./themes\";\nimport type { PowerlineConfig, LineConfig } from \"./config/loader\";\nimport { hexToAnsi, extractBgToFg } from \"./utils/colors\";\nimport { getTheme } from \"./themes\";\nimport {\n UsageProvider,\n UsageInfo,\n ContextProvider,\n ContextInfo,\n GitService,\n TmuxService,\n MetricsProvider,\n MetricsInfo,\n SegmentRenderer,\n PowerlineSymbols,\n AnySegmentConfig,\n GitSegmentConfig,\n UsageSegmentConfig,\n MetricsSegmentConfig,\n} from \"./segments\";\n\nexport class PowerlineRenderer {\n private readonly symbols: PowerlineSymbols;\n private readonly usageProvider: UsageProvider;\n private readonly contextProvider: ContextProvider;\n private readonly gitService: GitService;\n private readonly tmuxService: TmuxService;\n private readonly metricsProvider: MetricsProvider;\n private readonly segmentRenderer: SegmentRenderer;\n\n constructor(private readonly config: PowerlineConfig) {\n this.symbols = this.initializeSymbols();\n this.usageProvider = new UsageProvider();\n this.contextProvider = new ContextProvider();\n this.gitService = new GitService();\n this.tmuxService = new TmuxService();\n this.metricsProvider = new MetricsProvider();\n this.segmentRenderer = new SegmentRenderer(config, this.symbols);\n }\n\n private needsUsageInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.session?.enabled\n );\n }\n\n private needsGitInfo(): boolean {\n return this.config.display.lines.some((line) => line.segments.git?.enabled);\n }\n\n private needsTmuxInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.tmux?.enabled\n );\n }\n\n private needsContextInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.context?.enabled\n );\n }\n\n private needsMetricsInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.metrics?.enabled\n );\n }\n\n async generateStatusline(hookData: ClaudeHookData): Promise<string> {\n const usageInfo = this.needsUsageInfo()\n ? await this.usageProvider.getUsageInfo(hookData.session_id)\n : null;\n\n const contextInfo = this.needsContextInfo()\n ? this.contextProvider.calculateContextTokens(\n hookData.transcript_path,\n hookData.model?.id\n )\n : null;\n\n const metricsInfo = this.needsMetricsInfo()\n ? await this.metricsProvider.getMetricsInfo(hookData.session_id)\n : null;\n\n const lines = this.config.display.lines\n .map((lineConfig) =>\n this.renderLine(\n lineConfig,\n hookData,\n usageInfo,\n contextInfo,\n metricsInfo\n )\n )\n .filter((line) => line.length > 0);\n\n return lines.join(\"\\n\");\n }\n\n private renderLine(\n lineConfig: LineConfig,\n hookData: ClaudeHookData,\n usageInfo: UsageInfo | null,\n contextInfo: ContextInfo | null,\n metricsInfo: MetricsInfo | null\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(\n ([_, config]: [string, AnySegmentConfig | undefined]) => config?.enabled\n )\n .map(([type, config]: [string, AnySegmentConfig]) => ({ 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 contextInfo,\n metricsInfo,\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: { type: string; config: AnySegmentConfig },\n hookData: ClaudeHookData,\n usageInfo: UsageInfo | null,\n contextInfo: ContextInfo | null,\n metricsInfo: MetricsInfo | null,\n colors: PowerlineColors,\n currentDir: string\n ) {\n switch (segment.type) {\n case \"directory\":\n return this.segmentRenderer.renderDirectory(hookData, colors);\n\n case \"git\":\n if (!this.needsGitInfo()) return null;\n const showSha = (segment.config as GitSegmentConfig)?.showSha || false;\n const gitInfo = this.gitService.getGitInfo(\n currentDir,\n showSha,\n hookData.workspace?.project_dir\n );\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 if (!usageInfo) return null;\n const usageType =\n (segment.config as UsageSegmentConfig)?.type || \"cost\";\n return this.segmentRenderer.renderSession(usageInfo, colors, usageType);\n\n case \"tmux\":\n if (!this.needsTmuxInfo()) return null;\n const tmuxSessionId = this.tmuxService.getSessionId();\n return this.segmentRenderer.renderTmux(tmuxSessionId, colors);\n\n case \"context\":\n if (!this.needsContextInfo()) return null;\n return this.segmentRenderer.renderContext(contextInfo, colors);\n\n case \"metrics\":\n const metricsConfig = segment.config as MetricsSegmentConfig;\n return this.segmentRenderer.renderMetrics(\n metricsInfo,\n colors,\n metricsConfig\n );\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: \"⊡\",\n context_time: \"◷\",\n metrics_response: \"⧖\",\n metrics_duration: \"⧗\",\n metrics_messages: \"⟐\",\n metrics_burn: \"⟢\",\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 tmuxBg: hexToAnsi(colorTheme.tmux.bg, true),\n tmuxFg: hexToAnsi(colorTheme.tmux.fg, false),\n contextBg: hexToAnsi(colorTheme.context.bg, true),\n contextFg: hexToAnsi(colorTheme.context.fg, false),\n metricsBg: hexToAnsi(colorTheme.metrics.bg, true),\n metricsFg: hexToAnsi(colorTheme.metrics.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 \"tmux\":\n return colors.tmuxBg;\n case \"context\":\n return colors.contextBg;\n case \"metrics\":\n return colors.metricsBg;\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 { DEFAULT_CONFIG } from \"./defaults\";\nimport type { ColorTheme } from \"../themes\";\nimport type {\n SegmentConfig,\n GitSegmentConfig,\n UsageSegmentConfig,\n TmuxSegmentConfig,\n ContextSegmentConfig,\n MetricsSegmentConfig,\n} from \"../segments/renderer\";\n\nexport interface LineConfig {\n segments: {\n directory?: SegmentConfig;\n git?: GitSegmentConfig;\n model?: SegmentConfig;\n session?: UsageSegmentConfig;\n tmux?: TmuxSegmentConfig;\n context?: ContextSegmentConfig;\n metrics?: MetricsSegmentConfig;\n };\n}\n\nexport interface DisplayConfig {\n lines: LineConfig[];\n style?: \"minimal\" | \"powerline\";\n}\n\nexport interface BudgetItemConfig {\n amount?: number;\n warningThreshold?: number;\n}\n\nexport interface BudgetConfig {\n session?: BudgetItemConfig;\n}\n\nexport interface PowerlineConfig {\n theme: \"light\" | \"dark\" | \"nord\" | \"tokyo-night\" | \"rose-pine\" | \"custom\";\n display: DisplayConfig;\n colors?: {\n custom: ColorTheme;\n };\n budget?: BudgetConfig;\n usageType?: \"cost\" | \"tokens\" | \"both\" | \"breakdown\";\n}\n\nexport interface ConfigLoadOptions {\n configPath?: string;\n ignoreEnvVars?: boolean;\n cliOverrides?: Partial<PowerlineConfig>;\n projectDir?: string;\n}\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 const sourceValue = source[key];\n if (sourceValue !== undefined) {\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue)\n ) {\n const targetValue = result[key] || {};\n result[key] = deepMerge(\n targetValue as Record<string, any>,\n sourceValue as Record<string, any>\n ) as T[Extract<keyof T, string>];\n } else if (Array.isArray(sourceValue) && sourceValue.length === 0) {\n const targetValue = result[key];\n if (!Array.isArray(targetValue) || targetValue.length > 0) {\n continue;\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\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 if (!config.display) {\n config.display = { lines: [] };\n }\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 if ([\"cost\", \"tokens\", \"both\", \"breakdown\"].includes(usageType)) {\n config.usageType = usageType;\n }\n }\n\n if (process.env.CLAUDE_POWERLINE_SESSION_BUDGET) {\n const sessionBudget = parseFloat(process.env.CLAUDE_POWERLINE_SESSION_BUDGET);\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\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 if (!config.display) {\n config.display = { lines: [] };\n }\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 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.usageType = usageType;\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 if (config.usageType) {\n config.display.lines.forEach((line) => {\n if (line.segments.session) {\n line.segments.session.type = config.usageType!;\n }\n });\n delete config.usageType;\n }\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 \"./loader\";\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 tmux: { enabled: false },\n context: { enabled: true },\n metrics: { enabled: false },\n },\n },\n ],\n },\n budget: {\n session: {\n warningThreshold: 80,\n },\n },\n};\n"],"mappings":"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","names":["process","path","fs","execSync","os","execSync","execSync","homedir","join","readFileSync","readFile","readFile","fs","path","fs","path","os","path","fs","execSync","process"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/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/segments/git.ts","../src/utils/logger.ts","../src/segments/tmux.ts","../src/segments/session.ts","../src/segments/pricing.ts","../src/utils/claude.ts","../src/segments/context.ts","../src/segments/metrics.ts","../src/utils/formatters.ts","../src/utils/budget.ts","../src/segments/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 { json } from \"node:stream/consumers\";\nimport { PowerlineRenderer } from \"./powerline\";\nimport { loadConfigFromCLI } from \"./config/loader\";\nimport { debug } from \"./utils/logger\";\nexport interface ClaudeHookData {\n hook_event_name: string;\n session_id: string;\n transcript_path: string;\n cwd: string;\n model: {\n id: string;\n display_name: string;\n };\n workspace: {\n current_dir: string;\n project_dir: string;\n };\n}\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 const cleanup = () => {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\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 cleanup();\n process.removeListener(\"SIGINT\", cleanup);\n process.removeListener(\"SIGTERM\", cleanup);\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\nStandalone Commands:\n --install-fonts Install powerline fonts to system\n -h, --help Show this help\n\nDebugging:\n CLAUDE_POWERLINE_DEBUG=1 Enable debug logging for troubleshooting\n\nClaude Code Options (for settings.json):\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 --config=PATH Use custom config file path\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 if (process.stdin.isTTY === true) {\n console.error(`Error: This tool requires input from Claude Code\n\nclaude-powerline is designed to be used as a Claude Code statusLine command.\nIt reads hook data from stdin and outputs formatted statusline.\n\nAdd to ~/.claude/settings.json:\n{\n \"statusLine\": {\n \"type\": \"command\",\n \"command\": \"claude-powerline --style=powerline\"\n }\n}\n\nRun with --help for more options.\n\nTo test output manually:\necho '{\"session_id\":\"test-session\",\"workspace\":{\"project_dir\":\"/path/to/project\"},\"model\":{\"id\":\"claude-3-5-sonnet\",\"display_name\":\"Claude\"}}' | claude-powerline --style=powerline`);\n process.exit(1);\n }\n\n debug(`Working directory: ${process.cwd()}`);\n debug(`Process args:`, process.argv);\n\n const hookData = (await json(process.stdin)) as ClaudeHookData;\n debug(`Received hook data:`, JSON.stringify(hookData, null, 2));\n\n if (!hookData) {\n console.error(\"Error: No input data received from stdin\");\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 --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 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 \"./index\";\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 tmux: { bg: \"#2f4f2f\", fg: \"#90ee90\" },\n context: { bg: \"#4a5568\", fg: \"#cbd5e0\" },\n metrics: { bg: \"#374151\", fg: \"#d1d5db\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#32cd32\", fg: \"#ffffff\" },\n context: { bg: \"#718096\", fg: \"#ffffff\" },\n metrics: { bg: \"#6b7280\", fg: \"#ffffff\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#2e3440\", fg: \"#8fbcbb\" },\n context: { bg: \"#5e81ac\", fg: \"#eceff4\" },\n metrics: { bg: \"#b48ead\", fg: \"#2e3440\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#191b29\", fg: \"#4fd6be\" },\n context: { bg: \"#414868\", fg: \"#c0caf5\" },\n metrics: { bg: \"#3d59a1\", fg: \"#c0caf5\" },\n};\n","import type { ColorTheme } from \"./index\";\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 tmux: { bg: \"#26233a\", fg: \"#908caa\" },\n context: { bg: \"#393552\", fg: \"#e0def4\" },\n metrics: { bg: \"#524f67\", fg: \"#e0def4\" },\n};\n","import { darkTheme } from \"./dark\";\nimport { lightTheme } from \"./light\";\nimport { nordTheme } from \"./nord\";\nimport { tokyoNightTheme } from \"./tokyo-night\";\nimport { rosePineTheme } from \"./rose-pine\";\n\nexport interface SegmentColor {\n bg: string;\n fg: string;\n}\n\nexport interface ColorTheme {\n directory: SegmentColor;\n git: SegmentColor;\n model: SegmentColor;\n session: SegmentColor;\n tmux: SegmentColor;\n context: SegmentColor;\n metrics: SegmentColor;\n}\n\nexport interface PowerlineColors {\n reset: string;\n modeBg: string;\n modeFg: string;\n gitBg: string;\n gitFg: string;\n modelBg: string;\n modelFg: string;\n sessionBg: string;\n sessionFg: string;\n tmuxBg: string;\n tmuxFg: string;\n contextBg: string;\n contextFg: string;\n metricsBg: string;\n metricsFg: string;\n}\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 { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { debug } from \"../utils/logger\";\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 private cache: Map<string, { data: GitInfo | null; timestamp: number }> =\n new Map();\n private readonly CACHE_TTL = 1000;\n\n private isGitRepo(workingDir: string): boolean {\n try {\n return fs.existsSync(path.join(workingDir, \".git\"));\n } catch {\n return false;\n }\n }\n\n getGitInfo(\n workingDir: string,\n showSha = false,\n projectDir?: string\n ): GitInfo | null {\n const gitDir =\n projectDir && this.isGitRepo(projectDir) ? projectDir : workingDir;\n\n const cacheKey = `${gitDir}:${showSha}`;\n const cached = this.cache.get(cacheKey);\n const now = Date.now();\n\n if (cached && now - cached.timestamp < this.CACHE_TTL) {\n return cached.data;\n }\n\n if (!this.isGitRepo(gitDir)) {\n const result = {\n branch: \"detached\",\n status: \"clean\" as const,\n ahead: 0,\n behind: 0,\n sha: undefined,\n };\n this.cache.set(cacheKey, { data: result, timestamp: now });\n return result;\n }\n\n try {\n const branch = this.getBranch(gitDir);\n const status = this.getStatus(gitDir);\n const { ahead, behind } = this.getAheadBehind(gitDir);\n const sha = showSha ? this.getSha(gitDir) || undefined : undefined;\n\n const result = {\n branch: branch || \"detached\",\n status,\n ahead,\n behind,\n sha,\n };\n\n this.cache.set(cacheKey, { data: result, timestamp: now });\n return result;\n } catch {\n this.cache.set(cacheKey, { data: null, timestamp: now });\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: 5000,\n }).trim() || null\n );\n } catch (error) {\n debug(`Git branch command failed in ${workingDir}:`, error);\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: 5000,\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 (error) {\n debug(`Git status command failed in ${workingDir}:`, error);\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: 5000,\n }).trim();\n\n const behindResult = execSync(\"git rev-list --count HEAD..@{u}\", {\n cwd: workingDir,\n encoding: \"utf8\",\n timeout: 5000,\n }).trim();\n\n return {\n ahead: parseInt(aheadResult) || 0,\n behind: parseInt(behindResult) || 0,\n };\n } catch (error) {\n debug(`Git ahead/behind command failed in ${workingDir}:`, error);\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: 5000,\n }).trim();\n\n return sha || null;\n } catch {\n return null;\n }\n }\n}\n","const debug = (message: string, ...args: any[]): void => {\n if (process.env.CLAUDE_POWERLINE_DEBUG) {\n console.error(`[DEBUG] ${message}`, ...args);\n }\n};\n\nexport { debug };\n","import { execSync } from \"node:child_process\";\nimport { debug } from \"../utils/logger\";\n\nexport class TmuxService {\n getSessionId(): string | null {\n try {\n if (!process.env.TMUX_PANE) {\n debug(`TMUX_PANE not set, not in tmux session`);\n return null;\n }\n\n debug(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);\n\n const sessionId = execSync(\"tmux display-message -p '#S'\", {\n encoding: \"utf8\",\n timeout: 1000,\n }).trim();\n\n debug(`Tmux session ID: ${sessionId || \"empty\"}`);\n\n return sessionId || null;\n } catch (error) {\n debug(`Error getting tmux session ID:`, error);\n return null;\n }\n }\n\n isInTmux(): boolean {\n return !!process.env.TMUX_PANE;\n }\n}","import { readFile } from \"node:fs/promises\";\nimport { debug } from \"../utils/logger\";\nimport { PricingService } from \"./pricing\";\nimport { findTranscriptFile } from \"../utils/claude\";\n\nexport interface SessionUsageEntry {\n timestamp: string;\n message: {\n usage: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n costUSD?: number;\n}\n\nexport interface SessionUsage {\n totalCost: number;\n entries: SessionUsageEntry[];\n}\n\nexport interface TokenBreakdown {\n input: number;\n output: number;\n cacheCreation: number;\n cacheRead: number;\n}\n\nexport interface SessionInfo {\n cost: number | null;\n tokens: number | null;\n tokenBreakdown: TokenBreakdown | null;\n}\n\nexport interface UsageInfo {\n session: SessionInfo;\n}\n\nexport class SessionProvider {\n\n async getSessionUsage(sessionId: string): Promise<SessionUsage | null> {\n try {\n const transcriptPath = await findTranscriptFile(sessionId);\n if (!transcriptPath) {\n debug(`No transcript found for session: ${sessionId}`);\n return null;\n }\n\n debug(`Found transcript at: ${transcriptPath}`);\n \n const content = await readFile(transcriptPath, 'utf-8');\n const lines = content.trim().split('\\n').filter(line => line.trim());\n \n if (lines.length === 0) {\n return { totalCost: 0, entries: [] };\n }\n\n const entries: SessionUsageEntry[] = [];\n let totalCost = 0;\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as Record<string, unknown>;\n \n if (entry.message && typeof entry.message === 'object') {\n const message = entry.message as Record<string, unknown>;\n if (message.usage && typeof message.usage === 'object') {\n const sessionEntry: SessionUsageEntry = {\n timestamp: (entry.timestamp as string) || new Date().toISOString(),\n message: {\n usage: message.usage as SessionUsageEntry['message']['usage']\n }\n };\n\n if (typeof entry.costUSD === 'number') {\n sessionEntry.costUSD = entry.costUSD;\n totalCost += entry.costUSD;\n } else {\n const cost = await PricingService.calculateCostForEntry(entry);\n sessionEntry.costUSD = cost;\n totalCost += cost;\n }\n\n entries.push(sessionEntry);\n }\n }\n } catch (parseError) {\n debug(`Failed to parse JSONL line: ${parseError}`);\n continue;\n }\n }\n\n debug(`Parsed ${entries.length} usage entries, total cost: $${totalCost.toFixed(4)}`);\n return { totalCost, entries };\n\n } catch (error) {\n debug(`Error reading session usage for ${sessionId}:`, error);\n return null;\n }\n }\n\n calculateTokenBreakdown(entries: SessionUsageEntry[]): TokenBreakdown {\n return entries.reduce(\n (breakdown, entry) => ({\n input: breakdown.input + (entry.message.usage.input_tokens || 0),\n output: breakdown.output + (entry.message.usage.output_tokens || 0),\n cacheCreation: breakdown.cacheCreation + (entry.message.usage.cache_creation_input_tokens || 0),\n cacheRead: breakdown.cacheRead + (entry.message.usage.cache_read_input_tokens || 0),\n }),\n { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 }\n );\n }\n\n async getSessionInfo(sessionId: string): Promise<SessionInfo> {\n const sessionUsage = await this.getSessionUsage(sessionId);\n \n if (!sessionUsage || sessionUsage.entries.length === 0) {\n return { cost: null, tokens: null, tokenBreakdown: null };\n }\n\n const tokenBreakdown = this.calculateTokenBreakdown(sessionUsage.entries);\n const totalTokens = tokenBreakdown.input + tokenBreakdown.output + \n tokenBreakdown.cacheCreation + tokenBreakdown.cacheRead;\n\n return {\n cost: sessionUsage.totalCost,\n tokens: totalTokens,\n tokenBreakdown,\n };\n }\n}\n\nexport class UsageProvider {\n private sessionProvider = new SessionProvider();\n\n async getUsageInfo(sessionId: string): Promise<UsageInfo> {\n try {\n debug(`Starting usage info retrieval for session: ${sessionId}`);\n \n const sessionInfo = await this.sessionProvider.getSessionInfo(sessionId);\n \n return {\n session: sessionInfo,\n };\n } catch (error) {\n debug(`Error getting usage info for session ${sessionId}:`, error);\n return {\n session: { cost: null, tokens: null, tokenBreakdown: null },\n };\n }\n }\n}","import { debug } from \"../utils/logger\";\n\nexport interface ModelPricing {\n name: string;\n input: number;\n cache_write_5m: number;\n cache_write_1h: number;\n cache_read: number;\n output: number;\n}\nconst OFFLINE_PRICING_DATA: Record<string, ModelPricing> = {\n \"claude-3-haiku-20240307\": {\n name: \"Claude 3 Haiku\",\n input: 0.25,\n output: 1.25,\n cache_write_5m: 0.3,\n cache_write_1h: 0.5,\n cache_read: 0.03,\n },\n \"claude-3-5-haiku-20241022\": {\n name: \"Claude 3.5 Haiku\",\n input: 0.8,\n output: 4.0,\n cache_write_5m: 1.0,\n cache_write_1h: 1.6,\n cache_read: 0.08,\n },\n \"claude-3-5-haiku-latest\": {\n name: \"Claude 3.5 Haiku Latest\",\n input: 1.0,\n output: 5.0,\n cache_write_5m: 1.25,\n cache_write_1h: 2.0,\n cache_read: 0.1,\n },\n \"claude-3-opus-latest\": {\n name: \"Claude 3 Opus Latest\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-3-opus-20240229\": {\n name: \"Claude 3 Opus\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-3-5-sonnet-latest\": {\n name: \"Claude 3.5 Sonnet Latest\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-3-5-sonnet-20240620\": {\n name: \"Claude 3.5 Sonnet\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-3-5-sonnet-20241022\": {\n name: \"Claude 3.5 Sonnet\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-opus-4-20250514\": {\n name: \"Claude Opus 4\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-opus-4-1\": {\n name: \"Claude Opus 4.1\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-opus-4-1-20250805\": {\n name: \"Claude Opus 4.1\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-sonnet-4-20250514\": {\n name: \"Claude Sonnet 4\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-4-opus-20250514\": {\n name: \"Claude 4 Opus\",\n input: 15.0,\n output: 75.0,\n cache_write_5m: 18.75,\n cache_write_1h: 30.0,\n cache_read: 1.5,\n },\n \"claude-4-sonnet-20250514\": {\n name: \"Claude 4 Sonnet\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-3-7-sonnet-latest\": {\n name: \"Claude 3.7 Sonnet Latest\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n \"claude-3-7-sonnet-20250219\": {\n name: \"Claude 3.7 Sonnet\",\n input: 3.0,\n output: 15.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n },\n};\n\nexport class PricingService {\n private static memoryCache: Map<\n string,\n { data: Record<string, ModelPricing>; timestamp: number }\n > = new Map();\n private static readonly CACHE_TTL = 24 * 60 * 60 * 1000;\n private static readonly GITHUB_PRICING_URL =\n \"https://raw.githubusercontent.com/Owloops/claude-powerline/main/pricing.json\";\n\n private static getCacheFilePath(): string {\n const { homedir } = require(\"os\");\n const { join } = require(\"path\");\n const { mkdirSync } = require(\"fs\");\n\n const cacheDir = join(homedir(), \".claude\", \"cache\");\n try {\n mkdirSync(cacheDir, { recursive: true });\n } catch {}\n\n return join(cacheDir, \"pricing.json\");\n }\n\n private static loadDiskCache(): {\n data: Record<string, ModelPricing>;\n timestamp: number;\n } | null {\n try {\n const { readFileSync } = require(\"fs\");\n const cacheFile = this.getCacheFilePath();\n const content = readFileSync(cacheFile, \"utf-8\");\n const cached = JSON.parse(content);\n\n if (cached && cached.data && cached.timestamp) {\n return cached;\n }\n } catch {}\n return null;\n }\n\n private static saveDiskCache(data: Record<string, ModelPricing>): void {\n try {\n const { writeFileSync } = require(\"fs\");\n const cacheFile = this.getCacheFilePath();\n const cacheData = { data, timestamp: Date.now() };\n writeFileSync(cacheFile, JSON.stringify(cacheData));\n } catch (error) {\n debug(\"Failed to save pricing cache to disk:\", error);\n }\n }\n\n static async getCurrentPricing(): Promise<Record<string, ModelPricing>> {\n const now = Date.now();\n\n const memCached = this.memoryCache.get(\"pricing\");\n if (memCached && now - memCached.timestamp < this.CACHE_TTL) {\n debug(\n `Using memory cached pricing data for ${Object.keys(memCached.data).length} models`\n );\n return memCached.data;\n }\n\n const diskCached = this.loadDiskCache();\n if (diskCached && now - diskCached.timestamp < this.CACHE_TTL) {\n this.memoryCache.clear();\n this.memoryCache.set(\"pricing\", diskCached);\n debug(\n `Using disk cached pricing data for ${Object.keys(diskCached.data).length} models`\n );\n return diskCached.data;\n }\n\n try {\n const response = await globalThis.fetch(this.GITHUB_PRICING_URL, {\n headers: {\n \"User-Agent\": \"claude-powerline\",\n \"Cache-Control\": \"no-cache\",\n },\n });\n\n if (response.ok) {\n const data = await response.json();\n\n const dataObj = data as Record<string, unknown>;\n const meta = dataObj._meta as { updated?: string } | undefined;\n\n const pricingData: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(dataObj)) {\n if (key !== \"_meta\") {\n pricingData[key] = value;\n }\n }\n\n if (this.validatePricingData(pricingData)) {\n this.memoryCache.clear();\n this.memoryCache.set(\"pricing\", {\n data: pricingData,\n timestamp: now,\n });\n this.saveDiskCache(pricingData);\n debug(\n `Fetched fresh pricing from GitHub for ${Object.keys(pricingData).length} models`\n );\n debug(`Pricing last updated: ${meta?.updated || \"unknown\"}`);\n return pricingData;\n }\n }\n } catch (error) {\n debug(\"Failed to fetch pricing from GitHub, using fallback:\", error);\n }\n\n if (diskCached) {\n this.memoryCache.set(\"pricing\", diskCached);\n debug(\n `Using stale cached pricing data for ${Object.keys(diskCached.data).length} models`\n );\n return diskCached.data;\n }\n\n debug(\n `Using offline pricing data for ${Object.keys(OFFLINE_PRICING_DATA).length} models`\n );\n return OFFLINE_PRICING_DATA;\n }\n\n private static validatePricingData(\n data: unknown\n ): data is Record<string, ModelPricing> {\n if (!data || typeof data !== \"object\") return false;\n\n for (const [, value] of Object.entries(data)) {\n if (!value || typeof value !== \"object\") return false;\n const pricing = value as Record<string, unknown>;\n\n if (\n typeof pricing.input !== \"number\" ||\n typeof pricing.output !== \"number\" ||\n typeof pricing.cache_read !== \"number\"\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n static async getModelPricing(modelId: string): Promise<ModelPricing> {\n const allPricing = await this.getCurrentPricing();\n\n if (allPricing[modelId]) {\n return allPricing[modelId];\n }\n\n return this.fuzzyMatchModel(modelId, allPricing);\n }\n\n private static fuzzyMatchModel(\n modelId: string,\n allPricing: Record<string, ModelPricing>\n ): ModelPricing {\n const lowerModelId = modelId.toLowerCase();\n\n for (const [key, pricing] of Object.entries(allPricing)) {\n if (key.toLowerCase() === lowerModelId) {\n return pricing;\n }\n }\n const patterns = [\n {\n pattern: [\"opus-4-1\", \"claude-opus-4-1\"],\n fallback: \"claude-opus-4-1-20250805\",\n },\n {\n pattern: [\"opus-4\", \"claude-opus-4\"],\n fallback: \"claude-opus-4-20250514\",\n },\n {\n pattern: [\"sonnet-4\", \"claude-sonnet-4\"],\n fallback: \"claude-sonnet-4-20250514\",\n },\n {\n pattern: [\"sonnet-3.7\", \"3-7-sonnet\"],\n fallback: \"claude-3-7-sonnet-20250219\",\n },\n {\n pattern: [\"3-5-sonnet\", \"sonnet-3.5\"],\n fallback: \"claude-3-5-sonnet-20241022\",\n },\n {\n pattern: [\"3-5-haiku\", \"haiku-3.5\"],\n fallback: \"claude-3-5-haiku-20241022\",\n },\n { pattern: [\"haiku\", \"3-haiku\"], fallback: \"claude-3-haiku-20240307\" },\n { pattern: [\"opus\"], fallback: \"claude-opus-4-20250514\" },\n { pattern: [\"sonnet\"], fallback: \"claude-3-5-sonnet-20241022\" },\n ];\n\n for (const { pattern, fallback } of patterns) {\n if (pattern.some((p) => lowerModelId.includes(p))) {\n if (allPricing[fallback]) {\n return allPricing[fallback];\n }\n }\n }\n\n return (\n allPricing[\"claude-3-5-sonnet-20241022\"] || {\n name: `${modelId} (Unknown Model)`,\n input: 3.0,\n cache_write_5m: 3.75,\n cache_write_1h: 6.0,\n cache_read: 0.3,\n output: 15.0,\n }\n );\n }\n\n static async calculateCostForEntry(entry: any): Promise<number> {\n const message = entry.message;\n const usage = message?.usage;\n if (!usage) return 0;\n\n const modelId = this.extractModelId(entry);\n const pricing = await this.getModelPricing(modelId);\n\n const inputTokens = usage.input_tokens || 0;\n const outputTokens = usage.output_tokens || 0;\n const cacheCreationTokens = usage.cache_creation_input_tokens || 0;\n const cacheReadTokens = usage.cache_read_input_tokens || 0;\n\n const inputCost = (inputTokens / 1_000_000) * pricing.input;\n const outputCost = (outputTokens / 1_000_000) * pricing.output;\n const cacheReadCost = (cacheReadTokens / 1_000_000) * pricing.cache_read;\n const cacheCreationCost =\n (cacheCreationTokens / 1_000_000) * pricing.cache_write_5m;\n\n return inputCost + outputCost + cacheCreationCost + cacheReadCost;\n }\n\n private static extractModelId(entry: any): string {\n if (entry.model && typeof entry.model === \"string\") {\n return entry.model;\n }\n\n const message = entry.message;\n if (message?.model) {\n const model = message.model;\n if (typeof model === \"string\") {\n return model;\n }\n return model?.id || \"claude-3-5-sonnet-20241022\";\n }\n\n if (entry.model_id && typeof entry.model_id === \"string\") {\n return entry.model_id;\n }\n\n return \"claude-3-5-sonnet-20241022\";\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { debug } from \"./logger\";\n\nexport function getClaudePaths(): string[] {\n const paths: string[] = [];\n \n const homeDir = homedir();\n const defaultPath = join(homeDir, \".claude\");\n \n if (existsSync(defaultPath)) {\n paths.push(defaultPath);\n }\n \n return paths;\n}\n\nexport async function findProjectPaths(claudePaths: string[]): Promise<string[]> {\n const projectPaths: string[] = [];\n \n for (const claudePath of claudePaths) {\n const projectsDir = join(claudePath, \"projects\");\n \n if (existsSync(projectsDir)) {\n try {\n const entries = await readdir(projectsDir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (entry.isDirectory()) {\n const projectPath = join(projectsDir, entry.name);\n projectPaths.push(projectPath);\n }\n }\n } catch (error) {\n debug(`Failed to read projects directory ${projectsDir}:`, error);\n }\n }\n }\n \n return projectPaths;\n}\n\nexport async function findTranscriptFile(sessionId: string): Promise<string | null> {\n const claudePaths = getClaudePaths();\n const projectPaths = await findProjectPaths(claudePaths);\n \n for (const projectPath of projectPaths) {\n const transcriptPath = join(projectPath, `${sessionId}.jsonl`);\n if (existsSync(transcriptPath)) {\n return transcriptPath;\n }\n }\n \n return null;\n}","import { readFileSync } from \"node:fs\";\nimport { debug } from \"../utils/logger\";\n\nexport interface ContextInfo {\n inputTokens: number;\n percentage: number;\n usablePercentage: number;\n contextLeftPercentage: number;\n maxTokens: number;\n usableTokens: number;\n}\n\ninterface ContextUsageThresholds {\n LOW: number;\n MEDIUM: number;\n}\n\ninterface TranscriptEntry {\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n isSidechain?: boolean;\n timestamp?: string;\n}\n\nexport class ContextProvider {\n private readonly thresholds: ContextUsageThresholds = {\n LOW: 50,\n MEDIUM: 80,\n };\n\n getContextUsageThresholds(): ContextUsageThresholds {\n return this.thresholds;\n }\n\n private getContextLimit(_modelId: string): number {\n return 200000;\n }\n\n calculateContextTokens(\n transcriptPath: string,\n modelId?: string\n ): ContextInfo | null {\n try {\n debug(`Calculating context tokens from transcript: ${transcriptPath}`);\n\n const content = readFileSync(transcriptPath, \"utf-8\");\n if (!content) {\n debug(\"Transcript file is empty\");\n return null;\n }\n\n const lines = content.trim().split(\"\\n\");\n if (lines.length === 0) {\n debug(\"No lines in transcript\");\n return null;\n }\n\n let mostRecentEntry: TranscriptEntry | null = null;\n let mostRecentTime = 0;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n try {\n const entry: TranscriptEntry = JSON.parse(line);\n\n if (!entry.message?.usage?.input_tokens) continue;\n\n if (entry.isSidechain === true) continue;\n\n if (!entry.timestamp) continue;\n\n const entryTime = new Date(entry.timestamp).getTime();\n if (entryTime > mostRecentTime) {\n mostRecentTime = entryTime;\n mostRecentEntry = entry;\n }\n } catch {}\n }\n\n if (mostRecentEntry?.message?.usage) {\n const usage = mostRecentEntry.message.usage;\n const contextLength =\n (usage.input_tokens || 0) +\n (usage.cache_read_input_tokens || 0) +\n (usage.cache_creation_input_tokens || 0);\n\n const contextLimit = modelId ? this.getContextLimit(modelId) : 200000;\n\n debug(\n `Most recent main chain context: ${contextLength} tokens (limit: ${contextLimit})`\n );\n\n const percentage = Math.min(\n 100,\n Math.max(0, Math.round((contextLength / contextLimit) * 100))\n );\n\n const usableLimit = Math.round(contextLimit * 0.75);\n const usablePercentage = Math.min(\n 100,\n Math.max(0, Math.round((contextLength / usableLimit) * 100))\n );\n\n const contextLeftPercentage = Math.max(0, 100 - usablePercentage);\n\n return {\n inputTokens: contextLength,\n percentage,\n usablePercentage,\n contextLeftPercentage,\n maxTokens: contextLimit,\n usableTokens: usableLimit,\n };\n }\n\n debug(\"No main chain entries with usage data found\");\n return null;\n } catch (error) {\n debug(\n `Error reading transcript: ${error instanceof Error ? error.message : String(error)}`\n );\n return null;\n }\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { debug } from \"../utils/logger\";\nimport { PricingService } from \"./pricing\";\nimport { findTranscriptFile } from \"../utils/claude\";\n\nexport interface MetricsInfo {\n responseTime: number | null;\n sessionDuration: number | null;\n messageCount: number | null;\n costBurnRate: number | null;\n tokenBurnRate: number | null;\n}\n\ninterface TranscriptEntry {\n timestamp: string;\n type?: string;\n message?: {\n role?: string;\n type?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n costUSD?: number;\n isSidechain?: boolean;\n}\n\nexport class MetricsProvider {\n private async loadTranscriptEntries(\n sessionId: string\n ): Promise<TranscriptEntry[]> {\n try {\n const transcriptPath = await findTranscriptFile(sessionId);\n if (!transcriptPath) {\n debug(`No transcript found for session: ${sessionId}`);\n return [];\n }\n\n debug(`Loading transcript from: ${transcriptPath}`);\n\n const content = await readFile(transcriptPath, \"utf-8\");\n const lines = content\n .trim()\n .split(\"\\n\")\n .filter((line) => line.trim());\n\n const entries: TranscriptEntry[] = [];\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as TranscriptEntry;\n\n if (entry.isSidechain === true) {\n continue;\n }\n\n entries.push(entry);\n } catch (parseError) {\n debug(`Failed to parse JSONL line: ${parseError}`);\n continue;\n }\n }\n\n debug(`Loaded ${entries.length} transcript entries`);\n return entries;\n } catch (error) {\n debug(`Error loading transcript for ${sessionId}:`, error);\n return [];\n }\n }\n\n private calculateResponseTimes(entries: TranscriptEntry[]): number | null {\n const userMessages: Date[] = [];\n const assistantMessages: Date[] = [];\n\n for (const entry of entries) {\n if (!entry.timestamp) continue;\n\n try {\n const timestamp = new Date(entry.timestamp);\n\n const messageType =\n entry.type || entry.message?.role || entry.message?.type;\n\n if (messageType === \"user\" || messageType === \"human\") {\n userMessages.push(timestamp);\n debug(`Found user message at ${timestamp.toISOString()}`);\n } else if (messageType === \"assistant\" || messageType === \"ai\") {\n assistantMessages.push(timestamp);\n debug(`Found assistant message at ${timestamp.toISOString()}`);\n } else if (entry.message?.usage) {\n assistantMessages.push(timestamp);\n debug(\n `Found assistant message with usage at ${timestamp.toISOString()}`\n );\n } else {\n debug(\n `Unknown message type: ${messageType}, has usage: ${!!entry.message?.usage}`\n );\n }\n } catch {\n continue;\n }\n }\n\n if (userMessages.length === 0 || assistantMessages.length === 0) {\n return null;\n }\n\n const responseTimes: number[] = [];\n\n for (const assistantTime of assistantMessages) {\n const priorUsers = userMessages.filter(\n (userTime) => userTime < assistantTime\n );\n\n if (priorUsers.length > 0) {\n const userTime = new Date(\n Math.max(...priorUsers.map((d) => d.getTime()))\n );\n const responseTime =\n (assistantTime.getTime() - userTime.getTime()) / 1000;\n\n if (responseTime > 0.1 && responseTime < 300) {\n responseTimes.push(responseTime);\n debug(`Valid response time: ${responseTime.toFixed(1)}s`);\n } else {\n debug(\n `Rejected response time: ${responseTime.toFixed(1)}s (outside 0.1s-5m range)`\n );\n }\n }\n }\n\n if (responseTimes.length === 0) {\n return null;\n }\n\n const avgResponseTime =\n responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length;\n debug(\n `Calculated average response time: ${avgResponseTime.toFixed(2)}s from ${responseTimes.length} measurements`\n );\n debug(\n `Response times: [${responseTimes.map((t) => t.toFixed(1)).join(\", \")}]`\n );\n return avgResponseTime;\n }\n\n private calculateSessionDuration(entries: TranscriptEntry[]): number | null {\n const timestamps: Date[] = [];\n\n for (const entry of entries) {\n if (!entry.timestamp) continue;\n\n try {\n timestamps.push(new Date(entry.timestamp));\n } catch {\n continue;\n }\n }\n\n if (timestamps.length < 2) {\n return null;\n }\n\n timestamps.sort((a, b) => a.getTime() - b.getTime());\n\n const lastTimestamp = timestamps[timestamps.length - 1];\n const firstTimestamp = timestamps[0];\n\n if (!lastTimestamp || !firstTimestamp) {\n return null;\n }\n\n const duration =\n (lastTimestamp.getTime() - firstTimestamp.getTime()) / 1000;\n return duration > 0 ? duration : null;\n }\n\n private calculateBurnRateDuration(entries: TranscriptEntry[]): number | null {\n if (entries.length === 0) return null;\n\n const now = new Date();\n const timestamps = entries\n .map((entry) => entry.timestamp)\n .filter(Boolean)\n .map((ts) => new Date(ts))\n .filter((ts) => now.getTime() - ts.getTime() < 2 * 60 * 60 * 1000)\n .sort((a, b) => a.getTime() - b.getTime());\n\n if (timestamps.length === 0) return null;\n\n const sessionStart = timestamps[0];\n if (!sessionStart) return null;\n\n const durationFromStart = Math.max(\n (now.getTime() - sessionStart.getTime()) / 1000,\n 30 * 60\n );\n\n return durationFromStart;\n }\n\n private calculateMessageCount(entries: TranscriptEntry[]): number {\n return entries.filter((entry) => {\n const messageType =\n entry.type || entry.message?.role || entry.message?.type;\n return messageType === \"user\" || messageType === \"human\";\n }).length;\n }\n\n private async calculateTotalCost(\n entries: TranscriptEntry[]\n ): Promise<number> {\n let total = 0;\n const processedEntries = new Set<string>();\n\n for (const entry of entries) {\n const entryKey = `${entry.timestamp}-${JSON.stringify(entry.message?.usage || {})}`;\n\n if (processedEntries.has(entryKey)) {\n debug(`Skipping duplicate entry at ${entry.timestamp}`);\n continue;\n }\n processedEntries.add(entryKey);\n\n if (typeof entry.costUSD === \"number\") {\n total += entry.costUSD;\n } else if (entry.message?.usage) {\n const cost = await PricingService.calculateCostForEntry(entry);\n total += cost;\n }\n }\n\n return Math.round(total * 10000) / 10000;\n }\n\n private calculateTotalTokens(entries: TranscriptEntry[]): number {\n const processedEntries = new Set<string>();\n\n return entries.reduce((total, entry) => {\n const usage = entry.message?.usage;\n if (!usage) return total;\n\n const entryKey = `${entry.timestamp}-${JSON.stringify(usage)}`;\n\n if (processedEntries.has(entryKey)) {\n debug(`Skipping duplicate token entry at ${entry.timestamp}`);\n return total;\n }\n processedEntries.add(entryKey);\n\n return (\n total +\n (usage.input_tokens || 0) +\n (usage.output_tokens || 0) +\n (usage.cache_creation_input_tokens || 0) +\n (usage.cache_read_input_tokens || 0)\n );\n }, 0);\n }\n\n async getMetricsInfo(sessionId: string): Promise<MetricsInfo> {\n try {\n debug(`Starting metrics calculation for session: ${sessionId}`);\n\n const entries = await this.loadTranscriptEntries(sessionId);\n\n if (entries.length === 0) {\n return {\n responseTime: null,\n sessionDuration: null,\n messageCount: null,\n costBurnRate: null,\n tokenBurnRate: null,\n };\n }\n\n const responseTime = this.calculateResponseTimes(entries);\n const sessionDuration = this.calculateSessionDuration(entries);\n const messageCount = this.calculateMessageCount(entries);\n\n let costBurnRate: number | null = null;\n let tokenBurnRate: number | null = null;\n\n const burnRateDuration = this.calculateBurnRateDuration(entries);\n if (burnRateDuration && burnRateDuration > 60) {\n const hoursElapsed = burnRateDuration / 3600;\n\n if (hoursElapsed <= 0) {\n debug(`Invalid hours elapsed: ${hoursElapsed}`);\n } else {\n const totalCost = await this.calculateTotalCost(entries);\n const totalTokens = this.calculateTotalTokens(entries);\n\n if (totalCost > 0) {\n costBurnRate = Math.round((totalCost / hoursElapsed) * 100) / 100;\n debug(\n `Cost burn rate: $${costBurnRate}/h (total: $${totalCost}, duration: ${hoursElapsed}h)`\n );\n }\n\n if (totalTokens > 0) {\n tokenBurnRate = Math.round(totalTokens / hoursElapsed);\n debug(\n `Token burn rate: ${tokenBurnRate}/h (total: ${totalTokens}, duration: ${hoursElapsed}h)`\n );\n }\n }\n }\n\n debug(\n `Metrics calculated: responseTime=${responseTime?.toFixed(2) || \"null\"}s, sessionDuration=${sessionDuration?.toFixed(0) || \"null\"}s, messageCount=${messageCount}`\n );\n\n return {\n responseTime,\n sessionDuration,\n messageCount,\n costBurnRate,\n tokenBurnRate,\n };\n } catch (error) {\n debug(`Error calculating metrics for session ${sessionId}:`, error);\n return {\n responseTime: null,\n sessionDuration: null,\n messageCount: null,\n costBurnRate: null,\n tokenBurnRate: null,\n };\n }\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 \"$0.00\";\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 \"0 tokens\";\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 \"0 tokens\";\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","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 { ClaudeHookData } from \"../index\";\nimport type { PowerlineColors } from \"../themes\";\nimport type { PowerlineConfig } from \"../config/loader\";\n\nexport interface SegmentConfig {\n enabled: boolean;\n}\n\nexport interface GitSegmentConfig extends SegmentConfig {\n showSha: boolean;\n}\n\nexport interface UsageSegmentConfig extends SegmentConfig {\n type: \"cost\" | \"tokens\" | \"both\" | \"breakdown\";\n}\n\nexport interface TmuxSegmentConfig extends SegmentConfig {}\n\nexport interface ContextSegmentConfig extends SegmentConfig {}\n\nexport interface MetricsSegmentConfig extends SegmentConfig {\n showResponseTime?: boolean;\n showDuration?: boolean;\n showMessageCount?: boolean;\n showCostBurnRate?: boolean;\n showTokenBurnRate?: boolean;\n}\n\nexport type AnySegmentConfig =\n | SegmentConfig\n | GitSegmentConfig\n | UsageSegmentConfig\n | TmuxSegmentConfig\n | ContextSegmentConfig\n | MetricsSegmentConfig;\n\nimport {\n formatCost,\n formatTokens,\n formatTokenBreakdown,\n} from \"../utils/formatters\";\nimport { getBudgetStatus } from \"../utils/budget\";\nimport type {\n UsageInfo,\n TokenBreakdown,\n GitInfo,\n ContextInfo,\n MetricsInfo,\n} from \".\";\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 context_time: string;\n metrics_response: string;\n metrics_duration: string;\n metrics_messages: string;\n metrics_burn: 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(\n hookData: ClaudeHookData,\n colors: PowerlineColors\n ): 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: PowerlineColors,\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: PowerlineColors): 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(\n usageInfo: UsageInfo,\n colors: PowerlineColors,\n type = \"cost\"\n ): 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 renderTmux(\n sessionId: string | null,\n colors: PowerlineColors\n ): SegmentData | null {\n if (!sessionId) {\n return {\n text: `tmux:none`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n return {\n text: `tmux:${sessionId}`,\n bgColor: colors.tmuxBg,\n fgColor: colors.tmuxFg,\n };\n }\n\n renderContext(\n contextInfo: ContextInfo | null,\n colors: PowerlineColors\n ): SegmentData | null {\n if (!contextInfo) {\n return {\n text: `${this.symbols.context_time} 0 (100%)`,\n bgColor: colors.contextBg,\n fgColor: colors.contextFg,\n };\n }\n\n const tokenDisplay = contextInfo.inputTokens.toLocaleString();\n\n const contextLeft = `${contextInfo.contextLeftPercentage}%`;\n\n return {\n text: `${this.symbols.context_time} ${tokenDisplay} (${contextLeft})`,\n bgColor: colors.contextBg,\n fgColor: colors.contextFg,\n };\n }\n\n renderMetrics(\n metricsInfo: MetricsInfo | null,\n colors: PowerlineColors,\n config?: MetricsSegmentConfig\n ): SegmentData | null {\n if (!metricsInfo) {\n return {\n text: `${this.symbols.metrics_response} new`,\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n const parts: string[] = [];\n\n if (\n config?.showResponseTime !== false &&\n metricsInfo.responseTime !== null\n ) {\n const responseTime =\n metricsInfo.responseTime < 60\n ? `${metricsInfo.responseTime.toFixed(1)}s`\n : `${(metricsInfo.responseTime / 60).toFixed(1)}m`;\n parts.push(`${this.symbols.metrics_response} ${responseTime}`);\n }\n\n if (\n config?.showDuration !== false &&\n metricsInfo.sessionDuration !== null\n ) {\n const duration = this.formatDuration(metricsInfo.sessionDuration);\n parts.push(`${this.symbols.metrics_duration} ${duration}`);\n }\n\n if (\n config?.showMessageCount !== false &&\n metricsInfo.messageCount !== null\n ) {\n parts.push(\n `${this.symbols.metrics_messages} ${metricsInfo.messageCount}`\n );\n }\n\n if (config?.showCostBurnRate && metricsInfo.costBurnRate !== null) {\n const burnRate =\n metricsInfo.costBurnRate < 1\n ? `${(metricsInfo.costBurnRate * 100).toFixed(0)}¢/h`\n : `$${metricsInfo.costBurnRate.toFixed(2)}/h`;\n parts.push(`${this.symbols.metrics_burn} ${burnRate}`);\n }\n\n if (config?.showTokenBurnRate && metricsInfo.tokenBurnRate !== null) {\n const tokenRate = formatTokens(Math.round(metricsInfo.tokenBurnRate));\n parts.push(`${this.symbols.metrics_burn} ${tokenRate}/h`);\n }\n\n if (parts.length === 0) {\n return {\n text: `${this.symbols.metrics_response} active`,\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n return {\n text: parts.join(\" \"),\n bgColor: colors.metricsBg,\n fgColor: colors.metricsFg,\n };\n }\n\n private formatDuration(seconds: number): string {\n if (seconds < 60) {\n return `${seconds.toFixed(0)}s`;\n } else if (seconds < 3600) {\n return `${(seconds / 60).toFixed(0)}m`;\n } else if (seconds < 86400) {\n return `${(seconds / 3600).toFixed(1)}h`;\n } else {\n return `${(seconds / 86400).toFixed(1)}d`;\n }\n }\n\n private getDisplayDirectoryName(\n currentDir: string,\n projectDir?: string\n ): string {\n if (projectDir && projectDir !== currentDir) {\n if (currentDir.startsWith(projectDir)) {\n const relativePath = currentDir.slice(projectDir.length + 1);\n return relativePath || projectDir.split(\"/\").pop() || \"project\";\n }\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n return currentDir.split(\"/\").pop() || \"root\";\n }\n\n private formatUsageDisplay(\n cost: number | null,\n tokens: number | null,\n tokenBreakdown: TokenBreakdown | null,\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: TokenBreakdown | null,\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","import type { ClaudeHookData } from \"./index\";\nimport type { PowerlineColors } from \"./themes\";\nimport type { PowerlineConfig, LineConfig } from \"./config/loader\";\nimport { hexToAnsi, extractBgToFg } from \"./utils/colors\";\nimport { getTheme } from \"./themes\";\nimport {\n UsageProvider,\n UsageInfo,\n ContextProvider,\n ContextInfo,\n GitService,\n TmuxService,\n MetricsProvider,\n MetricsInfo,\n SegmentRenderer,\n PowerlineSymbols,\n AnySegmentConfig,\n GitSegmentConfig,\n UsageSegmentConfig,\n MetricsSegmentConfig,\n} from \"./segments\";\n\nexport class PowerlineRenderer {\n private readonly symbols: PowerlineSymbols;\n private readonly usageProvider: UsageProvider;\n private readonly contextProvider: ContextProvider;\n private readonly gitService: GitService;\n private readonly tmuxService: TmuxService;\n private readonly metricsProvider: MetricsProvider;\n private readonly segmentRenderer: SegmentRenderer;\n\n constructor(private readonly config: PowerlineConfig) {\n this.symbols = this.initializeSymbols();\n this.usageProvider = new UsageProvider();\n this.contextProvider = new ContextProvider();\n this.gitService = new GitService();\n this.tmuxService = new TmuxService();\n this.metricsProvider = new MetricsProvider();\n this.segmentRenderer = new SegmentRenderer(config, this.symbols);\n }\n\n private needsUsageInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.session?.enabled\n );\n }\n\n private needsGitInfo(): boolean {\n return this.config.display.lines.some((line) => line.segments.git?.enabled);\n }\n\n private needsTmuxInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.tmux?.enabled\n );\n }\n\n private needsContextInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.context?.enabled\n );\n }\n\n private needsMetricsInfo(): boolean {\n return this.config.display.lines.some(\n (line) => line.segments.metrics?.enabled\n );\n }\n\n async generateStatusline(hookData: ClaudeHookData): Promise<string> {\n const usageInfo = this.needsUsageInfo()\n ? await this.usageProvider.getUsageInfo(hookData.session_id)\n : null;\n\n const contextInfo = this.needsContextInfo()\n ? this.contextProvider.calculateContextTokens(\n hookData.transcript_path,\n hookData.model?.id\n )\n : null;\n\n const metricsInfo = this.needsMetricsInfo()\n ? await this.metricsProvider.getMetricsInfo(hookData.session_id)\n : null;\n\n const lines = this.config.display.lines\n .map((lineConfig) =>\n this.renderLine(\n lineConfig,\n hookData,\n usageInfo,\n contextInfo,\n metricsInfo\n )\n )\n .filter((line) => line.length > 0);\n\n return lines.join(\"\\n\");\n }\n\n private renderLine(\n lineConfig: LineConfig,\n hookData: ClaudeHookData,\n usageInfo: UsageInfo | null,\n contextInfo: ContextInfo | null,\n metricsInfo: MetricsInfo | null\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(\n ([_, config]: [string, AnySegmentConfig | undefined]) => config?.enabled\n )\n .map(([type, config]: [string, AnySegmentConfig]) => ({ 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 contextInfo,\n metricsInfo,\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: { type: string; config: AnySegmentConfig },\n hookData: ClaudeHookData,\n usageInfo: UsageInfo | null,\n contextInfo: ContextInfo | null,\n metricsInfo: MetricsInfo | null,\n colors: PowerlineColors,\n currentDir: string\n ) {\n switch (segment.type) {\n case \"directory\":\n return this.segmentRenderer.renderDirectory(hookData, colors);\n\n case \"git\":\n if (!this.needsGitInfo()) return null;\n const showSha = (segment.config as GitSegmentConfig)?.showSha || false;\n const gitInfo = this.gitService.getGitInfo(\n currentDir,\n showSha,\n hookData.workspace?.project_dir\n );\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 if (!usageInfo) return null;\n const usageType =\n (segment.config as UsageSegmentConfig)?.type || \"cost\";\n return this.segmentRenderer.renderSession(usageInfo, colors, usageType);\n\n case \"tmux\":\n if (!this.needsTmuxInfo()) return null;\n const tmuxSessionId = this.tmuxService.getSessionId();\n return this.segmentRenderer.renderTmux(tmuxSessionId, colors);\n\n case \"context\":\n if (!this.needsContextInfo()) return null;\n return this.segmentRenderer.renderContext(contextInfo, colors);\n\n case \"metrics\":\n const metricsConfig = segment.config as MetricsSegmentConfig;\n return this.segmentRenderer.renderMetrics(\n metricsInfo,\n colors,\n metricsConfig\n );\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: \"⊡\",\n context_time: \"◷\",\n metrics_response: \"⧖\",\n metrics_duration: \"⧗\",\n metrics_messages: \"⟐\",\n metrics_burn: \"⟢\",\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 tmuxBg: hexToAnsi(colorTheme.tmux.bg, true),\n tmuxFg: hexToAnsi(colorTheme.tmux.fg, false),\n contextBg: hexToAnsi(colorTheme.context.bg, true),\n contextFg: hexToAnsi(colorTheme.context.fg, false),\n metricsBg: hexToAnsi(colorTheme.metrics.bg, true),\n metricsFg: hexToAnsi(colorTheme.metrics.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 \"tmux\":\n return colors.tmuxBg;\n case \"context\":\n return colors.contextBg;\n case \"metrics\":\n return colors.metricsBg;\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 { DEFAULT_CONFIG } from \"./defaults\";\nimport type { ColorTheme } from \"../themes\";\nimport type {\n SegmentConfig,\n GitSegmentConfig,\n UsageSegmentConfig,\n TmuxSegmentConfig,\n ContextSegmentConfig,\n MetricsSegmentConfig,\n} from \"../segments/renderer\";\n\nexport interface LineConfig {\n segments: {\n directory?: SegmentConfig;\n git?: GitSegmentConfig;\n model?: SegmentConfig;\n session?: UsageSegmentConfig;\n tmux?: TmuxSegmentConfig;\n context?: ContextSegmentConfig;\n metrics?: MetricsSegmentConfig;\n };\n}\n\nexport interface DisplayConfig {\n lines: LineConfig[];\n style?: \"minimal\" | \"powerline\";\n}\n\nexport interface BudgetItemConfig {\n amount?: number;\n warningThreshold?: number;\n}\n\nexport interface BudgetConfig {\n session?: BudgetItemConfig;\n}\n\nexport interface PowerlineConfig {\n theme: \"light\" | \"dark\" | \"nord\" | \"tokyo-night\" | \"rose-pine\" | \"custom\";\n display: DisplayConfig;\n colors?: {\n custom: ColorTheme;\n };\n budget?: BudgetConfig;\n usageType?: \"cost\" | \"tokens\" | \"both\" | \"breakdown\";\n}\n\nexport interface ConfigLoadOptions {\n configPath?: string;\n ignoreEnvVars?: boolean;\n cliOverrides?: Partial<PowerlineConfig>;\n projectDir?: string;\n}\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 const sourceValue = source[key];\n if (sourceValue !== undefined) {\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue)\n ) {\n const targetValue = result[key] || {};\n result[key] = deepMerge(\n targetValue as Record<string, any>,\n sourceValue as Record<string, any>\n ) as T[Extract<keyof T, string>];\n } else if (Array.isArray(sourceValue) && sourceValue.length === 0) {\n const targetValue = result[key];\n if (!Array.isArray(targetValue) || targetValue.length > 0) {\n continue;\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\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 if (!config.display) {\n config.display = { lines: [] };\n }\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 if ([\"cost\", \"tokens\", \"both\", \"breakdown\"].includes(usageType)) {\n config.usageType = usageType;\n }\n }\n\n if (process.env.CLAUDE_POWERLINE_SESSION_BUDGET) {\n const sessionBudget = parseFloat(process.env.CLAUDE_POWERLINE_SESSION_BUDGET);\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\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 if (!config.display) {\n config.display = { lines: [] };\n }\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 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.usageType = usageType;\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 if (config.usageType) {\n config.display.lines.forEach((line) => {\n if (line.segments.session) {\n line.segments.session.type = config.usageType!;\n }\n });\n delete config.usageType;\n }\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 \"./loader\";\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 tmux: { enabled: false },\n context: { enabled: true },\n metrics: { enabled: false },\n },\n },\n ],\n },\n budget: {\n session: {\n warningThreshold: 80,\n },\n },\n};\n"],"mappings":"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","names":["process","path","fs","execSync","os","execSync","execSync","homedir","join","readFileSync","readFile","readFile","fs","path","fs","path","os","path","fs","process","execSync"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owloops/claude-powerline",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
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",
|