@owloops/claude-powerline 1.9.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +27 -26
  2. package/dist/index.js +9 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -54,9 +54,9 @@
54
54
 
55
55
  ### Usage Tracking
56
56
 
57
- - Real-time session costs from Claude Code hook data
58
- - 5-hour billing window token monitoring
59
- - Session budget alerts with percentages
57
+ - Real-time session costs
58
+ - 5-hour billing window monitoring
59
+ - Daily budget alerts with percentages
60
60
  - Token breakdown (input/output/cached)
61
61
 
62
62
  ### Git Integration
@@ -171,8 +171,8 @@ Config files reload automatically and no restart needed.
171
171
  | `git` | Branch, status, repository info | `showSha`, `showWorkingTree`, `showTag`, `showStashCount`, `showOperation`, `showTimeSinceCommit`, `showUpstream`, `showRepoName` |
172
172
  | `model` | Current Claude model | - |
173
173
  | `session` | Real-time usage for conversation | `type`: `cost`|`tokens`|`both`|`breakdown` |
174
- | `block` | 5-hour billing window token usage | `type`: `tokens`|`time`, `burnType`: `tokens`|`none` |
175
- | `today` | Daily token usage | `type`: `tokens`|`breakdown` |
174
+ | `block` | 5-hour billing window usage | `type`, `burnType`: `cost`|`tokens`|`both`|`none` |
175
+ | `today` | Daily usage with budget monitoring | `type` |
176
176
  | `context` | Context window usage | - |
177
177
  | `tmux` | Tmux session info | - |
178
178
  | `metrics` | Performance analytics | `showResponseTime`, `showLastResponseTime`, `showDuration`, `showMessageCount`, `showLinesAdded`, `showLinesRemoved` |
@@ -322,13 +322,15 @@ Shows real-time usage for current Claude conversation.
322
322
  ```json
323
323
  "session": {
324
324
  "enabled": true,
325
- "type": "tokens"
325
+ "type": "tokens",
326
+ "costSource": "calculated"
326
327
  }
327
328
  ```
328
329
 
329
330
  **Options:**
330
331
 
331
332
  - `type`: Display format - `cost` | `tokens` | `both` | `breakdown`
333
+ - `costSource`: Cost calculation method - `calculated` (ccusage-style) | `official` (hook data)
332
334
 
333
335
  **Symbols:** `§` Session
334
336
 
@@ -336,20 +338,20 @@ Shows real-time usage for current Claude conversation.
336
338
 
337
339
  #### Block
338
340
 
339
- Shows token usage within current 5-hour billing window (Claude\'s rate limit period).
341
+ Shows usage within current 5-hour billing window (Claude\'s rate limit period).
340
342
 
341
343
  ```json
342
344
  "block": {
343
345
  "enabled": true,
344
- "type": "tokens",
345
- "burnType": "tokens"
346
+ "type": "cost",
347
+ "burnType": "cost"
346
348
  }
347
349
  ```
348
350
 
349
351
  **Options:**
350
352
 
351
- - `type`: Display format - `tokens` | `time`
352
- - `burnType`: Burn rate display - `tokens` | `none`
353
+ - `type`: Display format - `cost` | `tokens` | `both` | `time`
354
+ - `burnType`: Burn rate display - `cost` | `tokens` | `both` | `none`
353
355
 
354
356
  **Symbols:** `◱` Block
355
357
 
@@ -357,28 +359,27 @@ Shows token usage within current 5-hour billing window (Claude\'s rate limit per
357
359
 
358
360
  #### Today
359
361
 
360
- Shows total daily token usage.
362
+ Shows total daily usage with budget monitoring.
361
363
 
362
364
  ```json
363
365
  "today": {
364
366
  "enabled": true,
365
- "type": "tokens"
367
+ "type": "cost"
366
368
  }
367
369
  ```
368
370
 
369
371
  **Options:**
370
372
 
371
- - `type`: Display format - `tokens` | `breakdown`
373
+ - `type`: Display format - `cost` | `tokens` | `both` | `breakdown`
372
374
 
373
375
  **Symbols:** `☉` Today
374
376
 
375
377
  ### Budget Configuration
376
378
 
377
- Session cost budget monitoring with percentage indicators.
378
-
379
379
  ```json
380
380
  "budget": {
381
- "session": { "amount": 10.0, "warningThreshold": 80 }
381
+ "session": { "amount": 10.0, "warningThreshold": 80 },
382
+ "today": { "amount": 25.0, "warningThreshold": 80 }
382
383
  }
383
384
  ```
384
385
 
@@ -441,8 +442,8 @@ Create custom themes by defining segment colors.
441
442
 
442
443
  ## Performance
443
444
 
444
- • **~80ms** default config (`directory`, `git`, `model`, `session`, `today`, `context`)
445
- • **~300ms** full-featured
445
+ • **~50ms** default config (`directory`, `git`, `model`, `session`, `today`, `context`)
446
+ • **~190ms** full-featured
446
447
 
447
448
  **Benchmark Tool:**
448
449
 
@@ -452,14 +453,14 @@ Create custom themes by defining segment colors.
452
453
  |-------------|-----------|----------|--------------------------------|
453
454
  | `directory` | ~40ms | ✗ | No external commands |
454
455
  | `model` | ~40ms | ✗ | Uses hook data |
455
- | `session` | ~40ms | ✗ | Minimal transcript parsing |
456
+ | `session` | ~41ms | ✗ | Minimal transcript parsing |
456
457
  | `context` | ~40ms | ✗ | Hook data calculation |
457
458
  | `metrics` | ~40ms | ✗ | Transcript analysis |
458
- | `git` | ~60ms | ✗ | Default config parameters |
459
- | `tmux` | ~50ms | ✗ | Environment check + command |
460
- | `block` | ~240ms | ✗ | 5-hour window transcript load |
461
- | `today` | ~250ms | ~45ms | Full daily transcript load |
462
- | `version` | ~40ms | ✗ | Uses hook data |
459
+ | `git` | ~70ms | ✗ | No caching for fresh data |
460
+ | `tmux` | ~90ms | ✗ | Environment check + command |
461
+ | `block` | ~165ms | ✗ | 5-hour window transcript load |
462
+ | `today` | ~460ms | ~55ms | Full daily transcript load |
463
+ | `version` | ~40ms | ✗ | Uses hook data |
463
464
 
464
465
  • **Tips:** Install globally (`npm install -g`) to avoid npx overhead
465
466
  • Disable unused segments
@@ -513,7 +514,7 @@ See [CONTRIBUTORS.md](CONTRIBUTORS.md) for people who have contributed outside o
513
514
 
514
515
  ### Library Usage
515
516
 
516
- Claude-powerline is designed as a CLI tool for Claude Code statuslines. While the codebase contains reusable components like `PowerlineRenderer`, we currently focus on the CLI use case to keep the project simple and maintainable.
517
+ Claude-powerline is designed as a CLI tool for Claude Code statuslines. While the codebase contains reusable components like `PricingService` and `PowerlineRenderer`, we currently focus on the CLI use case to keep the project simple and maintainable.
517
518
 
518
519
  ## License
519
520
 
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import h from'process';import S,{join,posix}from'path';import w,{existsSync,readFileSync,createReadStream}from'fs';import {exec,execSync}from'child_process';import $,{homedir}from'os';import {json}from'stream/consumers';import {promisify}from'util';import {readdir,stat,readFile}from'fs/promises';import {createInterface}from'readline';import {createHash}from'crypto';import {setTimeout}from'timers/promises';function ee(s,e){if(e&&(s.toLowerCase()==="transparent"||s.toLowerCase()==="none"))return "\x1B[49m";let t=parseInt(s.slice(1,3),16),n=parseInt(s.slice(3,5),16),r=parseInt(s.slice(5,7),16);return `\x1B[${e?"48":"38"};2;${t};${n};${r}m`}function te(s){let e=s.match(/48;2;(\d+);(\d+);(\d+)/);return e?`\x1B[38;2;${e[1]};${e[2]};${e[3]}m`:s.replace("48","38")}var ce={directory:{bg:"#8b4513",fg:"#ffffff"},git:{bg:"#404040",fg:"#ffffff"},model:{bg:"#2d2d2d",fg:"#ffffff"},session:{bg:"#202020",fg:"#00ffff"},block:{bg:"#2a2a2a",fg:"#87ceeb"},today:{bg:"#1a1a1a",fg:"#98fb98"},tmux:{bg:"#2f4f2f",fg:"#90ee90"},context:{bg:"#4a5568",fg:"#cbd5e0"},metrics:{bg:"#374151",fg:"#d1d5db"},version:{bg:"#3a3a4a",fg:"#b8b8d0"}};var ge={directory:{bg:"#ff6b47",fg:"#ffffff"},git:{bg:"#4fb3d9",fg:"#ffffff"},model:{bg:"#87ceeb",fg:"#000000"},session:{bg:"#da70d6",fg:"#ffffff"},block:{bg:"#6366f1",fg:"#ffffff"},today:{bg:"#10b981",fg:"#ffffff"},tmux:{bg:"#32cd32",fg:"#ffffff"},context:{bg:"#718096",fg:"#ffffff"},metrics:{bg:"#6b7280",fg:"#ffffff"},version:{bg:"#8b7dd8",fg:"#ffffff"}};var me={directory:{bg:"#434c5e",fg:"#d8dee9"},git:{bg:"#3b4252",fg:"#a3be8c"},model:{bg:"#4c566a",fg:"#81a1c1"},session:{bg:"#2e3440",fg:"#88c0d0"},block:{bg:"#3b4252",fg:"#81a1c1"},today:{bg:"#2e3440",fg:"#8fbcbb"},tmux:{bg:"#2e3440",fg:"#8fbcbb"},context:{bg:"#5e81ac",fg:"#eceff4"},metrics:{bg:"#b48ead",fg:"#2e3440"},version:{bg:"#434c5e",fg:"#88c0d0"}};var ue={directory:{bg:"#2f334d",fg:"#82aaff"},git:{bg:"#1e2030",fg:"#c3e88d"},model:{bg:"#191b29",fg:"#fca7ea"},session:{bg:"#222436",fg:"#86e1fc"},block:{bg:"#2d3748",fg:"#7aa2f7"},today:{bg:"#1a202c",fg:"#4fd6be"},tmux:{bg:"#191b29",fg:"#4fd6be"},context:{bg:"#414868",fg:"#c0caf5"},metrics:{bg:"#3d59a1",fg:"#c0caf5"},version:{bg:"#292e42",fg:"#bb9af7"}};var fe={directory:{bg:"#26233a",fg:"#c4a7e7"},git:{bg:"#1f1d2e",fg:"#9ccfd8"},model:{bg:"#191724",fg:"#ebbcba"},session:{bg:"#26233a",fg:"#f6c177"},block:{bg:"#2a273f",fg:"#eb6f92"},today:{bg:"#232136",fg:"#9ccfd8"},tmux:{bg:"#26233a",fg:"#908caa"},context:{bg:"#393552",fg:"#e0def4"},metrics:{bg:"#524f67",fg:"#e0def4"},version:{bg:"#2a273f",fg:"#c4a7e7"}};var ve={dark:ce,light:ge,nord:me,"tokyo-night":ue,"rose-pine":fe};function O(s){return ve[s]||null}var c=(s,...e)=>{process.env.CLAUDE_POWERLINE_DEBUG&&console.error(`[DEBUG] ${s}`,...e);};var k=promisify(exec),D=class{isGitRepo(e){try{return w.existsSync(S.join(e,".git"))}catch{return false}}async getGitInfo(e,t={},n){let r=n&&this.isGitRepo(n)?n:e;if(!this.isGitRepo(r))return null;try{let o=await this.getStatusWithBranchAsync(r),i=await this.getAheadBehindAsync(r),a={branch:o.branch||"detached",status:o.status,ahead:i.ahead,behind:i.behind};t.showWorkingTree&&o.workingTree&&(a.staged=o.workingTree.staged,a.unstaged=o.workingTree.unstaged,a.untracked=o.workingTree.untracked,a.conflicts=o.workingTree.conflicts);let l={},g={};t.showSha&&(l.sha=this.getShaAsync(r)),t.showTag&&(l.tag=this.getNearestTagAsync(r)),t.showTimeSinceCommit&&(l.timeSinceCommit=this.getTimeSinceLastCommitAsync(r)),t.showStashCount&&(g.stashCount=this.getStashCountAsync(r)),t.showUpstream&&(g.upstream=this.getUpstreamAsync(r)),t.showRepoName&&(g.repoName=this.getRepoNameAsync(r));let m=new Map;for(let[f,u]of Object.entries(l))try{let d=await u;m.set(f,d);}catch{}return Object.keys(g).length>0&&(await Promise.allSettled(Object.entries(g).map(async([u,d])=>({key:u,value:await d})))).forEach(u=>{u.status==="fulfilled"&&m.set(u.value.key,u.value.value);}),t.showSha&&(a.sha=m.get("sha")||void 0),t.showOperation&&(a.operation=this.getOngoingOperation(r)||void 0),t.showTag&&(a.tag=m.get("tag")||void 0),t.showTimeSinceCommit&&(a.timeSinceCommit=m.get("timeSinceCommit")||void 0),t.showStashCount&&(a.stashCount=m.get("stashCount")||0),t.showUpstream&&(a.upstream=m.get("upstream")||void 0),t.showRepoName&&(a.repoName=m.get("repoName")||void 0,a.isWorktree=this.isWorktree(r)),a}catch{return null}}async getShaAsync(e){try{return (await k("git rev-parse --short=7 HEAD",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}getOngoingOperation(e){try{let t=S.join(e,".git");return w.existsSync(S.join(t,"MERGE_HEAD"))?"MERGE":w.existsSync(S.join(t,"CHERRY_PICK_HEAD"))?"CHERRY-PICK":w.existsSync(S.join(t,"REVERT_HEAD"))?"REVERT":w.existsSync(S.join(t,"BISECT_LOG"))?"BISECT":w.existsSync(S.join(t,"rebase-merge"))||w.existsSync(S.join(t,"rebase-apply"))?"REBASE":null}catch{return null}}async getNearestTagAsync(e){try{return (await k("git describe --tags --abbrev=0",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}async getTimeSinceLastCommitAsync(e){try{let n=(await k("git log -1 --format=%ct",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(!n)return null;let r=parseInt(n)*1e3,o=Date.now();return Math.floor((o-r)/1e3)}catch{return null}}async getStashCountAsync(e){try{let n=(await k("git stash list",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();return n?n.split(`
3
- `).length:0}catch{return 0}}async getUpstreamAsync(e){try{return (await k("git rev-parse --abbrev-ref @{u}",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}async getRepoNameAsync(e){try{let n=(await k("git config --get remote.origin.url",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();return n?n.match(/\/([^/]+?)(\.git)?$/)?.[1]||S.basename(e):S.basename(e)}catch{return S.basename(e)}}isWorktree(e){try{let t=S.join(e,".git");return !!(w.existsSync(t)&&w.statSync(t).isFile())}catch{return false}}async getStatusWithBranchAsync(e){try{c(`[GIT-EXEC] Running git status in ${e}`);let r=(await k("git status --porcelain -b",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.split(`
4
- `),o=null,i="clean",a=0,l=0,g=0,m=0;for(let f of r)if(f){if(f.startsWith("## ")){let d=f.substring(3).split("...")[0];d&&d!=="HEAD (no branch)"&&(o=d);continue}if(f.length>=2){let u=f.charAt(0),d=f.charAt(1);if(u==="?"&&d==="?"){g++,i==="clean"&&(i="dirty");continue}let y=u+d;if(["DD","AU","UD","UA","DU","AA","UU"].includes(y)){m++,i="conflicts";continue}u!==" "&&u!=="?"&&(a++,i==="clean"&&(i="dirty")),d!==" "&&d!=="?"&&(l++,i==="clean"&&(i="dirty"));}}return {branch:o||await this.getFallbackBranch(e),status:i,workingTree:{staged:a,unstaged:l,untracked:g,conflicts:m}}}catch(t){return c(`Git status with branch command failed in ${e}:`,t),{branch:await this.getFallbackBranch(e),status:"clean"}}}async getFallbackBranch(e){try{let n=(await k("git branch --show-current",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(n)return n}catch{try{let n=(await k("git symbolic-ref --short HEAD",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(n)return n}catch{return null}}return null}async getAheadBehindAsync(e){try{c(`[GIT-EXEC] Running git ahead/behind in ${e}`);let[t,n]=await Promise.all([k("git rev-list --count @{u}..HEAD",{cwd:e,encoding:"utf8",timeout:2e3}),k("git rev-list --count HEAD..@{u}",{cwd:e,encoding:"utf8",timeout:2e3})]);return {ahead:parseInt(t.stdout.trim())||0,behind:parseInt(n.stdout.trim())||0}}catch(t){return c(`Git ahead/behind command failed in ${e}:`,t),{ahead:0,behind:0}}}};var De=promisify(exec),B=class{async getSessionId(){try{if(!process.env.TMUX_PANE)return c("TMUX_PANE not set, not in tmux session"),null;c(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);let t=(await De("tmux display-message -p '#S'",{encoding:"utf8",timeout:1e3})).stdout.trim();return c(`Tmux session ID: ${t||"empty"}`),t||null}catch(e){return c("Error getting tmux session ID:",e),null}}isInTmux(){return !!process.env.TMUX_PANE}};function H(){let s=[],e=process.env.CLAUDE_CONFIG_DIR;if(e&&e.split(",").forEach(t=>{let n=t.trim();existsSync(n)&&s.push(n);}),s.length===0){let t=homedir(),n=join(t,".config","claude"),r=join(t,".claude");existsSync(n)?s.push(n):existsSync(r)&&s.push(r);}return s}async function G(s){let e=[];for(let t of s){let n=join(t,"projects");if(existsSync(n))try{let r=await readdir(n,{withFileTypes:!0});for(let o of r)if(o.isDirectory()){let i=posix.join(n,o.name);e.push(i);}}catch(r){c(`Failed to read projects directory ${n}:`,r);}}return e}async function W(s){let e=H(),t=await G(e);for(let n of t){let r=posix.join(n,`${s}.jsonl`);if(existsSync(r))return r}return null}async function Ae(s){try{let t=(await readFile(s,"utf-8")).trim().split(`
5
- `),n=null;for(let r of t)if(r.trim())try{let o=JSON.parse(r);if(o.timestamp&&typeof o.timestamp=="string"){let i=new Date(o.timestamp);isNaN(i.getTime())||(n===null||i<n)&&(n=i);}}catch{continue}return n}catch(e){return c(`Failed to get earliest timestamp for ${s}:`,e),null}}async function Ie(s,e=true){return (await Promise.all(s.map(async n=>({file:n,timestamp:await Ae(n)})))).sort((n,r)=>n.timestamp===null&&r.timestamp===null?0:n.timestamp===null?1:r.timestamp===null?-1:(e?1:-1)*(n.timestamp.getTime()-r.timestamp.getTime())).map(n=>n.file)}async function se(s){try{return (await stat(s)).mtime}catch{return null}}function Me(s){let e=s.message?.id||(typeof s.raw.message=="object"&&s.raw.message!==null&&"id"in s.raw.message?s.raw.message.id:void 0),t="requestId"in s.raw?s.raw.requestId:void 0;return !e||!t?null:`${e}:${t}`}var Le=1024*1024;async function F(s){try{let t=(await stat(s)).size,n;return t>Le?(c(`Using streaming parser for large file ${s} (${Math.round(t/1024)}KB)`),n=await je(s)):n=await Ne(s),c(`Parsed ${n.length} entries from ${s}`),n}catch(e){return c(`Failed to read file ${s}:`,e),[]}}async function Ne(s){let t=(await readFile(s,"utf-8")).trim().split(`
6
- `).filter(r=>r.trim()),n=[];for(let r of t)try{let o=JSON.parse(r);if(!o.timestamp)continue;let i={timestamp:new Date(o.timestamp),message:o.message,costUSD:typeof o.costUSD=="number"?o.costUSD:void 0,isSidechain:o.isSidechain===!0,raw:o};n.push(i);}catch(o){c(`Failed to parse JSONL line: ${o}`);continue}return n}async function je(s){return new Promise((e,t)=>{let n=[],r=createReadStream(s,{encoding:"utf8"}),o=createInterface({input:r,crlfDelay:1/0});o.on("line",i=>{let a=i.trim();if(a)try{let l=JSON.parse(a);if(!l.timestamp)return;let g={timestamp:new Date(l.timestamp),message:l.message,costUSD:typeof l.costUSD=="number"?l.costUSD:void 0,isSidechain:l.isSidechain===!0,raw:l};n.push(g);}catch(l){c(`Failed to parse JSONL line: ${l}`);}}),o.on("close",()=>{e(n);}),o.on("error",i=>{c(`Streaming parser error for ${s}:`,i),t(i);}),r.on("error",i=>{c(`File stream error for ${s}:`,i),t(i);});})}async function V(s,e,t=false){let n=H(),r=await G(n),o=new Set,i=r.map(async u=>{try{let b=(await readdir(u)).filter(C=>C.endsWith(".jsonl")).map(async C=>{let Z=posix.join(u,C);if(existsSync(Z)){let xe=await se(Z);return {filePath:Z,mtime:xe}}return null});return (await Promise.all(b)).filter(C=>C?.mtime&&(!e||e(C.filePath,C.mtime)))}catch(d){return c(`Failed to read project directory ${u}:`,d),[]}}),l=(await Promise.all(i)).flat().filter(u=>u!==null).map(u=>u.filePath);if(t){let u=await Ie(l,false);l.length=0,l.push(...u);}let g=[],m=l.map(async u=>(await F(u)).filter(y=>{let b=Me(y);return b&&o.has(b)?false:(b&&o.add(b),!s||s(y))})),f=await Promise.all(m);for(let u of f)g.push(...u);return g}function Oe(s){return {timestamp:s.timestamp.toISOString(),message:{usage:{input_tokens:s.message?.usage?.input_tokens||0,output_tokens:s.message?.usage?.output_tokens||0,cache_creation_input_tokens:s.message?.usage?.cache_creation_input_tokens,cache_read_input_tokens:s.message?.usage?.cache_read_input_tokens}}}}var Y=class{async getSessionUsage(e){try{let t=await W(e);if(!t)return c(`No transcript found for session: ${e}`),null;c(`Found transcript at: ${t}`);let n=await F(t);if(n.length===0)return {entries:[]};let r=[];for(let o of n)if(o.message?.usage){let i=Oe(o);r.push(i);}return c(`Parsed ${r.length} usage entries`),{entries:r}}catch(t){return c(`Error reading session usage for ${e}:`,t),null}}calculateTokenBreakdown(e){return e.reduce((t,n)=>({input:t.input+(n.message.usage.input_tokens||0),output:t.output+(n.message.usage.output_tokens||0),cacheCreation:t.cacheCreation+(n.message.usage.cache_creation_input_tokens||0),cacheRead:t.cacheRead+(n.message.usage.cache_read_input_tokens||0)}),{input:0,output:0,cacheCreation:0,cacheRead:0})}async getSessionInfo(e,t){let n=await this.getSessionUsage(e);if(!n||n.entries.length===0)return {cost:null,tokens:null,tokenBreakdown:null};let r=this.calculateTokenBreakdown(n.entries),o=r.input+r.output+r.cacheCreation+r.cacheRead;return {cost:t?.cost?.total_cost_usd??null,tokens:o,tokenBreakdown:r}}},U=class{sessionProvider=new Y;async getUsageInfo(e,t){try{return c(`Starting usage info retrieval for session: ${e}`),{session:await this.sessionProvider.getSessionInfo(e,t)}}catch(n){return c(`Error getting usage info for session ${e}:`,n),{session:{cost:null,tokens:null,tokenBreakdown:null}}}}};var A=class{thresholds={LOW:50,MEDIUM:80};getContextUsageThresholds(){return this.thresholds}getContextLimit(e){return 2e5}async calculateContextTokens(e,t){try{c(`Calculating context tokens from transcript: ${e}`);try{if(!readFileSync(e,"utf-8"))return c("Transcript file is empty"),null}catch{return c("Could not read transcript file"),null}let n=await F(e);if(n.length===0)return c("No entries in transcript"),null;let r=null;for(let o=n.length-1;o>=0;o--){let i=n[o];if(i&&i.message?.usage?.input_tokens&&i.isSidechain!==!0){r=i,c(`Context segment: Found most recent entry at ${i.timestamp.toISOString()}, stopping search`);break}}if(r?.message?.usage){let o=r.message.usage,i=(o.input_tokens||0)+(o.cache_read_input_tokens||0)+(o.cache_creation_input_tokens||0),a=t?this.getContextLimit(t):2e5;c(`Most recent main chain context: ${i} tokens (limit: ${a})`);let l=Math.min(100,Math.max(0,Math.round(i/a*100))),g=Math.round(a*.75),m=Math.min(100,Math.max(0,Math.round(i/g*100))),f=Math.max(0,100-m);return {inputTokens:i,percentage:l,usablePercentage:m,contextLeftPercentage:f,maxTokens:a,usableTokens:g}}return c("No main chain entries with usage data found"),null}catch(n){return c(`Error reading transcript: ${n instanceof Error?n.message:String(n)}`),null}}};var I=class{async loadTranscriptEntries(e){try{let t=await W(e);if(!t)return c(`No transcript found for session: ${e}`),[];c(`Loading transcript from: ${t}`);let r=(await readFile(t,"utf-8")).trim().split(`
7
- `).filter(i=>i.trim()),o=[];for(let i of r)try{let a=JSON.parse(i);if(a.isSidechain===!0)continue;o.push(a);}catch(a){c(`Failed to parse JSONL line: ${a}`);continue}return c(`Loaded ${o.length} transcript entries`),o}catch(t){return c(`Error loading transcript for ${e}:`,t),[]}}calculateMessageCount(e){return e.filter(t=>{let n=t.type||t.message?.role||t.message?.type,r=t.type==="user"&&t.message?.content?.[0]?.type==="tool_result";return n==="user"&&!r}).length}calculateLastResponseTime(e){if(e.length===0)return null;let t=e.slice(-20),n=null,r=null;for(let o of t)if(o.timestamp)try{let i=new Date(o.timestamp),a=o.type||o.message?.role||o.message?.type,l=o.type==="user"&&o.message?.content?.[0]?.type==="tool_result";if(a==="user"&&!l)n=i;else if(a==="assistant"&&n){let m=(i.getTime()-n.getTime())/1e3;m>.1&&m<300&&(r=m);}}catch{continue}return r}async getMetricsInfo(e,t){try{if(c(`Getting metrics from hook data for session: ${e}`),!t.cost)return c("No cost data available in hook data"),{responseTime:null,lastResponseTime:null,sessionDuration:null,messageCount:null,linesAdded:null,linesRemoved:null};let n=await this.loadTranscriptEntries(e),r=this.calculateMessageCount(n),o=this.calculateLastResponseTime(n);return {responseTime:t.cost.total_api_duration_ms/1e3,lastResponseTime:o,sessionDuration:t.cost.total_duration_ms/1e3,messageCount:r,linesAdded:t.cost.total_lines_added,linesRemoved:t.cost.total_lines_removed}}catch(n){return c(`Error getting metrics from hook data for session ${e}:`,n),{responseTime:null,lastResponseTime:null,sessionDuration:null,messageCount:null,linesAdded:null,linesRemoved:null}}}};function _(s){return s===null||s===0?"0 tokens":s>=1e6?`${(s/1e6).toFixed(1)}M tokens`:s>=1e3?`${(s/1e3).toFixed(1)}K tokens`:`${s} tokens`}function ye(s){if(!s)return "0 tokens";let e=[];if(s.input>0&&e.push(`${_(s.input).replace(" tokens","")}in`),s.output>0&&e.push(`${_(s.output).replace(" tokens","")}out`),s.cacheCreation>0||s.cacheRead>0){let t=s.cacheCreation+s.cacheRead;e.push(`${_(t).replace(" tokens","")}cached`);}return e.length>0?e.join(" + "):"0 tokens"}function be(s){return s<60?`${s}s`:s<3600?`${Math.floor(s/60)}m`:s<86400?`${Math.floor(s/3600)}h`:s<604800?`${Math.floor(s/86400)}d`:`${Math.floor(s/604800)}w`}function Ce(s){return s<60?`${s.toFixed(0)}s`:s<3600?`${(s/60).toFixed(0)}m`:s<86400?`${(s/3600).toFixed(1)}h`:`${(s/86400).toFixed(1)}d`}var M=class{constructor(e,t){this.config=e;this.symbols=t;}renderDirectory(e,t,n){let r=e.workspace?.current_dir||e.cwd||"/",o=e.workspace?.project_dir;if(n?.showBasename)return {text:S.basename(r)||"root",bgColor:t.modeBg,fgColor:t.modeFg};let i=process.env.HOME||process.env.USERPROFILE,a=r,l=o;return i&&(r.startsWith(i)&&(a=r.replace(i,"~")),o&&o.startsWith(i)&&(l=o.replace(i,"~"))),{text:this.getDisplayDirectoryName(a,l),bgColor:t.modeBg,fgColor:t.modeFg}}renderGit(e,t,n){if(!e)return null;let r=[];if(n?.showRepoName&&e.repoName&&(r.push(e.repoName),e.isWorktree&&r.push(this.symbols.git_worktree)),n?.showOperation&&e.operation&&r.push(`[${e.operation}]`),r.push(`${this.symbols.branch} ${e.branch}`),n?.showTag&&e.tag&&r.push(`${this.symbols.git_tag} ${e.tag}`),n?.showSha&&e.sha&&r.push(`${this.symbols.git_sha} ${e.sha}`),n?.showAheadBehind!==false&&(e.ahead>0&&e.behind>0?r.push(`${this.symbols.git_ahead}${e.ahead}${this.symbols.git_behind}${e.behind}`):e.ahead>0?r.push(`${this.symbols.git_ahead}${e.ahead}`):e.behind>0&&r.push(`${this.symbols.git_behind}${e.behind}`)),n?.showWorkingTree){let i=[];e.staged&&e.staged>0&&i.push(`+${e.staged}`),e.unstaged&&e.unstaged>0&&i.push(`~${e.unstaged}`),e.untracked&&e.untracked>0&&i.push(`?${e.untracked}`),e.conflicts&&e.conflicts>0&&i.push(`!${e.conflicts}`),i.length>0&&r.push(`(${i.join(" ")})`);}if(n?.showUpstream&&e.upstream&&r.push(`${this.symbols.git_upstream}${e.upstream}`),n?.showStashCount&&e.stashCount&&e.stashCount>0&&r.push(`${this.symbols.git_stash} ${e.stashCount}`),n?.showTimeSinceCommit&&e.timeSinceCommit!==void 0){let i=be(e.timeSinceCommit);r.push(`${this.symbols.git_time} ${i}`);}let o=this.symbols.git_clean;return e.status==="conflicts"?o=this.symbols.git_conflicts:e.status==="dirty"&&(o=this.symbols.git_dirty),r.push(o),{text:r.join(" "),bgColor:t.gitBg,fgColor:t.gitFg}}renderModel(e,t){let n=e.model?.display_name||"Claude";return {text:`${this.symbols.model} ${n}`,bgColor:t.modelBg,fgColor:t.modelFg}}renderSession(e,t,n="cost"){let r=this.config.budget?.session;return {text:`${this.symbols.session_cost} ${this.formatUsageWithBudget(e.session.cost,e.session.tokens,e.session.tokenBreakdown,n,r?.amount,r?.warningThreshold||80)}`,bgColor:t.sessionBg,fgColor:t.sessionFg}}renderTmux(e,t){return e?{text:`tmux:${e}`,bgColor:t.tmuxBg,fgColor:t.tmuxFg}:{text:"tmux:none",bgColor:t.tmuxBg,fgColor:t.tmuxFg}}renderContext(e,t){if(!e)return {text:`${this.symbols.context_time} 0 (100%)`,bgColor:t.contextBg,fgColor:t.contextFg};let n=e.inputTokens.toLocaleString(),r=`${e.contextLeftPercentage}%`;return {text:`${this.symbols.context_time} ${n} (${r})`,bgColor:t.contextBg,fgColor:t.contextFg}}renderMetrics(e,t,n,r){if(!e)return {text:`${this.symbols.metrics_response} new`,bgColor:t.metricsBg,fgColor:t.metricsFg};let o=[];if(r?.showLastResponseTime&&e.lastResponseTime!==null){let i=e.lastResponseTime<60?`${e.lastResponseTime.toFixed(1)}s`:`${(e.lastResponseTime/60).toFixed(1)}m`;o.push(`${this.symbols.metrics_last_response} ${i}`);}if(r?.showResponseTime!==false&&e.responseTime!==null){let i=e.responseTime<60?`${e.responseTime.toFixed(1)}s`:`${(e.responseTime/60).toFixed(1)}m`;o.push(`${this.symbols.metrics_response} ${i}`);}if(r?.showDuration!==false&&e.sessionDuration!==null){let i=Ce(e.sessionDuration);o.push(`${this.symbols.metrics_duration} ${i}`);}return r?.showMessageCount!==false&&e.messageCount!==null&&o.push(`${this.symbols.metrics_messages} ${e.messageCount}`),r?.showLinesAdded!==false&&e.linesAdded!==null&&e.linesAdded>0&&o.push(`${this.symbols.metrics_lines_added} ${e.linesAdded}`),r?.showLinesRemoved!==false&&e.linesRemoved!==null&&e.linesRemoved>0&&o.push(`${this.symbols.metrics_lines_removed} ${e.linesRemoved}`),o.length===0?{text:`${this.symbols.metrics_response} active`,bgColor:t.metricsBg,fgColor:t.metricsFg}:{text:o.join(" "),bgColor:t.metricsBg,fgColor:t.metricsFg}}renderBlock(e,t,n){let r;if(e.tokens===null)r="No active block";else {let o=n?.type||"tokens",i=n?.burnType,a=e.timeRemaining!==null?(()=>{let m=Math.floor(e.timeRemaining/60),f=e.timeRemaining%60;return m>0?`${m}h ${f}m`:`${f}m`})():null,l;switch(o){case "tokens":l=_(e.tokens);break;case "time":l=a||"N/A";break;default:l=_(e.tokens);}let g="";if(i&&i!=="none")switch(i){case "tokens":g=` | ${e.tokenBurnRate!==null?`${_(Math.round(e.tokenBurnRate))}/h`:"N/A"}`;break}o==="time"?r=l:r=a?`${l}${g} (${a} left)`:`${l}${g}`;}return {text:`${this.symbols.block_cost} ${r}`,bgColor:t.blockBg,fgColor:t.blockFg}}renderToday(e,t,n="tokens"){return {text:`${this.symbols.today_cost} ${this.formatUsageWithBudget(null,e.tokens,e.tokenBreakdown,n,void 0,void 0)}`,bgColor:t.todayBg,fgColor:t.todayFg}}getDisplayDirectoryName(e,t){return e.startsWith("~")?e:t&&t!==e?e.startsWith(t)?e.slice(t.length+1)||S.basename(t)||"project":S.basename(e)||"root":S.basename(e)||"root"}formatUsageDisplay(e,t,n,r){switch(r){case "cost":return e!==null?`$${e.toFixed(2)}`:"No cost data";case "tokens":return _(t);case "both":return e!==null?`$${e.toFixed(2)} (${_(t)})`:_(t);case "breakdown":return ye(n);default:return _(t)}}formatUsageWithBudget(e,t,n,r,o,i=80){let a=this.formatUsageDisplay(e,t,n,r);if(o&&o>0&&e!==null&&(r==="cost"||r==="both")){let l=Math.min(100,e/o*100),g=l>=i,m=`${l.toFixed(0)}%`,f="";return g?f=` !${m}`:l>=50?f=` +${m}`:f=` ${m}`,a+f}return a}renderVersion(e,t,n){return e.version?{text:`${this.symbols.version} v${e.version}`,bgColor:t.versionBg,fgColor:t.versionFg}:null}};function We(s){return {timestamp:s.timestamp,usage:{inputTokens:s.message?.usage?.input_tokens||0,outputTokens:s.message?.usage?.output_tokens||0,cacheCreationInputTokens:s.message?.usage?.cache_creation_input_tokens||0,cacheReadInputTokens:s.message?.usage?.cache_read_input_tokens||0},model:s.message?.model||"unknown"}}var q=class{sessionDurationHours=5;floorToHour(e){let t=new Date(e);return t.setUTCMinutes(0,0,0),t}identifySessionBlocks(e){if(e.length===0)return [];let t=this.sessionDurationHours*60*60*1e3,n=[],r=[...e].sort((a,l)=>a.timestamp.getTime()-l.timestamp.getTime()),o=null,i=[];for(let a of r){let l=a.timestamp;if(o==null)o=this.floorToHour(l),i=[a];else {let g=l.getTime()-o.getTime(),m=i[i.length-1];if(m==null)continue;let f=m.timestamp,u=l.getTime()-f.getTime();g>t||u>t?(n.push(i),o=this.floorToHour(l),i=[a]):i.push(a);}}return o!=null&&i.length>0&&n.push(i),n}createBlockInfo(e,t){let n=new Date,r=this.sessionDurationHours*60*60*1e3,o=new Date(e.getTime()+r),i=t[t.length-1],a=i!=null?i.timestamp:e,l=n.getTime()-a.getTime()<r&&n<o;return {block:t,isActive:l}}findActiveBlock(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(!n||n.length===0)continue;let r=n[0];if(!r)continue;let o=this.floorToHour(r.timestamp),i=this.createBlockInfo(o,n);if(i.isActive)return i.block}return null}async loadUsageEntries(){try{c("Block segment: Loading entries for dynamic session blocks");let e=new Date;e.setDate(e.getDate()-1);let n=await V(void 0,(l,g)=>g>=e,!0),r=[];for(let l of n)if(l.message?.usage){let g=We(l);r.push(g);}let o=this.identifySessionBlocks(r);c(`Block segment: Found ${o.length} session blocks`);let i=this.findActiveBlock(o),a=[];if(i&&i.length>0){c(`Block segment: Found active block with ${i.length} entries`);let l=i[0],g=i[i.length-1];l&&g&&c(`Block segment: Active block from ${l.timestamp.toISOString()} to ${g.timestamp.toISOString()}`),a=i;}else c("Block segment: No active block found"),a=[];return a}catch(e){return c("Error loading block entries:",e),[]}}async getActiveBlockInfo(){try{let e=await this.loadUsageEntries();if(e.length===0)return c("Block segment: No entries in current block"),{tokens:null,timeRemaining:null,tokenBurnRate:null};let t=e.reduce((i,a)=>i+a.usage.inputTokens+a.usage.outputTokens+a.usage.cacheCreationInputTokens+a.usage.cacheReadInputTokens,0),n=new Date,r=null;if(e.length>0){let i=e[0];if(i){let a=this.sessionDurationHours*60*60*1e3,l=this.floorToHour(i.timestamp),g=new Date(l.getTime()+a);r=Math.max(0,Math.round((g.getTime()-n.getTime())/(1e3*60)));}}let o=null;if(e.length>=1&&t>0){let i=e.map(g=>g.timestamp).sort((g,m)=>g.getTime()-m.getTime()),a=i[0],l=i[i.length-1];if(a&&l){let g=(l.getTime()-a.getTime())/6e4;g>0&&t>0&&(o=t/g*60);}}return c(`Block segment: ${t} tokens, ${r}m remaining, token burn rate: ${o?o.toFixed(0)+" tokens/hr":"N/A"}`),{tokens:t,timeRemaining:r,tokenBurnRate:o}}catch(e){return c("Error getting active block info:",e),{tokens:null,timeRemaining:null,tokenBurnRate:null}}}};var P=class{static CACHE_DIR=S.join(homedir(),".claude","powerline");static USAGE_CACHE_DIR=S.join(this.CACHE_DIR,"usage");static LOCKS_DIR=S.join(this.CACHE_DIR,"locks");static isLocked(e){let t=S.join(this.LOCKS_DIR,e);if(!w.existsSync(t))return false;try{let n=w.readFileSync(t,"utf-8"),r=parseInt(n.trim(),10);if(isNaN(r))return c(`Invalid PID in lock file ${e}, removing stale lock`),w.unlinkSync(t),!1;try{return process.kill(r,0),!0}catch(o){return o.code==="ESRCH"?(c(`Removing stale lock file ${e} for dead process ${r}`),w.unlinkSync(t),!1):(c(`Error checking process ${r} for lock ${e}:`,o),!0)}}catch(n){return c(`Error reading lock file ${e}:`,n),true}}static async acquireLock(e,t=5e3){await this.ensureCacheDirectories();let o=S.join(this.LOCKS_DIR,e),i=Date.now(),a=String(process.pid);for(;Date.now()-i<t;)try{return await w.promises.writeFile(o,a,{flag:"wx"}),c(`Lock acquired for ${e}`),!0}catch(l){if(l.code==="EEXIST")await setTimeout(50);else throw l}return c(`Failed to acquire lock for ${e} within ${t}ms`),false}static async releaseLock(e){let t=S.join(this.LOCKS_DIR,e);try{await w.promises.unlink(t),c(`Lock released for ${e}`);}catch(n){n.code!=="ENOENT"&&c(`Error releasing lock for ${e}:`,n);}}static async ensureCacheDirectories(){try{await Promise.all([w.promises.mkdir(this.CACHE_DIR,{recursive:!0}),w.promises.mkdir(this.USAGE_CACHE_DIR,{recursive:!0}),w.promises.mkdir(this.LOCKS_DIR,{recursive:!0})]);}catch(e){c("Failed to create cache directories:",e);}}static createProjectHash(e){return createHash("md5").update(e).digest("hex").substring(0,8)}static async getUsageCache(e,t){let o="utf-8";await this.ensureCacheDirectories();let i=S.join(this.USAGE_CACHE_DIR,`${e}.json`),a=`${e}.usage.lock`;for(let l=0;l<3;l++){if(this.isLocked(a)){c(`Cache for ${e} is locked, waiting...`),await setTimeout(75);continue}try{let m=await w.promises.readFile(i,o),f=JSON.parse(m);return !t||f.timestamp>=t?(c(`[CACHE-HIT] ${e} disk cache: found`),this.deserializeDates(f.data)):(c(`${e} cache outdated: cache=${f.timestamp}, latest=${t}`),null)}catch(m){if(m.code==="ENOENT")return c(`No shared ${e} usage cache found`),null;let f=l+1;c(`Attempt ${f} failed to read ${e} cache: ${m.message}. Retrying...`),await setTimeout(75);}}return c(`Failed to read ${e} cache after 3 attempts.`),null}static deserializeDates(e){return Array.isArray(e)?e.map(t=>({...t,timestamp:new Date(t.timestamp)})):e}static async setUsageCache(e,t,n){let r=`${e}.usage.lock`;if(!await this.acquireLock(r)){c(`Could not acquire lock to set usage cache for ${e}`);return}try{await this.ensureCacheDirectories();let i=S.join(this.USAGE_CACHE_DIR,`${e}.json`),a=n||Date.now(),g=JSON.stringify({data:t,timestamp:a});await w.promises.writeFile(i,g,"utf-8"),c(`[CACHE-SET] ${e} disk cache stored`);}catch(i){c(`Failed to save ${e} usage cache:`,i);}finally{await this.releaseLock(r);}}static async getLatestTranscriptMtime(){try{let e=H(),t=await G(e),n=0;for(let r of t)try{let i=(await w.promises.readdir(r)).filter(a=>a.endsWith(".jsonl"));for(let a of i){let l=S.join(r,a),g=await se(l);g&&g.getTime()>n&&(n=g.getTime());}}catch(o){c(`Failed to read project directory ${r}:`,o);continue}return n}catch(e){return c("Failed to get latest transcript mtime:",e),Date.now()}}};function L(s){let e=s.getFullYear(),t=String(s.getMonth()+1).padStart(2,"0"),n=String(s.getDate()).padStart(2,"0");return `${e}-${t}-${n}`}function Je(s){return s.inputTokens+s.outputTokens+s.cacheCreationInputTokens+s.cacheReadInputTokens}function qe(s){return {timestamp:s.timestamp,usage:{inputTokens:s.message?.usage?.input_tokens||0,outputTokens:s.message?.usage?.output_tokens||0,cacheCreationInputTokens:s.message?.usage?.cache_creation_input_tokens||0,cacheReadInputTokens:s.message?.usage?.cache_read_input_tokens||0},model:s.message?.model||"unknown"}}var X=class{async loadTodayEntries(){let t=L(new Date);c(`Today segment: Loading entries for date ${t}`);let n=await P.getLatestTranscriptMtime(),r=await P.getUsageCache("today",n);if(r)return c("Using shared today usage cache"),r;let o=new Date;o.setDate(o.getDate()-1),o.setHours(0,0,0,0);let i=(u,d)=>d>=o,a=new Date;a.setHours(0,0,0,0);let g=await V(u=>u.timestamp>=a,i,true),m=[],f=0;for(let u of g)if(L(u.timestamp)===t&&u.message?.usage){let y=qe(u);m.push(y),f++;}return c(`Today segment: Found ${f} entries for today (${t})`),await P.setUsageCache("today",m,n),m}async getTodayEntries(){try{return await this.loadTodayEntries()}catch(e){return c("Error loading today's entries:",e),[]}}async getTodayInfo(){try{let e=await this.getTodayEntries();if(e.length===0)return {tokens:null,tokenBreakdown:null,date:L(new Date)};let t=e.reduce((r,o)=>r+Je(o.usage),0),n=e.reduce((r,o)=>({input:r.input+o.usage.inputTokens,output:r.output+o.usage.outputTokens,cacheCreation:r.cacheCreation+o.usage.cacheCreationInputTokens,cacheRead:r.cacheRead+o.usage.cacheReadInputTokens}),{input:0,output:0,cacheCreation:0,cacheRead:0});return c(`Today segment: ${t} tokens total`),{tokens:t,tokenBreakdown:n,date:L(new Date)}}catch(e){return c("Error getting today's info:",e),{tokens:null,tokenBreakdown:null,date:L(new Date)}}}};var N="\x1B[0m",p={right:"\uE0B0",branch:"\u2387",model:"\u26A1",git_clean:"\u2713",git_dirty:"\u25CF",git_conflicts:"\u26A0",git_ahead:"\u2191",git_behind:"\u2193",git_worktree:"\u29C9",git_tag:"\u2302",git_sha:"\u266F",git_upstream:"\u2192",git_stash:"\u29C7",git_time:"\u25F7",session_cost:"\xA7",block_cost:"\u25F1",today_cost:"\u2609",context_time:"\u25D4",metrics_response:"\u29D6",metrics_last_response:"\u0394",metrics_duration:"\u29D7",metrics_messages:"\u27D0",metrics_lines_added:"+",metrics_lines_removed:"-",metrics_burn:"\u27E2",version:"\u25C8"};var K=class{constructor(e){this.config=e;this.symbols=this.initializeSymbols();}symbols;_usageProvider;_blockProvider;_todayProvider;_contextProvider;_gitService;_tmuxService;_metricsProvider;_segmentRenderer;get usageProvider(){return this._usageProvider||(this._usageProvider=new U),this._usageProvider}get blockProvider(){return this._blockProvider||(this._blockProvider=new q),this._blockProvider}get todayProvider(){return this._todayProvider||(this._todayProvider=new X),this._todayProvider}get contextProvider(){return this._contextProvider||(this._contextProvider=new A),this._contextProvider}get gitService(){return this._gitService||(this._gitService=new D),this._gitService}get tmuxService(){return this._tmuxService||(this._tmuxService=new B),this._tmuxService}get metricsProvider(){return this._metricsProvider||(this._metricsProvider=new I),this._metricsProvider}get segmentRenderer(){return this._segmentRenderer||(this._segmentRenderer=new M(this.config,this.symbols)),this._segmentRenderer}needsSegmentInfo(e){return this.config.display.lines.some(t=>t.segments[e]?.enabled)}async generateStatusline(e){let t=this.needsSegmentInfo("session")?await this.usageProvider.getUsageInfo(e.session_id,e):null,n=this.needsSegmentInfo("block")?await this.blockProvider.getActiveBlockInfo():null,r=this.needsSegmentInfo("today")?await this.todayProvider.getTodayInfo():null,o=this.needsSegmentInfo("context")?await this.contextProvider.calculateContextTokens(e.transcript_path,e.model?.id):null,i=this.needsSegmentInfo("metrics")?await this.metricsProvider.getMetricsInfo(e.session_id,e):null;return (await Promise.all(this.config.display.lines.map(l=>this.renderLine(l,e,t,n,r,o,i)))).filter(l=>l.length>0).join(`
8
- `)}async renderLine(e,t,n,r,o,i,a){let l=this.getThemeColors(),g=t.workspace?.current_dir||t.cwd||"/",m=Object.entries(e.segments).filter(([u,d])=>d?.enabled).map(([u,d])=>({type:u,config:d})),f=l.reset;for(let u=0;u<m.length;u++){let d=m[u];if(!d)continue;let y=u===m.length-1,b=y?null:m[u+1],R=b?this.getSegmentBgColor(b.type,l):"",C=await this.renderSegment(d,t,n,r,o,i,a,l,g);C&&(f+=this.formatSegment(C.bgColor,C.fgColor,C.text,y?void 0:R));}return f}async renderSegment(e,t,n,r,o,i,a,l,g){return e.type==="directory"?this.segmentRenderer.renderDirectory(t,l,e.config):e.type==="model"?this.segmentRenderer.renderModel(t,l):e.type==="git"?await this.renderGitSegment(e.config,t,l,g):e.type==="session"?this.renderSessionSegment(e.config,n,l):e.type==="tmux"?await this.renderTmuxSegment(l):e.type==="context"?this.renderContextSegment(i,l):e.type==="metrics"?this.renderMetricsSegment(e.config,a,r,l):e.type==="block"?this.renderBlockSegment(e.config,r,l):e.type==="today"?this.renderTodaySegment(e.config,o,l):e.type==="version"?this.renderVersionSegment(e.config,t,l):null}async renderGitSegment(e,t,n,r){if(!this.needsSegmentInfo("git"))return null;let o=await this.gitService.getGitInfo(r,{showSha:e?.showSha,showWorkingTree:e?.showWorkingTree,showOperation:e?.showOperation,showTag:e?.showTag,showTimeSinceCommit:e?.showTimeSinceCommit,showStashCount:e?.showStashCount,showUpstream:e?.showUpstream,showRepoName:e?.showRepoName},t.workspace?.project_dir);return o?this.segmentRenderer.renderGit(o,n,e):null}renderSessionSegment(e,t,n){if(!t)return null;let r=e?.type||"cost";return this.segmentRenderer.renderSession(t,n,r)}async renderTmuxSegment(e){if(!this.needsSegmentInfo("tmux"))return null;let t=await this.tmuxService.getSessionId();return this.segmentRenderer.renderTmux(t,e)}renderContextSegment(e,t){return this.needsSegmentInfo("context")?this.segmentRenderer.renderContext(e,t):null}renderMetricsSegment(e,t,n,r){return this.segmentRenderer.renderMetrics(t,r,n,e)}renderBlockSegment(e,t,n){return t?this.segmentRenderer.renderBlock(t,n,e):null}renderTodaySegment(e,t,n){if(!t)return null;let r=e?.type||"cost";return this.segmentRenderer.renderToday(t,n,r)}renderVersionSegment(e,t,n){return this.segmentRenderer.renderVersion(t,n,e)}initializeSymbols(){return {right:this.config.display.style==="minimal"?"":p.right,branch:p.branch,model:p.model,git_clean:p.git_clean,git_dirty:p.git_dirty,git_conflicts:p.git_conflicts,git_ahead:p.git_ahead,git_behind:p.git_behind,git_worktree:p.git_worktree,git_tag:p.git_tag,git_sha:p.git_sha,git_upstream:p.git_upstream,git_stash:p.git_stash,git_time:p.git_time,session_cost:p.session_cost,block_cost:p.block_cost,today_cost:p.today_cost,context_time:p.context_time,metrics_response:p.metrics_response,metrics_last_response:p.metrics_last_response,metrics_duration:p.metrics_duration,metrics_messages:p.metrics_messages,metrics_lines_added:p.metrics_lines_added,metrics_lines_removed:p.metrics_lines_removed,metrics_burn:p.metrics_burn,version:p.version}}getThemeColors(){let e=this.config.theme,t;if(e==="custom"){if(t=this.config.colors?.custom,!t)throw new Error("Custom theme selected but no colors provided in configuration")}else t=O(e),t||(console.warn(`Built-in theme '${e}' not found, falling back to 'dark' theme`),t=O("dark"));let n=O("dark"),r=b=>{let R=t[b]||n[b];return {bg:ee(R.bg,true),fg:ee(R.fg,false)}},o=r("directory"),i=r("git"),a=r("model"),l=r("session"),g=r("block"),m=r("today"),f=r("tmux"),u=r("context"),d=r("metrics"),y=r("version");return {reset:N,modeBg:o.bg,modeFg:o.fg,gitBg:i.bg,gitFg:i.fg,modelBg:a.bg,modelFg:a.fg,sessionBg:l.bg,sessionFg:l.fg,blockBg:g.bg,blockFg:g.fg,todayBg:m.bg,todayFg:m.fg,tmuxBg:f.bg,tmuxFg:f.fg,contextBg:u.bg,contextFg:u.fg,metricsBg:d.bg,metricsFg:d.fg,versionBg:y.bg,versionFg:y.fg}}getSegmentBgColor(e,t){switch(e){case "directory":return t.modeBg;case "git":return t.gitBg;case "model":return t.modelBg;case "session":return t.sessionBg;case "block":return t.blockBg;case "today":return t.todayBg;case "tmux":return t.tmuxBg;case "context":return t.contextBg;case "metrics":return t.metricsBg;case "version":return t.versionBg;default:return t.modeBg}}formatSegment(e,t,n,r){let o=`${e}${t} ${n} `;if(r){let i=te(e);o+=`${N}${r}${i}${this.symbols.right}`;}else o+=`${N}${te(e)}${this.symbols.right}${N}`;return o}};var Se={theme:"dark",display:{style:"minimal",lines:[{segments:{directory:{enabled:true,showBasename:true},git:{enabled:true,showSha:false,showWorkingTree:false,showOperation:false,showTag:false,showTimeSinceCommit:false,showStashCount:false,showUpstream:false,showRepoName:false},model:{enabled:true},session:{enabled:true,type:"both"},today:{enabled:true,type:"tokens"},block:{enabled:false,type:"tokens",burnType:"tokens"},version:{enabled:false},tmux:{enabled:false},context:{enabled:true},metrics:{enabled:false,showResponseTime:true,showLastResponseTime:true,showDuration:true,showMessageCount:true,showLinesAdded:true,showLinesRemoved:true}}}]},budget:{session:{warningThreshold:80}}};function ae(s){return ["light","dark","nord","tokyo-night","rose-pine","custom"].includes(s)}function le(s){return s==="minimal"||s==="powerline"}function Q(s,e){let t={...s};for(let n in e){let r=e[n];if(r!==void 0)if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let o=t[n]||{};t[n]=Q(o,r);}else t[n]=r;}return t}function Xe(s,e){return s?w.existsSync(s)?s:null:[...e?[S.join(e,".claude-powerline.json")]:[],S.join(process.cwd(),".claude-powerline.json"),S.join($.homedir(),".claude","claude-powerline.json"),S.join($.homedir(),".config","claude-powerline","config.json")].find(w.existsSync)||null}function Ke(s){try{let e=w.readFileSync(s,"utf-8");return JSON.parse(e)}catch(e){throw new Error(`Failed to load config file ${s}: ${e instanceof Error?e.message:String(e)}`)}}function ze(){let s={},e={},t=process.env.CLAUDE_POWERLINE_THEME;t&&ae(t)&&(s.theme=t);let n=process.env.CLAUDE_POWERLINE_STYLE;return n&&(le(n)?e.style=n:(console.warn(`Invalid display style '${n}' from environment variable, falling back to 'minimal'`),e.style="minimal")),Object.keys(e).length>0&&(s.display=e),s}function Qe(){return process.env.CLAUDE_POWERLINE_CONFIG}function Ze(s){let e={},t={},n=s.find(o=>o.startsWith("--theme="))?.split("=")[1];n&&ae(n)&&(e.theme=n);let r=s.find(o=>o.startsWith("--style="))?.split("=")[1];return r&&(le(r)?t.style=r:(console.warn(`Invalid display style '${r}' from CLI argument, falling back to 'minimal'`),t.style="minimal")),Object.keys(t).length>0&&(e.display=t),e}function et(s=process.argv,e){let t=JSON.parse(JSON.stringify(Se)),n=s.find(a=>a.startsWith("--config="))?.split("=")[1]||Qe(),r=Xe(n,e);if(r)try{let a=Ke(r);t=Q(t,a);}catch(a){console.warn(`Warning: ${a instanceof Error?a.message:String(a)}`);}t.display?.style&&!le(t.display.style)&&(console.warn(`Invalid display style '${t.display.style}' in config file, falling back to 'minimal'`),t.display.style="minimal"),t.theme&&!ae(t.theme)&&(console.warn(`Invalid theme '${t.theme}' in config file, falling back to 'dark'`),t.theme="dark");let o=ze();t=Q(t,o);let i=Ze(s);return t=Q(t,i),t}var ke=et;async function nt(){try{let s=$.platform(),e;if(s==="darwin")e=S.join($.homedir(),"Library","Fonts");else if(s==="linux")e=S.join($.homedir(),".local","share","fonts");else if(s==="win32")e=S.join($.homedir(),"AppData","Local","Microsoft","Windows","Fonts");else {console.log("Unsupported platform for font installation");return}w.existsSync(e)||w.mkdirSync(e,{recursive:!0}),console.log("Installing Powerline Fonts..."),console.log("Downloading from https://github.com/powerline/fonts");let t=S.join($.tmpdir(),"powerline-fonts"),n=()=>{w.existsSync(t)&&w.rmSync(t,{recursive:!0,force:!0});};h.on("SIGINT",n),h.on("SIGTERM",n);try{w.existsSync(t)&&w.rmSync(t,{recursive:!0,force:!0}),console.log("Cloning powerline fonts repository..."),execSync("git clone --depth=1 https://github.com/powerline/fonts.git powerline-fonts",{stdio:"inherit",cwd:$.tmpdir()}),console.log("Installing fonts...");let r=S.join(t,"install.sh");if(w.existsSync(r))w.chmodSync(r,493),execSync("./install.sh",{stdio:"inherit",cwd:t});else throw new Error("Install script not found in powerline fonts repository");console.log("Powerline fonts installation complete!"),console.log("Please restart your terminal and set your terminal font to a powerline font."),console.log("Popular choices: Source Code Pro Powerline, DejaVu Sans Mono Powerline, Ubuntu Mono Powerline");}finally{n(),h.removeListener("SIGINT",n),h.removeListener("SIGTERM",n);}}catch(s){console.error("Error installing fonts:",s instanceof Error?s.message:String(s)),console.log("You can manually install fonts from: https://github.com/powerline/fonts");}}function Te(){console.log(`
2
+ import p from'process';import _,{join,posix}from'path';import w,{existsSync,readFileSync,createReadStream}from'fs';import {exec,execSync}from'child_process';import D,{homedir}from'os';import {json}from'stream/consumers';import {promisify}from'util';import {get}from'https';import {URL}from'url';import {createHash}from'crypto';import {setTimeout}from'timers/promises';import {readdir,stat,readFile}from'fs/promises';import {createInterface}from'readline';function re(s,e){if(e&&(s.toLowerCase()==="transparent"||s.toLowerCase()==="none"))return "\x1B[49m";let t=parseInt(s.slice(1,3),16),n=parseInt(s.slice(3,5),16),r=parseInt(s.slice(5,7),16);return `\x1B[${e?"48":"38"};2;${t};${n};${r}m`}function se(s){let e=s.match(/48;2;(\d+);(\d+);(\d+)/);return e?`\x1B[38;2;${e[1]};${e[2]};${e[3]}m`:s.replace("48","38")}var de={directory:{bg:"#8b4513",fg:"#ffffff"},git:{bg:"#404040",fg:"#ffffff"},model:{bg:"#2d2d2d",fg:"#ffffff"},session:{bg:"#202020",fg:"#00ffff"},block:{bg:"#2a2a2a",fg:"#87ceeb"},today:{bg:"#1a1a1a",fg:"#98fb98"},tmux:{bg:"#2f4f2f",fg:"#90ee90"},context:{bg:"#4a5568",fg:"#cbd5e0"},metrics:{bg:"#374151",fg:"#d1d5db"},version:{bg:"#3a3a4a",fg:"#b8b8d0"}};var fe={directory:{bg:"#ff6b47",fg:"#ffffff"},git:{bg:"#4fb3d9",fg:"#ffffff"},model:{bg:"#87ceeb",fg:"#000000"},session:{bg:"#da70d6",fg:"#ffffff"},block:{bg:"#6366f1",fg:"#ffffff"},today:{bg:"#10b981",fg:"#ffffff"},tmux:{bg:"#32cd32",fg:"#ffffff"},context:{bg:"#718096",fg:"#ffffff"},metrics:{bg:"#6b7280",fg:"#ffffff"},version:{bg:"#8b7dd8",fg:"#ffffff"}};var he={directory:{bg:"#434c5e",fg:"#d8dee9"},git:{bg:"#3b4252",fg:"#a3be8c"},model:{bg:"#4c566a",fg:"#81a1c1"},session:{bg:"#2e3440",fg:"#88c0d0"},block:{bg:"#3b4252",fg:"#81a1c1"},today:{bg:"#2e3440",fg:"#8fbcbb"},tmux:{bg:"#2e3440",fg:"#8fbcbb"},context:{bg:"#5e81ac",fg:"#eceff4"},metrics:{bg:"#b48ead",fg:"#2e3440"},version:{bg:"#434c5e",fg:"#88c0d0"}};var pe={directory:{bg:"#2f334d",fg:"#82aaff"},git:{bg:"#1e2030",fg:"#c3e88d"},model:{bg:"#191b29",fg:"#fca7ea"},session:{bg:"#222436",fg:"#86e1fc"},block:{bg:"#2d3748",fg:"#7aa2f7"},today:{bg:"#1a202c",fg:"#4fd6be"},tmux:{bg:"#191b29",fg:"#4fd6be"},context:{bg:"#414868",fg:"#c0caf5"},metrics:{bg:"#3d59a1",fg:"#c0caf5"},version:{bg:"#292e42",fg:"#bb9af7"}};var ye={directory:{bg:"#26233a",fg:"#c4a7e7"},git:{bg:"#1f1d2e",fg:"#9ccfd8"},model:{bg:"#191724",fg:"#ebbcba"},session:{bg:"#26233a",fg:"#f6c177"},block:{bg:"#2a273f",fg:"#eb6f92"},today:{bg:"#232136",fg:"#9ccfd8"},tmux:{bg:"#26233a",fg:"#908caa"},context:{bg:"#393552",fg:"#e0def4"},metrics:{bg:"#524f67",fg:"#e0def4"},version:{bg:"#2a273f",fg:"#c4a7e7"}};var Re={dark:de,light:fe,nord:he,"tokyo-night":pe,"rose-pine":ye};function G(s){return Re[s]||null}var c=(s,...e)=>{process.env.CLAUDE_POWERLINE_DEBUG&&console.error(`[DEBUG] ${s}`,...e);};var k=promisify(exec),U=class{isGitRepo(e){try{return w.existsSync(_.join(e,".git"))}catch{return false}}async getGitInfo(e,t={},n){let r=n&&this.isGitRepo(n)?n:e;if(!this.isGitRepo(r))return null;try{let o=await this.getStatusWithBranchAsync(r),i=await this.getAheadBehindAsync(r),l={branch:o.branch||"detached",status:o.status,ahead:i.ahead,behind:i.behind};t.showWorkingTree&&o.workingTree&&(l.staged=o.workingTree.staged,l.unstaged=o.workingTree.unstaged,l.untracked=o.workingTree.untracked,l.conflicts=o.workingTree.conflicts);let a={},u={};t.showSha&&(a.sha=this.getShaAsync(r)),t.showTag&&(a.tag=this.getNearestTagAsync(r)),t.showTimeSinceCommit&&(a.timeSinceCommit=this.getTimeSinceLastCommitAsync(r)),t.showStashCount&&(u.stashCount=this.getStashCountAsync(r)),t.showUpstream&&(u.upstream=this.getUpstreamAsync(r)),t.showRepoName&&(u.repoName=this.getRepoNameAsync(r));let m=new Map;for(let[d,g]of Object.entries(a))try{let f=await g;m.set(d,f);}catch{}return Object.keys(u).length>0&&(await Promise.allSettled(Object.entries(u).map(async([g,f])=>({key:g,value:await f})))).forEach(g=>{g.status==="fulfilled"&&m.set(g.value.key,g.value.value);}),t.showSha&&(l.sha=m.get("sha")||void 0),t.showOperation&&(l.operation=this.getOngoingOperation(r)||void 0),t.showTag&&(l.tag=m.get("tag")||void 0),t.showTimeSinceCommit&&(l.timeSinceCommit=m.get("timeSinceCommit")||void 0),t.showStashCount&&(l.stashCount=m.get("stashCount")||0),t.showUpstream&&(l.upstream=m.get("upstream")||void 0),t.showRepoName&&(l.repoName=m.get("repoName")||void 0,l.isWorktree=this.isWorktree(r)),l}catch{return null}}async getShaAsync(e){try{return (await k("git rev-parse --short=7 HEAD",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}getOngoingOperation(e){try{let t=_.join(e,".git");return w.existsSync(_.join(t,"MERGE_HEAD"))?"MERGE":w.existsSync(_.join(t,"CHERRY_PICK_HEAD"))?"CHERRY-PICK":w.existsSync(_.join(t,"REVERT_HEAD"))?"REVERT":w.existsSync(_.join(t,"BISECT_LOG"))?"BISECT":w.existsSync(_.join(t,"rebase-merge"))||w.existsSync(_.join(t,"rebase-apply"))?"REBASE":null}catch{return null}}async getNearestTagAsync(e){try{return (await k("git describe --tags --abbrev=0",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}async getTimeSinceLastCommitAsync(e){try{let n=(await k("git log -1 --format=%ct",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(!n)return null;let r=parseInt(n)*1e3,o=Date.now();return Math.floor((o-r)/1e3)}catch{return null}}async getStashCountAsync(e){try{let n=(await k("git stash list",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();return n?n.split(`
3
+ `).length:0}catch{return 0}}async getUpstreamAsync(e){try{return (await k("git rev-parse --abbrev-ref @{u}",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim()||null}catch{return null}}async getRepoNameAsync(e){try{let n=(await k("git config --get remote.origin.url",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();return n?n.match(/\/([^/]+?)(\.git)?$/)?.[1]||_.basename(e):_.basename(e)}catch{return _.basename(e)}}isWorktree(e){try{let t=_.join(e,".git");return !!(w.existsSync(t)&&w.statSync(t).isFile())}catch{return false}}async getStatusWithBranchAsync(e){try{c(`[GIT-EXEC] Running git status in ${e}`);let r=(await k("git status --porcelain -b",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.split(`
4
+ `),o=null,i="clean",l=0,a=0,u=0,m=0;for(let d of r)if(d){if(d.startsWith("## ")){let f=d.substring(3).split("...")[0];f&&f!=="HEAD (no branch)"&&(o=f);continue}if(d.length>=2){let g=d.charAt(0),f=d.charAt(1);if(g==="?"&&f==="?"){u++,i==="clean"&&(i="dirty");continue}let y=g+f;if(["DD","AU","UD","UA","DU","AA","UU"].includes(y)){m++,i="conflicts";continue}g!==" "&&g!=="?"&&(l++,i==="clean"&&(i="dirty")),f!==" "&&f!=="?"&&(a++,i==="clean"&&(i="dirty"));}}return {branch:o||await this.getFallbackBranch(e),status:i,workingTree:{staged:l,unstaged:a,untracked:u,conflicts:m}}}catch(t){return c(`Git status with branch command failed in ${e}:`,t),{branch:await this.getFallbackBranch(e),status:"clean"}}}async getFallbackBranch(e){try{let n=(await k("git branch --show-current",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(n)return n}catch{try{let n=(await k("git symbolic-ref --short HEAD",{cwd:e,encoding:"utf8",timeout:2e3})).stdout.trim();if(n)return n}catch{return null}}return null}async getAheadBehindAsync(e){try{c(`[GIT-EXEC] Running git ahead/behind in ${e}`);let[t,n]=await Promise.all([k("git rev-list --count @{u}..HEAD",{cwd:e,encoding:"utf8",timeout:2e3}),k("git rev-list --count HEAD..@{u}",{cwd:e,encoding:"utf8",timeout:2e3})]);return {ahead:parseInt(t.stdout.trim())||0,behind:parseInt(n.stdout.trim())||0}}catch(t){return c(`Git ahead/behind command failed in ${e}:`,t),{ahead:0,behind:0}}}};var Me=promisify(exec),F=class{async getSessionId(){try{if(!process.env.TMUX_PANE)return c("TMUX_PANE not set, not in tmux session"),null;c(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);let t=(await Me("tmux display-message -p '#S'",{encoding:"utf8",timeout:1e3})).stdout.trim();return c(`Tmux session ID: ${t||"empty"}`),t||null}catch(e){return c("Error getting tmux session ID:",e),null}}isInTmux(){return !!process.env.TMUX_PANE}};function W(){let s=[],e=process.env.CLAUDE_CONFIG_DIR;if(e&&e.split(",").forEach(t=>{let n=t.trim();existsSync(n)&&s.push(n);}),s.length===0){let t=homedir(),n=join(t,".config","claude"),r=join(t,".claude");existsSync(n)?s.push(n):existsSync(r)&&s.push(r);}return s}async function V(s){let e=[];for(let t of s){let n=join(t,"projects");if(existsSync(n))try{let r=await readdir(n,{withFileTypes:!0});for(let o of r)if(o.isDirectory()){let i=posix.join(n,o.name);e.push(i);}}catch(r){c(`Failed to read projects directory ${n}:`,r);}}return e}async function J(s){let e=W(),t=await V(e);for(let n of t){let r=posix.join(n,`${s}.jsonl`);if(existsSync(r))return r}return null}async function je(s){try{let t=(await readFile(s,"utf-8")).trim().split(`
5
+ `),n=null;for(let r of t)if(r.trim())try{let o=JSON.parse(r);if(o.timestamp&&typeof o.timestamp=="string"){let i=new Date(o.timestamp);isNaN(i.getTime())||(n===null||i<n)&&(n=i);}}catch{continue}return n}catch(e){return c(`Failed to get earliest timestamp for ${s}:`,e),null}}async function Ne(s,e=true){return (await Promise.all(s.map(async n=>({file:n,timestamp:await je(n)})))).sort((n,r)=>n.timestamp===null&&r.timestamp===null?0:n.timestamp===null?1:r.timestamp===null?-1:(e?1:-1)*(n.timestamp.getTime()-r.timestamp.getTime())).map(n=>n.file)}async function ae(s){try{return (await stat(s)).mtime}catch{return null}}function Oe(s){let e=s.message?.id||(typeof s.raw.message=="object"&&s.raw.message!==null&&"id"in s.raw.message?s.raw.message.id:void 0),t="requestId"in s.raw?s.raw.requestId:void 0;return !e||!t?null:`${e}:${t}`}var He=1024*1024;async function M(s){try{let t=(await stat(s)).size,n;return t>He?(c(`Using streaming parser for large file ${s} (${Math.round(t/1024)}KB)`),n=await We(s)):n=await Ge(s),c(`Parsed ${n.length} entries from ${s}`),n}catch(e){return c(`Failed to read file ${s}:`,e),[]}}async function Ge(s){let t=(await readFile(s,"utf-8")).trim().split(`
6
+ `).filter(r=>r.trim()),n=[];for(let r of t)try{let o=JSON.parse(r);if(!o.timestamp)continue;let i={timestamp:new Date(o.timestamp),message:o.message,costUSD:typeof o.costUSD=="number"?o.costUSD:void 0,isSidechain:o.isSidechain===!0,raw:o};n.push(i);}catch(o){c(`Failed to parse JSONL line: ${o}`);continue}return n}async function We(s){return new Promise((e,t)=>{let n=[],r=createReadStream(s,{encoding:"utf8"}),o=createInterface({input:r,crlfDelay:1/0});o.on("line",i=>{let l=i.trim();if(l)try{let a=JSON.parse(l);if(!a.timestamp)return;let u={timestamp:new Date(a.timestamp),message:a.message,costUSD:typeof a.costUSD=="number"?a.costUSD:void 0,isSidechain:a.isSidechain===!0,raw:a};n.push(u);}catch(a){c(`Failed to parse JSONL line: ${a}`);}}),o.on("close",()=>{e(n);}),o.on("error",i=>{c(`Streaming parser error for ${s}:`,i),t(i);}),r.on("error",i=>{c(`File stream error for ${s}:`,i),t(i);});})}async function Y(s,e,t=false){let n=W(),r=await V(n),o=new Set,i=r.map(async g=>{try{let b=(await readdir(g)).filter(C=>C.endsWith(".jsonl")).map(async C=>{let ne=posix.join(g,C);if(existsSync(ne)){let $e=await ae(ne);return {filePath:ne,mtime:$e}}return null});return (await Promise.all(b)).filter(C=>C?.mtime&&(!e||e(C.filePath,C.mtime)))}catch(f){return c(`Failed to read project directory ${g}:`,f),[]}}),a=(await Promise.all(i)).flat().filter(g=>g!==null).map(g=>g.filePath);if(t){let g=await Ne(a,false);a.length=0,a.push(...g);}let u=[],m=a.map(async g=>(await M(g)).filter(y=>{let b=Oe(y);return b&&o.has(b)?false:(b&&o.add(b),!s||s(y))})),d=await Promise.all(m);for(let g of d)u.push(...g);return u}var E=class{static CACHE_DIR=_.join(homedir(),".claude","powerline");static USAGE_CACHE_DIR=_.join(this.CACHE_DIR,"usage");static LOCKS_DIR=_.join(this.CACHE_DIR,"locks");static isLocked(e){let t=_.join(this.LOCKS_DIR,e);if(!w.existsSync(t))return false;try{let n=w.readFileSync(t,"utf-8"),r=parseInt(n.trim(),10);if(isNaN(r))return c(`Invalid PID in lock file ${e}, removing stale lock`),w.unlinkSync(t),!1;try{return process.kill(r,0),!0}catch(o){return o.code==="ESRCH"?(c(`Removing stale lock file ${e} for dead process ${r}`),w.unlinkSync(t),!1):(c(`Error checking process ${r} for lock ${e}:`,o),!0)}}catch(n){return c(`Error reading lock file ${e}:`,n),true}}static async acquireLock(e,t=5e3){await this.ensureCacheDirectories();let o=_.join(this.LOCKS_DIR,e),i=Date.now(),l=String(process.pid);for(;Date.now()-i<t;)try{return await w.promises.writeFile(o,l,{flag:"wx"}),c(`Lock acquired for ${e}`),!0}catch(a){if(a.code==="EEXIST")await setTimeout(50);else throw a}return c(`Failed to acquire lock for ${e} within ${t}ms`),false}static async releaseLock(e){let t=_.join(this.LOCKS_DIR,e);try{await w.promises.unlink(t),c(`Lock released for ${e}`);}catch(n){n.code!=="ENOENT"&&c(`Error releasing lock for ${e}:`,n);}}static async ensureCacheDirectories(){try{await Promise.all([w.promises.mkdir(this.CACHE_DIR,{recursive:!0}),w.promises.mkdir(this.USAGE_CACHE_DIR,{recursive:!0}),w.promises.mkdir(this.LOCKS_DIR,{recursive:!0})]);}catch(e){c("Failed to create cache directories:",e);}}static createProjectHash(e){return createHash("md5").update(e).digest("hex").substring(0,8)}static async getUsageCache(e,t){let o="utf-8";await this.ensureCacheDirectories();let i=_.join(this.USAGE_CACHE_DIR,`${e}.json`),l=`${e}.usage.lock`;for(let a=0;a<3;a++){if(this.isLocked(l)){c(`Cache for ${e} is locked, waiting...`),await setTimeout(75);continue}try{let m=await w.promises.readFile(i,o),d=JSON.parse(m);return !t||d.timestamp>=t?(c(`[CACHE-HIT] ${e} disk cache: found`),this.deserializeDates(d.data)):(c(`${e} cache outdated: cache=${d.timestamp}, latest=${t}`),null)}catch(m){if(m.code==="ENOENT")return c(`No shared ${e} usage cache found`),null;let d=a+1;c(`Attempt ${d} failed to read ${e} cache: ${m.message}. Retrying...`),await setTimeout(75);}}return c(`Failed to read ${e} cache after 3 attempts.`),null}static deserializeDates(e){return Array.isArray(e)?e.map(t=>({...t,timestamp:new Date(t.timestamp)})):e}static async setUsageCache(e,t,n){let r=`${e}.usage.lock`;if(!await this.acquireLock(r)){c(`Could not acquire lock to set usage cache for ${e}`);return}try{await this.ensureCacheDirectories();let i=_.join(this.USAGE_CACHE_DIR,`${e}.json`),l=n||Date.now(),u=JSON.stringify({data:t,timestamp:l});await w.promises.writeFile(i,u,"utf-8"),c(`[CACHE-SET] ${e} disk cache stored`);}catch(i){c(`Failed to save ${e} usage cache:`,i);}finally{await this.releaseLock(r);}}static async getLatestTranscriptMtime(){try{let e=W(),t=await V(e),n=0;for(let r of t)try{let i=(await w.promises.readdir(r)).filter(l=>l.endsWith(".jsonl"));for(let l of i){let a=_.join(r,l),u=await ae(a);u&&u.getTime()>n&&(n=u.getTime());}}catch(o){c(`Failed to read project directory ${r}:`,o);continue}return n}catch(e){return c("Failed to get latest transcript mtime:",e),Date.now()}}};var q={"claude-3-haiku-20240307":{name:"Claude 3 Haiku",input:.25,output:1.25,cache_write_5m:.3,cache_write_1h:.5,cache_read:.03},"claude-3-5-haiku-20241022":{name:"Claude 3.5 Haiku",input:.8,output:4,cache_write_5m:1,cache_write_1h:1.6,cache_read:.08},"claude-3-5-haiku-latest":{name:"Claude 3.5 Haiku Latest",input:1,output:5,cache_write_5m:1.25,cache_write_1h:2,cache_read:.1},"claude-3-opus-latest":{name:"Claude 3 Opus Latest",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-3-opus-20240229":{name:"Claude 3 Opus",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-3-5-sonnet-latest":{name:"Claude 3.5 Sonnet Latest",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-3-5-sonnet-20240620":{name:"Claude 3.5 Sonnet",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-3-5-sonnet-20241022":{name:"Claude 3.5 Sonnet",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-opus-4-20250514":{name:"Claude Opus 4",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-opus-4-1":{name:"Claude Opus 4.1",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-opus-4-1-20250805":{name:"Claude Opus 4.1",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-sonnet-4-20250514":{name:"Claude Sonnet 4",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-4-opus-20250514":{name:"Claude 4 Opus",input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-4-sonnet-20250514":{name:"Claude 4 Sonnet",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-3-7-sonnet-latest":{name:"Claude 3.7 Sonnet Latest",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-3-7-sonnet-20250219":{name:"Claude 3.7 Sonnet",input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3}},v=class{static executionCache=null;static modelPricingCache=new Map;static GITHUB_PRICING_URL="https://raw.githubusercontent.com/Owloops/claude-powerline/main/pricing.json";static async loadDiskCache(){let t=Date.now()-864e5;return await E.getUsageCache("pricing",t)}static async saveDiskCache(e){await E.setUsageCache("pricing",e);}static async fetchPricingData(){return new Promise(e=>{let t=new URL(this.GITHUB_PRICING_URL),n=get({hostname:t.hostname,path:t.pathname,headers:{"User-Agent":"claude-powerline","Cache-Control":"no-cache"},timeout:5e3},r=>{if(r.statusCode!==200){c(`HTTP ${r.statusCode}: ${r.statusMessage}`),e(null);return}let o="",i=0,l=1024*1024;r.on("data",a=>{if(i+=a.length,i>l){c("Response too large"),n.destroy(),e(null);return}o+=a;}),r.on("end",()=>{try{let u=JSON.parse(o),m=u._meta,d={};for(let[g,f]of Object.entries(u))g!=="_meta"&&(d[g]=f);this.validatePricingData(d)?(c(`Fetched fresh pricing from GitHub for ${Object.keys(d).length} models`),c(`Pricing last updated: ${m?.updated||"unknown"}`),e(d)):(c("Invalid pricing data structure"),e(null));}catch(a){c("Failed to parse JSON:",a),e(null);}}),r.on("error",a=>{c("Response error:",a),e(null);});});n.on("error",r=>{c("Request error:",r),e(null);}),n.on("timeout",()=>{c("Request timeout"),n.destroy(),e(null);}),n.end();})}static async getCurrentPricing(){if(this.executionCache!==null)return c(`[CACHE-HIT] Pricing execution cache: ${Object.keys(this.executionCache).length} models`),this.executionCache;let e=await this.loadDiskCache();if(e)return c(`[CACHE-HIT] Pricing disk cache: ${Object.keys(e).length} models`),this.executionCache=e,c(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(e).length} models`),e;let t=await this.fetchPricingData();return t?(await this.saveDiskCache(t),c(`[CACHE-SET] Pricing disk cache stored: ${Object.keys(t).length} models`),this.executionCache=t,c(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(t).length} models`),t):(c(`[CACHE-FALLBACK] Using offline pricing data: ${Object.keys(q).length} models`),this.executionCache=q,c(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(q).length} models`),q)}static validatePricingData(e){if(!e||typeof e!="object")return false;for(let[,t]of Object.entries(e)){if(!t||typeof t!="object")return false;let n=t;if(typeof n.input!="number"||typeof n.output!="number"||typeof n.cache_read!="number")return false}return true}static async getModelPricing(e){if(this.modelPricingCache.has(e))return c(`[CACHE-HIT] Model pricing cache: ${e}`),this.modelPricingCache.get(e);let t=await this.getCurrentPricing(),n;return t[e]?n=t[e]:n=this.fuzzyMatchModel(e,t),this.modelPricingCache.set(e,n),c(`[CACHE-SET] Model pricing cache: ${e}`),n}static fuzzyMatchModel(e,t){let n=e.toLowerCase();for(let[o,i]of Object.entries(t))if(o.toLowerCase()===n)return i;let r=[{pattern:["opus-4-1","claude-opus-4-1"],fallback:"claude-opus-4-1-20250805"},{pattern:["opus-4","claude-opus-4"],fallback:"claude-opus-4-20250514"},{pattern:["sonnet-4","claude-sonnet-4"],fallback:"claude-sonnet-4-20250514"},{pattern:["sonnet-3.7","3-7-sonnet"],fallback:"claude-3-7-sonnet-20250219"},{pattern:["3-5-sonnet","sonnet-3.5"],fallback:"claude-3-5-sonnet-20241022"},{pattern:["3-5-haiku","haiku-3.5"],fallback:"claude-3-5-haiku-20241022"},{pattern:["haiku","3-haiku"],fallback:"claude-3-haiku-20240307"},{pattern:["opus"],fallback:"claude-opus-4-20250514"},{pattern:["sonnet"],fallback:"claude-3-5-sonnet-20241022"}];for(let{pattern:o,fallback:i}of r)if(o.some(l=>n.includes(l))&&t[i])return t[i];return t["claude-3-5-sonnet-20241022"]||{name:`${e} (Unknown Model)`,input:3,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3,output:15}}static async calculateCostForEntry(e){let n=e.message?.usage;if(!n)return 0;let r=this.extractModelId(e),o=await this.getModelPricing(r),i=n.input_tokens||0,l=n.output_tokens||0,a=n.cache_creation_input_tokens||0,u=n.cache_read_input_tokens||0,m=i/1e6*o.input,d=l/1e6*o.output,g=u/1e6*o.cache_read,f=a/1e6*o.cache_write_5m;return m+d+f+g}static extractModelId(e){if(e.model&&typeof e.model=="string")return e.model;let t=e.message;if(t?.model){let n=t.model;return typeof n=="string"?n:n?.id||"claude-3-5-sonnet-20241022"}return e.model_id&&typeof e.model_id=="string"?e.model_id:"claude-3-5-sonnet-20241022"}};function Xe(s){return {timestamp:s.timestamp.toISOString(),message:{usage:{input_tokens:s.message?.usage?.input_tokens||0,output_tokens:s.message?.usage?.output_tokens||0,cache_creation_input_tokens:s.message?.usage?.cache_creation_input_tokens,cache_read_input_tokens:s.message?.usage?.cache_read_input_tokens}},costUSD:s.costUSD}}var X=class{async getSessionUsage(e){try{let t=await J(e);if(!t)return c(`No transcript found for session: ${e}`),null;c(`Found transcript at: ${t}`);let n=await M(t);if(n.length===0)return {totalCost:0,entries:[]};let r=[],o=0;for(let i of n)if(i.message?.usage){let l=Xe(i);if(l.costUSD!==void 0)o+=l.costUSD;else {let a=await v.calculateCostForEntry(i.raw);l.costUSD=a,o+=a;}r.push(l);}return c(`Parsed ${r.length} usage entries, total cost: $${o.toFixed(4)}`),{totalCost:o,entries:r}}catch(t){return c(`Error reading session usage for ${e}:`,t),null}}calculateTokenBreakdown(e){return e.reduce((t,n)=>({input:t.input+(n.message.usage.input_tokens||0),output:t.output+(n.message.usage.output_tokens||0),cacheCreation:t.cacheCreation+(n.message.usage.cache_creation_input_tokens||0),cacheRead:t.cacheRead+(n.message.usage.cache_read_input_tokens||0)}),{input:0,output:0,cacheCreation:0,cacheRead:0})}async getSessionInfo(e,t){let n=await this.getSessionUsage(e);if(!n||n.entries.length===0)return {cost:null,calculatedCost:null,officialCost:null,tokens:null,tokenBreakdown:null};let r=this.calculateTokenBreakdown(n.entries),o=r.input+r.output+r.cacheCreation+r.cacheRead,i=n.totalCost,l=t?.cost?.total_cost_usd??null;return {cost:i??l,calculatedCost:i,officialCost:l,tokens:o,tokenBreakdown:r}}},A=class{sessionProvider=new X;async getUsageInfo(e,t){try{return c(`Starting usage info retrieval for session: ${e}`),{session:await this.sessionProvider.getSessionInfo(e,t)}}catch(n){return c(`Error getting usage info for session ${e}:`,n),{session:{cost:null,calculatedCost:null,officialCost:null,tokens:null,tokenBreakdown:null}}}}};var L=class{thresholds={LOW:50,MEDIUM:80};getContextUsageThresholds(){return this.thresholds}getContextLimit(e){return 2e5}async calculateContextTokens(e,t){try{c(`Calculating context tokens from transcript: ${e}`);try{if(!readFileSync(e,"utf-8"))return c("Transcript file is empty"),null}catch{return c("Could not read transcript file"),null}let n=await M(e);if(n.length===0)return c("No entries in transcript"),null;let r=null;for(let o=n.length-1;o>=0;o--){let i=n[o];if(i&&i.message?.usage?.input_tokens&&i.isSidechain!==!0){r=i,c(`Context segment: Found most recent entry at ${i.timestamp.toISOString()}, stopping search`);break}}if(r?.message?.usage){let o=r.message.usage,i=(o.input_tokens||0)+(o.cache_read_input_tokens||0)+(o.cache_creation_input_tokens||0),l=t?this.getContextLimit(t):2e5;c(`Most recent main chain context: ${i} tokens (limit: ${l})`);let a=Math.min(100,Math.max(0,Math.round(i/l*100))),u=Math.round(l*.75),m=Math.min(100,Math.max(0,Math.round(i/u*100))),d=Math.max(0,100-m);return {inputTokens:i,percentage:a,usablePercentage:m,contextLeftPercentage:d,maxTokens:l,usableTokens:u}}return c("No main chain entries with usage data found"),null}catch(n){return c(`Error reading transcript: ${n instanceof Error?n.message:String(n)}`),null}}};var I=class{async loadTranscriptEntries(e){try{let t=await J(e);if(!t)return c(`No transcript found for session: ${e}`),[];c(`Loading transcript from: ${t}`);let r=(await readFile(t,"utf-8")).trim().split(`
7
+ `).filter(i=>i.trim()),o=[];for(let i of r)try{let l=JSON.parse(i);if(l.isSidechain===!0)continue;o.push(l);}catch(l){c(`Failed to parse JSONL line: ${l}`);continue}return c(`Loaded ${o.length} transcript entries`),o}catch(t){return c(`Error loading transcript for ${e}:`,t),[]}}calculateMessageCount(e){return e.filter(t=>{let n=t.type||t.message?.role||t.message?.type,r=t.type==="user"&&t.message?.content?.[0]?.type==="tool_result";return n==="user"&&!r}).length}calculateLastResponseTime(e){if(e.length===0)return null;let t=e.slice(-20),n=null,r=null;for(let o of t)if(o.timestamp)try{let i=new Date(o.timestamp),l=o.type||o.message?.role||o.message?.type,a=o.type==="user"&&o.message?.content?.[0]?.type==="tool_result";if(l==="user"&&!a)n=i;else if(l==="assistant"&&n){let m=(i.getTime()-n.getTime())/1e3;m>.1&&m<300&&(r=m);}}catch{continue}return r}async getMetricsInfo(e,t){try{if(c(`Getting metrics from hook data for session: ${e}`),!t.cost)return c("No cost data available in hook data"),{responseTime:null,lastResponseTime:null,sessionDuration:null,messageCount:null,linesAdded:null,linesRemoved:null};let n=await this.loadTranscriptEntries(e),r=this.calculateMessageCount(n),o=this.calculateLastResponseTime(n);return {responseTime:t.cost.total_api_duration_ms/1e3,lastResponseTime:o,sessionDuration:t.cost.total_duration_ms/1e3,messageCount:r,linesAdded:t.cost.total_lines_added,linesRemoved:t.cost.total_lines_removed}}catch(n){return c(`Error getting metrics from hook data for session ${e}:`,n),{responseTime:null,lastResponseTime:null,sessionDuration:null,messageCount:null,linesAdded:null,linesRemoved:null}}}};function T(s){return s===null?"$0.00":s<.01?"<$0.01":`$${s.toFixed(2)}`}function S(s){return s===null||s===0?"0 tokens":s>=1e6?`${(s/1e6).toFixed(1)}M tokens`:s>=1e3?`${(s/1e3).toFixed(1)}K tokens`:`${s} tokens`}function le(s){if(!s)return "0 tokens";let e=[];if(s.input>0&&e.push(`${S(s.input).replace(" tokens","")}in`),s.output>0&&e.push(`${S(s.output).replace(" tokens","")}out`),s.cacheCreation>0||s.cacheRead>0){let t=s.cacheCreation+s.cacheRead;e.push(`${S(t).replace(" tokens","")}cached`);}return e.length>0?e.join(" + "):"0 tokens"}function we(s){return s<60?`${s}s`:s<3600?`${Math.floor(s/60)}m`:s<86400?`${Math.floor(s/3600)}h`:s<604800?`${Math.floor(s/86400)}d`:`${Math.floor(s/604800)}w`}function Se(s){return s<60?`${s.toFixed(0)}s`:s<3600?`${(s/60).toFixed(0)}m`:s<86400?`${(s/3600).toFixed(1)}h`:`${(s/86400).toFixed(1)}d`}function Ze(s,e){return !e||e<=0||s<0?null:Math.min(100,s/e*100)}function ke(s,e,t=80){let n=Ze(s,e);if(n===null)return {percentage:null,isWarning:false,displayText:""};let r=`${n.toFixed(0)}%`,o=n>=t,i="";return o?i=` !${r}`:n>=50?i=` +${r}`:i=` ${r}`,{percentage:n,isWarning:o,displayText:i}}var j=class{constructor(e,t){this.config=e;this.symbols=t;}renderDirectory(e,t,n){let r=e.workspace?.current_dir||e.cwd||"/",o=e.workspace?.project_dir;if(n?.showBasename)return {text:_.basename(r)||"root",bgColor:t.modeBg,fgColor:t.modeFg};let i=process.env.HOME||process.env.USERPROFILE,l=r,a=o;return i&&(r.startsWith(i)&&(l=r.replace(i,"~")),o&&o.startsWith(i)&&(a=o.replace(i,"~"))),{text:this.getDisplayDirectoryName(l,a),bgColor:t.modeBg,fgColor:t.modeFg}}renderGit(e,t,n){if(!e)return null;let r=[];if(n?.showRepoName&&e.repoName&&(r.push(e.repoName),e.isWorktree&&r.push(this.symbols.git_worktree)),n?.showOperation&&e.operation&&r.push(`[${e.operation}]`),r.push(`${this.symbols.branch} ${e.branch}`),n?.showTag&&e.tag&&r.push(`${this.symbols.git_tag} ${e.tag}`),n?.showSha&&e.sha&&r.push(`${this.symbols.git_sha} ${e.sha}`),n?.showAheadBehind!==false&&(e.ahead>0&&e.behind>0?r.push(`${this.symbols.git_ahead}${e.ahead}${this.symbols.git_behind}${e.behind}`):e.ahead>0?r.push(`${this.symbols.git_ahead}${e.ahead}`):e.behind>0&&r.push(`${this.symbols.git_behind}${e.behind}`)),n?.showWorkingTree){let i=[];e.staged&&e.staged>0&&i.push(`+${e.staged}`),e.unstaged&&e.unstaged>0&&i.push(`~${e.unstaged}`),e.untracked&&e.untracked>0&&i.push(`?${e.untracked}`),e.conflicts&&e.conflicts>0&&i.push(`!${e.conflicts}`),i.length>0&&r.push(`(${i.join(" ")})`);}if(n?.showUpstream&&e.upstream&&r.push(`${this.symbols.git_upstream}${e.upstream}`),n?.showStashCount&&e.stashCount&&e.stashCount>0&&r.push(`${this.symbols.git_stash} ${e.stashCount}`),n?.showTimeSinceCommit&&e.timeSinceCommit!==void 0){let i=we(e.timeSinceCommit);r.push(`${this.symbols.git_time} ${i}`);}let o=this.symbols.git_clean;return e.status==="conflicts"?o=this.symbols.git_conflicts:e.status==="dirty"&&(o=this.symbols.git_dirty),r.push(o),{text:r.join(" "),bgColor:t.gitBg,fgColor:t.gitFg}}renderModel(e,t){let n=e.model?.display_name||"Claude";return {text:`${this.symbols.model} ${n}`,bgColor:t.modelBg,fgColor:t.modelFg}}renderSession(e,t,n){let r=n?.type||"cost",o=n?.costSource,i=this.config.budget?.session,l=o?this.formatSessionUsageDisplay(e.session,r,o):this.formatUsageWithBudget(e.session.cost,e.session.tokens,e.session.tokenBreakdown,r,i?.amount,i?.warningThreshold||80);return {text:`${this.symbols.session_cost} ${l}`,bgColor:t.sessionBg,fgColor:t.sessionFg}}renderTmux(e,t){return e?{text:`tmux:${e}`,bgColor:t.tmuxBg,fgColor:t.tmuxFg}:{text:"tmux:none",bgColor:t.tmuxBg,fgColor:t.tmuxFg}}renderContext(e,t){if(!e)return {text:`${this.symbols.context_time} 0 (100%)`,bgColor:t.contextBg,fgColor:t.contextFg};let n=e.inputTokens.toLocaleString(),r=`${e.contextLeftPercentage}%`;return {text:`${this.symbols.context_time} ${n} (${r})`,bgColor:t.contextBg,fgColor:t.contextFg}}renderMetrics(e,t,n,r){if(!e)return {text:`${this.symbols.metrics_response} new`,bgColor:t.metricsBg,fgColor:t.metricsFg};let o=[];if(r?.showLastResponseTime&&e.lastResponseTime!==null){let i=e.lastResponseTime<60?`${e.lastResponseTime.toFixed(1)}s`:`${(e.lastResponseTime/60).toFixed(1)}m`;o.push(`${this.symbols.metrics_last_response} ${i}`);}if(r?.showResponseTime!==false&&e.responseTime!==null){let i=e.responseTime<60?`${e.responseTime.toFixed(1)}s`:`${(e.responseTime/60).toFixed(1)}m`;o.push(`${this.symbols.metrics_response} ${i}`);}if(r?.showDuration!==false&&e.sessionDuration!==null){let i=Se(e.sessionDuration);o.push(`${this.symbols.metrics_duration} ${i}`);}return r?.showMessageCount!==false&&e.messageCount!==null&&o.push(`${this.symbols.metrics_messages} ${e.messageCount}`),r?.showLinesAdded!==false&&e.linesAdded!==null&&e.linesAdded>0&&o.push(`${this.symbols.metrics_lines_added} ${e.linesAdded}`),r?.showLinesRemoved!==false&&e.linesRemoved!==null&&e.linesRemoved>0&&o.push(`${this.symbols.metrics_lines_removed} ${e.linesRemoved}`),o.length===0?{text:`${this.symbols.metrics_response} active`,bgColor:t.metricsBg,fgColor:t.metricsFg}:{text:o.join(" "),bgColor:t.metricsBg,fgColor:t.metricsFg}}renderBlock(e,t,n){let r;if(e.cost===null&&e.tokens===null)r="No active block";else {let o=n?.type||"cost",i=n?.burnType,l=e.timeRemaining!==null?(()=>{let m=Math.floor(e.timeRemaining/60),d=e.timeRemaining%60;return m>0?`${m}h ${d}m`:`${d}m`})():null,a;switch(o){case "cost":a=T(e.cost);break;case "tokens":a=S(e.tokens);break;case "both":a=`${T(e.cost)} / ${S(e.tokens)}`;break;case "time":a=l||"N/A";break;default:a=T(e.cost);}let u="";if(i&&i!=="none")switch(i){case "cost":u=` | ${e.burnRate!==null?e.burnRate<1?`${(e.burnRate*100).toFixed(0)}\xA2/h`:`$${e.burnRate.toFixed(2)}/h`:"N/A"}`;break;case "tokens":u=` | ${e.tokenBurnRate!==null?`${S(Math.round(e.tokenBurnRate))}/h`:"N/A"}`;break;case "both":let g=e.burnRate!==null?e.burnRate<1?`${(e.burnRate*100).toFixed(0)}\xA2/h`:`$${e.burnRate.toFixed(2)}/h`:"N/A",f=e.tokenBurnRate!==null?`${S(Math.round(e.tokenBurnRate))}/h`:"N/A";u=` | ${g} / ${f}`;break}o==="time"?r=a:r=l?`${a}${u} (${l} left)`:`${a}${u}`;}return {text:`${this.symbols.block_cost} ${r}`,bgColor:t.blockBg,fgColor:t.blockFg}}renderToday(e,t,n="cost"){let r=this.config.budget?.today;return {text:`${this.symbols.today_cost} ${this.formatUsageWithBudget(e.cost,e.tokens,e.tokenBreakdown,n,r?.amount,r?.warningThreshold)}`,bgColor:t.todayBg,fgColor:t.todayFg}}getDisplayDirectoryName(e,t){return e.startsWith("~")?e:t&&t!==e?e.startsWith(t)?e.slice(t.length+1)||_.basename(t)||"project":_.basename(e)||"root":_.basename(e)||"root"}formatUsageDisplay(e,t,n,r){switch(r){case "cost":return T(e);case "tokens":return S(t);case "both":return `${T(e)} (${S(t)})`;case "breakdown":return le(n);default:return T(e)}}formatSessionUsageDisplay(e,t,n){let r=()=>n==="calculated"?e.calculatedCost:n==="official"?e.officialCost:e.cost;switch(t){case "cost":return T(r());case "tokens":return S(e.tokens);case "both":return `${T(r())} (${S(e.tokens)})`;case "breakdown":return le(e.tokenBreakdown);default:return T(r())}}formatUsageWithBudget(e,t,n,r,o,i=80){let l=this.formatUsageDisplay(e,t,n,r);if(o&&o>0&&e!==null){let a=ke(e,o,i);return l+a.displayText}return l}renderVersion(e,t,n){return e.version?{text:`${this.symbols.version} v${e.version}`,bgColor:t.versionBg,fgColor:t.versionFg}:null}};function Qe(s){return {timestamp:s.timestamp,usage:{inputTokens:s.message?.usage?.input_tokens||0,outputTokens:s.message?.usage?.output_tokens||0,cacheCreationInputTokens:s.message?.usage?.cache_creation_input_tokens||0,cacheReadInputTokens:s.message?.usage?.cache_read_input_tokens||0},costUSD:s.costUSD||0,model:s.message?.model||"unknown"}}var K=class{sessionDurationHours=5;floorToHour(e){let t=new Date(e);return t.setUTCMinutes(0,0,0),t}identifySessionBlocks(e){if(e.length===0)return [];let t=this.sessionDurationHours*60*60*1e3,n=[],r=[...e].sort((l,a)=>l.timestamp.getTime()-a.timestamp.getTime()),o=null,i=[];for(let l of r){let a=l.timestamp;if(o==null)o=this.floorToHour(a),i=[l];else {let u=a.getTime()-o.getTime(),m=i[i.length-1];if(m==null)continue;let d=m.timestamp,g=a.getTime()-d.getTime();u>t||g>t?(n.push(i),o=this.floorToHour(a),i=[l]):i.push(l);}}return o!=null&&i.length>0&&n.push(i),n}createBlockInfo(e,t){let n=new Date,r=this.sessionDurationHours*60*60*1e3,o=new Date(e.getTime()+r),i=t[t.length-1],l=i!=null?i.timestamp:e,a=n.getTime()-l.getTime()<r&&n<o;return {block:t,isActive:a}}findActiveBlock(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(!n||n.length===0)continue;let r=n[0];if(!r)continue;let o=this.floorToHour(r.timestamp),i=this.createBlockInfo(o,n);if(i.isActive)return i.block}return null}async loadUsageEntries(){try{c("Block segment: Loading entries for dynamic session blocks");let e=new Date;e.setDate(e.getDate()-1);let n=await Y(void 0,(a,u)=>u>=e,!0),r=[];for(let a of n)if(a.message?.usage){let u=Qe(a);!u.costUSD&&a.raw&&(u.costUSD=await v.calculateCostForEntry(a.raw)),r.push(u);}let o=this.identifySessionBlocks(r);c(`Block segment: Found ${o.length} session blocks`);let i=this.findActiveBlock(o),l=[];if(i&&i.length>0){c(`Block segment: Found active block with ${i.length} entries`);let a=i[0],u=i[i.length-1];a&&u&&c(`Block segment: Active block from ${a.timestamp.toISOString()} to ${u.timestamp.toISOString()}`),l=i;}else c("Block segment: No active block found"),l=[];return l}catch(e){return c("Error loading block entries:",e),[]}}async getActiveBlockInfo(){try{let e=await this.loadUsageEntries();if(e.length===0)return c("Block segment: No entries in current block"),{cost:null,tokens:null,timeRemaining:null,burnRate:null,tokenBurnRate:null};let t=e.reduce((a,u)=>a+u.costUSD,0),n=e.reduce((a,u)=>a+u.usage.inputTokens+u.usage.outputTokens+u.usage.cacheCreationInputTokens+u.usage.cacheReadInputTokens,0),r=new Date,o=null;if(e.length>0){let a=e[0];if(a){let u=this.sessionDurationHours*60*60*1e3,m=this.floorToHour(a.timestamp),d=new Date(m.getTime()+u);o=Math.max(0,Math.round((d.getTime()-r.getTime())/(1e3*60)));}}let i=null,l=null;if(e.length>=1&&(t>0||n>0)){let a=e.map(d=>d.timestamp).sort((d,g)=>d.getTime()-g.getTime()),u=a[0],m=a[a.length-1];if(u&&m){let d=(m.getTime()-u.getTime())/6e4;d>0&&(t>0&&(i=t/d*60),n>0&&(l=n/d*60));}}return c(`Block segment: $${t.toFixed(2)}, ${n} tokens, ${o}m remaining, burn rate: ${i?"$"+i.toFixed(2)+"/hr":"N/A"}`),{cost:t,tokens:n,timeRemaining:o,burnRate:i,tokenBurnRate:l}}catch(e){return c("Error getting active block info:",e),{cost:null,tokens:null,timeRemaining:null,burnRate:null,tokenBurnRate:null}}}};function N(s){let e=s.getFullYear(),t=String(s.getMonth()+1).padStart(2,"0"),n=String(s.getDate()).padStart(2,"0");return `${e}-${t}-${n}`}function et(s){return s.inputTokens+s.outputTokens+s.cacheCreationInputTokens+s.cacheReadInputTokens}function tt(s){return {timestamp:s.timestamp,usage:{inputTokens:s.message?.usage?.input_tokens||0,outputTokens:s.message?.usage?.output_tokens||0,cacheCreationInputTokens:s.message?.usage?.cache_creation_input_tokens||0,cacheReadInputTokens:s.message?.usage?.cache_read_input_tokens||0},costUSD:s.costUSD||0,model:s.message?.model||"unknown"}}var Z=class{async loadTodayEntries(){let t=N(new Date);c(`Today segment: Loading entries for date ${t}`);let n=await E.getLatestTranscriptMtime(),r=await E.getUsageCache("today",n);if(r)return c("Using shared today usage cache"),r;let o=new Date;o.setDate(o.getDate()-1),o.setHours(0,0,0,0);let i=(g,f)=>f>=o,l=new Date;l.setHours(0,0,0,0);let u=await Y(g=>g.timestamp>=l,i,true),m=[],d=0;for(let g of u)if(N(g.timestamp)===t&&g.message?.usage){let y=tt(g);!y.costUSD&&g.raw&&(y.costUSD=await v.calculateCostForEntry(g.raw)),m.push(y),d++;}return c(`Today segment: Found ${d} entries for today (${t})`),await E.setUsageCache("today",m,n),m}async getTodayEntries(){try{return await this.loadTodayEntries()}catch(e){return c("Error loading today's entries:",e),[]}}async getTodayInfo(){try{let e=await this.getTodayEntries();if(e.length===0)return {cost:null,tokens:null,tokenBreakdown:null,date:N(new Date)};let t=e.reduce((o,i)=>o+i.costUSD,0),n=e.reduce((o,i)=>o+et(i.usage),0),r=e.reduce((o,i)=>({input:o.input+i.usage.inputTokens,output:o.output+i.usage.outputTokens,cacheCreation:o.cacheCreation+i.usage.cacheCreationInputTokens,cacheRead:o.cacheRead+i.usage.cacheReadInputTokens}),{input:0,output:0,cacheCreation:0,cacheRead:0});return c(`Today segment: $${t.toFixed(2)}, ${n} tokens total`),{cost:t,tokens:n,tokenBreakdown:r,date:N(new Date)}}catch(e){return c("Error getting today's info:",e),{cost:null,tokens:null,tokenBreakdown:null,date:N(new Date)}}}};var O="\x1B[0m",h={right:"\uE0B0",branch:"\u2387",model:"\u26A1",git_clean:"\u2713",git_dirty:"\u25CF",git_conflicts:"\u26A0",git_ahead:"\u2191",git_behind:"\u2193",git_worktree:"\u29C9",git_tag:"\u2302",git_sha:"\u266F",git_upstream:"\u2192",git_stash:"\u29C7",git_time:"\u25F7",session_cost:"\xA7",block_cost:"\u25F1",today_cost:"\u2609",context_time:"\u25D4",metrics_response:"\u29D6",metrics_last_response:"\u0394",metrics_duration:"\u29D7",metrics_messages:"\u27D0",metrics_lines_added:"+",metrics_lines_removed:"-",metrics_burn:"\u27E2",version:"\u25C8"};var Q=class{constructor(e){this.config=e;this.symbols=this.initializeSymbols();}symbols;_usageProvider;_blockProvider;_todayProvider;_contextProvider;_gitService;_tmuxService;_metricsProvider;_segmentRenderer;get usageProvider(){return this._usageProvider||(this._usageProvider=new A),this._usageProvider}get blockProvider(){return this._blockProvider||(this._blockProvider=new K),this._blockProvider}get todayProvider(){return this._todayProvider||(this._todayProvider=new Z),this._todayProvider}get contextProvider(){return this._contextProvider||(this._contextProvider=new L),this._contextProvider}get gitService(){return this._gitService||(this._gitService=new U),this._gitService}get tmuxService(){return this._tmuxService||(this._tmuxService=new F),this._tmuxService}get metricsProvider(){return this._metricsProvider||(this._metricsProvider=new I),this._metricsProvider}get segmentRenderer(){return this._segmentRenderer||(this._segmentRenderer=new j(this.config,this.symbols)),this._segmentRenderer}needsSegmentInfo(e){return this.config.display.lines.some(t=>t.segments[e]?.enabled)}async generateStatusline(e){let t=this.needsSegmentInfo("session")?await this.usageProvider.getUsageInfo(e.session_id,e):null,n=this.needsSegmentInfo("block")?await this.blockProvider.getActiveBlockInfo():null,r=this.needsSegmentInfo("today")?await this.todayProvider.getTodayInfo():null,o=this.needsSegmentInfo("context")?await this.contextProvider.calculateContextTokens(e.transcript_path,e.model?.id):null,i=this.needsSegmentInfo("metrics")?await this.metricsProvider.getMetricsInfo(e.session_id,e):null;return (await Promise.all(this.config.display.lines.map(a=>this.renderLine(a,e,t,n,r,o,i)))).filter(a=>a.length>0).join(`
8
+ `)}async renderLine(e,t,n,r,o,i,l){let a=this.getThemeColors(),u=t.workspace?.current_dir||t.cwd||"/",m=Object.entries(e.segments).filter(([g,f])=>f?.enabled).map(([g,f])=>({type:g,config:f})),d=a.reset;for(let g=0;g<m.length;g++){let f=m[g];if(!f)continue;let y=g===m.length-1,b=y?null:m[g+1],B=b?this.getSegmentBgColor(b.type,a):"",C=await this.renderSegment(f,t,n,r,o,i,l,a,u);C&&(d+=this.formatSegment(C.bgColor,C.fgColor,C.text,y?void 0:B));}return d}async renderSegment(e,t,n,r,o,i,l,a,u){return e.type==="directory"?this.segmentRenderer.renderDirectory(t,a,e.config):e.type==="model"?this.segmentRenderer.renderModel(t,a):e.type==="git"?await this.renderGitSegment(e.config,t,a,u):e.type==="session"?this.renderSessionSegment(e.config,n,a):e.type==="tmux"?await this.renderTmuxSegment(a):e.type==="context"?this.renderContextSegment(i,a):e.type==="metrics"?this.renderMetricsSegment(e.config,l,r,a):e.type==="block"?this.renderBlockSegment(e.config,r,a):e.type==="today"?this.renderTodaySegment(e.config,o,a):e.type==="version"?this.renderVersionSegment(e.config,t,a):null}async renderGitSegment(e,t,n,r){if(!this.needsSegmentInfo("git"))return null;let o=await this.gitService.getGitInfo(r,{showSha:e?.showSha,showWorkingTree:e?.showWorkingTree,showOperation:e?.showOperation,showTag:e?.showTag,showTimeSinceCommit:e?.showTimeSinceCommit,showStashCount:e?.showStashCount,showUpstream:e?.showUpstream,showRepoName:e?.showRepoName},t.workspace?.project_dir);return o?this.segmentRenderer.renderGit(o,n,e):null}renderSessionSegment(e,t,n){return t?this.segmentRenderer.renderSession(t,n,e):null}async renderTmuxSegment(e){if(!this.needsSegmentInfo("tmux"))return null;let t=await this.tmuxService.getSessionId();return this.segmentRenderer.renderTmux(t,e)}renderContextSegment(e,t){return this.needsSegmentInfo("context")?this.segmentRenderer.renderContext(e,t):null}renderMetricsSegment(e,t,n,r){return this.segmentRenderer.renderMetrics(t,r,n,e)}renderBlockSegment(e,t,n){return t?this.segmentRenderer.renderBlock(t,n,e):null}renderTodaySegment(e,t,n){if(!t)return null;let r=e?.type||"cost";return this.segmentRenderer.renderToday(t,n,r)}renderVersionSegment(e,t,n){return this.segmentRenderer.renderVersion(t,n,e)}initializeSymbols(){return {right:this.config.display.style==="minimal"?"":h.right,branch:h.branch,model:h.model,git_clean:h.git_clean,git_dirty:h.git_dirty,git_conflicts:h.git_conflicts,git_ahead:h.git_ahead,git_behind:h.git_behind,git_worktree:h.git_worktree,git_tag:h.git_tag,git_sha:h.git_sha,git_upstream:h.git_upstream,git_stash:h.git_stash,git_time:h.git_time,session_cost:h.session_cost,block_cost:h.block_cost,today_cost:h.today_cost,context_time:h.context_time,metrics_response:h.metrics_response,metrics_last_response:h.metrics_last_response,metrics_duration:h.metrics_duration,metrics_messages:h.metrics_messages,metrics_lines_added:h.metrics_lines_added,metrics_lines_removed:h.metrics_lines_removed,metrics_burn:h.metrics_burn,version:h.version}}getThemeColors(){let e=this.config.theme,t;if(e==="custom"){if(t=this.config.colors?.custom,!t)throw new Error("Custom theme selected but no colors provided in configuration")}else t=G(e),t||(console.warn(`Built-in theme '${e}' not found, falling back to 'dark' theme`),t=G("dark"));let n=G("dark"),r=b=>{let B=t[b]||n[b];return {bg:re(B.bg,true),fg:re(B.fg,false)}},o=r("directory"),i=r("git"),l=r("model"),a=r("session"),u=r("block"),m=r("today"),d=r("tmux"),g=r("context"),f=r("metrics"),y=r("version");return {reset:O,modeBg:o.bg,modeFg:o.fg,gitBg:i.bg,gitFg:i.fg,modelBg:l.bg,modelFg:l.fg,sessionBg:a.bg,sessionFg:a.fg,blockBg:u.bg,blockFg:u.fg,todayBg:m.bg,todayFg:m.fg,tmuxBg:d.bg,tmuxFg:d.fg,contextBg:g.bg,contextFg:g.fg,metricsBg:f.bg,metricsFg:f.fg,versionBg:y.bg,versionFg:y.fg}}getSegmentBgColor(e,t){switch(e){case "directory":return t.modeBg;case "git":return t.gitBg;case "model":return t.modelBg;case "session":return t.sessionBg;case "block":return t.blockBg;case "today":return t.todayBg;case "tmux":return t.tmuxBg;case "context":return t.contextBg;case "metrics":return t.metricsBg;case "version":return t.versionBg;default:return t.modeBg}}formatSegment(e,t,n,r){let o=`${e}${t} ${n} `;if(r){let i=se(e);o+=`${O}${r}${i}${this.symbols.right}`;}else o+=`${O}${se(e)}${this.symbols.right}${O}`;return o}};var Te={theme:"dark",display:{style:"minimal",lines:[{segments:{directory:{enabled:true,showBasename:true},git:{enabled:true,showSha:false,showWorkingTree:false,showOperation:false,showTag:false,showTimeSinceCommit:false,showStashCount:false,showUpstream:false,showRepoName:false},model:{enabled:true},session:{enabled:true,type:"tokens",costSource:"calculated"},today:{enabled:true,type:"cost"},block:{enabled:false,type:"cost",burnType:"cost"},version:{enabled:false},tmux:{enabled:false},context:{enabled:true},metrics:{enabled:false,showResponseTime:true,showLastResponseTime:true,showDuration:true,showMessageCount:true,showLinesAdded:true,showLinesRemoved:true}}}]},budget:{session:{warningThreshold:80},today:{warningThreshold:80,amount:50}}};function ge(s){return ["light","dark","nord","tokyo-night","rose-pine","custom"].includes(s)}function me(s){return s==="minimal"||s==="powerline"}function te(s,e){let t={...s};for(let n in e){let r=e[n];if(r!==void 0)if(typeof r=="object"&&r!==null&&!Array.isArray(r)){let o=t[n]||{};t[n]=te(o,r);}else t[n]=r;}return t}function nt(s,e){return s?w.existsSync(s)?s:null:[...e?[_.join(e,".claude-powerline.json")]:[],_.join(process.cwd(),".claude-powerline.json"),_.join(D.homedir(),".claude","claude-powerline.json"),_.join(D.homedir(),".config","claude-powerline","config.json")].find(w.existsSync)||null}function rt(s){try{let e=w.readFileSync(s,"utf-8");return JSON.parse(e)}catch(e){throw new Error(`Failed to load config file ${s}: ${e instanceof Error?e.message:String(e)}`)}}function st(){let s={},e={},t=process.env.CLAUDE_POWERLINE_THEME;t&&ge(t)&&(s.theme=t);let n=process.env.CLAUDE_POWERLINE_STYLE;return n&&(me(n)?e.style=n:(console.warn(`Invalid display style '${n}' from environment variable, falling back to 'minimal'`),e.style="minimal")),Object.keys(e).length>0&&(s.display=e),s}function ot(){return process.env.CLAUDE_POWERLINE_CONFIG}function it(s){let e={},t={},n=s.find(o=>o.startsWith("--theme="))?.split("=")[1];n&&ge(n)&&(e.theme=n);let r=s.find(o=>o.startsWith("--style="))?.split("=")[1];return r&&(me(r)?t.style=r:(console.warn(`Invalid display style '${r}' from CLI argument, falling back to 'minimal'`),t.style="minimal")),Object.keys(t).length>0&&(e.display=t),e}function at(s=process.argv,e){let t=JSON.parse(JSON.stringify(Te)),n=s.find(l=>l.startsWith("--config="))?.split("=")[1]||ot(),r=nt(n,e);if(r)try{let l=rt(r);t=te(t,l);}catch(l){console.warn(`Warning: ${l instanceof Error?l.message:String(l)}`);}t.display?.style&&!me(t.display.style)&&(console.warn(`Invalid display style '${t.display.style}' in config file, falling back to 'minimal'`),t.display.style="minimal"),t.theme&&!ge(t.theme)&&(console.warn(`Invalid theme '${t.theme}' in config file, falling back to 'dark'`),t.theme="dark");let o=st();t=te(t,o);let i=it(s);return t=te(t,i),t}var Pe=at;async function lt(){try{let s=D.platform(),e;if(s==="darwin")e=_.join(D.homedir(),"Library","Fonts");else if(s==="linux")e=_.join(D.homedir(),".local","share","fonts");else if(s==="win32")e=_.join(D.homedir(),"AppData","Local","Microsoft","Windows","Fonts");else {console.log("Unsupported platform for font installation");return}w.existsSync(e)||w.mkdirSync(e,{recursive:!0}),console.log("Installing Powerline Fonts..."),console.log("Downloading from https://github.com/powerline/fonts");let t=_.join(D.tmpdir(),"powerline-fonts"),n=()=>{w.existsSync(t)&&w.rmSync(t,{recursive:!0,force:!0});};p.on("SIGINT",n),p.on("SIGTERM",n);try{w.existsSync(t)&&w.rmSync(t,{recursive:!0,force:!0}),console.log("Cloning powerline fonts repository..."),execSync("git clone --depth=1 https://github.com/powerline/fonts.git powerline-fonts",{stdio:"inherit",cwd:D.tmpdir()}),console.log("Installing fonts...");let r=_.join(t,"install.sh");if(w.existsSync(r))w.chmodSync(r,493),execSync("./install.sh",{stdio:"inherit",cwd:t});else throw new Error("Install script not found in powerline fonts repository");console.log("Powerline fonts installation complete!"),console.log("Please restart your terminal and set your terminal font to a powerline font."),console.log("Popular choices: Source Code Pro Powerline, DejaVu Sans Mono Powerline, Ubuntu Mono Powerline");}finally{n(),p.removeListener("SIGINT",n),p.removeListener("SIGTERM",n);}}catch(s){console.error("Error installing fonts:",s instanceof Error?s.message:String(s)),console.log("You can manually install fonts from: https://github.com/powerline/fonts");}}function ve(){console.log(`
9
9
  claude-powerline - Beautiful powerline statusline for Claude Code
10
10
 
11
11
  Usage: claude-powerline [options]
@@ -24,7 +24,7 @@ Claude Code Options (for settings.json):
24
24
 
25
25
  See example config at: https://github.com/Owloops/claude-powerline/blob/main/.claude-powerline.json
26
26
 
27
- `);}async function rt(){try{let s=h.argv.includes("--help")||h.argv.includes("-h");h.argv.includes("--install-fonts")&&(await nt(),h.exit(0)),s&&(Te(),h.exit(0)),h.stdin.isTTY===!0&&(console.error(`Error: This tool requires input from Claude Code
27
+ `);}async function ut(){try{let s=p.argv.includes("--help")||p.argv.includes("-h");p.argv.includes("--install-fonts")&&(await lt(),p.exit(0)),s&&(ve(),p.exit(0)),p.stdin.isTTY===!0&&(console.error(`Error: This tool requires input from Claude Code
28
28
 
29
29
  claude-powerline is designed to be used as a Claude Code statusLine command.
30
30
  It reads hook data from stdin and outputs formatted statusline.
@@ -40,4 +40,4 @@ Add to ~/.claude/settings.json:
40
40
  Run with --help for more options.
41
41
 
42
42
  To test output manually:
43
- echo '{"session_id":"test-session","workspace":{"project_dir":"/path/to/project"},"model":{"id":"claude-3-5-sonnet","display_name":"Claude"}}' | claude-powerline --style=powerline`),h.exit(1)),c(`Working directory: ${h.cwd()}`),c("Process args:",h.argv);let t=await json(h.stdin);c("Received hook data:",JSON.stringify(t,null,2)),t||(console.error("Error: No input data received from stdin"),Te(),h.exit(1));let n=t.workspace?.project_dir,r=ke(h.argv,n),i=await new K(r).generateStatusline(t);console.log(i);}catch(s){let e=s instanceof Error?s.message:String(s);console.error("Error generating statusline:",e),h.exit(1);}}rt();
43
+ echo '{"session_id":"test-session","workspace":{"project_dir":"/path/to/project"},"model":{"id":"claude-3-5-sonnet","display_name":"Claude"}}' | claude-powerline --style=powerline`),p.exit(1)),c(`Working directory: ${p.cwd()}`),c("Process args:",p.argv);let t=await json(p.stdin);c("Received hook data:",JSON.stringify(t,null,2)),t||(console.error("Error: No input data received from stdin"),ve(),p.exit(1));let n=t.workspace?.project_dir,r=Pe(p.argv,n),i=await new Q(r).generateStatusline(t);console.log(i);}catch(s){let e=s instanceof Error?s.message:String(s);console.error("Error generating statusline:",e),p.exit(1);}}ut();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owloops/claude-powerline",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Beautiful vim-style powerline statusline for Claude Code with real-time usage tracking, git integration, and custom themes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",