claude-statusline 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.bundle.js +4 -4
- package/dist/index.bundle.js.map +7 -0
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/metafile.json +479 -0
- package/dist/metafile.prod.json +3 -3
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Simple statusline for Claude Code with project-branch, git indicators, and context usage. Optimized for speed with bun. Just the essentials, none of the bloat.
|
|
4
4
|
|
|
5
5
|

|
|
6
|
-

|
|
7
7
|

|
|
8
8
|

|
|
9
9
|

|
package/dist/index.bundle.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{readFileSync as St}from"fs";import{z as u}from"zod";import{readFileSync as q,existsSync as Q}from"fs";import{homedir as tt}from"os";import{join as P,dirname as et}from"path";import{parse as rt}from"yaml";var I=u.object({cacheTTL:u.number().default(300),cacheDir:u.string().default("/tmp/.claude-statusline-cache"),maxLength:u.number().default(1e3),noEmoji:u.boolean().default(!1),noGitStatus:u.boolean().default(!1),noContextWindow:u.boolean().default(!1),envContext:u.boolean().default(!1),truncate:u.boolean().default(!1),softWrap:u.boolean().default(!1),noSoftWrap:u.boolean().default(!1),forceWidth:u.number().optional(),debugWidth:u.boolean().default(!1),rightMargin:u.number().default(15),symbols:u.object({git:u.string().default("\uF418"),model:u.string().default("\u{F06A9}"),contextWindow:u.string().default("\u26A1\uFE0E"),staged:u.string().default("+"),conflict:u.string().default("\xD7"),stashed:u.string().default("\u2691"),ahead:u.string().default("\u21E1"),behind:u.string().default("\u21E3"),diverged:u.string().default("\u21D5"),renamed:u.string().default("\xBB"),deleted:u.string().default("\u2718")}).default({}),asciiSymbols:u.object({git:u.string().default("@"),model:u.string().default("*"),contextWindow:u.string().default("#"),staged:u.string().default("+"),conflict:u.string().default("C"),stashed:u.string().default("$"),ahead:u.string().default("A"),behind:u.string().default("B"),diverged:u.string().default("D"),renamed:u.string().default(">"),deleted:u.string().default("X")}).default({})}),nt=I.parse({}),ot=["claude-statusline.json","claude-statusline.yaml"];function W(n=process.cwd()){let t={...nt};return t={...t,...st(n)},t={...t,...it()},I.parse(t)}function st(n){let t=[n,et(n),P(tt(),".claude")];for(let r of t)for(let e of ot){let o=P(r,e);if(Q(o))try{let s=q(o,"utf-8");if(e.endsWith(".json"))return JSON.parse(s);if(e.endsWith(".yaml"))return rt(s)}catch{}}return{}}function it(){let n={};if(process.env.CLAUDE_CODE_STATUSLINE_NO_EMOJI==="1"&&(n.noEmoji=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_GITSTATUS==="1"&&(n.noGitStatus=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_CONTEXT_WINDOW==="1"&&(n.noContextWindow=!0),process.env.CLAUDE_CODE_STATUSLINE_ENV_CONTEXT==="1"&&(n.envContext=!0),process.env.CLAUDE_CODE_STATUSLINE_TRUNCATE==="1"&&(n.truncate=!0),process.env.CLAUDE_CODE_STATUSLINE_SOFT_WRAP==="1"&&(n.softWrap=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_SOFT_WRAP==="1"&&(n.noSoftWrap=!0),process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH){let t=parseInt(process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH,10);!isNaN(t)&&t>0&&(n.forceWidth=t)}return process.env.CLAUDE_CODE_STATUSLINE_DEBUG_WIDTH==="1"&&(n.debugWidth=!0),process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR&&(n.cacheDir=process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR),n}var at=4096,ct=[/\.\./,/\.\.\\/,/\[/,/;/,/&/,/</,/>/,/`/];function O(n,t){if(!n||typeof n!="string")return!1;let r=n.trimEnd();if(r.length===0||r.length>t.maxLength||!r.includes("{")||!r.includes("}"))return!1;let e=(r.match(/"/g)||[]).length;if(e===0||e%2!==0)return!1;try{JSON.parse(r)}catch{return!1}return!0}function lt(n){if(!n||typeof n!="string"||n.length>at)return!1;for(let t of ct)if(t.test(n))return!1;if(n.includes("${")||n.includes("`")||n.includes("$("))return!1;try{let t=n.replace(/\/+/g,"/").replace(/\\+/g,"\\");if(t.includes("../")||t.includes("..\\")||t.startsWith("/")&&!t.startsWith("/home/")&&!t.startsWith("/Users/")&&!t.startsWith("/tmp/")&&!["/home","/Users","/tmp","/var","/opt"].some(o=>t.startsWith(o)))return!1;if(t.includes(":")&&/^[A-Za-z]:/.test(t)){let r=t.charAt(0).toUpperCase();if(r<"C"||r>"Z")return!1}}catch{return!1}return!0}async function R(n){if(!lt(n))return!1;try{let{access:t}=await import("fs/promises"),{constants:r}=await import("fs");return await t(n,r.R_OK),!0}catch{return!1}}import{readFile as $,writeFile as A,mkdir as ut}from"fs/promises";import{existsSync as k}from"fs";import{join as w}from"path";var T=class{config;constructor(t){this.config=t}async ensureCacheDir(){try{await ut(this.config.cacheDir,{recursive:!0})}catch{}}getCachePath(t){return w(this.config.cacheDir,t)}getTimestampPath(t){return w(this.config.cacheDir,`${t}.time`)}async get(t,r=this.config.cacheTTL){let e=this.getCachePath(t),o=this.getTimestampPath(t);try{if(!k(e)||!k(o))return null;let s=await $(o,"utf-8"),c=parseInt(s.trim(),10);if(isNaN(c)||Math.floor(Date.now()/1e3)-c>=r)return null;let d=await $(e,"utf-8");try{return JSON.parse(d)}catch{return d}}catch{return null}}async set(t,r){let e=this.getCachePath(t),o=this.getTimestampPath(t);try{await this.ensureCacheDir();let s;typeof r=="string"?s=r:s=JSON.stringify(r);let c=Math.floor(Date.now()/1e3);return await Promise.all([A(e,s,"utf-8"),A(o,c.toString(),"utf-8")]),!0}catch{return!1}}async has(t,r=this.config.cacheTTL){return await this.get(t,r)!==null}async delete(t){let r=this.getCachePath(t),e=this.getTimestampPath(t);try{let{unlink:o}=await import("fs/promises");return await Promise.allSettled([o(r),o(e)]),!0}catch{return!1}}async clear(){try{let{readdir:t,unlink:r}=await import("fs/promises"),e=await t(this.config.cacheDir);return await Promise.allSettled(e.map(o=>r(w(this.config.cacheDir,o)))),!0}catch{return!1}}async getStats(){try{let{readdir:t,stat:r}=await import("fs/promises"),e=await t(this.config.cacheDir),o=0,s=0;for(let c of e)if(!c.endsWith(".time")){s++;let i=w(this.config.cacheDir,c);try{let a=await r(i);o+=a.size}catch{}}return{total:s,size:o}}catch{return{total:0,size:0}}}},S={NODE_VERSION:"node_version",PYTHON_VERSION:"python_version",PYTHON3_VERSION:"python3_version",DOCKER_VERSION:"docker_version",GIT_REMOTE_URL:n=>`git_remote_${Buffer.from(n).toString("base64")}`,GIT_BRANCH:n=>`git_branch_${Buffer.from(n).toString("base64")}`};async function D(n,t,r,e=[],o=300){let s=await n.get(t,o);if(s!==null)return s;try{let{exec:c}=await import("child_process"),{promisify:i}=await import("util"),a=i(c),{stdout:l}=await a(`${r} ${e.join(" ")}`,{timeout:5e3,encoding:"utf-8"}),d=l.trim();return d&&await n.set(t,d),d}catch{return null}}import{spawn as dt}from"child_process";async function E(n,t={}){return new Promise((r,e)=>{let o=dt("git",n,{cwd:t.cwd||process.cwd(),stdio:["ignore","pipe","pipe"],timeout:t.timeout||5e3}),s="",c="";o.stdout.on("data",i=>{s+=i.toString()}),o.stderr.on("data",i=>{c+=i.toString()}),o.on("close",i=>{i===0?r(s):e(new Error(`Git command failed with code ${i}: ${c||s}`))}),o.on("error",i=>{e(new Error(`Failed to execute git command: ${i.message}`))})})}async function
|
|
3
|
-
`);for(let o of e)if(o.startsWith("* "))return o.substring(2).trim()}catch{}return null}async function
|
|
2
|
+
import{readFileSync as St}from"fs";import{z as u}from"zod";import{readFileSync as q,existsSync as Q}from"fs";import{homedir as tt}from"os";import{join as P,dirname as et}from"path";import{parse as rt}from"yaml";var I=u.object({cacheTTL:u.number().default(300),cacheDir:u.string().default("/tmp/.claude-statusline-cache"),maxLength:u.number().default(1e3),noEmoji:u.boolean().default(!1),noGitStatus:u.boolean().default(!1),noContextWindow:u.boolean().default(!1),envContext:u.boolean().default(!1),truncate:u.boolean().default(!1),softWrap:u.boolean().default(!1),noSoftWrap:u.boolean().default(!1),forceWidth:u.number().optional(),debugWidth:u.boolean().default(!1),rightMargin:u.number().default(15),symbols:u.object({git:u.string().default("\uF418"),model:u.string().default("\u{F06A9}"),contextWindow:u.string().default("\u26A1\uFE0E"),staged:u.string().default("+"),conflict:u.string().default("\xD7"),stashed:u.string().default("\u2691"),ahead:u.string().default("\u21E1"),behind:u.string().default("\u21E3"),diverged:u.string().default("\u21D5"),renamed:u.string().default("\xBB"),deleted:u.string().default("\u2718")}).default({}),asciiSymbols:u.object({git:u.string().default("@"),model:u.string().default("*"),contextWindow:u.string().default("#"),staged:u.string().default("+"),conflict:u.string().default("C"),stashed:u.string().default("$"),ahead:u.string().default("A"),behind:u.string().default("B"),diverged:u.string().default("D"),renamed:u.string().default(">"),deleted:u.string().default("X")}).default({})}),nt=I.parse({}),ot=["claude-statusline.json","claude-statusline.yaml"];function W(n=process.cwd()){let t={...nt};return t={...t,...st(n)},t={...t,...it()},I.parse(t)}function st(n){let t=[n,et(n),P(tt(),".claude")];for(let r of t)for(let e of ot){let o=P(r,e);if(Q(o))try{let s=q(o,"utf-8");if(e.endsWith(".json"))return JSON.parse(s);if(e.endsWith(".yaml"))return rt(s)}catch{}}return{}}function it(){let n={};if(process.env.CLAUDE_CODE_STATUSLINE_NO_EMOJI==="1"&&(n.noEmoji=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_GITSTATUS==="1"&&(n.noGitStatus=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_CONTEXT_WINDOW==="1"&&(n.noContextWindow=!0),process.env.CLAUDE_CODE_STATUSLINE_ENV_CONTEXT==="1"&&(n.envContext=!0),process.env.CLAUDE_CODE_STATUSLINE_TRUNCATE==="1"&&(n.truncate=!0),process.env.CLAUDE_CODE_STATUSLINE_SOFT_WRAP==="1"&&(n.softWrap=!0),process.env.CLAUDE_CODE_STATUSLINE_NO_SOFT_WRAP==="1"&&(n.noSoftWrap=!0),process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH){let t=parseInt(process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH,10);!isNaN(t)&&t>0&&(n.forceWidth=t)}return process.env.CLAUDE_CODE_STATUSLINE_DEBUG_WIDTH==="1"&&(n.debugWidth=!0),process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR&&(n.cacheDir=process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR),n}var at=4096,ct=[/\.\./,/\.\.\\/,/\[/,/;/,/&/,/</,/>/,/`/];function O(n,t){if(!n||typeof n!="string")return!1;let r=n.trimEnd();if(r.length===0||r.length>t.maxLength||!r.includes("{")||!r.includes("}"))return!1;let e=(r.match(/"/g)||[]).length;if(e===0||e%2!==0)return!1;try{JSON.parse(r)}catch{return!1}return!0}function lt(n){if(!n||typeof n!="string"||n.length>at)return!1;for(let t of ct)if(t.test(n))return!1;if(n.includes("${")||n.includes("`")||n.includes("$("))return!1;try{let t=n.replace(/\/+/g,"/").replace(/\\+/g,"\\");if(t.includes("../")||t.includes("..\\")||t.startsWith("/")&&!t.startsWith("/home/")&&!t.startsWith("/Users/")&&!t.startsWith("/tmp/")&&!["/home","/Users","/tmp","/var","/opt"].some(o=>t.startsWith(o)))return!1;if(t.includes(":")&&/^[A-Za-z]:/.test(t)){let r=t.charAt(0).toUpperCase();if(r<"C"||r>"Z")return!1}}catch{return!1}return!0}async function R(n){if(!lt(n))return!1;try{let{access:t}=await import("fs/promises"),{constants:r}=await import("fs");return await t(n,r.R_OK),!0}catch{return!1}}import{readFile as $,writeFile as A,mkdir as ut}from"fs/promises";import{existsSync as k}from"fs";import{join as w}from"path";var T=class{config;constructor(t){this.config=t}async ensureCacheDir(){try{await ut(this.config.cacheDir,{recursive:!0})}catch{}}getCachePath(t){return w(this.config.cacheDir,t)}getTimestampPath(t){return w(this.config.cacheDir,`${t}.time`)}async get(t,r=this.config.cacheTTL){let e=this.getCachePath(t),o=this.getTimestampPath(t);try{if(!k(e)||!k(o))return null;let s=await $(o,"utf-8"),c=parseInt(s.trim(),10);if(isNaN(c)||Math.floor(Date.now()/1e3)-c>=r)return null;let d=await $(e,"utf-8");try{return JSON.parse(d)}catch{return d}}catch{return null}}async set(t,r){let e=this.getCachePath(t),o=this.getTimestampPath(t);try{await this.ensureCacheDir();let s;typeof r=="string"?s=r:s=JSON.stringify(r);let c=Math.floor(Date.now()/1e3);return await Promise.all([A(e,s,"utf-8"),A(o,c.toString(),"utf-8")]),!0}catch{return!1}}async has(t,r=this.config.cacheTTL){return await this.get(t,r)!==null}async delete(t){let r=this.getCachePath(t),e=this.getTimestampPath(t);try{let{unlink:o}=await import("fs/promises");return await Promise.allSettled([o(r),o(e)]),!0}catch{return!1}}async clear(){try{let{readdir:t,unlink:r}=await import("fs/promises"),e=await t(this.config.cacheDir);return await Promise.allSettled(e.map(o=>r(w(this.config.cacheDir,o)))),!0}catch{return!1}}async getStats(){try{let{readdir:t,stat:r}=await import("fs/promises"),e=await t(this.config.cacheDir),o=0,s=0;for(let c of e)if(!c.endsWith(".time")){s++;let i=w(this.config.cacheDir,c);try{let a=await r(i);o+=a.size}catch{}}return{total:s,size:o}}catch{return{total:0,size:0}}}},S={NODE_VERSION:"node_version",PYTHON_VERSION:"python_version",PYTHON3_VERSION:"python3_version",DOCKER_VERSION:"docker_version",GIT_REMOTE_URL:n=>`git_remote_${Buffer.from(n).toString("base64")}`,GIT_BRANCH:n=>`git_branch_${Buffer.from(n).toString("base64")}`};async function D(n,t,r,e=[],o=300){let s=await n.get(t,o);if(s!==null)return s;try{let{exec:c}=await import("child_process"),{promisify:i}=await import("util"),a=i(c),{stdout:l}=await a(`${r} ${e.join(" ")}`,{timeout:5e3,encoding:"utf-8"}),d=l.trim();return d&&await n.set(t,d),d}catch{return null}}import{spawn as dt}from"child_process";async function E(n,t={}){return new Promise((r,e)=>{let o=dt("git",n,{cwd:t.cwd||process.cwd(),stdio:["ignore","pipe","pipe"],timeout:t.timeout||5e3}),s="",c="";o.stdout.on("data",i=>{s+=i.toString()}),o.stderr.on("data",i=>{c+=i.toString()}),o.on("close",i=>{i===0?r(s):e(new Error(`Git command failed with code ${i}: ${c||s}`))}),o.on("error",i=>{e(new Error(`Failed to execute git command: ${i.message}`))})})}async function M(n){try{return await E(["rev-parse","--git-dir"],n?{cwd:n}:{}),!0}catch{return!1}}async function U(n){let t=n?{cwd:n}:{};try{let e=(await E(["branch","--show-current"],t)).trim();if(e)return e}catch{}try{let e=(await E(["rev-parse","--abbrev-ref","HEAD"],t)).trim();if(e&&e!=="HEAD")return e}catch{}try{let e=(await E(["branch","--no-color"],t)).split(`
|
|
3
|
+
`);for(let o of e)if(o.startsWith("* "))return o.substring(2).trim()}catch{}return null}async function G(n){return E(["status","--porcelain"],n?{cwd:n}:{})}async function L(n){try{return E(["stash","list"],n?{cwd:n}:{})}catch{return""}}async function B(n){try{return(await E(["rev-parse","--abbrev-ref","@{u}"],n?{cwd:n}:{})).trim()}catch{return""}}async function H(n){try{let e=(await E(["rev-list","--count","--left-right","@{u}...HEAD"],n?{cwd:n}:{})).trim().split(" ");if(e.length===2){let o=parseInt(e[0]||"0",10);return{ahead:parseInt(e[1]||"0",10),behind:o}}}catch{}return{ahead:0,behind:0}}var ft={stashed:0,staged:0,modified:0,untracked:0,renamed:0,deleted:0,conflicts:0,ahead:0,behind:0,diverged:!1},v=class{config;cache;constructor(t,r){this.config=t,this.cache=r}async getGitInfo(t){if(this.config.noGitStatus)return null;try{if(!await M(t))return null;let e=await this.getCurrentBranch(t);if(!e)return null;let o=await this.getGitIndicators(t);return{branch:e,indicators:o}}catch{return null}}async getCurrentBranch(t){let r=`${S.GIT_BRANCH(t)}_current`,e=await this.cache.get(r,60);if(e)return e;try{let o=await U(t);return o?(await this.cache.set(r,o),o):null}catch{return null}}async getGitIndicators(t){let r={...ft};try{let o=(await G(t)).split(`
|
|
4
4
|
`).map(i=>i.trimEnd()).filter(i=>i.length>0);for(let i of o){if(i.length<2)continue;let a=i.charAt(0),l=i.charAt(1);if(a==="U"||l==="U"||a==="A"&&l==="A"||a==="D"&&l==="D")r.conflicts++;else if(a==="?"&&l==="?")r.untracked++;else{switch(a){case"M":r.staged++;break;case"A":r.staged++;break;case"D":r.deleted++;break;case"R":r.renamed++;break;case"C":r.staged++;break}switch(l){case"M":r.modified++;break;case"D":r.deleted++;break;case"R":r.renamed++;break}}}r.stashed=await this.getStashedCount(t);let{ahead:s,behind:c}=await this.getAheadBehind(t);r.ahead=s,r.behind=c,r.diverged=s>0&&c>0}catch{}return r}async getStashedCount(t){try{return(await L(t)).trim().split(`
|
|
5
|
-
`).filter(e=>e.trim().length>0).length}catch{return 0}}async getAheadBehind(t){try{return await B(t)?await H(t):{ahead:0,behind:0}}catch{}return{ahead:0,behind:0}}formatIndicators(t,r){let e=[],o=["stashed","renamed","modified","staged","untracked","deleted","conflicts"];return t.stashed>0&&e.push(r.stashed),t.renamed>0&&e.push(r.renamed),t.modified>0&&e.push("!"),t.staged>0&&e.push(r.staged),t.untracked>0&&e.push("?"),t.deleted>0&&e.push(r.deleted),t.conflicts>0&&e.push(r.conflict),t.diverged?e.push(r.diverged):(t.ahead>0&&e.push(r.ahead),t.behind>0&&e.push(r.behind)),e.join("")}formatGitStatus(t,r){let e=this.formatIndicators(t.indicators,r),o=(this.config.noEmoji,r.git);return e?` ${o} ${t.branch} [${e}]`:` ${o} ${t.branch}`}};var j=new Map,mt=1,V={git:"@",model:"*",contextWindow:"#",staged:"+",conflict:"C",stashed:"$",ahead:"A",behind:"B",diverged:"D",renamed:">",deleted:"X"},ht={git:"\uF418",model:"\u{F06A9}",contextWindow:"\u26A1\uFE0E",staged:"+",conflict:"\xD7",stashed:"\u2691",ahead:"\u21E1",behind:"\u21E3",diverged:"\u21D5",renamed:"\xBB",deleted:"\u2718"};async function z(n){let t=process.env.NERD_FONT+"|"+process.env.TERM_PROGRAM+"|"+process.env.TERM,r=`${mt}:${n.noEmoji?"ascii":"nerd"}:${t}`,e=j.get(r);if(e&&Date.now()-e.timestamp<6e4)return e.symbols;let o;return n.noEmoji?o={...V,...n.symbols,...n.asciiSymbols}:(await gt()).hasNerdFont?o={...ht,...n.symbols}:o={...V,...n.asciiSymbols},j.set(r,{symbols:o,timestamp:Date.now()}),o}async function gt(){let n={hasNerdFont:!1,terminal:"",font:"",method:""};if(process.env.NERD_FONT==="1")return n.hasNerdFont=!0,n.method="NERD_FONT env var",n;let t=process.env.TERM_PROGRAM,r=process.env.TERM;if(t&&(n.terminal=t,n.method="TERM_PROGRAM detection",["vscode","ghostty","wezterm","iterm"].includes(t))||r&&(n.terminal=r,n.method="TERM detection",["alacritty","kitty","wezterm","ghostty","xterm-256color"].includes(r)))return n.hasNerdFont=!0,n;let e=await pt();if(e.hasNerdFont)return n.hasNerdFont=!0,n.font=e.font,n.method="font list detection",n;let o=await yt();return o.hasNerdFont?(n.hasNerdFont=!0,n.font=o.font,n.method="installation detection",n):bt().hasNerdFont?(n.hasNerdFont=!0,n.method="environment detection",n):((await Et()).hasNerdFont&&(n.hasNerdFont=!0,n.method="platform-specific detection"),n)}async function pt(){try{let{exec:n}=await import("child_process"),{promisify:t}=await import("util"),r=t(n),e="",o=process.platform;if(o==="linux"?e="fc-list":o==="darwin"&&(e="system_profiler SPFontsDataType 2>/dev/null || system_profiler SPFontsDataType"),e){let{stdout:s}=await r(e,{timeout:3e3,encoding:"utf-8"}),c=[/nerd font/i,/symbols only/i,/jetbrains mono.*nerd/i,/fira code.*nerd/i,/hack.*nerd/i,/source code pro.*nerd/i,/ubuntu mono.*nerd/i,/anonymous pro.*nerd/i];for(let i of c)if(i.test(s)){let a=s.match(/([^:\n]*)(?=\s*(nerd|symbols))/i);return{hasNerdFont:!0,font:(a?a[1]:"Nerd Font")?.trim()||"Nerd Font"}}}}catch{}return{hasNerdFont:!1,font:""}}async function yt(){try{let{access:n,readdir:t}=await import("fs/promises"),{homedir:r}=await import("os"),e=process.platform,o=[];e==="darwin"?o.push(`${r()}/Library/Fonts`,"/System/Library/Fonts","/Library/Fonts"):e==="linux"&&o.push(`${r()}/.local/share/fonts`,`${r()}/.fonts`,"/usr/share/fonts","/usr/local/share/fonts");let s=["jetbrains-mono-nerd-font","fira-code-nerd-font","hack-nerd-font","source-code-pro-nerd-font","ubuntu-mono-nerd-font","anonymous-pro-nerd-font"];for(let c of o)try{await n(c);let i=await t(c);for(let a of i){let l=a.toLowerCase();for(let d of s)if(l.includes(d))return{hasNerdFont:!0,font:a}}}catch{}}catch{}return{hasNerdFont:!1,font:""}}function bt(){let n=["POWERLINE_COMMAND","NERDFONTS","FONT_FAMILY"];for(let t of n){let r=process.env[t];if(r&&r.toLowerCase().includes("nerd"))return{hasNerdFont:!0}}return process.env.VSCODE_PID||process.env.TERM_PROGRAM==="vscode"||process.env.TERM_PROGRAM==="ghostty"||process.env.TERM_PROGRAM==="wezterm"?{hasNerdFont:!0}:{hasNerdFont:!1}}async function Et(){if(process.platform==="darwin")try{let{exec:t}=await import("child_process"),{promisify:r}=await import("util"),e=r(t),{stdout:o}=await e("brew list | grep -i font",{timeout:2e3,encoding:"utf-8"});if(o.includes("nerd"))return{hasNerdFont:!0}}catch{}return{hasNerdFont:!1}}function K(n){return{node:"\uE718",python:"\uE235",docker:"\uF308",git:n.git,model:n.model}}async function x(n){if(n.forceWidth&&n.forceWidth>0)return n.forceWidth;let t=process.env.COLUMNS;if(t){let i=parseInt(t,10);if(!isNaN(i)&&i>0)return i}if(process.stdout.columns&&process.stdout.columns>0)return process.stdout.columns;let r=await Y("tput",["cols"]);if(r)return r;let e=await J();if(e)return e;let o=process.env.CLAUDE_CODE_TERMINAL_WIDTH;if(o){let i=parseInt(o,10);if(!isNaN(i)&&i>0)return i}let s=process.env.TERM_PROGRAM,c=process.env.TERM;return s==="vscode"&&process.env.VSCODE_PID||["ghostty","wezterm","iterm"].includes(s||"")||c&&["alacritty","kitty","wezterm","ghostty","xterm-256color"].includes(c)||process.env.WT_SESSION||process.env.WT_PROFILE_ID?120:80}async function Y(n,t){try{let{exec:r}=await import("child_process"),{promisify:e}=await import("util"),o=e(r),{stdout:s}=await o(`${n} ${t.join(" ")}`,{timeout:1e3,encoding:"utf-8"}),c=parseInt(s.trim(),10);if(!isNaN(c)&&c>0)return c}catch{}return null}async function J(){try{let{exec:n}=await import("child_process"),{promisify:t}=await import("util"),r=t(n),{stdout:e}=await r("stty size",{timeout:1e3,encoding:"utf-8"}),o=e.trim().split(" ");if(o.length===2){let s=parseInt(o[1]||"0",10);if(!isNaN(s)&&s>0)return s}}catch{}return null}async function X(n){if(!n.debugWidth)return;process.stdout.columns;let t=process.env.COLUMNS,r=await Y("tput",["cols"]),e=await J(),o=await x(n)}function F(n,t){return n.length<=t?n:t<4?"..":`${n.substring(0,t-2)}..`}function Z(n,t,r,e){if(n.length+t.length<=r)return"";let o=r-t.length-2;if(o>=5)return`${n.substring(0,o)}..${t}`;let s="",c=t.match(/\[([^\]]+)\]/);c&&(s=c[1]||"");let i=r-s.length-8;if(i>=8){let a=t.substring(0,Math.min(t.length,i));return`${n.substring(0,4)}..${a}..${s?` [${s}]`:""}`}return`${n.substring(0,r)}..`}function y(n){let t=0;for(let r of n){let e=r.codePointAt(0)??0;e>=4352&&(e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65135||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=131072&&e<=196605||e>=196608&&e<=262141)||e>=127744&&e<=129535||e>=9728&&e<=10175||e>=65024&&e<=65039||e>=126976&&e<=127023||e>=57344&&e<=63743||e>=983040&&e<=1048573||e>=1048576&&e<=1114109?t+=2:e>=768&&e<=879||e>=7616&&e<=7679||e>=8400&&e<=8447||e>=65056&&e<=65071||(t+=1)}return t}var N=class{config;cache;constructor(t,r){this.config=t,this.cache=r}async getEnvironmentInfo(){if(!this.config.envContext)return null;let t={},[r,e,o]=await Promise.allSettled([this.getNodeVersion(),this.getPythonVersion(),this.getDockerVersion()]);return r.status==="fulfilled"&&r.value&&(t.node=r.value),e.status==="fulfilled"&&e.value&&(t.python=e.value),o.status==="fulfilled"&&o.value&&(t.docker=o.value),Object.keys(t).length===0?null:t}async getNodeVersion(){let t=S.NODE_VERSION,r=this.config.cacheTTL*96,e=await this.cache.get(t,r);if(e)return e;try{let o=await D(this.cache,t,"node",["--version"],r);return o?o.replace(/^v/,"").trim():null}catch{return null}}async getPythonVersion(){let t=S.PYTHON3_VERSION,r=S.PYTHON_VERSION,e=this.config.cacheTTL*96;try{let o=await D(this.cache,t,"python3",["--version"],e);if(o){let s=o.match(/(\d+\.\d+\.\d+)/);if(s)return s[1]||null}}catch{}try{let o=await D(this.cache,r,"python",["--version"],e);if(o){let s=o.match(/(\d+\.\d+\.\d+)/);if(s)return s[1]||null}}catch{}return null}async getDockerVersion(){let t="docker_version";try{let r=await D(this.cache,t,"docker",["--version"],this.config.cacheTTL*96);if(r){let e=r.match(/Docker version (\d+\.\d+\.\d+)/);if(e)return e[1]||null}return null}catch{return null}}formatEnvironmentInfo(t,r){let e=[];return t.node&&e.push(`${r.node}${t.node}`),t.python&&e.push(`${r.python}${t.python}`),t.docker&&e.push(`${r.docker}${t.docker}`),e.join(" ")}async getAdditionalTools(){return{}}async isToolAvailable(t){try{let{exec:r}=await import("child_process"),{promisify:e}=await import("util");return await e(r)(`command -v ${t}`,{timeout:2e3}),!0}catch{return!1}}getShellEnvironment(){let t=process.env.SHELL||"unknown",r;return t.includes("bash")?r=process.env.BASH_VERSION:t.includes("zsh")?r=process.env.ZSH_VERSION:t.includes("fish")&&(r=process.env.FISH_VERSION),r?{shell:t,shellVersion:r}:{shell:t}}getOSInfo(){let t=process.platform,r=process.arch,e=process.env.OSTYPE||process.env.OS;return e?{platform:t,arch:r,release:e}:{platform:t,arch:r}}},_=class{symbols;constructor(t){this.symbols=t}format(t,r="compact"){switch(r){case"compact":return this.formatCompact(t);case"verbose":return this.formatVerbose(t);case"minimal":return this.formatMinimal(t);default:return this.formatCompact(t)}}formatCompact(t){let r=[];return t.node&&r.push(`Node${t.node}`),t.python&&r.push(`Py${t.python}`),t.docker&&r.push(`Docker${t.docker}`),r.join(" ")}formatVerbose(t){let r=[];return t.node&&r.push(`Node.js v${t.node}`),t.python&&r.push(`Python ${t.python}`),t.docker&&r.push(`Docker ${t.docker}`),r.join(" \u2022 ")}formatMinimal(t){let r=[];if(t.node){let e=t.node.split(".")[0];r.push(`N${e}`)}if(t.python){let e=t.python.split(".")[0];r.push(`P${e}`)}if(t.docker){let e=t.docker.split(".")[0];r.push(`D${e}`)}return r.join(" ")}formatWithIcons(t){let r=[];return t.node&&r.push(`${this.symbols.node}${t.node}`),t.python&&r.push(`${this.symbols.python}${t.python}`),t.docker&&r.push(`${this.symbols.docker}${t.docker}`),r.join(" ")}};async function Ct(){try{let n=W(),t=new T(n),r=new v(n,t),e=new N(n,t);await X(n);let o=await Dt();O(JSON.stringify(o),n)||process.exit(1);let{fullDir:s,modelName:c,contextWindow:i}=wt(o);(!s||!c)&&process.exit(1),await R(s)||process.exit(1);let l=[r.getGitInfo(s),e.getEnvironmentInfo(),z(n)],d;n.truncate&&l.push(x(n));let m=await Promise.all(l),[h,p,b]=m;n.truncate&&m.length>3&&(d=m[3]);let f=await Tt({fullDir:s,modelName:c,contextWindow:i,gitInfo:h,envInfo:p,symbols:b,...d&&{terminalWidth:d},config:n,gitOps:r});process.stdout.write(f)}catch{process.exit(1)}}async function Dt(){try{let n=St(0,"utf-8");return JSON.parse(n.trim())}catch(n){throw new Error(`Failed to read or parse input: ${n instanceof Error?n.message:String(n)}`)}}function wt(n){let t=n.workspace?.current_dir||"",r=n.model?.display_name||"Unknown",e=n.context_window;return{fullDir:t,modelName:r,contextWindow:e}}async function Tt(n){let{fullDir:t,modelName:r,contextWindow:e,gitInfo:o,envInfo:s,symbols:c,terminalWidth:i,config:a,gitOps:l}=n,d=t.split("/").pop()||t.split("\\").pop()||"project",m="";o&&(m=l.formatGitStatus(o,c));let h="";if(s){let g=K(c);h=` ${new _(g).formatWithIcons(s)}`}let p="";if(e&&!a.noContextWindow){let g=vt(e);g!==null&&(p=` ${c.contextWindow}${g}%`)}let b=`${c.model}${r}${h}${p}`,f=`${d}${m} ${b}`;return a.truncate&&(i||process.exit(1),f=Nt({statusline:f,projectName:d,gitStatus:m,modelString:b,terminalWidth:i,config:a,symbols:c})),f}function vt(n){try{let{current_usage:t,context_window_size:r}=n;if(!r||r===0)return null;if(!t)return 0;let e=t.input_tokens+(t.cache_creation_input_tokens||0)+(t.cache_read_input_tokens||0),o=Math.round(e/r*100);return Math.max(0,Math.min(100,o))}catch{return 0}}function Nt(n){let{statusline:t,projectName:r,gitStatus:e,modelString:o,terminalWidth:s,config:c}=n,i=Math.max(s-c.rightMargin,30),a=`${r}${e}`;if(y(t)<=i)return t;let d=y(a);if(d+1<=i)if(c.noSoftWrap){let h=i-d-1,p=F(o,h);return`${a} ${p}`}else{let h=i-d-1,p=/^[*]/,b=y(o);if(p.test(o)&&b>h)return`${a}
|
|
6
|
-
${o}`;let f=
|
|
5
|
+
`).filter(e=>e.trim().length>0).length}catch{return 0}}async getAheadBehind(t){try{return await B(t)?await H(t):{ahead:0,behind:0}}catch{}return{ahead:0,behind:0}}formatIndicators(t,r){let e=[],o=["stashed","renamed","modified","staged","untracked","deleted","conflicts"];return t.stashed>0&&e.push(r.stashed),t.renamed>0&&e.push(r.renamed),t.modified>0&&e.push("!"),t.staged>0&&e.push(r.staged),t.untracked>0&&e.push("?"),t.deleted>0&&e.push(r.deleted),t.conflicts>0&&e.push(r.conflict),t.diverged?e.push(r.diverged):(t.ahead>0&&e.push(r.ahead),t.behind>0&&e.push(r.behind)),e.join("")}formatGitStatus(t,r){let e=this.formatIndicators(t.indicators,r),o=(this.config.noEmoji,r.git);return e?` ${o} ${t.branch} [${e}]`:` ${o} ${t.branch}`}};var j=new Map,mt=1,V={git:"@",model:"*",contextWindow:"#",staged:"+",conflict:"C",stashed:"$",ahead:"A",behind:"B",diverged:"D",renamed:">",deleted:"X"},ht={git:"\uF418",model:"\u{F06A9}",contextWindow:"\u26A1\uFE0E",staged:"+",conflict:"\xD7",stashed:"\u2691",ahead:"\u21E1",behind:"\u21E3",diverged:"\u21D5",renamed:"\xBB",deleted:"\u2718"};async function z(n){let t=process.env.NERD_FONT+"|"+process.env.TERM_PROGRAM+"|"+process.env.TERM,r=`${mt}:${n.noEmoji?"ascii":"nerd"}:${t}`,e=j.get(r);if(e&&Date.now()-e.timestamp<6e4)return e.symbols;let o;return n.noEmoji?o={...V,...n.symbols,...n.asciiSymbols}:(await gt()).hasNerdFont?o={...ht,...n.symbols}:o={...V,...n.asciiSymbols},j.set(r,{symbols:o,timestamp:Date.now()}),o}async function gt(){let n={hasNerdFont:!1,terminal:"",font:"",method:""};if(process.env.NERD_FONT==="1")return n.hasNerdFont=!0,n.method="NERD_FONT env var",n;let t=process.env.TERM_PROGRAM,r=process.env.TERM;if(t&&(n.terminal=t,n.method="TERM_PROGRAM detection",["vscode","ghostty","wezterm","iterm"].includes(t))||r&&(n.terminal=r,n.method="TERM detection",["alacritty","kitty","wezterm","ghostty","xterm-256color"].includes(r)))return n.hasNerdFont=!0,n;let e=await pt();if(e.hasNerdFont)return n.hasNerdFont=!0,n.font=e.font,n.method="font list detection",n;let o=await yt();return o.hasNerdFont?(n.hasNerdFont=!0,n.font=o.font,n.method="installation detection",n):bt().hasNerdFont?(n.hasNerdFont=!0,n.method="environment detection",n):((await Et()).hasNerdFont&&(n.hasNerdFont=!0,n.method="platform-specific detection"),n)}async function pt(){try{let{exec:n}=await import("child_process"),{promisify:t}=await import("util"),r=t(n),e="",o=process.platform;if(o==="linux"?e="fc-list":o==="darwin"&&(e="system_profiler SPFontsDataType 2>/dev/null || system_profiler SPFontsDataType"),e){let{stdout:s}=await r(e,{timeout:3e3,encoding:"utf-8"}),c=[/nerd font/i,/symbols only/i,/jetbrains mono.*nerd/i,/fira code.*nerd/i,/hack.*nerd/i,/source code pro.*nerd/i,/ubuntu mono.*nerd/i,/anonymous pro.*nerd/i];for(let i of c)if(i.test(s)){let a=s.match(/([^:\n]*)(?=\s*(nerd|symbols))/i);return{hasNerdFont:!0,font:(a?a[1]:"Nerd Font")?.trim()||"Nerd Font"}}}}catch{}return{hasNerdFont:!1,font:""}}async function yt(){try{let{access:n,readdir:t}=await import("fs/promises"),{homedir:r}=await import("os"),e=process.platform,o=[];e==="darwin"?o.push(`${r()}/Library/Fonts`,"/System/Library/Fonts","/Library/Fonts"):e==="linux"&&o.push(`${r()}/.local/share/fonts`,`${r()}/.fonts`,"/usr/share/fonts","/usr/local/share/fonts");let s=["jetbrains-mono-nerd-font","fira-code-nerd-font","hack-nerd-font","source-code-pro-nerd-font","ubuntu-mono-nerd-font","anonymous-pro-nerd-font"];for(let c of o)try{await n(c);let i=await t(c);for(let a of i){let l=a.toLowerCase();for(let d of s)if(l.includes(d))return{hasNerdFont:!0,font:a}}}catch{}}catch{}return{hasNerdFont:!1,font:""}}function bt(){let n=["POWERLINE_COMMAND","NERDFONTS","FONT_FAMILY"];for(let t of n){let r=process.env[t];if(r&&r.toLowerCase().includes("nerd"))return{hasNerdFont:!0}}return process.env.VSCODE_PID||process.env.TERM_PROGRAM==="vscode"||process.env.TERM_PROGRAM==="ghostty"||process.env.TERM_PROGRAM==="wezterm"?{hasNerdFont:!0}:{hasNerdFont:!1}}async function Et(){if(process.platform==="darwin")try{let{exec:t}=await import("child_process"),{promisify:r}=await import("util"),e=r(t),{stdout:o}=await e("brew list | grep -i font",{timeout:2e3,encoding:"utf-8"});if(o.includes("nerd"))return{hasNerdFont:!0}}catch{}return{hasNerdFont:!1}}function K(n){return{node:"\uE718",python:"\uE235",docker:"\uF308",git:n.git,model:n.model}}async function x(n){if(n.forceWidth&&n.forceWidth>0)return n.forceWidth;let t=process.env.COLUMNS;if(t){let i=parseInt(t,10);if(!isNaN(i)&&i>0)return i}if(process.stdout.columns&&process.stdout.columns>0)return process.stdout.columns;let r=await Y("tput",["cols"]);if(r)return r;let e=await J();if(e)return e;let o=process.env.CLAUDE_CODE_TERMINAL_WIDTH;if(o){let i=parseInt(o,10);if(!isNaN(i)&&i>0)return i}let s=process.env.TERM_PROGRAM,c=process.env.TERM;return s==="vscode"&&process.env.VSCODE_PID||["ghostty","wezterm","iterm"].includes(s||"")||c&&["alacritty","kitty","wezterm","ghostty","xterm-256color"].includes(c)||process.env.WT_SESSION||process.env.WT_PROFILE_ID?120:80}async function Y(n,t){try{let{exec:r}=await import("child_process"),{promisify:e}=await import("util"),o=e(r),{stdout:s}=await o(`${n} ${t.join(" ")}`,{timeout:1e3,encoding:"utf-8"}),c=parseInt(s.trim(),10);if(!isNaN(c)&&c>0)return c}catch{}return null}async function J(){try{let{exec:n}=await import("child_process"),{promisify:t}=await import("util"),r=t(n),{stdout:e}=await r("stty size",{timeout:1e3,encoding:"utf-8"}),o=e.trim().split(" ");if(o.length===2){let s=parseInt(o[1]||"0",10);if(!isNaN(s)&&s>0)return s}}catch{}return null}async function X(n){if(!n.debugWidth)return;process.stdout.columns;let t=process.env.COLUMNS,r=await Y("tput",["cols"]),e=await J(),o=await x(n)}function F(n,t){return n.length<=t?n:t<4?"..":`${n.substring(0,t-2)}..`}function Z(n,t,r,e){if(n.length+t.length<=r)return"";let o=r-t.length-2;if(o>=5)return`${n.substring(0,o)}..${t}`;let s="",c=t.match(/\[([^\]]+)\]/);c&&(s=c[1]||"");let i=r-s.length-8;if(i>=8){let a=t.substring(0,Math.min(t.length,i));return`${n.substring(0,4)}..${a}..${s?` [${s}]`:""}`}return`${n.substring(0,r)}..`}function y(n){let t=0;for(let r of n){let e=r.codePointAt(0)??0;e>=4352&&(e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65135||e>=65280&&e<=65376||e>=65504&&e<=65510||e>=131072&&e<=196605||e>=196608&&e<=262141)||e>=127744&&e<=129535||e>=9728&&e<=10175||e>=65024&&e<=65039||e>=126976&&e<=127023||e>=57344&&e<=63743||e>=983040&&e<=1048573||e>=1048576&&e<=1114109?t+=2:e>=768&&e<=879||e>=7616&&e<=7679||e>=8400&&e<=8447||e>=65056&&e<=65071||(t+=1)}return t}var _=class{config;cache;constructor(t,r){this.config=t,this.cache=r}async getEnvironmentInfo(){if(!this.config.envContext)return null;let t={},[r,e,o]=await Promise.allSettled([this.getNodeVersion(),this.getPythonVersion(),this.getDockerVersion()]);return r.status==="fulfilled"&&r.value&&(t.node=r.value),e.status==="fulfilled"&&e.value&&(t.python=e.value),o.status==="fulfilled"&&o.value&&(t.docker=o.value),Object.keys(t).length===0?null:t}async getNodeVersion(){let t=S.NODE_VERSION,r=this.config.cacheTTL*96,e=await this.cache.get(t,r);if(e)return e;try{let o=await D(this.cache,t,"node",["--version"],r);return o?o.replace(/^v/,"").trim():null}catch{return null}}async getPythonVersion(){let t=S.PYTHON3_VERSION,r=S.PYTHON_VERSION,e=this.config.cacheTTL*96;try{let o=await D(this.cache,t,"python3",["--version"],e);if(o){let s=o.match(/(\d+\.\d+\.\d+)/);if(s)return s[1]||null}}catch{}try{let o=await D(this.cache,r,"python",["--version"],e);if(o){let s=o.match(/(\d+\.\d+\.\d+)/);if(s)return s[1]||null}}catch{}return null}async getDockerVersion(){let t="docker_version";try{let r=await D(this.cache,t,"docker",["--version"],this.config.cacheTTL*96);if(r){let e=r.match(/Docker version (\d+\.\d+\.\d+)/);if(e)return e[1]||null}return null}catch{return null}}formatEnvironmentInfo(t,r){let e=[];return t.node&&e.push(`${r.node}${t.node}`),t.python&&e.push(`${r.python}${t.python}`),t.docker&&e.push(`${r.docker}${t.docker}`),e.join(" ")}async getAdditionalTools(){return{}}async isToolAvailable(t){try{let{exec:r}=await import("child_process"),{promisify:e}=await import("util");return await e(r)(`command -v ${t}`,{timeout:2e3}),!0}catch{return!1}}getShellEnvironment(){let t=process.env.SHELL||"unknown",r;return t.includes("bash")?r=process.env.BASH_VERSION:t.includes("zsh")?r=process.env.ZSH_VERSION:t.includes("fish")&&(r=process.env.FISH_VERSION),r?{shell:t,shellVersion:r}:{shell:t}}getOSInfo(){let t=process.platform,r=process.arch,e=process.env.OSTYPE||process.env.OS;return e?{platform:t,arch:r,release:e}:{platform:t,arch:r}}},N=class{symbols;constructor(t){this.symbols=t}format(t,r="compact"){switch(r){case"compact":return this.formatCompact(t);case"verbose":return this.formatVerbose(t);case"minimal":return this.formatMinimal(t);default:return this.formatCompact(t)}}formatCompact(t){let r=[];return t.node&&r.push(`Node${t.node}`),t.python&&r.push(`Py${t.python}`),t.docker&&r.push(`Docker${t.docker}`),r.join(" ")}formatVerbose(t){let r=[];return t.node&&r.push(`Node.js v${t.node}`),t.python&&r.push(`Python ${t.python}`),t.docker&&r.push(`Docker ${t.docker}`),r.join(" \u2022 ")}formatMinimal(t){let r=[];if(t.node){let e=t.node.split(".")[0];r.push(`N${e}`)}if(t.python){let e=t.python.split(".")[0];r.push(`P${e}`)}if(t.docker){let e=t.docker.split(".")[0];r.push(`D${e}`)}return r.join(" ")}formatWithIcons(t){let r=[];return t.node&&r.push(`${this.symbols.node}${t.node}`),t.python&&r.push(`${this.symbols.python}${t.python}`),t.docker&&r.push(`${this.symbols.docker}${t.docker}`),r.join(" ")}};async function Ct(){try{let n=W(),t=new T(n),r=new v(n,t),e=new _(n,t);await X(n);let o=await Dt();O(JSON.stringify(o),n)||process.exit(1);let{fullDir:s,modelName:c,contextWindow:i}=wt(o);(!s||!c)&&process.exit(1),await R(s)||process.exit(1);let l=[r.getGitInfo(s),e.getEnvironmentInfo(),z(n)],d;n.truncate&&l.push(x(n));let m=await Promise.all(l),[h,p,b]=m;n.truncate&&m.length>3&&(d=m[3]);let f=await Tt({fullDir:s,modelName:c,contextWindow:i,gitInfo:h,envInfo:p,symbols:b,...d&&{terminalWidth:d},config:n,gitOps:r});process.stdout.write(f)}catch{process.exit(1)}}async function Dt(){try{let n=St(0,"utf-8");return JSON.parse(n.trim())}catch(n){throw new Error(`Failed to read or parse input: ${n instanceof Error?n.message:String(n)}`)}}function wt(n){let t=n.workspace?.current_dir||"",r=n.model?.display_name||"Unknown",e=n.context_window;return{fullDir:t,modelName:r,contextWindow:e}}async function Tt(n){let{fullDir:t,modelName:r,contextWindow:e,gitInfo:o,envInfo:s,symbols:c,terminalWidth:i,config:a,gitOps:l}=n,d=t.split("/").pop()||t.split("\\").pop()||"project",m="";o&&(m=l.formatGitStatus(o,c));let h="";if(s){let g=K(c);h=` ${new N(g).formatWithIcons(s)}`}let p="";if(e&&!a.noContextWindow){let g=vt(e);g!==null&&(p=` ${c.contextWindow}${g}%`)}let b=`${c.model}${r}${h}${p}`,f=`${d}${m} ${b}`;return a.truncate&&(i||process.exit(1),f=_t({statusline:f,projectName:d,gitStatus:m,modelString:b,terminalWidth:i,config:a,symbols:c})),f}function vt(n){try{if(n.used_percentage!==void 0&&n.used_percentage!==null)return Math.max(0,Math.min(100,Math.round(n.used_percentage)));let{current_usage:t,context_window_size:r}=n;if(!r||r===0)return null;if(!t)return 0;let e=t.input_tokens+(t.cache_creation_input_tokens||0)+(t.cache_read_input_tokens||0),o=Math.round(e/r*100);return Math.max(0,Math.min(100,o))}catch{return 0}}function _t(n){let{statusline:t,projectName:r,gitStatus:e,modelString:o,terminalWidth:s,config:c}=n,i=Math.max(s-c.rightMargin,30),a=`${r}${e}`;if(y(t)<=i)return t;let d=y(a);if(d+1<=i)if(c.noSoftWrap){let h=i-d-1,p=F(o,h);return`${a} ${p}`}else{let h=i-d-1,p=/^[*]/,b=y(o);if(p.test(o)&&b>h)return`${a}
|
|
6
|
+
${o}`;let f=Nt(o,h);return`${a} ${f}`}let m=Z(r,e,i,c);return m||F(t,i)}function Nt(n,t){if(y(n)<=t)return n;if(/^[*]/.test(n))return xt(n,t);let o=!1,s=Array.from(n),c=0,i=s.length,a=-1;for(let f=0;f<s.length;f++){let g=s[f];if(!g)break;g===" "&&(a=f);let C=y(g);if(c+=C,c>t){a>=0?i=a:i=f,o=a>=0;break}}if(i>=s.length)return n;let l=s.length>0?s[0]:"",d=l&&l!==" "&&Buffer.byteLength(l,"utf8")>1;if(!o&&t-c>-3&&!d)return n;if(d&&i<=2&&t>=3){let f=0;for(let g=0;g<s.length;g++){let C=s[g];if(!C)break;if(f+=y(C),f>=3||f>=t){i=g,o=!0;break}}}let m=s.slice(0,i),h=s.slice(i);h.length>0&&h[0]===" "&&h.shift();let p=m.join(""),b=h.join("");return b?`${p}
|
|
7
7
|
${b}`:p}function xt(n,t){if(y(n)<=t)return n;let e=Array.from(n),o=[];for(let a=0;a<e.length;a++)e[a]===" "&&o.push(a);let s=-1;for(let a=0;a<e.length;a++){let l=e[a];if(l==="\u26A1"||l==="#"){s=a;break}}if(s>0){let a=e.findIndex((l,d)=>d<s&&l===" ");if(a>0){let l=e.slice(a+1).join("");if(y(l)<=t)return`${e.slice(0,a).join("")}
|
|
8
8
|
${l}`}}if(o.length>0){let a=o[0];if(a!==void 0&&a>1){let l=e.slice(0,a).join("");if(y(l)<=t){let m=e.slice(a+1).join("");return m?`${l}
|
|
9
9
|
${m}`:l}}}let c=0,i=e.length;for(let a=0;a<e.length;a++){let l=e[a];if(!l)break;let d=y(l);if(c+d>t){i=a;break}c+=d}if(i<e.length&&i>0){let a=e.slice(0,i).join(""),l=e.slice(i).join("");return l?`${a}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/core/config.ts", "../src/core/security.ts", "../src/core/cache.ts", "../src/git/native.ts", "../src/git/status.ts", "../src/ui/symbols.ts", "../src/ui/width.ts", "../src/env/context.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\n/**\n * Claude Statusline - TypeScript v2.0\n * Main entry point\n */\n\nimport { readFileSync } from 'fs';\nimport { loadConfig, Config } from './core/config.js';\nimport { validateInput, validateDirectory } from './core/security.js';\nimport { Cache } from './core/cache.js';\nimport { GitOperations } from './git/status.js';\nimport { detectSymbols, getEnvironmentSymbols, SymbolSet } from './ui/symbols.js';\nimport { getTerminalWidth, truncateText, smartTruncate, debugWidthDetection, getStringDisplayWidth } from './ui/width.js';\nimport { EnvironmentDetector, EnvironmentFormatter } from './env/context.js';\n\n/**\n * Claude Code input interface\n */\ninterface ClaudeInput {\n workspace: {\n current_dir: string;\n };\n model: {\n display_name: string;\n };\n context_window?: {\n total_input_tokens: number;\n total_output_tokens: number;\n context_window_size: number;\n // New in Claude Code v2.1.15: Pre-calculated percentages\n used_percentage?: number;\n remaining_percentage?: number;\n // Legacy: Current usage for manual calculation\n current_usage?: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n };\n };\n}\n\n/**\n * Main execution function\n */\nexport async function main(): Promise<void> {\n try {\n // Load configuration\n const config = loadConfig();\n\n // Initialize components\n const cache = new Cache(config);\n const gitOps = new GitOperations(config, cache);\n const envDetector = new EnvironmentDetector(config, cache);\n\n // Debug width detection if enabled\n await debugWidthDetection(config);\n\n // Read and validate input from stdin\n const input = await readInput();\n if (!validateInput(JSON.stringify(input), config)) {\n console.error('[ERROR] Invalid input received');\n process.exit(1);\n }\n\n // Extract information from input\n const { fullDir, modelName, contextWindow } = extractInputInfo(input);\n if (!fullDir || !modelName) {\n console.error('[ERROR] Failed to extract required information from input');\n process.exit(1);\n }\n\n // Validate directory\n const isValidDir = await validateDirectory(fullDir);\n if (!isValidDir) {\n console.error('[ERROR] Invalid or inaccessible directory:', fullDir);\n process.exit(1);\n }\n\n // Get components (run in parallel for better performance)\n const operations: Promise<any>[] = [\n gitOps.getGitInfo(fullDir),\n envDetector.getEnvironmentInfo(),\n detectSymbols(config),\n ];\n\n // Only get terminal width if smart truncation is enabled\n let terminalWidth: number | undefined;\n if (config.truncate) {\n operations.push(getTerminalWidth(config));\n }\n\n const results = await Promise.all(operations);\n const [gitInfo, envInfo, symbols] = results;\n\n // Extract terminal width from results if it was requested\n if (config.truncate && results.length > 3) {\n terminalWidth = results[3];\n }\n\n // Build statusline\n const statusline = await buildStatusline({\n fullDir,\n modelName,\n contextWindow,\n gitInfo,\n envInfo,\n symbols,\n ...(terminalWidth && { terminalWidth }), // Only include if defined\n config,\n gitOps,\n });\n\n // Output result\n process.stdout.write(statusline);\n\n } catch (error) {\n console.error('[ERROR]', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n\n/**\n * Read JSON input from stdin\n */\nasync function readInput(): Promise<ClaudeInput> {\n try {\n const input = readFileSync(0, 'utf-8'); // Read from stdin (fd 0)\n const parsed = JSON.parse(input.trim());\n return parsed as ClaudeInput;\n } catch (error) {\n throw new Error(`Failed to read or parse input: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Extract directory and model name from Claude input\n */\nfunction extractInputInfo(input: ClaudeInput): { fullDir: string; modelName: string; contextWindow?: ClaudeInput['context_window'] } {\n const fullDir = input.workspace?.current_dir || '';\n const modelName = input.model?.display_name || 'Unknown';\n const contextWindow = input.context_window;\n\n return { fullDir, modelName, contextWindow };\n}\n\n/**\n * Build the complete statusline string\n */\nasync function buildStatusline(params: {\n fullDir: string;\n modelName: string;\n contextWindow?: ClaudeInput['context_window'];\n gitInfo: any;\n envInfo: any;\n symbols: SymbolSet;\n terminalWidth?: number; // Optional - only needed for smart truncation\n config: Config;\n gitOps: GitOperations;\n}): Promise<string> {\n const { fullDir, modelName, contextWindow, gitInfo, envInfo, symbols, terminalWidth, config, gitOps } = params;\n\n // Get project name\n const projectName = fullDir.split('/').pop() || fullDir.split('\\\\').pop() || 'project';\n\n // Build git status string\n let gitStatus = '';\n if (gitInfo) {\n gitStatus = gitOps.formatGitStatus(gitInfo, symbols);\n }\n\n // Build environment context string\n let envContext = '';\n if (envInfo) {\n const envSymbols = getEnvironmentSymbols(symbols);\n const envFormatter = new EnvironmentFormatter(envSymbols);\n envContext = ` ${envFormatter.formatWithIcons(envInfo)}`;\n }\n\n // Build context window usage string\n let contextUsage = '';\n if (contextWindow && !config.noContextWindow) {\n const percentage = calculateContextWindowPercentage(contextWindow);\n if (percentage !== null) {\n contextUsage = ` ${symbols.contextWindow}${percentage}%`;\n }\n }\n\n // Build model string\n const modelString = `${symbols.model}${modelName}${envContext}${contextUsage}`;\n\n // Initial statusline\n let statusline = `${projectName}${gitStatus} ${modelString}`;\n\n // Apply smart truncation if enabled\n if (config.truncate) {\n if (!terminalWidth) {\n console.error('[ERROR] Smart truncation enabled but terminal width not available');\n process.exit(1);\n }\n statusline = applySmartTruncation({\n statusline,\n projectName,\n gitStatus,\n modelString,\n terminalWidth,\n config,\n symbols,\n });\n }\n // No basic truncation - let terminal handle overflow\n\n return statusline;\n}\n\n/**\n * Calculate context window usage percentage\n *\n * Prioritizes the pre-calculated used_percentage field (Claude Code v2.1.15+)\n * Falls back to manual calculation from current_usage if not available\n */\nfunction calculateContextWindowPercentage(contextWindow: NonNullable<ClaudeInput['context_window']>): number | null {\n try {\n // Try pre-calculated percentage first (Claude Code v2.1.15+)\n if (contextWindow.used_percentage !== undefined && contextWindow.used_percentage !== null) {\n // Cap at 100% and ensure non-negative\n return Math.max(0, Math.min(100, Math.round(contextWindow.used_percentage)));\n }\n\n // Fall back to manual calculation for older Claude Code versions\n const { current_usage, context_window_size } = contextWindow;\n\n if (!context_window_size || context_window_size === 0) {\n return null;\n }\n\n // If current_usage is null or undefined, we cannot calculate the percentage\n if (!current_usage) {\n return 0;\n }\n\n // Calculate total tokens used (input + cache tokens from current_usage)\n // Note: Output tokens are NOT included in context window calculation\n // per Claude Code documentation\n const totalUsed = current_usage.input_tokens +\n (current_usage.cache_creation_input_tokens || 0) +\n (current_usage.cache_read_input_tokens || 0);\n\n // Calculate percentage\n const percentage = Math.round((totalUsed / context_window_size) * 100);\n\n // Cap at 100% and ensure non-negative\n return Math.max(0, Math.min(100, percentage));\n } catch {\n return 0;\n }\n}\n\n/**\n * Apply smart truncation with branch prioritization\n */\nfunction applySmartTruncation(params: {\n statusline: string;\n projectName: string;\n gitStatus: string;\n modelString: string;\n terminalWidth: number;\n config: Config;\n symbols: SymbolSet;\n}): string {\n const { statusline, projectName, gitStatus, modelString, terminalWidth, config } = params;\n\n // Use 15-char margin for Claude telemetry compatibility\n const maxLen = Math.max(terminalWidth - config.rightMargin, 30);\n const projectGit = `${projectName}${gitStatus}`;\n\n // Check if everything fits (using display width for accuracy)\n const statuslineDisplayWidth = getStringDisplayWidth(statusline);\n if (statuslineDisplayWidth <= maxLen) {\n return statusline;\n }\n\n // Check if project + space fits, truncate model part only (using display width)\n const projectGitDisplayWidth = getStringDisplayWidth(projectGit);\n if (projectGitDisplayWidth + 1 <= maxLen) {\n // Smart truncation with soft-wrapping (default behavior)\n // Allow disabling soft-wrapping with config setting\n if (config.noSoftWrap) {\n // Legacy behavior: simple truncation only\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n const truncatedModel = truncateText(modelString, modelMaxLen);\n return `${projectGit} ${truncatedModel}`;\n } else {\n // Default: soft-wrap model part\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n\n // If model string needs wrapping and it starts with model icon,\n // prefer wrapping the entire model string to next line\n const modelIconPattern = /^[\uDB81\uDEA9*]/;\n const modelDisplayWidth = getStringDisplayWidth(modelString);\n if (modelIconPattern.test(modelString) && modelDisplayWidth > modelMaxLen) {\n // Wrap entire model to next line\n return `${projectGit}\\n${modelString}`;\n }\n\n const wrappedModel = applySoftWrap(modelString, modelMaxLen);\n return `${projectGit} ${wrappedModel}`;\n }\n }\n\n // Smart truncation of project+git part\n const truncated = smartTruncate(projectName, gitStatus, maxLen, config);\n if (truncated) {\n return truncated;\n }\n\n // Basic fallback\n return truncateText(statusline, maxLen);\n}\n\n/**\n * Apply soft wrapping to text\n */\nfunction applySoftWrap(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n // Check if this is a model string (starts with model icon)\n const modelIconPattern = /^[\uDB81\uDEA9*]/; // Nerd Font or ASCII model icon\n if (modelIconPattern.test(text)) {\n return applySoftWrapToModelString(text, maxLength);\n }\n\n // Find a good break point using display width\n let foundBreak = false;\n\n // Work with actual Unicode characters to avoid splitting multi-byte sequences\n const chars = Array.from(text); // This splits by actual Unicode characters\n let currentDisplayWidth = 0;\n let breakCharIndex = chars.length; // Default to no break\n let lastSpaceIndex = -1;\n\n // Find the best break point by display width\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n\n // Track spaces for potential break points\n if (char === ' ') {\n lastSpaceIndex = i;\n }\n\n // Calculate display width for this character\n const charWidth = getStringDisplayWidth(char);\n currentDisplayWidth += charWidth;\n\n // Check if we've exceeded the max length\n if (currentDisplayWidth > maxLength) {\n // If we found a space before this point, use it\n if (lastSpaceIndex >= 0) {\n breakCharIndex = lastSpaceIndex;\n } else {\n // No space found, break before current character\n breakCharIndex = i;\n }\n foundBreak = lastSpaceIndex >= 0;\n break;\n }\n }\n\n // If everything fits, return as is\n if (breakCharIndex >= chars.length) {\n return text;\n }\n\n // If no safe break found and we're very close to max_length, just fit without wrapping\n // But only if we're not dealing with a model string that starts with an icon\n const firstChar = chars.length > 0 ? chars[0] : '';\n const startsWithIcon = firstChar && firstChar !== ' ' && Buffer.byteLength(firstChar, 'utf8') > 1;\n if (!foundBreak && maxLength - currentDisplayWidth > -3 && !startsWithIcon) {\n return text;\n }\n\n // Special case: if we're starting with an icon and breaking very early,\n // try to keep at least the icon and 1-2 more characters\n if (startsWithIcon && breakCharIndex <= 2 && maxLength >= 3) {\n // Find a better break point after at least 3 characters total (by display width)\n let testWidth = 0;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n testWidth += getStringDisplayWidth(char);\n if (testWidth >= 3 || testWidth >= maxLength) {\n breakCharIndex = i;\n foundBreak = true;\n break;\n }\n }\n }\n\n // Build the strings using character indices\n const firstChars = chars.slice(0, breakCharIndex);\n const secondChars = chars.slice(breakCharIndex);\n\n // Remove leading space from second line if we broke at space\n if (secondChars.length > 0 && secondChars[0] === ' ') {\n secondChars.shift();\n }\n\n // Join characters back into strings\n const firstLine = firstChars.join('');\n const secondLine = secondChars.join('');\n\n // Only wrap if second line has meaningful content\n if (secondLine) {\n return `${firstLine}\\n${secondLine}`;\n } else {\n return firstLine;\n }\n}\n\n/**\n * Apply soft wrapping specifically to model strings, keeping the model icon\n * with the model name and context usage as a unit\n */\nfunction applySoftWrapToModelString(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n const chars = Array.from(text);\n\n // Find all space positions to understand the structure\n const spacePositions: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === ' ') {\n spacePositions.push(i);\n }\n }\n\n // If we have context usage (marked by context window icon like \u26A1\uFE0E or #)\n // The structure is: [icon][model] [env] [context icon][percentage]\n // We want to prefer keeping: [icon][model] [context icon][percentage] together if possible\n\n let contextIconIndex = -1;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (char === '\u26A1' || char === '#') {\n contextIconIndex = i;\n break;\n }\n }\n\n // Strategy 1: If we have context usage, try to keep it with the model on the second line\n // This ensures the icon and percentage stay together\n if (contextIconIndex > 0) {\n // Find the space before context usage\n const spaceBeforeContext = chars.findIndex((c, i) => i < contextIconIndex && c === ' ');\n\n if (spaceBeforeContext > 0) {\n // Check if we can fit model + icon + percentage on second line (using display width)\n const contextPart = chars.slice(spaceBeforeContext + 1).join('');\n const contextPartWidth = getStringDisplayWidth(contextPart);\n if (contextPartWidth <= maxLength) {\n // Put model name on first line, context on second line\n const modelPart = chars.slice(0, spaceBeforeContext).join('');\n return `${modelPart}\\n${contextPart}`;\n }\n }\n }\n\n // Strategy 2: Try to find a break point that keeps the model icon with model name\n // Look for first space after model name (if no context or if context doesn't fit)\n if (spacePositions.length > 0) {\n const firstSpaceAfterModel = spacePositions[0];\n if (firstSpaceAfterModel !== undefined && firstSpaceAfterModel > 1) {\n // Check if the model part fits (using display width)\n const modelPart = chars.slice(0, firstSpaceAfterModel).join('');\n const modelPartWidth = getStringDisplayWidth(modelPart);\n if (modelPartWidth <= maxLength) {\n const remainingPart = chars.slice(firstSpaceAfterModel + 1).join('');\n if (remainingPart) {\n return `${modelPart}\\n${remainingPart}`;\n }\n return modelPart;\n }\n }\n }\n\n // Strategy 3: Find break point by display width (not character count)\n // This is the critical fix for the garbled output artifacts\n let currentWidth = 0;\n let breakCharIndex = chars.length;\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n const charWidth = getStringDisplayWidth(char);\n if (currentWidth + charWidth > maxLength) {\n breakCharIndex = i;\n break;\n }\n currentWidth += charWidth;\n }\n\n // If we found a valid break point\n if (breakCharIndex < chars.length && breakCharIndex > 0) {\n const firstPart = chars.slice(0, breakCharIndex).join('');\n const secondPart = chars.slice(breakCharIndex).join('');\n if (secondPart) {\n return `${firstPart}\\n${secondPart}`;\n }\n return firstPart;\n }\n\n return text;\n}\n\n// Run main function if this file is executed directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main();\n}", "import { z } from 'zod';\nimport { readFileSync, existsSync } from 'fs';\nimport { homedir } from 'os';\nimport { join, dirname } from 'path';\nimport { parse as parseYaml } from 'yaml';\n\n/**\n * Configuration schema for claude-statusline\n */\nexport const ConfigSchema = z.object({\n // Core settings\n cacheTTL: z.number().default(300), // 5 minutes\n cacheDir: z.string().default('/tmp/.claude-statusline-cache'),\n maxLength: z.number().default(1000), // Maximum input length\n\n // Feature toggles\n noEmoji: z.boolean().default(false), // Force ASCII mode\n noGitStatus: z.boolean().default(false), // Disable git indicators\n noContextWindow: z.boolean().default(false), // Disable context window usage\n envContext: z.boolean().default(false), // Show environment versions\n truncate: z.boolean().default(false), // Smart truncation\n softWrap: z.boolean().default(false), // Soft wrapping (legacy)\n noSoftWrap: z.boolean().default(false), // Disable soft-wrapping\n\n // Width and display settings\n forceWidth: z.number().optional(), // Manual width override\n debugWidth: z.boolean().default(false), // Width debugging\n rightMargin: z.number().default(15), // Right margin for Claude telemetry\n\n // Symbol settings\n symbols: z.object({\n git: z.string().default('\uF418'),\n model: z.string().default('\uDB81\uDEA9'),\n contextWindow: z.string().default('\u26A1\uFE0E'),\n staged: z.string().default('+'),\n conflict: z.string().default('\u00D7'),\n stashed: z.string().default('\u2691'),\n ahead: z.string().default('\u21E1'),\n behind: z.string().default('\u21E3'),\n diverged: z.string().default('\u21D5'),\n renamed: z.string().default('\u00BB'),\n deleted: z.string().default('\u2718'),\n }).default({}),\n\n // ASCII fallback symbols\n asciiSymbols: z.object({\n git: z.string().default('@'),\n model: z.string().default('*'),\n contextWindow: z.string().default('#'),\n staged: z.string().default('+'),\n conflict: z.string().default('C'),\n stashed: z.string().default('$'),\n ahead: z.string().default('A'),\n behind: z.string().default('B'),\n diverged: z.string().default('D'),\n renamed: z.string().default('>'),\n deleted: z.string().default('X'),\n }).default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\n/**\n * Default configuration instance\n */\nexport const defaultConfig: Config = ConfigSchema.parse({});\n\n/**\n * Configuration file names to search for (in order of preference)\n */\nconst CONFIG_FILES = [\n 'claude-statusline.json',\n 'claude-statusline.yaml',\n];\n\n/**\n * Load configuration from file and environment variables\n */\nexport function loadConfig(cwd: string = process.cwd()): Config {\n let config = { ...defaultConfig };\n\n // 1. Load from configuration file\n config = { ...config, ...loadConfigFile(cwd) };\n\n // 2. Override with environment variables\n config = { ...config, ...loadEnvConfig() };\n\n // Validate final configuration\n return ConfigSchema.parse(config);\n}\n\n/**\n * Load configuration from file in the current directory or home directory\n */\nfunction loadConfigFile(cwd: string): Partial<Config> {\n // Search in current directory first, then parent directories, then ~/.claude/\n const searchPaths = [cwd, dirname(cwd), join(homedir(), '.claude')];\n\n for (const searchPath of searchPaths) {\n for (const filename of CONFIG_FILES) {\n const configPath = join(searchPath, filename);\n\n if (existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, 'utf-8');\n\n if (filename.endsWith('.json')) {\n return JSON.parse(content);\n } else if (filename.endsWith('.yaml')) {\n return parseYaml(content);\n }\n } catch (error) {\n console.warn(`[WARNING] Failed to parse config file ${configPath}:`, error instanceof Error ? error.message : String(error));\n }\n }\n }\n }\n\n return {};\n}\n\n/**\n * Load configuration from environment variables\n * Maps v1.0 environment variables to new configuration format\n */\nfunction loadEnvConfig(): Partial<Config> {\n const env: Partial<Config> = {};\n\n // Feature toggles\n if (process.env.CLAUDE_CODE_STATUSLINE_NO_EMOJI === '1') {\n env.noEmoji = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_NO_GITSTATUS === '1') {\n env.noGitStatus = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_NO_CONTEXT_WINDOW === '1') {\n env.noContextWindow = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_ENV_CONTEXT === '1') {\n env.envContext = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_TRUNCATE === '1') {\n env.truncate = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_SOFT_WRAP === '1') {\n env.softWrap = true;\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_NO_SOFT_WRAP === '1') {\n env.noSoftWrap = true;\n }\n\n // Width settings\n if (process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH) {\n const width = parseInt(process.env.CLAUDE_CODE_STATUSLINE_FORCE_WIDTH, 10);\n if (!isNaN(width) && width > 0) {\n env.forceWidth = width;\n }\n }\n\n if (process.env.CLAUDE_CODE_STATUSLINE_DEBUG_WIDTH === '1') {\n env.debugWidth = true;\n }\n\n // Cache directory override\n if (process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR) {\n env.cacheDir = process.env.CLAUDE_CODE_STATUSLINE_CACHE_DIR;\n }\n\n return env;\n}\n\n/**\n * Get configuration file path for writing\n */\nexport function getConfigFilePath(cwd: string = process.cwd()): string | null {\n // Prefer claude-statusline.json in the current directory\n const configPath = join(cwd, 'claude-statusline.json');\n return configPath;\n}\n\n/**\n * Generate a sample configuration file\n */\nexport function generateSampleConfig(): string {\n return JSON.stringify({\n $schema: 'https://raw.githubusercontent.com/shrwnsan/claude-statusline/main/config-schema.json',\n // Core settings\n cacheTTL: 300, // 5 minutes\n maxLength: 1000,\n\n // Feature toggles\n noEmoji: false, // Set to true to force ASCII mode\n noGitStatus: false, // Set to true to disable git indicators\n noContextWindow: false, // Set to true to disable context window usage\n envContext: true, // Set to true to show Node.js, Python versions\n truncate: true, // Set to true to enable smart truncation\n softWrap: false, // Set to true to enable soft wrapping\n\n // Display settings\n rightMargin: 15, // Right margin for Claude telemetry compatibility\n debugWidth: false, // Set to true for width debugging output\n\n // Custom symbols (optional - will use defaults if not specified)\n symbols: {\n git: '\uF418',\n model: '\uDB81\uDEA9',\n contextWindow: '\u26A1\uFE0E',\n staged: '+',\n conflict: '\u00D7',\n stashed: '\u2691',\n ahead: '\u21E1',\n behind: '\u21E3',\n diverged: '\u21D5',\n renamed: '\u00BB',\n deleted: '\u2718',\n },\n }, null, 2);\n}", "import { Config } from './config.js';\n\n/**\n * Security-focused input validation\n * Ported from bash script with enhanced TypeScript safety\n */\n\n/**\n * Maximum allowed input length (matches bash CONFIG_MAX_LENGTH)\n */\nconst MAX_INPUT_LENGTH = 1000;\n\n/**\n * Maximum allowed path length (prevents buffer overflow attacks)\n */\nconst MAX_PATH_LENGTH = 4096;\n\n/**\n * Dangerous characters and patterns to check in paths\n */\nconst DANGEROUS_PATH_PATTERNS = [\n /\\.\\./, // Directory traversal\n /\\.\\.\\\\/, // Windows traversal\n /\\[/, // Potential command injection\n /;/, // Command separator\n /&/, // Background execution\n /</, // Input redirection\n />/, // Output redirection\n /`/, // Command substitution\n];\n\n/**\n * Validates JSON input from Claude Code\n * Implements the same security checks as the bash version\n */\nexport function validateInput(input: string, config: Config): boolean {\n // Basic input sanity checks\n if (!input || typeof input !== 'string') {\n return false;\n }\n\n // Strip trailing whitespace\n const cleanedInput = input.trimEnd();\n\n // Length validation\n if (cleanedInput.length === 0 || cleanedInput.length > config.maxLength) {\n return false;\n }\n\n // Basic JSON structure validation\n if (!cleanedInput.includes('{') || !cleanedInput.includes('}')) {\n return false;\n }\n\n // Quote validation - must have balanced quotes\n const quoteCount = (cleanedInput.match(/\"/g) || []).length;\n if (quoteCount === 0 || quoteCount % 2 !== 0) {\n return false;\n }\n\n // Try to parse JSON to ensure it's valid\n try {\n JSON.parse(cleanedInput);\n } catch {\n return false;\n }\n\n return true;\n}\n\n/**\n * Validates file system paths to prevent directory traversal and command injection\n */\nexport function validatePath(path: string): boolean {\n // Basic input validation\n if (!path || typeof path !== 'string') {\n return false;\n }\n\n // Length validation\n if (path.length > MAX_PATH_LENGTH) {\n return false;\n }\n\n // Check for dangerous patterns\n for (const pattern of DANGEROUS_PATH_PATTERNS) {\n if (pattern.test(path)) {\n return false;\n }\n }\n\n // Additional safety checks for common attack vectors\n if (path.includes('${') || path.includes('`') || path.includes('$(')) {\n return false;\n }\n\n // Normalize path and check for resolved traversal attempts\n try {\n // This would require importing path module, but for now we'll do basic checks\n const normalized = path.replace(/\\/+/g, '/').replace(/\\\\+/g, '\\\\');\n\n // Still contains traversal after normalization?\n if (normalized.includes('../') || normalized.includes('..\\\\')) {\n return false;\n }\n\n // Check for absolute paths that might be suspicious\n if (normalized.startsWith('/') && !normalized.startsWith('/home/') && !normalized.startsWith('/Users/') && !normalized.startsWith('/tmp/')) {\n // Allow common safe absolute paths but be cautious\n const safeRoots = ['/home', '/Users', '/tmp', '/var', '/opt'];\n const isSafeRoot = safeRoots.some(root => normalized.startsWith(root));\n if (!isSafeRoot) {\n return false;\n }\n }\n\n // Windows path checks\n if (normalized.includes(':') && /^[A-Za-z]:/.test(normalized)) {\n // Windows drive letter - check if it's a reasonable path\n const driveLetter = normalized.charAt(0).toUpperCase();\n if (driveLetter < 'C' || driveLetter > 'Z') {\n return false;\n }\n }\n\n } catch {\n return false;\n }\n\n return true;\n}\n\n/**\n * Sanitizes string input for safe display\n * Removes or escapes potentially dangerous characters\n */\nexport function sanitizeString(input: string, maxLength: number = 200): string {\n if (!input || typeof input !== 'string') {\n return '';\n }\n\n // Remove control characters except common safe ones\n let sanitized = input.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\n // Limit length\n if (sanitized.length > maxLength) {\n sanitized = sanitized.substring(0, maxLength);\n }\n\n return sanitized;\n}\n\n/**\n * Validates that a directory exists and is accessible\n */\nexport async function validateDirectory(path: string): Promise<boolean> {\n if (!validatePath(path)) {\n return false;\n }\n\n try {\n // Use dynamic import for fs/promises to avoid issues in some environments\n const { access } = await import('fs/promises');\n const { constants } = await import('fs');\n\n await access(path, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Security configuration object\n */\nexport const SECURITY_CONFIG = {\n MAX_INPUT_LENGTH,\n MAX_PATH_LENGTH,\n DANGEROUS_PATH_PATTERNS,\n} as const;", "import { readFile, writeFile, mkdir } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { Config } from './config.js';\n\n/**\n * Simple caching system with TTL support\n * Ported from bash implementation with Node.js optimizations\n */\n\n\n/**\n * Cache wrapper that handles TTL and file operations\n */\nexport class Cache {\n private config: Config;\n\n constructor(config: Config) {\n this.config = config;\n }\n\n /**\n * Ensure cache directory exists\n */\n private async ensureCacheDir(): Promise<void> {\n try {\n await mkdir(this.config.cacheDir, { recursive: true });\n } catch (error) {\n // Directory might already exist or we can't create it\n console.warn('[WARNING] Failed to create cache directory:', this.config.cacheDir);\n }\n }\n\n /**\n * Get cache file path for a given key\n */\n private getCachePath(key: string): string {\n return join(this.config.cacheDir, key);\n }\n\n /**\n * Get cache timestamp file path for a given key\n */\n private getTimestampPath(key: string): string {\n return join(this.config.cacheDir, `${key}.time`);\n }\n\n /**\n * Read cached data with TTL validation\n */\n async get<T = string>(key: string, ttl: number = this.config.cacheTTL): Promise<T | null> {\n const cachePath = this.getCachePath(key);\n const timestampPath = this.getTimestampPath(key);\n\n try {\n // Check if cache files exist\n if (!existsSync(cachePath) || !existsSync(timestampPath)) {\n return null;\n }\n\n // Read timestamp and check TTL\n const timestampContent = await readFile(timestampPath, 'utf-8');\n const timestamp = parseInt(timestampContent.trim(), 10);\n\n if (isNaN(timestamp)) {\n return null;\n }\n\n const currentTime = Math.floor(Date.now() / 1000);\n const age = currentTime - timestamp;\n\n // In development, reduce cache TTL to prevent stale data\n const effectiveTTL = process.env.NODE_ENV === 'development' ? Math.min(ttl, 5) : ttl;\n\n if (age >= effectiveTTL) {\n // Cache expired\n return null;\n }\n\n // Read cached data\n const dataContent = await readFile(cachePath, 'utf-8');\n\n // Try to parse as JSON, fallback to string\n try {\n return JSON.parse(dataContent) as T;\n } catch {\n return dataContent as T;\n }\n\n } catch (error) {\n // Any error reading cache should result in cache miss\n console.debug('[DEBUG] Cache read error for key:', key, error instanceof Error ? error.message : String(error));\n return null;\n }\n }\n\n /**\n * Write data to cache with timestamp\n */\n async set<T = string>(key: string, data: T): Promise<boolean> {\n const cachePath = this.getCachePath(key);\n const timestampPath = this.getTimestampPath(key);\n\n try {\n // Ensure cache directory exists\n await this.ensureCacheDir();\n\n // Prepare data for storage\n let dataContent: string;\n if (typeof data === 'string') {\n dataContent = data;\n } else {\n dataContent = JSON.stringify(data);\n }\n\n // Write data and timestamp\n const currentTime = Math.floor(Date.now() / 1000);\n\n await Promise.all([\n writeFile(cachePath, dataContent, 'utf-8'),\n writeFile(timestampPath, currentTime.toString(), 'utf-8'),\n ]);\n\n return true;\n\n } catch (error) {\n console.warn('[WARNING] Failed to write cache for key:', key, error instanceof Error ? error.message : String(error));\n return false;\n }\n }\n\n /**\n * Check if cache entry exists and is valid\n */\n async has(key: string, ttl: number = this.config.cacheTTL): Promise<boolean> {\n const value = await this.get(key, ttl);\n return value !== null;\n }\n\n /**\n * Delete cache entry\n */\n async delete(key: string): Promise<boolean> {\n const cachePath = this.getCachePath(key);\n const timestampPath = this.getTimestampPath(key);\n\n try {\n const { unlink } = await import('fs/promises');\n\n await Promise.allSettled([\n unlink(cachePath),\n unlink(timestampPath),\n ]);\n\n return true;\n } catch (error) {\n console.warn('[WARNING] Failed to delete cache for key:', key, error instanceof Error ? error.message : String(error));\n return false;\n }\n }\n\n /**\n * Clear all cache entries\n */\n async clear(): Promise<boolean> {\n try {\n const { readdir, unlink } = await import('fs/promises');\n const files = await readdir(this.config.cacheDir);\n\n await Promise.allSettled(\n files.map(file => unlink(join(this.config.cacheDir, file)))\n );\n\n return true;\n } catch (error) {\n console.warn('[WARNING] Failed to clear cache:', error instanceof Error ? error.message : String(error));\n return false;\n }\n }\n\n /**\n * Get cache statistics\n */\n async getStats(): Promise<{ total: number; size: number }> {\n try {\n const { readdir, stat } = await import('fs/promises');\n const files = await readdir(this.config.cacheDir);\n\n let totalSize = 0;\n let cacheFiles = 0;\n\n for (const file of files) {\n if (!file.endsWith('.time')) {\n cacheFiles++;\n const filePath = join(this.config.cacheDir, file);\n try {\n const stats = await stat(filePath);\n totalSize += stats.size;\n } catch {\n // Skip files that can't be stat'ed\n }\n }\n }\n\n return { total: cacheFiles, size: totalSize };\n } catch (error) {\n console.warn('[WARNING] Failed to get cache stats:', error instanceof Error ? error.message : String(error));\n return { total: 0, size: 0 };\n }\n }\n}\n\n/**\n * Cache key generators for common use cases\n */\nexport const CacheKeys = {\n NODE_VERSION: 'node_version',\n PYTHON_VERSION: 'python_version',\n PYTHON3_VERSION: 'python3_version',\n DOCKER_VERSION: 'docker_version',\n GIT_REMOTE_URL: (dir: string) => `git_remote_${Buffer.from(dir).toString('base64')}`,\n GIT_BRANCH: (dir: string) => `git_branch_${Buffer.from(dir).toString('base64')}`,\n} as const;\n\n/**\n * Cached command execution helper\n * Runs a command and caches the result\n */\nexport async function cachedCommand(\n cache: Cache,\n key: string,\n command: string,\n args: string[] = [],\n ttl: number = 300\n): Promise<string | null> {\n // Try to get from cache first\n const cached = await cache.get<string>(key, ttl);\n if (cached !== null) {\n return cached;\n }\n\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n const { stdout } = await execAsync(`${command} ${args.join(' ')}`, {\n timeout: 5000, // 5 second timeout\n encoding: 'utf-8',\n });\n\n const result = stdout.trim();\n if (result) {\n // Cache the successful result\n await cache.set(key, result);\n }\n\n return result;\n\n } catch (error) {\n console.debug('[DEBUG] Command execution failed:', command, error instanceof Error ? error.message : String(error));\n return null;\n }\n}", "import { spawn } from 'child_process';\n\n/**\n * Execute a git command using child_process.spawn\n * Provides native git execution without external dependencies\n */\nexport async function executeGitCommand(\n args: string[],\n options: {\n cwd?: string;\n timeout?: number;\n } = {}\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const git = spawn('git', args, {\n cwd: options.cwd || process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n timeout: options.timeout || 5000,\n });\n\n let stdout = '';\n let stderr = '';\n\n git.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n git.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n git.on('close', (code) => {\n if (code === 0) {\n resolve(stdout);\n } else {\n reject(new Error(`Git command failed with code ${code}: ${stderr || stdout}`));\n }\n });\n\n git.on('error', (error) => {\n reject(new Error(`Failed to execute git command: ${error.message}`));\n });\n });\n}\n\n/**\n * Check if directory is a git repository\n */\nexport async function checkIsRepo(cwd?: string): Promise<boolean> {\n try {\n const options = cwd ? { cwd } : {};\n await executeGitCommand(['rev-parse', '--git-dir'], options);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get current branch name using multiple fallback methods\n */\nexport async function getCurrentBranch(cwd?: string): Promise<string | null> {\n const options = cwd ? { cwd } : {};\n\n // Method 1: git branch --show-current (most reliable)\n try {\n const result = await executeGitCommand(['branch', '--show-current'], options);\n const branch = result.trim();\n if (branch) {\n return branch;\n }\n } catch {\n // Continue to next method\n }\n\n // Method 2: git rev-parse --abbrev-ref HEAD\n try {\n const result = await executeGitCommand(['rev-parse', '--abbrev-ref', 'HEAD'], options);\n const branch = result.trim();\n // Filter out HEAD if not on a branch\n if (branch && branch !== 'HEAD') {\n return branch;\n }\n } catch {\n // Continue to next method\n }\n\n // Method 3: Parse git branch output for current branch\n try {\n const result = await executeGitCommand(['branch', '--no-color'], options);\n const lines = result.split('\\n');\n for (const line of lines) {\n if (line.startsWith('* ')) {\n return line.substring(2).trim();\n }\n }\n } catch {\n // All methods failed\n }\n\n return null;\n}\n\n/**\n * Get git status in porcelain format\n */\nexport async function getPorcelainStatus(cwd?: string): Promise<string> {\n const options = cwd ? { cwd } : {};\n return executeGitCommand(['status', '--porcelain'], options);\n}\n\n/**\n * Get stash list\n */\nexport async function getStashList(cwd?: string): Promise<string> {\n try {\n const options = cwd ? { cwd } : {};\n return executeGitCommand(['stash', 'list'], options);\n } catch {\n return '';\n }\n}\n\n/**\n * Get upstream branch reference\n */\nexport async function getUpstreamRef(cwd?: string): Promise<string> {\n try {\n const options = cwd ? { cwd } : {};\n const result = await executeGitCommand(['rev-parse', '--abbrev-ref', '@{u}'], options);\n return result.trim();\n } catch {\n return '';\n }\n}\n\n/**\n * Get ahead/behind counts\n */\nexport async function getAheadBehind(cwd?: string): Promise<{ ahead: number; behind: number }> {\n try {\n const options = cwd ? { cwd } : {};\n const result = await executeGitCommand(['rev-list', '--count', '--left-right', '@{u}...HEAD'], options);\n const counts = result.trim().split('\\t');\n\n if (counts.length === 2) {\n const behind = parseInt(counts[0] || '0', 10);\n const ahead = parseInt(counts[1] || '0', 10);\n return { ahead, behind };\n }\n } catch {\n // No upstream or other error\n }\n\n return { ahead: 0, behind: 0 };\n}", "import { Config } from '../core/config.js';\nimport { Cache, CacheKeys } from '../core/cache.js';\nimport {\n checkIsRepo,\n getCurrentBranch,\n getPorcelainStatus,\n getStashList,\n getUpstreamRef,\n getAheadBehind,\n} from './native.js';\n\n/**\n * Git status information interface\n */\nexport interface GitInfo {\n branch: string;\n indicators: GitIndicators;\n}\n\n/**\n * Git status indicators\n */\nexport interface GitIndicators {\n stashed: number;\n staged: number;\n modified: number;\n untracked: number;\n renamed: number;\n deleted: number;\n conflicts: number;\n ahead: number;\n behind: number;\n diverged: boolean;\n}\n\n/**\n * Empty git indicators (no changes)\n */\nexport const EMPTY_INDICATORS: GitIndicators = {\n stashed: 0,\n staged: 0,\n modified: 0,\n untracked: 0,\n renamed: 0,\n deleted: 0,\n conflicts: 0,\n ahead: 0,\n behind: 0,\n diverged: false,\n};\n\n/**\n * Git operations and status parsing\n * Ported from bash implementation with enhanced TypeScript safety\n */\nexport class GitOperations {\n private config: Config;\n private cache: Cache;\n\n constructor(config: Config, cache: Cache) {\n this.config = config;\n this.cache = cache;\n }\n\n /**\n * Get git information for a directory\n */\n async getGitInfo(directory: string): Promise<GitInfo | null> {\n if (this.config.noGitStatus) {\n return null;\n }\n\n try {\n // Check if this is a git repository\n const isRepo = await checkIsRepo(directory);\n if (!isRepo) {\n return null;\n }\n\n // Get current branch\n const branch = await this.getCurrentBranch(directory);\n if (!branch) {\n return null;\n }\n\n // Get status indicators\n const indicators = await this.getGitIndicators(directory);\n\n return { branch, indicators };\n\n } catch (error) {\n console.debug('[DEBUG] Git operation failed:', error instanceof Error ? error.message : String(error));\n return null;\n }\n }\n\n /**\n * Get current branch name with caching\n */\n private async getCurrentBranch(directory: string): Promise<string | null> {\n const cacheKey = `${CacheKeys.GIT_BRANCH(directory)}_current`;\n\n // Try cache first\n const cached = await this.cache.get<string>(cacheKey, 60); // 1 minute TTL for branch\n if (cached) {\n return cached;\n }\n\n try {\n const branch = await getCurrentBranch(directory);\n\n if (branch) {\n await this.cache.set(cacheKey, branch);\n return branch;\n }\n\n return null;\n\n } catch (error) {\n console.debug('[DEBUG] Failed to get current branch:', error instanceof Error ? error.message : String(error));\n return null;\n }\n }\n\n /**\n * Get comprehensive git status indicators\n */\n private async getGitIndicators(directory: string): Promise<GitIndicators> {\n const indicators = { ...EMPTY_INDICATORS };\n\n try {\n // Get porcelain status for parsing\n const statusResult = await getPorcelainStatus(directory);\n const statusLines = statusResult.split('\\n')\n .map(line => line.trimEnd()) // Only trim trailing whitespace, not leading!\n .filter(line => line.length > 0);\n\n // Parse each status line\n for (const line of statusLines) {\n if (line.length < 2) continue;\n\n const stagedChar = line.charAt(0);\n const unstagedChar = line.charAt(1);\n\n // Check for conflicts (U = unmerged)\n if (stagedChar === 'U' || unstagedChar === 'U' ||\n (stagedChar === 'A' && unstagedChar === 'A') ||\n (stagedChar === 'D' && unstagedChar === 'D')) {\n indicators.conflicts++;\n }\n // Check for untracked files\n else if (stagedChar === '?' && unstagedChar === '?') {\n indicators.untracked++;\n } else {\n // Parse staged changes (first character)\n switch (stagedChar) {\n case 'M':\n indicators.staged++; // Modified\n break;\n case 'A':\n indicators.staged++; // Added\n break;\n case 'D':\n indicators.deleted++; // Deleted (staged)\n break;\n case 'R':\n indicators.renamed++; // Renamed (staged)\n break;\n case 'C':\n indicators.staged++; // Copied (staged)\n break;\n }\n\n // Parse unstaged changes (second character)\n switch (unstagedChar) {\n case 'M':\n indicators.modified++; // Modified\n break;\n case 'D':\n indicators.deleted++; // Deleted (unstaged)\n break;\n case 'R':\n indicators.renamed++; // Renamed (unstaged)\n break;\n }\n }\n }\n\n // Get stashed changes count\n indicators.stashed = await this.getStashedCount(directory);\n\n // Get ahead/behind information\n const { ahead, behind } = await this.getAheadBehind(directory);\n indicators.ahead = ahead;\n indicators.behind = behind;\n indicators.diverged = ahead > 0 && behind > 0;\n\n } catch (error) {\n console.debug('[DEBUG] Failed to parse git status:', error instanceof Error ? error.message : String(error));\n }\n\n return indicators;\n }\n\n /**\n * Get number of stashed changes\n */\n private async getStashedCount(directory: string): Promise<number> {\n try {\n const stashList = await getStashList(directory);\n return stashList.trim().split('\\n').filter(line => line.trim().length > 0).length;\n } catch {\n return 0;\n }\n }\n\n /**\n * Get ahead/behind count for tracking branch\n */\n private async getAheadBehind(directory: string): Promise<{ ahead: number; behind: number }> {\n try {\n // Check if we have an upstream branch\n const upstream = await getUpstreamRef(directory);\n if (!upstream) {\n return { ahead: 0, behind: 0 };\n }\n\n // Get ahead/behind count\n return await getAheadBehind(directory);\n\n } catch {\n // No upstream or other error\n }\n\n return { ahead: 0, behind: 0 };\n }\n\n /**\n * Format git indicators into display string\n */\n formatIndicators(indicators: GitIndicators, symbols: Config['symbols']): string {\n const indicatorChars: string[] = [];\n\n // Custom order matching user preference: \u2691\u00BB!+?\u2718\u00D7\u21D5\u21E1\u21E3\n // IMPORTANT: Do NOT change this order without updating documentation\n const expectedOrder = ['stashed', 'renamed', 'modified', 'staged', 'untracked', 'deleted', 'conflicts'];\n\n // Debug logging for order validation (only in development)\n if (process.env.NODE_ENV !== 'production') {\n const actualOrder: string[] = [];\n if (indicators.stashed > 0) actualOrder.push('stashed');\n if (indicators.renamed > 0) actualOrder.push('renamed');\n if (indicators.modified > 0) actualOrder.push('modified');\n if (indicators.staged > 0) actualOrder.push('staged');\n if (indicators.untracked > 0) actualOrder.push('untracked');\n if (indicators.deleted > 0) actualOrder.push('deleted');\n if (indicators.conflicts > 0) actualOrder.push('conflicts');\n\n // Validate order consistency\n for (let i = 0; i < actualOrder.length - 1; i++) {\n const currentIndex = expectedOrder.indexOf(actualOrder[i]!);\n const nextIndex = expectedOrder.indexOf(actualOrder[i + 1]!);\n if (currentIndex !== -1 && nextIndex !== -1 && currentIndex > nextIndex) {\n console.warn(`[WARN] Indicator order violation: ${actualOrder[i]!} should not come before ${actualOrder[i + 1]!}`);\n }\n }\n }\n\n if (indicators.stashed > 0) indicatorChars.push(symbols.stashed);\n if (indicators.renamed > 0) indicatorChars.push(symbols.renamed);\n if (indicators.modified > 0) indicatorChars.push('!');\n if (indicators.staged > 0) indicatorChars.push(symbols.staged);\n if (indicators.untracked > 0) indicatorChars.push('?');\n if (indicators.deleted > 0) indicatorChars.push(symbols.deleted);\n if (indicators.conflicts > 0) indicatorChars.push(symbols.conflict);\n\n // Ahead/behind status\n if (indicators.diverged) {\n indicatorChars.push(symbols.diverged);\n } else {\n if (indicators.ahead > 0) indicatorChars.push(symbols.ahead);\n if (indicators.behind > 0) indicatorChars.push(symbols.behind);\n }\n\n return indicatorChars.join('');\n }\n\n /**\n * Get git status string for display\n */\n formatGitStatus(gitInfo: GitInfo, symbols: Config['symbols']): string {\n const indicators = this.formatIndicators(gitInfo.indicators, symbols);\n const gitSymbol = this.config.noEmoji ? symbols.git : symbols.git;\n\n if (indicators) {\n return ` ${gitSymbol} ${gitInfo.branch} [${indicators}]`;\n } else {\n return ` ${gitSymbol} ${gitInfo.branch}`;\n }\n }\n}", "import { Config } from '../core/config.js';\n\n/**\n * Symbol detection cache - symbols don't change during runtime\n * Added cache version to handle potential stale data issues\n */\nconst symbolCache = new Map<string, { symbols: SymbolSet; timestamp: number }>();\nconst CACHE_VERSION = 1; // Increment to invalidate all caches\n\n/**\n * Symbol configuration interface\n */\nexport interface SymbolSet {\n git: string;\n model: string;\n contextWindow: string;\n staged: string;\n conflict: string;\n stashed: string;\n ahead: string;\n behind: string;\n diverged: string;\n renamed: string;\n deleted: string;\n}\n\n/**\n * ASCII symbol set (fallback)\n */\nconst ASCII_SYMBOLS: SymbolSet = {\n git: '@',\n model: '*',\n contextWindow: '#',\n staged: '+',\n conflict: 'C',\n stashed: '$',\n ahead: 'A',\n behind: 'B',\n diverged: 'D',\n renamed: '>',\n deleted: 'X',\n};\n\n/**\n * Nerd Font symbol set (enhanced)\n */\nconst NERD_FONT_SYMBOLS: SymbolSet = {\n git: '\uF418',\n model: '\uDB81\uDEA9',\n contextWindow: '\u26A1\uFE0E',\n staged: '+',\n conflict: '\u00D7',\n stashed: '\u2691',\n ahead: '\u21E1',\n behind: '\u21E3',\n diverged: '\u21D5',\n renamed: '\u00BB',\n deleted: '\u2718',\n};\n\n/**\n * Terminal detection results\n */\ninterface TerminalInfo {\n hasNerdFont: boolean;\n terminal: string;\n font: string;\n method: string;\n}\n\n/**\n * Detect Nerd Font support and return appropriate symbols (with caching)\n */\nexport async function detectSymbols(config: Config): Promise<SymbolSet> {\n // Create cache key based on config and environment\n const envFingerprint = process.env.NERD_FONT + '|' + process.env.TERM_PROGRAM + '|' + process.env.TERM;\n const cacheKey = `${CACHE_VERSION}:${config.noEmoji ? 'ascii' : 'nerd'}:${envFingerprint}`;\n\n // Check cache first with timestamp validation\n const cached = symbolCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < 60000) { // 1 minute cache TTL\n return cached.symbols;\n }\n\n let symbols: SymbolSet;\n\n // If emoji/nerd font is explicitly disabled, use ASCII\n if (config.noEmoji) {\n symbols = { ...ASCII_SYMBOLS, ...config.symbols, ...config.asciiSymbols };\n } else {\n // Try to detect Nerd Font support\n const detection = await detectNerdFontSupport();\n\n if (detection.hasNerdFont) {\n // Merge user's custom symbols with Nerd Font defaults\n symbols = { ...NERD_FONT_SYMBOLS, ...config.symbols };\n } else {\n // Merge user's custom ASCII symbols with ASCII defaults\n symbols = { ...ASCII_SYMBOLS, ...config.asciiSymbols };\n }\n }\n\n // Cache the result with timestamp\n symbolCache.set(cacheKey, { symbols, timestamp: Date.now() });\n return symbols;\n}\n\n/**\n * Comprehensive Nerd Font support detection\n */\nasync function detectNerdFontSupport(): Promise<TerminalInfo> {\n const terminalInfo: TerminalInfo = {\n hasNerdFont: false,\n terminal: '',\n font: '',\n method: '',\n };\n\n // Method 1: Environment variable NERD_FONT=1\n if (process.env.NERD_FONT === '1') {\n terminalInfo.hasNerdFont = true;\n terminalInfo.method = 'NERD_FONT env var';\n return terminalInfo;\n }\n\n // Method 2: Terminal program detection\n const termProgram = process.env.TERM_PROGRAM;\n const term = process.env.TERM;\n\n if (termProgram) {\n terminalInfo.terminal = termProgram;\n terminalInfo.method = 'TERM_PROGRAM detection';\n\n // These terminals commonly have Nerd Font support\n const nerdFontTerminals = ['vscode', 'ghostty', 'wezterm', 'iterm'];\n if (nerdFontTerminals.includes(termProgram)) {\n terminalInfo.hasNerdFont = true;\n return terminalInfo;\n }\n }\n\n if (term) {\n terminalInfo.terminal = term;\n terminalInfo.method = 'TERM detection';\n\n // These terminal types commonly support Nerd Fonts\n const nerdFontTerms = ['alacritty', 'kitty', 'wezterm', 'ghostty', 'xterm-256color'];\n if (nerdFontTerms.includes(term)) {\n terminalInfo.hasNerdFont = true;\n return terminalInfo;\n }\n }\n\n // Method 3: Try to detect via font list (Unix/Linux/macOS)\n const fontDetection = await detectViaFontList();\n if (fontDetection.hasNerdFont) {\n terminalInfo.hasNerdFont = true;\n terminalInfo.font = fontDetection.font;\n terminalInfo.method = 'font list detection';\n return terminalInfo;\n }\n\n // Method 4: Check for common Nerd Font installation patterns\n const installDetection = await detectNerdFontInstallation();\n if (installDetection.hasNerdFont) {\n terminalInfo.hasNerdFont = true;\n terminalInfo.font = installDetection.font;\n terminalInfo.method = 'installation detection';\n return terminalInfo;\n }\n\n // Method 5: Check environment variables that might indicate font support\n const envDetection = detectFromEnvironment();\n if (envDetection.hasNerdFont) {\n terminalInfo.hasNerdFont = true;\n terminalInfo.method = 'environment detection';\n return terminalInfo;\n }\n\n // Method 6: Platform-specific detection\n const platformDetection = await detectPlatformSpecific();\n if (platformDetection.hasNerdFont) {\n terminalInfo.hasNerdFont = true;\n terminalInfo.method = 'platform-specific detection';\n return terminalInfo;\n }\n\n // Default: no Nerd Font detected\n return terminalInfo;\n}\n\n/**\n * Detect Nerd Font via font list command\n */\nasync function detectViaFontList(): Promise<{ hasNerdFont: boolean; font: string }> {\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n // Try fc-list (Linux) or system_profiler (macOS)\n let fontListCommand = '';\n const platform = process.platform;\n\n if (platform === 'linux') {\n fontListCommand = 'fc-list';\n } else if (platform === 'darwin') {\n fontListCommand = 'system_profiler SPFontsDataType 2>/dev/null || system_profiler SPFontsDataType';\n }\n\n if (fontListCommand) {\n const { stdout } = await execAsync(fontListCommand, {\n timeout: 3000,\n encoding: 'utf-8',\n });\n\n const nerdFontPatterns = [\n /nerd font/i,\n /symbols only/i,\n /jetbrains mono.*nerd/i,\n /fira code.*nerd/i,\n /hack.*nerd/i,\n /source code pro.*nerd/i,\n /ubuntu mono.*nerd/i,\n /anonymous pro.*nerd/i,\n ];\n\n for (const pattern of nerdFontPatterns) {\n if (pattern.test(stdout)) {\n // Try to extract font name\n const match = stdout.match(/([^:\\n]*)(?=\\s*(nerd|symbols))/i);\n const fontName = match ? match[1] : 'Nerd Font';\n return { hasNerdFont: true, font: fontName?.trim() || 'Nerd Font' };\n }\n }\n }\n } catch {\n // Font detection failed\n }\n\n return { hasNerdFont: false, font: '' };\n}\n\n/**\n * Detect Nerd Font installation in common locations\n */\nasync function detectNerdFontInstallation(): Promise<{ hasNerdFont: boolean; font: string }> {\n try {\n const { access, readdir } = await import('fs/promises');\n const { homedir } = await import('os');\n\n const platform = process.platform;\n const fontPaths: string[] = [];\n\n if (platform === 'darwin') {\n fontPaths.push(\n `${homedir()}/Library/Fonts`,\n '/System/Library/Fonts',\n '/Library/Fonts'\n );\n } else if (platform === 'linux') {\n fontPaths.push(\n `${homedir()}/.local/share/fonts`,\n `${homedir()}/.fonts`,\n '/usr/share/fonts',\n '/usr/local/share/fonts'\n );\n }\n\n const nerdFontNames = [\n 'jetbrains-mono-nerd-font',\n 'fira-code-nerd-font',\n 'hack-nerd-font',\n 'source-code-pro-nerd-font',\n 'ubuntu-mono-nerd-font',\n 'anonymous-pro-nerd-font',\n ];\n\n for (const fontPath of fontPaths) {\n try {\n await access(fontPath);\n const files = await readdir(fontPath);\n\n for (const file of files) {\n const fileName = file.toLowerCase();\n for (const nerdFontName of nerdFontNames) {\n if (fileName.includes(nerdFontName)) {\n return { hasNerdFont: true, font: file };\n }\n }\n }\n } catch {\n // Can't access this font directory\n }\n }\n } catch {\n // Font detection failed\n }\n\n return { hasNerdFont: false, font: '' };\n}\n\n/**\n * Detect Nerd Font support from environment variables\n */\nfunction detectFromEnvironment(): { hasNerdFont: boolean } {\n // Check for various environment variables that might indicate Nerd Font support\n const nerdFontEnvVars = [\n 'POWERLINE_COMMAND', // Often used with Nerd Fonts\n 'NERDFONTS', // Some terminals set this\n 'FONT_FAMILY', // Some terminals expose the current font\n ];\n\n for (const envVar of nerdFontEnvVars) {\n const value = process.env[envVar];\n if (value && value.toLowerCase().includes('nerd')) {\n return { hasNerdFont: true };\n }\n }\n\n // Check if we're in a development environment that likely has Nerd Fonts\n if (\n process.env.VSCODE_PID ||\n process.env.TERM_PROGRAM === 'vscode' ||\n process.env.TERM_PROGRAM === 'ghostty' ||\n process.env.TERM_PROGRAM === 'wezterm'\n ) {\n return { hasNerdFont: true };\n }\n\n return { hasNerdFont: false };\n}\n\n/**\n * Platform-specific Nerd Font detection\n */\nasync function detectPlatformSpecific(): Promise<{ hasNerdFont: boolean }> {\n const platform = process.platform;\n\n if (platform === 'darwin') {\n // macOS: check if we're in a common development environment\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n // Check for Homebrew-installed Nerd Fonts\n const { stdout } = await execAsync('brew list | grep -i font', {\n timeout: 2000,\n encoding: 'utf-8',\n });\n\n if (stdout.includes('nerd')) {\n return { hasNerdFont: true };\n }\n } catch {\n // brew command failed or not available\n }\n }\n\n return { hasNerdFont: false };\n}\n\n/**\n * Get environment symbols with version information\n */\nexport function getEnvironmentSymbols(symbolSet: SymbolSet): { [key: string]: string } {\n return {\n node: '\uE718', // Node.js\n python: '\uE235', // Python\n docker: '\uF308', // Docker\n git: symbolSet.git,\n model: symbolSet.model,\n };\n}\n\n/**\n * Test if symbols can be displayed properly\n */\nexport async function testSymbolDisplay(_symbols: SymbolSet): Promise<boolean> {\n // In a terminal environment, we can't easily test if symbols display correctly\n // For now, we'll assume that if we detected Nerd Font support, they can be displayed\n return true;\n}", "import { Config } from '../core/config.js';\n\n/**\n * Terminal width detection utilities\n * Ported from bash implementation with cross-platform Node.js support\n */\n\n/**\n * Get terminal width using multiple detection methods\n * Ordered from most reliable to fallback methods\n */\nexport async function getTerminalWidth(config: Config): Promise<number> {\n // Method 0: Respect manual width override first (for testing)\n if (config.forceWidth && config.forceWidth > 0) {\n return config.forceWidth;\n }\n\n // Method 1: Try COLUMNS environment variable\n const columnsEnv = process.env.COLUMNS;\n if (columnsEnv) {\n const columns = parseInt(columnsEnv, 10);\n if (!isNaN(columns) && columns > 0) {\n return columns;\n }\n }\n\n // Method 2: Try Node.js process.stdout.columns\n if (process.stdout.columns && process.stdout.columns > 0) {\n return process.stdout.columns;\n }\n\n // Method 3: Try tput command (Unix/Linux/macOS)\n const tputWidth = await tryCommand('tput', ['cols']);\n if (tputWidth) {\n return tputWidth;\n }\n\n // Method 4: Try stty command (Unix/Linux/macOS)\n const sttyWidth = await tryStty();\n if (sttyWidth) {\n return sttyWidth;\n }\n\n // Method 5: Check Claude Code specific environment\n const claudeWidth = process.env.CLAUDE_CODE_TERMINAL_WIDTH;\n if (claudeWidth) {\n const width = parseInt(claudeWidth, 10);\n if (!isNaN(width) && width > 0) {\n return width;\n }\n }\n\n // Method 6: Terminal-specific defaults\n const termProgram = process.env.TERM_PROGRAM;\n const term = process.env.TERM;\n\n if (termProgram === 'vscode' && process.env.VSCODE_PID) {\n return 120; // VS Code default\n }\n\n if (['ghostty', 'wezterm', 'iterm'].includes(termProgram || '')) {\n return 120; // Modern terminals default to wider\n }\n\n if (term && ['alacritty', 'kitty', 'wezterm', 'ghostty', 'xterm-256color'].includes(term)) {\n return 120; // Modern terminals\n }\n\n // Method 7: Check for Windows Terminal\n if (process.env.WT_SESSION || process.env.WT_PROFILE_ID) {\n return 120; // Windows Terminal\n }\n\n // Final fallback: conservative 80-column default\n return 80;\n}\n\n/**\n * Execute a command and parse numeric output\n */\nasync function tryCommand(command: string, args: string[]): Promise<number | null> {\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n const { stdout } = await execAsync(`${command} ${args.join(' ')}`, {\n timeout: 1000, // 1 second timeout\n encoding: 'utf-8',\n });\n\n const width = parseInt(stdout.trim(), 10);\n if (!isNaN(width) && width > 0) {\n return width;\n }\n } catch {\n // Command failed or not available\n }\n\n return null;\n}\n\n/**\n * Try stty size command\n */\nasync function tryStty(): Promise<number | null> {\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n const { stdout } = await execAsync('stty size', {\n timeout: 1000,\n encoding: 'utf-8',\n });\n\n // stty size returns: \"rows cols\"\n const parts = stdout.trim().split(' ');\n if (parts.length === 2) {\n const width = parseInt(parts[1] || '0', 10);\n if (!isNaN(width) && width > 0) {\n return width;\n }\n }\n } catch {\n // stty failed or not available\n }\n\n return null;\n}\n\n/**\n * Debug width detection (matches bash implementation)\n */\nexport async function debugWidthDetection(config: Config): Promise<void> {\n if (!config.debugWidth) {\n return;\n }\n\n console.error('[WIDTH DEBUG] Debug mode enabled');\n\n console.error('[WIDTH DEBUG] Methods tried:');\n\n // Test process.stdout.columns\n if (process.stdout.columns) {\n console.error(`[WIDTH DEBUG] process.stdout.columns: ${process.stdout.columns}`);\n } else {\n console.error('[WIDTH DEBUG] process.stdout.columns: not available');\n }\n\n // Test COLUMNS variable\n const columnsEnv = process.env.COLUMNS;\n if (columnsEnv) {\n console.error(`[WIDTH DEBUG] COLUMNS variable: ${columnsEnv}`);\n } else {\n console.error('[WIDTH DEBUG] COLUMNS variable: not set');\n }\n\n // Test tput\n const tputWidth = await tryCommand('tput', ['cols']);\n if (tputWidth) {\n console.error(`[WIDTH DEBUG] tput cols: ${tputWidth}`);\n } else {\n console.error('[WIDTH DEBUG] tput: not available or failed');\n }\n\n // Test stty\n const sttyWidth = await tryStty();\n if (sttyWidth) {\n console.error(`[WIDTH DEBUG] stty size: ${sttyWidth}`);\n } else {\n console.error('[WIDTH DEBUG] stty: not available or failed');\n }\n\n // Test environment variables\n console.error(`[WIDTH DEBUG] CLAUDE_CODE_STATUSLINE_FORCE_WIDTH: ${config.forceWidth || 'not set'}`);\n console.error(`[WIDTH DEBUG] COLUMNS variable: ${columnsEnv || 'not set'}`);\n console.error(`[WIDTH DEBUG] CLAUDE_CODE_TERMINAL_WIDTH: ${process.env.CLAUDE_CODE_TERMINAL_WIDTH || 'not set'}`);\n console.error(`[WIDTH DEBUG] TERM_PROGRAM: ${process.env.TERM_PROGRAM || 'not set'}`);\n console.error(`[WIDTH DEBUG] TERM: ${process.env.TERM || 'not set'}`);\n\n // Show final result\n const finalWidth = await getTerminalWidth(config);\n console.error(`[WIDTH DEBUG] Final detected width: ${finalWidth}`);\n console.error(`[WIDTH DEBUG] Statusline will use: ${finalWidth - config.rightMargin} columns max`);\n}\n\n/**\n * Text truncation utilities\n */\n\n/**\n * Simple text truncation with ellipsis\n */\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n\n // Edge case: if maxLength is too small, return minimal result\n if (maxLength < 4) {\n return '..';\n }\n\n return `${text.substring(0, maxLength - 2)}..`;\n}\n\n/**\n * Smart truncation with branch prioritization (matches bash implementation)\n */\nexport function smartTruncate(\n project: string,\n gitInfo: string,\n maxLen: number,\n _config: Config\n): string {\n // Step 1: Check if everything fits\n if (project.length + gitInfo.length <= maxLen) {\n return '';\n }\n\n // Step 2: Truncate project only (preserve branch)\n const projLen = maxLen - gitInfo.length - 2;\n if (projLen >= 5) {\n return `${project.substring(0, projLen)}..${gitInfo}`;\n }\n\n // Step 3: Truncate project + branch (preserve indicators)\n let indicators = '';\n const bracketMatch = gitInfo.match(/\\[([^\\]]+)\\]/);\n if (bracketMatch) {\n indicators = bracketMatch[1] || '';\n }\n\n const branchLen = maxLen - indicators.length - 8;\n if (branchLen >= 8) {\n const gitPrefix = gitInfo.substring(0, Math.min(gitInfo.length, branchLen));\n return `${project.substring(0, 4)}..${gitPrefix}..${indicators ? ` [${indicators}]` : ''}`;\n }\n\n // Step 4: Basic fallback\n return `${project.substring(0, maxLen)}..`;\n}\n\n/**\n * Get the display width of a string, accounting for wide characters (CJK, emoji, Nerd Font icons)\n * Uses wcwidth-style logic where wide characters = 2 columns, narrow = 1 column\n */\nexport function getStringDisplayWidth(str: string): number {\n let width = 0;\n for (const char of str) {\n const code = char.codePointAt(0) ?? 0;\n\n // Wide character ranges (CJK, emoji, Nerd Font icons, etc.)\n // CJK Unified Ideographs\n if (code >= 0x1100 && (\n (code >= 0x1100 && code <= 0x115F) || // Hangul Jamo\n (code >= 0x2E80 && code <= 0xA4CF) || // CJK\u548C\u5404\u79CD\u7B26\u53F7\n (code >= 0xAC00 && code <= 0xD7A3) || // Hangul Syllables\n (code >= 0xF900 && code <= 0xFAFF) || // CJK Compatibility Ideographs\n (code >= 0xFE10 && code <= 0xFE19) || // Vertical forms\n (code >= 0xFE30 && code <= 0xFE6F) || // CJK Compatibility Forms\n (code >= 0xFF00 && code <= 0xFF60) || // Fullwidth Forms\n (code >= 0xFFE0 && code <= 0xFFE6) ||\n (code >= 0x20000 && code <= 0x2FFFD) ||\n (code >= 0x30000 && code <= 0x3FFFD)\n )) {\n width += 2;\n }\n // Emoji and various symbols (including Nerd Font icons in Private Use Area)\n else if (\n (code >= 0x1F300 && code <= 0x1F9FF) || // Emoji\n (code >= 0x2600 && code <= 0x27BF) || // Miscellaneous symbols\n (code >= 0xFE00 && code <= 0xFE0F) || // Variation Selectors\n (code >= 0x1F000 && code <= 0x1F02F) || // Mahjong tiles\n (code >= 0xE000 && code <= 0xF8FF) || // Private Use Area (Nerd Font icons)\n (code >= 0xF0000 && code <= 0xFFFFD) || // Supplementary Private Use Area-A\n (code >= 0x100000 && code <= 0x10FFFD) // Supplementary Private Use Area-B\n ) {\n width += 2;\n }\n // Combining characters (zero width)\n else if (\n (code >= 0x0300 && code <= 0x036F) || // Combining diacritical marks\n (code >= 0x1DC0 && code <= 0x1DFF) || // Combining diacritical marks extended\n (code >= 0x20D0 && code <= 0x20FF) || // Combining marks for symbols\n (code >= 0xFE20 && code <= 0xFE2F) // Combining half marks\n ) {\n // Zero width, don't increment\n }\n // Normal ASCII and narrow characters\n else {\n width += 1;\n }\n }\n return width;\n}\n\n/**\n * Soft wrapping function (experimental)\n */\nexport function softWrapText(\n text: string,\n maxLength: number,\n wrapChar: 'newline' | 'space' = 'newline',\n modelPrefix: string = '*'\n): string {\n if (text.length <= maxLength) {\n return text;\n }\n\n if (wrapChar === 'newline') {\n // Smart wrap: try to break at space or safe character\n let breakPos = maxLength;\n let foundBreak = false;\n\n // Look for safe break points (spaces)\n for (let i = Math.min(maxLength - 1, text.length - 1); i > Math.max(maxLength - 20, 0) && i >= 0; i--) {\n const char = text[i];\n if (char === ' ') {\n breakPos = i;\n foundBreak = true;\n break;\n }\n }\n\n // If no safe break found and we're very close to max_length, just fit without wrapping\n if (!foundBreak && maxLength - text.length > -3) {\n return text;\n }\n\n // Adjust break position to avoid splitting multi-byte UTF-8 characters\n // UTF-8 continuation bytes have their two most significant bits set to 10 (0x80 to 0xBF)\n while (breakPos > 0 && (text.charCodeAt(breakPos) & 0xC0) === 0x80) {\n breakPos--;\n }\n\n const firstLine = text.substring(0, breakPos);\n let secondLine = text.substring(breakPos);\n\n // Remove leading space from second line if we broke at space\n if (secondLine.startsWith(' ')) {\n secondLine = secondLine.substring(1);\n }\n\n // Only wrap if second line has meaningful content\n if (secondLine) {\n return `${firstLine}\\n${modelPrefix}${secondLine}`;\n } else {\n return firstLine;\n }\n } else {\n // Use space separator for wrapping\n let breakPos = maxLength;\n\n // Adjust break position to avoid splitting multi-byte UTF-8 characters\n // UTF-8 continuation bytes have their two most significant bits set to 10 (0x80 to 0xBF)\n while (breakPos > 0 && (text.charCodeAt(breakPos) & 0xC0) === 0x80) {\n breakPos--;\n }\n\n const firstLine = text.substring(0, breakPos);\n const secondLine = text.substring(breakPos);\n return `${firstLine} ${secondLine}`;\n }\n}", "import { Config } from '../core/config.js';\nimport { Cache, cachedCommand, CacheKeys } from '../core/cache.js';\nimport { getEnvironmentSymbols } from '../ui/symbols.js';\n\n/**\n * Environment version information interface\n */\nexport interface EnvironmentInfo {\n node?: string;\n python?: string;\n docker?: string;\n}\n\n/**\n * Environment context detection\n * Ported from bash implementation with enhanced TypeScript safety\n */\nexport class EnvironmentDetector {\n private config: Config;\n private cache: Cache;\n\n constructor(config: Config, cache: Cache) {\n this.config = config;\n this.cache = cache;\n }\n\n /**\n * Get environment information if context is enabled\n */\n async getEnvironmentInfo(): Promise<EnvironmentInfo | null> {\n if (!this.config.envContext) {\n return null;\n }\n\n const envInfo: EnvironmentInfo = {};\n\n // Get version information in parallel for better performance\n const [nodeVersion, pythonVersion, dockerVersion] = await Promise.allSettled([\n this.getNodeVersion(),\n this.getPythonVersion(),\n this.getDockerVersion(),\n ]);\n\n if (nodeVersion.status === 'fulfilled' && nodeVersion.value) {\n envInfo.node = nodeVersion.value;\n }\n\n if (pythonVersion.status === 'fulfilled' && pythonVersion.value) {\n envInfo.python = pythonVersion.value;\n }\n\n if (dockerVersion.status === 'fulfilled' && dockerVersion.value) {\n envInfo.docker = dockerVersion.value;\n }\n\n // Return null if no environment versions were found\n if (Object.keys(envInfo).length === 0) {\n return null;\n }\n\n return envInfo;\n }\n\n /**\n * Get Node.js version with caching\n */\n private async getNodeVersion(): Promise<string | null> {\n const cacheKey = CacheKeys.NODE_VERSION;\n // Environment versions change rarely, cache for 8 hours (96x default TTL)\n // Covers a full workday - users rarely update Node/Python/Docker multiple times per day\n const envCacheTTL = this.config.cacheTTL * 96;\n\n // Try cache first\n const cached = await this.cache.get<string>(cacheKey, envCacheTTL);\n if (cached) {\n return cached;\n }\n\n try {\n // Method 1: node --version\n let version = await cachedCommand(\n this.cache,\n cacheKey,\n 'node',\n ['--version'],\n envCacheTTL\n );\n\n if (version) {\n // Remove 'v' prefix and clean up\n return version.replace(/^v/, '').trim();\n }\n\n return null;\n\n } catch (error) {\n console.debug('[DEBUG] Failed to get Node.js version:', error instanceof Error ? error.message : String(error));\n return null;\n }\n }\n\n /**\n * Get Python version with caching (tries python3 first, then python)\n */\n private async getPythonVersion(): Promise<string | null> {\n const python3Key = CacheKeys.PYTHON3_VERSION;\n const pythonKey = CacheKeys.PYTHON_VERSION;\n // Environment versions change rarely, cache for 8 hours (96x default TTL)\n // Covers a full workday - users rarely update Node/Python/Docker multiple times per day\n const envCacheTTL = this.config.cacheTTL * 96;\n\n // Try python3 first\n try {\n let version = await cachedCommand(\n this.cache,\n python3Key,\n 'python3',\n ['--version'],\n envCacheTTL\n );\n\n if (version) {\n // Extract version number from \"Python 3.x.y\" format\n const versionMatch = version.match(/(\\d+\\.\\d+\\.\\d+)/);\n if (versionMatch) {\n return versionMatch[1] || null;\n }\n }\n } catch {\n // python3 not available, try python\n }\n\n // Fallback to python\n try {\n let version = await cachedCommand(\n this.cache,\n pythonKey,\n 'python',\n ['--version'],\n envCacheTTL\n );\n\n if (version) {\n // Extract version number from \"Python 3.x.y\" or \"Python 2.x.y\" format\n const versionMatch = version.match(/(\\d+\\.\\d+\\.\\d+)/);\n if (versionMatch) {\n return versionMatch[1] || null;\n }\n }\n } catch {\n // python not available either\n }\n\n return null;\n }\n\n /**\n * Get Docker version with caching\n */\n private async getDockerVersion(): Promise<string | null> {\n const cacheKey = 'docker_version';\n\n try {\n let version = await cachedCommand(\n this.cache,\n cacheKey,\n 'docker',\n ['--version'],\n this.config.cacheTTL * 96 // Longer TTL for Docker (8 hours vs 5 minutes)\n );\n\n if (version) {\n // Extract version number from \"Docker version 20.x.y\" format\n const versionMatch = version.match(/Docker version (\\d+\\.\\d+\\.\\d+)/);\n if (versionMatch) {\n return versionMatch[1] || null;\n }\n }\n\n return null;\n\n } catch (error) {\n console.debug('[DEBUG] Failed to get Docker version:', error instanceof Error ? error.message : String(error));\n return null;\n }\n }\n\n /**\n * Format environment information for display\n */\n formatEnvironmentInfo(envInfo: EnvironmentInfo, symbols: ReturnType<typeof getEnvironmentSymbols>): string {\n const parts: string[] = [];\n\n if (envInfo.node) {\n parts.push(`${symbols.node}${envInfo.node}`);\n }\n\n if (envInfo.python) {\n parts.push(`${symbols.python}${envInfo.python}`);\n }\n\n if (envInfo.docker) {\n parts.push(`${symbols.docker}${envInfo.docker}`);\n }\n\n return parts.join(' ');\n }\n\n /**\n * Get additional tool versions (for future expansion)\n */\n async getAdditionalTools(): Promise<{ [key: string]: string }> {\n const additionalTools: { [key: string]: string } = {};\n\n // Future tools could include:\n // - Go version\n // - Rust version\n // - Java version\n // - Ruby version\n // - Kubernetes version\n // - Helm version\n // - etc.\n\n return additionalTools;\n }\n\n /**\n * Check if a specific tool is available in the environment\n */\n async isToolAvailable(tool: string): Promise<boolean> {\n try {\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n await execAsync(`command -v ${tool}`, { timeout: 2000 });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get shell environment information\n */\n getShellEnvironment(): { shell: string; shellVersion?: string } {\n const shell = process.env.SHELL || 'unknown';\n\n // Try to extract shell version (basic implementation)\n let shellVersion: string | undefined;\n\n if (shell.includes('bash')) {\n shellVersion = process.env.BASH_VERSION;\n } else if (shell.includes('zsh')) {\n shellVersion = process.env.ZSH_VERSION;\n } else if (shell.includes('fish')) {\n shellVersion = process.env.FISH_VERSION;\n }\n\n return shellVersion ? { shell, shellVersion } : { shell };\n }\n\n /**\n * Get operating system information\n */\n getOSInfo(): { platform: string; arch: string; release?: string } {\n const platform = process.platform;\n const arch = process.arch;\n const release = process.env.OSTYPE || process.env.OS;\n\n return release ? { platform, arch, release } : { platform, arch };\n }\n}\n\n/**\n * Environment information formatter for different display modes\n */\nexport class EnvironmentFormatter {\n private symbols: ReturnType<typeof getEnvironmentSymbols>;\n\n constructor(symbols: ReturnType<typeof getEnvironmentSymbols>) {\n this.symbols = symbols;\n }\n\n /**\n * Format environment info in different styles\n */\n format(envInfo: EnvironmentInfo, style: 'compact' | 'verbose' | 'minimal' = 'compact'): string {\n switch (style) {\n case 'compact':\n return this.formatCompact(envInfo);\n case 'verbose':\n return this.formatVerbose(envInfo);\n case 'minimal':\n return this.formatMinimal(envInfo);\n default:\n return this.formatCompact(envInfo);\n }\n }\n\n /**\n * Compact format: Node22.17 Py3.13 Docker28.3\n */\n private formatCompact(envInfo: EnvironmentInfo): string {\n const parts: string[] = [];\n\n if (envInfo.node) {\n parts.push(`Node${envInfo.node}`);\n }\n\n if (envInfo.python) {\n parts.push(`Py${envInfo.python}`);\n }\n\n if (envInfo.docker) {\n parts.push(`Docker${envInfo.docker}`);\n }\n\n return parts.join(' ');\n }\n\n /**\n * Verbose format: Node.js v22.17.1 \u2022 Python 3.13.5 \u2022 Docker 28.3.3\n */\n private formatVerbose(envInfo: EnvironmentInfo): string {\n const parts: string[] = [];\n\n if (envInfo.node) {\n parts.push(`Node.js v${envInfo.node}`);\n }\n\n if (envInfo.python) {\n parts.push(`Python ${envInfo.python}`);\n }\n\n if (envInfo.docker) {\n parts.push(`Docker ${envInfo.docker}`);\n }\n\n return parts.join(' \u2022 ');\n }\n\n /**\n * Minimal format: N22 P17 D28 (just major versions)\n */\n private formatMinimal(envInfo: EnvironmentInfo): string {\n const parts: string[] = [];\n\n if (envInfo.node) {\n const majorVersion = envInfo.node.split('.')[0];\n parts.push(`N${majorVersion}`);\n }\n\n if (envInfo.python) {\n const majorVersion = envInfo.python.split('.')[0];\n parts.push(`P${majorVersion}`);\n }\n\n if (envInfo.docker) {\n const majorVersion = envInfo.docker.split('.')[0];\n parts.push(`D${majorVersion}`);\n }\n\n return parts.join(' ');\n }\n\n /**\n * Format with icons: \uE71822.17 \uE2353.13 \uF30828.3\n */\n formatWithIcons(envInfo: EnvironmentInfo): string {\n const parts: string[] = [];\n\n if (envInfo.node) {\n parts.push(`${this.symbols.node}${envInfo.node}`);\n }\n\n if (envInfo.python) {\n parts.push(`${this.symbols.python}${envInfo.python}`);\n }\n\n if (envInfo.docker) {\n parts.push(`${this.symbols.docker}${envInfo.docker}`);\n }\n\n return parts.join(' ');\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["readFileSync", "existsSync", "join", "homedir", "readFileSync"]
|
|
7
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -153,15 +153,23 @@ async function buildStatusline(params) {
|
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
155
|
* Calculate context window usage percentage
|
|
156
|
+
*
|
|
157
|
+
* Prioritizes the pre-calculated used_percentage field (Claude Code v2.1.15+)
|
|
158
|
+
* Falls back to manual calculation from current_usage if not available
|
|
156
159
|
*/
|
|
157
160
|
function calculateContextWindowPercentage(contextWindow) {
|
|
158
161
|
try {
|
|
162
|
+
// Try pre-calculated percentage first (Claude Code v2.1.15+)
|
|
163
|
+
if (contextWindow.used_percentage !== undefined && contextWindow.used_percentage !== null) {
|
|
164
|
+
// Cap at 100% and ensure non-negative
|
|
165
|
+
return Math.max(0, Math.min(100, Math.round(contextWindow.used_percentage)));
|
|
166
|
+
}
|
|
167
|
+
// Fall back to manual calculation for older Claude Code versions
|
|
159
168
|
const { current_usage, context_window_size } = contextWindow;
|
|
160
169
|
if (!context_window_size || context_window_size === 0) {
|
|
161
170
|
return null;
|
|
162
171
|
}
|
|
163
172
|
// If current_usage is null or undefined, we cannot calculate the percentage
|
|
164
|
-
// This matches the official Claude Code documentation behavior
|
|
165
173
|
if (!current_usage) {
|
|
166
174
|
return 0;
|
|
167
175
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Claude Statusline - TypeScript v2.0\n * Main entry point\n */\n\nimport { readFileSync } from 'fs';\nimport { loadConfig, Config } from './core/config.js';\nimport { validateInput, validateDirectory } from './core/security.js';\nimport { Cache } from './core/cache.js';\nimport { GitOperations } from './git/status.js';\nimport { detectSymbols, getEnvironmentSymbols, SymbolSet } from './ui/symbols.js';\nimport { getTerminalWidth, truncateText, smartTruncate, debugWidthDetection, getStringDisplayWidth } from './ui/width.js';\nimport { EnvironmentDetector, EnvironmentFormatter } from './env/context.js';\n\n/**\n * Claude Code input interface\n */\ninterface ClaudeInput {\n workspace: {\n current_dir: string;\n };\n model: {\n display_name: string;\n };\n context_window?: {\n total_input_tokens: number;\n total_output_tokens: number;\n context_window_size: number;\n current_usage: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n };\n };\n}\n\n/**\n * Main execution function\n */\nexport async function main(): Promise<void> {\n try {\n // Load configuration\n const config = loadConfig();\n\n // Initialize components\n const cache = new Cache(config);\n const gitOps = new GitOperations(config, cache);\n const envDetector = new EnvironmentDetector(config, cache);\n\n // Debug width detection if enabled\n await debugWidthDetection(config);\n\n // Read and validate input from stdin\n const input = await readInput();\n if (!validateInput(JSON.stringify(input), config)) {\n console.error('[ERROR] Invalid input received');\n process.exit(1);\n }\n\n // Extract information from input\n const { fullDir, modelName, contextWindow } = extractInputInfo(input);\n if (!fullDir || !modelName) {\n console.error('[ERROR] Failed to extract required information from input');\n process.exit(1);\n }\n\n // Validate directory\n const isValidDir = await validateDirectory(fullDir);\n if (!isValidDir) {\n console.error('[ERROR] Invalid or inaccessible directory:', fullDir);\n process.exit(1);\n }\n\n // Get components (run in parallel for better performance)\n const operations: Promise<any>[] = [\n gitOps.getGitInfo(fullDir),\n envDetector.getEnvironmentInfo(),\n detectSymbols(config),\n ];\n\n // Only get terminal width if smart truncation is enabled\n let terminalWidth: number | undefined;\n if (config.truncate) {\n operations.push(getTerminalWidth(config));\n }\n\n const results = await Promise.all(operations);\n const [gitInfo, envInfo, symbols] = results;\n\n // Extract terminal width from results if it was requested\n if (config.truncate && results.length > 3) {\n terminalWidth = results[3];\n }\n\n // Build statusline\n const statusline = await buildStatusline({\n fullDir,\n modelName,\n contextWindow,\n gitInfo,\n envInfo,\n symbols,\n ...(terminalWidth && { terminalWidth }), // Only include if defined\n config,\n gitOps,\n });\n\n // Output result\n process.stdout.write(statusline);\n\n } catch (error) {\n console.error('[ERROR]', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n\n/**\n * Read JSON input from stdin\n */\nasync function readInput(): Promise<ClaudeInput> {\n try {\n const input = readFileSync(0, 'utf-8'); // Read from stdin (fd 0)\n const parsed = JSON.parse(input.trim());\n return parsed as ClaudeInput;\n } catch (error) {\n throw new Error(`Failed to read or parse input: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Extract directory and model name from Claude input\n */\nfunction extractInputInfo(input: ClaudeInput): { fullDir: string; modelName: string; contextWindow?: ClaudeInput['context_window'] } {\n const fullDir = input.workspace?.current_dir || '';\n const modelName = input.model?.display_name || 'Unknown';\n const contextWindow = input.context_window;\n\n return { fullDir, modelName, contextWindow };\n}\n\n/**\n * Build the complete statusline string\n */\nasync function buildStatusline(params: {\n fullDir: string;\n modelName: string;\n contextWindow?: ClaudeInput['context_window'];\n gitInfo: any;\n envInfo: any;\n symbols: SymbolSet;\n terminalWidth?: number; // Optional - only needed for smart truncation\n config: Config;\n gitOps: GitOperations;\n}): Promise<string> {\n const { fullDir, modelName, contextWindow, gitInfo, envInfo, symbols, terminalWidth, config, gitOps } = params;\n\n // Get project name\n const projectName = fullDir.split('/').pop() || fullDir.split('\\\\').pop() || 'project';\n\n // Build git status string\n let gitStatus = '';\n if (gitInfo) {\n gitStatus = gitOps.formatGitStatus(gitInfo, symbols);\n }\n\n // Build environment context string\n let envContext = '';\n if (envInfo) {\n const envSymbols = getEnvironmentSymbols(symbols);\n const envFormatter = new EnvironmentFormatter(envSymbols);\n envContext = ` ${envFormatter.formatWithIcons(envInfo)}`;\n }\n\n // Build context window usage string\n let contextUsage = '';\n if (contextWindow && !config.noContextWindow) {\n const percentage = calculateContextWindowPercentage(contextWindow);\n if (percentage !== null) {\n contextUsage = ` ${symbols.contextWindow}${percentage}%`;\n }\n }\n\n // Build model string\n const modelString = `${symbols.model}${modelName}${envContext}${contextUsage}`;\n\n // Initial statusline\n let statusline = `${projectName}${gitStatus} ${modelString}`;\n\n // Apply smart truncation if enabled\n if (config.truncate) {\n if (!terminalWidth) {\n console.error('[ERROR] Smart truncation enabled but terminal width not available');\n process.exit(1);\n }\n statusline = applySmartTruncation({\n statusline,\n projectName,\n gitStatus,\n modelString,\n terminalWidth,\n config,\n symbols,\n });\n }\n // No basic truncation - let terminal handle overflow\n\n return statusline;\n}\n\n/**\n * Calculate context window usage percentage\n */\nfunction calculateContextWindowPercentage(contextWindow: NonNullable<ClaudeInput['context_window']>): number | null {\n try {\n const { current_usage, context_window_size } = contextWindow;\n\n if (!context_window_size || context_window_size === 0) {\n return null;\n }\n\n // If current_usage is null or undefined, we cannot calculate the percentage\n // This matches the official Claude Code documentation behavior\n if (!current_usage) {\n return 0;\n }\n\n // Calculate total tokens used (input + cache tokens from current_usage)\n // Note: Output tokens are NOT included in context window calculation\n // per Claude Code documentation\n const totalUsed = current_usage.input_tokens +\n (current_usage.cache_creation_input_tokens || 0) +\n (current_usage.cache_read_input_tokens || 0);\n\n // Calculate percentage\n const percentage = Math.round((totalUsed / context_window_size) * 100);\n\n // Cap at 100% and ensure non-negative\n return Math.max(0, Math.min(100, percentage));\n } catch {\n return 0;\n }\n}\n\n/**\n * Apply smart truncation with branch prioritization\n */\nfunction applySmartTruncation(params: {\n statusline: string;\n projectName: string;\n gitStatus: string;\n modelString: string;\n terminalWidth: number;\n config: Config;\n symbols: SymbolSet;\n}): string {\n const { statusline, projectName, gitStatus, modelString, terminalWidth, config } = params;\n\n // Use 15-char margin for Claude telemetry compatibility\n const maxLen = Math.max(terminalWidth - config.rightMargin, 30);\n const projectGit = `${projectName}${gitStatus}`;\n\n // Check if everything fits (using display width for accuracy)\n const statuslineDisplayWidth = getStringDisplayWidth(statusline);\n if (statuslineDisplayWidth <= maxLen) {\n return statusline;\n }\n\n // Check if project + space fits, truncate model part only (using display width)\n const projectGitDisplayWidth = getStringDisplayWidth(projectGit);\n if (projectGitDisplayWidth + 1 <= maxLen) {\n // Smart truncation with soft-wrapping (default behavior)\n // Allow disabling soft-wrapping with config setting\n if (config.noSoftWrap) {\n // Legacy behavior: simple truncation only\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n const truncatedModel = truncateText(modelString, modelMaxLen);\n return `${projectGit} ${truncatedModel}`;\n } else {\n // Default: soft-wrap model part\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n\n // If model string needs wrapping and it starts with model icon,\n // prefer wrapping the entire model string to next line\n const modelIconPattern = /^[*]/;\n const modelDisplayWidth = getStringDisplayWidth(modelString);\n if (modelIconPattern.test(modelString) && modelDisplayWidth > modelMaxLen) {\n // Wrap entire model to next line\n return `${projectGit}\\n${modelString}`;\n }\n\n const wrappedModel = applySoftWrap(modelString, modelMaxLen);\n return `${projectGit} ${wrappedModel}`;\n }\n }\n\n // Smart truncation of project+git part\n const truncated = smartTruncate(projectName, gitStatus, maxLen, config);\n if (truncated) {\n return truncated;\n }\n\n // Basic fallback\n return truncateText(statusline, maxLen);\n}\n\n/**\n * Apply soft wrapping to text\n */\nfunction applySoftWrap(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n // Check if this is a model string (starts with model icon)\n const modelIconPattern = /^[*]/; // Nerd Font or ASCII model icon\n if (modelIconPattern.test(text)) {\n return applySoftWrapToModelString(text, maxLength);\n }\n\n // Find a good break point using display width\n let foundBreak = false;\n\n // Work with actual Unicode characters to avoid splitting multi-byte sequences\n const chars = Array.from(text); // This splits by actual Unicode characters\n let currentDisplayWidth = 0;\n let breakCharIndex = chars.length; // Default to no break\n let lastSpaceIndex = -1;\n\n // Find the best break point by display width\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n\n // Track spaces for potential break points\n if (char === ' ') {\n lastSpaceIndex = i;\n }\n\n // Calculate display width for this character\n const charWidth = getStringDisplayWidth(char);\n currentDisplayWidth += charWidth;\n\n // Check if we've exceeded the max length\n if (currentDisplayWidth > maxLength) {\n // If we found a space before this point, use it\n if (lastSpaceIndex >= 0) {\n breakCharIndex = lastSpaceIndex;\n } else {\n // No space found, break before current character\n breakCharIndex = i;\n }\n foundBreak = lastSpaceIndex >= 0;\n break;\n }\n }\n\n // If everything fits, return as is\n if (breakCharIndex >= chars.length) {\n return text;\n }\n\n // If no safe break found and we're very close to max_length, just fit without wrapping\n // But only if we're not dealing with a model string that starts with an icon\n const firstChar = chars.length > 0 ? chars[0] : '';\n const startsWithIcon = firstChar && firstChar !== ' ' && Buffer.byteLength(firstChar, 'utf8') > 1;\n if (!foundBreak && maxLength - currentDisplayWidth > -3 && !startsWithIcon) {\n return text;\n }\n\n // Special case: if we're starting with an icon and breaking very early,\n // try to keep at least the icon and 1-2 more characters\n if (startsWithIcon && breakCharIndex <= 2 && maxLength >= 3) {\n // Find a better break point after at least 3 characters total (by display width)\n let testWidth = 0;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n testWidth += getStringDisplayWidth(char);\n if (testWidth >= 3 || testWidth >= maxLength) {\n breakCharIndex = i;\n foundBreak = true;\n break;\n }\n }\n }\n\n // Build the strings using character indices\n const firstChars = chars.slice(0, breakCharIndex);\n const secondChars = chars.slice(breakCharIndex);\n\n // Remove leading space from second line if we broke at space\n if (secondChars.length > 0 && secondChars[0] === ' ') {\n secondChars.shift();\n }\n\n // Join characters back into strings\n const firstLine = firstChars.join('');\n const secondLine = secondChars.join('');\n\n // Only wrap if second line has meaningful content\n if (secondLine) {\n return `${firstLine}\\n${secondLine}`;\n } else {\n return firstLine;\n }\n}\n\n/**\n * Apply soft wrapping specifically to model strings, keeping the model icon\n * with the model name and context usage as a unit\n */\nfunction applySoftWrapToModelString(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n const chars = Array.from(text);\n\n // Find all space positions to understand the structure\n const spacePositions: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === ' ') {\n spacePositions.push(i);\n }\n }\n\n // If we have context usage (marked by context window icon like ⚡︎ or #)\n // The structure is: [icon][model] [env] [context icon][percentage]\n // We want to prefer keeping: [icon][model] [context icon][percentage] together if possible\n\n let contextIconIndex = -1;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (char === '⚡' || char === '#') {\n contextIconIndex = i;\n break;\n }\n }\n\n // Strategy 1: If we have context usage, try to keep it with the model on the second line\n // This ensures the icon and percentage stay together\n if (contextIconIndex > 0) {\n // Find the space before context usage\n const spaceBeforeContext = chars.findIndex((c, i) => i < contextIconIndex && c === ' ');\n\n if (spaceBeforeContext > 0) {\n // Check if we can fit model + icon + percentage on second line (using display width)\n const contextPart = chars.slice(spaceBeforeContext + 1).join('');\n const contextPartWidth = getStringDisplayWidth(contextPart);\n if (contextPartWidth <= maxLength) {\n // Put model name on first line, context on second line\n const modelPart = chars.slice(0, spaceBeforeContext).join('');\n return `${modelPart}\\n${contextPart}`;\n }\n }\n }\n\n // Strategy 2: Try to find a break point that keeps the model icon with model name\n // Look for first space after model name (if no context or if context doesn't fit)\n if (spacePositions.length > 0) {\n const firstSpaceAfterModel = spacePositions[0];\n if (firstSpaceAfterModel !== undefined && firstSpaceAfterModel > 1) {\n // Check if the model part fits (using display width)\n const modelPart = chars.slice(0, firstSpaceAfterModel).join('');\n const modelPartWidth = getStringDisplayWidth(modelPart);\n if (modelPartWidth <= maxLength) {\n const remainingPart = chars.slice(firstSpaceAfterModel + 1).join('');\n if (remainingPart) {\n return `${modelPart}\\n${remainingPart}`;\n }\n return modelPart;\n }\n }\n }\n\n // Strategy 3: Find break point by display width (not character count)\n // This is the critical fix for the garbled output artifacts\n let currentWidth = 0;\n let breakCharIndex = chars.length;\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n const charWidth = getStringDisplayWidth(char);\n if (currentWidth + charWidth > maxLength) {\n breakCharIndex = i;\n break;\n }\n currentWidth += charWidth;\n }\n\n // If we found a valid break point\n if (breakCharIndex < chars.length && breakCharIndex > 0) {\n const firstPart = chars.slice(0, breakCharIndex).join('');\n const secondPart = chars.slice(breakCharIndex).join('');\n if (secondPart) {\n return `${firstPart}\\n${secondPart}`;\n }\n return firstPart;\n }\n\n return text;\n}\n\n// Run main function if this file is executed directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main();\n}"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Claude Statusline - TypeScript v2.0\n * Main entry point\n */\n\nimport { readFileSync } from 'fs';\nimport { loadConfig, Config } from './core/config.js';\nimport { validateInput, validateDirectory } from './core/security.js';\nimport { Cache } from './core/cache.js';\nimport { GitOperations } from './git/status.js';\nimport { detectSymbols, getEnvironmentSymbols, SymbolSet } from './ui/symbols.js';\nimport { getTerminalWidth, truncateText, smartTruncate, debugWidthDetection, getStringDisplayWidth } from './ui/width.js';\nimport { EnvironmentDetector, EnvironmentFormatter } from './env/context.js';\n\n/**\n * Claude Code input interface\n */\ninterface ClaudeInput {\n workspace: {\n current_dir: string;\n };\n model: {\n display_name: string;\n };\n context_window?: {\n total_input_tokens: number;\n total_output_tokens: number;\n context_window_size: number;\n // New in Claude Code v2.1.15: Pre-calculated percentages\n used_percentage?: number;\n remaining_percentage?: number;\n // Legacy: Current usage for manual calculation\n current_usage?: {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n };\n };\n}\n\n/**\n * Main execution function\n */\nexport async function main(): Promise<void> {\n try {\n // Load configuration\n const config = loadConfig();\n\n // Initialize components\n const cache = new Cache(config);\n const gitOps = new GitOperations(config, cache);\n const envDetector = new EnvironmentDetector(config, cache);\n\n // Debug width detection if enabled\n await debugWidthDetection(config);\n\n // Read and validate input from stdin\n const input = await readInput();\n if (!validateInput(JSON.stringify(input), config)) {\n console.error('[ERROR] Invalid input received');\n process.exit(1);\n }\n\n // Extract information from input\n const { fullDir, modelName, contextWindow } = extractInputInfo(input);\n if (!fullDir || !modelName) {\n console.error('[ERROR] Failed to extract required information from input');\n process.exit(1);\n }\n\n // Validate directory\n const isValidDir = await validateDirectory(fullDir);\n if (!isValidDir) {\n console.error('[ERROR] Invalid or inaccessible directory:', fullDir);\n process.exit(1);\n }\n\n // Get components (run in parallel for better performance)\n const operations: Promise<any>[] = [\n gitOps.getGitInfo(fullDir),\n envDetector.getEnvironmentInfo(),\n detectSymbols(config),\n ];\n\n // Only get terminal width if smart truncation is enabled\n let terminalWidth: number | undefined;\n if (config.truncate) {\n operations.push(getTerminalWidth(config));\n }\n\n const results = await Promise.all(operations);\n const [gitInfo, envInfo, symbols] = results;\n\n // Extract terminal width from results if it was requested\n if (config.truncate && results.length > 3) {\n terminalWidth = results[3];\n }\n\n // Build statusline\n const statusline = await buildStatusline({\n fullDir,\n modelName,\n contextWindow,\n gitInfo,\n envInfo,\n symbols,\n ...(terminalWidth && { terminalWidth }), // Only include if defined\n config,\n gitOps,\n });\n\n // Output result\n process.stdout.write(statusline);\n\n } catch (error) {\n console.error('[ERROR]', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n}\n\n/**\n * Read JSON input from stdin\n */\nasync function readInput(): Promise<ClaudeInput> {\n try {\n const input = readFileSync(0, 'utf-8'); // Read from stdin (fd 0)\n const parsed = JSON.parse(input.trim());\n return parsed as ClaudeInput;\n } catch (error) {\n throw new Error(`Failed to read or parse input: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Extract directory and model name from Claude input\n */\nfunction extractInputInfo(input: ClaudeInput): { fullDir: string; modelName: string; contextWindow?: ClaudeInput['context_window'] } {\n const fullDir = input.workspace?.current_dir || '';\n const modelName = input.model?.display_name || 'Unknown';\n const contextWindow = input.context_window;\n\n return { fullDir, modelName, contextWindow };\n}\n\n/**\n * Build the complete statusline string\n */\nasync function buildStatusline(params: {\n fullDir: string;\n modelName: string;\n contextWindow?: ClaudeInput['context_window'];\n gitInfo: any;\n envInfo: any;\n symbols: SymbolSet;\n terminalWidth?: number; // Optional - only needed for smart truncation\n config: Config;\n gitOps: GitOperations;\n}): Promise<string> {\n const { fullDir, modelName, contextWindow, gitInfo, envInfo, symbols, terminalWidth, config, gitOps } = params;\n\n // Get project name\n const projectName = fullDir.split('/').pop() || fullDir.split('\\\\').pop() || 'project';\n\n // Build git status string\n let gitStatus = '';\n if (gitInfo) {\n gitStatus = gitOps.formatGitStatus(gitInfo, symbols);\n }\n\n // Build environment context string\n let envContext = '';\n if (envInfo) {\n const envSymbols = getEnvironmentSymbols(symbols);\n const envFormatter = new EnvironmentFormatter(envSymbols);\n envContext = ` ${envFormatter.formatWithIcons(envInfo)}`;\n }\n\n // Build context window usage string\n let contextUsage = '';\n if (contextWindow && !config.noContextWindow) {\n const percentage = calculateContextWindowPercentage(contextWindow);\n if (percentage !== null) {\n contextUsage = ` ${symbols.contextWindow}${percentage}%`;\n }\n }\n\n // Build model string\n const modelString = `${symbols.model}${modelName}${envContext}${contextUsage}`;\n\n // Initial statusline\n let statusline = `${projectName}${gitStatus} ${modelString}`;\n\n // Apply smart truncation if enabled\n if (config.truncate) {\n if (!terminalWidth) {\n console.error('[ERROR] Smart truncation enabled but terminal width not available');\n process.exit(1);\n }\n statusline = applySmartTruncation({\n statusline,\n projectName,\n gitStatus,\n modelString,\n terminalWidth,\n config,\n symbols,\n });\n }\n // No basic truncation - let terminal handle overflow\n\n return statusline;\n}\n\n/**\n * Calculate context window usage percentage\n *\n * Prioritizes the pre-calculated used_percentage field (Claude Code v2.1.15+)\n * Falls back to manual calculation from current_usage if not available\n */\nfunction calculateContextWindowPercentage(contextWindow: NonNullable<ClaudeInput['context_window']>): number | null {\n try {\n // Try pre-calculated percentage first (Claude Code v2.1.15+)\n if (contextWindow.used_percentage !== undefined && contextWindow.used_percentage !== null) {\n // Cap at 100% and ensure non-negative\n return Math.max(0, Math.min(100, Math.round(contextWindow.used_percentage)));\n }\n\n // Fall back to manual calculation for older Claude Code versions\n const { current_usage, context_window_size } = contextWindow;\n\n if (!context_window_size || context_window_size === 0) {\n return null;\n }\n\n // If current_usage is null or undefined, we cannot calculate the percentage\n if (!current_usage) {\n return 0;\n }\n\n // Calculate total tokens used (input + cache tokens from current_usage)\n // Note: Output tokens are NOT included in context window calculation\n // per Claude Code documentation\n const totalUsed = current_usage.input_tokens +\n (current_usage.cache_creation_input_tokens || 0) +\n (current_usage.cache_read_input_tokens || 0);\n\n // Calculate percentage\n const percentage = Math.round((totalUsed / context_window_size) * 100);\n\n // Cap at 100% and ensure non-negative\n return Math.max(0, Math.min(100, percentage));\n } catch {\n return 0;\n }\n}\n\n/**\n * Apply smart truncation with branch prioritization\n */\nfunction applySmartTruncation(params: {\n statusline: string;\n projectName: string;\n gitStatus: string;\n modelString: string;\n terminalWidth: number;\n config: Config;\n symbols: SymbolSet;\n}): string {\n const { statusline, projectName, gitStatus, modelString, terminalWidth, config } = params;\n\n // Use 15-char margin for Claude telemetry compatibility\n const maxLen = Math.max(terminalWidth - config.rightMargin, 30);\n const projectGit = `${projectName}${gitStatus}`;\n\n // Check if everything fits (using display width for accuracy)\n const statuslineDisplayWidth = getStringDisplayWidth(statusline);\n if (statuslineDisplayWidth <= maxLen) {\n return statusline;\n }\n\n // Check if project + space fits, truncate model part only (using display width)\n const projectGitDisplayWidth = getStringDisplayWidth(projectGit);\n if (projectGitDisplayWidth + 1 <= maxLen) {\n // Smart truncation with soft-wrapping (default behavior)\n // Allow disabling soft-wrapping with config setting\n if (config.noSoftWrap) {\n // Legacy behavior: simple truncation only\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n const truncatedModel = truncateText(modelString, modelMaxLen);\n return `${projectGit} ${truncatedModel}`;\n } else {\n // Default: soft-wrap model part\n const modelMaxLen = maxLen - projectGitDisplayWidth - 1;\n\n // If model string needs wrapping and it starts with model icon,\n // prefer wrapping the entire model string to next line\n const modelIconPattern = /^[*]/;\n const modelDisplayWidth = getStringDisplayWidth(modelString);\n if (modelIconPattern.test(modelString) && modelDisplayWidth > modelMaxLen) {\n // Wrap entire model to next line\n return `${projectGit}\\n${modelString}`;\n }\n\n const wrappedModel = applySoftWrap(modelString, modelMaxLen);\n return `${projectGit} ${wrappedModel}`;\n }\n }\n\n // Smart truncation of project+git part\n const truncated = smartTruncate(projectName, gitStatus, maxLen, config);\n if (truncated) {\n return truncated;\n }\n\n // Basic fallback\n return truncateText(statusline, maxLen);\n}\n\n/**\n * Apply soft wrapping to text\n */\nfunction applySoftWrap(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n // Check if this is a model string (starts with model icon)\n const modelIconPattern = /^[*]/; // Nerd Font or ASCII model icon\n if (modelIconPattern.test(text)) {\n return applySoftWrapToModelString(text, maxLength);\n }\n\n // Find a good break point using display width\n let foundBreak = false;\n\n // Work with actual Unicode characters to avoid splitting multi-byte sequences\n const chars = Array.from(text); // This splits by actual Unicode characters\n let currentDisplayWidth = 0;\n let breakCharIndex = chars.length; // Default to no break\n let lastSpaceIndex = -1;\n\n // Find the best break point by display width\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n\n // Track spaces for potential break points\n if (char === ' ') {\n lastSpaceIndex = i;\n }\n\n // Calculate display width for this character\n const charWidth = getStringDisplayWidth(char);\n currentDisplayWidth += charWidth;\n\n // Check if we've exceeded the max length\n if (currentDisplayWidth > maxLength) {\n // If we found a space before this point, use it\n if (lastSpaceIndex >= 0) {\n breakCharIndex = lastSpaceIndex;\n } else {\n // No space found, break before current character\n breakCharIndex = i;\n }\n foundBreak = lastSpaceIndex >= 0;\n break;\n }\n }\n\n // If everything fits, return as is\n if (breakCharIndex >= chars.length) {\n return text;\n }\n\n // If no safe break found and we're very close to max_length, just fit without wrapping\n // But only if we're not dealing with a model string that starts with an icon\n const firstChar = chars.length > 0 ? chars[0] : '';\n const startsWithIcon = firstChar && firstChar !== ' ' && Buffer.byteLength(firstChar, 'utf8') > 1;\n if (!foundBreak && maxLength - currentDisplayWidth > -3 && !startsWithIcon) {\n return text;\n }\n\n // Special case: if we're starting with an icon and breaking very early,\n // try to keep at least the icon and 1-2 more characters\n if (startsWithIcon && breakCharIndex <= 2 && maxLength >= 3) {\n // Find a better break point after at least 3 characters total (by display width)\n let testWidth = 0;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n testWidth += getStringDisplayWidth(char);\n if (testWidth >= 3 || testWidth >= maxLength) {\n breakCharIndex = i;\n foundBreak = true;\n break;\n }\n }\n }\n\n // Build the strings using character indices\n const firstChars = chars.slice(0, breakCharIndex);\n const secondChars = chars.slice(breakCharIndex);\n\n // Remove leading space from second line if we broke at space\n if (secondChars.length > 0 && secondChars[0] === ' ') {\n secondChars.shift();\n }\n\n // Join characters back into strings\n const firstLine = firstChars.join('');\n const secondLine = secondChars.join('');\n\n // Only wrap if second line has meaningful content\n if (secondLine) {\n return `${firstLine}\\n${secondLine}`;\n } else {\n return firstLine;\n }\n}\n\n/**\n * Apply soft wrapping specifically to model strings, keeping the model icon\n * with the model name and context usage as a unit\n */\nfunction applySoftWrapToModelString(text: string, maxLength: number): string {\n // Use display width for accurate measurement\n const displayWidth = getStringDisplayWidth(text);\n if (displayWidth <= maxLength) {\n return text;\n }\n\n const chars = Array.from(text);\n\n // Find all space positions to understand the structure\n const spacePositions: number[] = [];\n for (let i = 0; i < chars.length; i++) {\n if (chars[i] === ' ') {\n spacePositions.push(i);\n }\n }\n\n // If we have context usage (marked by context window icon like ⚡︎ or #)\n // The structure is: [icon][model] [env] [context icon][percentage]\n // We want to prefer keeping: [icon][model] [context icon][percentage] together if possible\n\n let contextIconIndex = -1;\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (char === '⚡' || char === '#') {\n contextIconIndex = i;\n break;\n }\n }\n\n // Strategy 1: If we have context usage, try to keep it with the model on the second line\n // This ensures the icon and percentage stay together\n if (contextIconIndex > 0) {\n // Find the space before context usage\n const spaceBeforeContext = chars.findIndex((c, i) => i < contextIconIndex && c === ' ');\n\n if (spaceBeforeContext > 0) {\n // Check if we can fit model + icon + percentage on second line (using display width)\n const contextPart = chars.slice(spaceBeforeContext + 1).join('');\n const contextPartWidth = getStringDisplayWidth(contextPart);\n if (contextPartWidth <= maxLength) {\n // Put model name on first line, context on second line\n const modelPart = chars.slice(0, spaceBeforeContext).join('');\n return `${modelPart}\\n${contextPart}`;\n }\n }\n }\n\n // Strategy 2: Try to find a break point that keeps the model icon with model name\n // Look for first space after model name (if no context or if context doesn't fit)\n if (spacePositions.length > 0) {\n const firstSpaceAfterModel = spacePositions[0];\n if (firstSpaceAfterModel !== undefined && firstSpaceAfterModel > 1) {\n // Check if the model part fits (using display width)\n const modelPart = chars.slice(0, firstSpaceAfterModel).join('');\n const modelPartWidth = getStringDisplayWidth(modelPart);\n if (modelPartWidth <= maxLength) {\n const remainingPart = chars.slice(firstSpaceAfterModel + 1).join('');\n if (remainingPart) {\n return `${modelPart}\\n${remainingPart}`;\n }\n return modelPart;\n }\n }\n }\n\n // Strategy 3: Find break point by display width (not character count)\n // This is the critical fix for the garbled output artifacts\n let currentWidth = 0;\n let breakCharIndex = chars.length;\n\n for (let i = 0; i < chars.length; i++) {\n const char = chars[i];\n if (!char) break;\n const charWidth = getStringDisplayWidth(char);\n if (currentWidth + charWidth > maxLength) {\n breakCharIndex = i;\n break;\n }\n currentWidth += charWidth;\n }\n\n // If we found a valid break point\n if (breakCharIndex < chars.length && breakCharIndex > 0) {\n const firstPart = chars.slice(0, breakCharIndex).join('');\n const secondPart = chars.slice(breakCharIndex).join('');\n if (secondPart) {\n return `${firstPart}\\n${secondPart}`;\n }\n return firstPart;\n }\n\n return text;\n}\n\n// Run main function if this file is executed directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n main();\n}"]}
|
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inputs": {
|
|
3
|
+
"src/core/config.ts": {
|
|
4
|
+
"bytes": 6754,
|
|
5
|
+
"imports": [
|
|
6
|
+
{
|
|
7
|
+
"path": "zod",
|
|
8
|
+
"kind": "import-statement",
|
|
9
|
+
"external": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"path": "fs",
|
|
13
|
+
"kind": "import-statement",
|
|
14
|
+
"external": true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "os",
|
|
18
|
+
"kind": "import-statement",
|
|
19
|
+
"external": true
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "path",
|
|
23
|
+
"kind": "import-statement",
|
|
24
|
+
"external": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "yaml",
|
|
28
|
+
"kind": "import-statement",
|
|
29
|
+
"external": true
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"format": "esm"
|
|
33
|
+
},
|
|
34
|
+
"src/core/security.ts": {
|
|
35
|
+
"bytes": 4599,
|
|
36
|
+
"imports": [
|
|
37
|
+
{
|
|
38
|
+
"path": "./config.js",
|
|
39
|
+
"kind": "import-statement",
|
|
40
|
+
"external": true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"path": "fs/promises",
|
|
44
|
+
"kind": "dynamic-import",
|
|
45
|
+
"external": true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "fs",
|
|
49
|
+
"kind": "dynamic-import",
|
|
50
|
+
"external": true
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"format": "esm"
|
|
54
|
+
},
|
|
55
|
+
"src/core/cache.ts": {
|
|
56
|
+
"bytes": 7063,
|
|
57
|
+
"imports": [
|
|
58
|
+
{
|
|
59
|
+
"path": "fs/promises",
|
|
60
|
+
"kind": "import-statement",
|
|
61
|
+
"external": true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"path": "fs",
|
|
65
|
+
"kind": "import-statement",
|
|
66
|
+
"external": true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"path": "path",
|
|
70
|
+
"kind": "import-statement",
|
|
71
|
+
"external": true
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"path": "./config.js",
|
|
75
|
+
"kind": "import-statement",
|
|
76
|
+
"external": true
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"path": "fs/promises",
|
|
80
|
+
"kind": "dynamic-import",
|
|
81
|
+
"external": true
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"path": "fs/promises",
|
|
85
|
+
"kind": "dynamic-import",
|
|
86
|
+
"external": true
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"path": "fs/promises",
|
|
90
|
+
"kind": "dynamic-import",
|
|
91
|
+
"external": true
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"path": "child_process",
|
|
95
|
+
"kind": "dynamic-import",
|
|
96
|
+
"external": true
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "util",
|
|
100
|
+
"kind": "dynamic-import",
|
|
101
|
+
"external": true
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"format": "esm"
|
|
105
|
+
},
|
|
106
|
+
"src/git/native.ts": {
|
|
107
|
+
"bytes": 3861,
|
|
108
|
+
"imports": [
|
|
109
|
+
{
|
|
110
|
+
"path": "child_process",
|
|
111
|
+
"kind": "import-statement",
|
|
112
|
+
"external": true
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"format": "esm"
|
|
116
|
+
},
|
|
117
|
+
"src/git/status.ts": {
|
|
118
|
+
"bytes": 8767,
|
|
119
|
+
"imports": [
|
|
120
|
+
{
|
|
121
|
+
"path": "../core/config.js",
|
|
122
|
+
"kind": "import-statement",
|
|
123
|
+
"external": true
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"path": "src/core/cache.ts",
|
|
127
|
+
"kind": "import-statement",
|
|
128
|
+
"original": "../core/cache.js"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"path": "src/git/native.ts",
|
|
132
|
+
"kind": "import-statement",
|
|
133
|
+
"original": "./native.js"
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"format": "esm"
|
|
137
|
+
},
|
|
138
|
+
"src/ui/symbols.ts": {
|
|
139
|
+
"bytes": 10486,
|
|
140
|
+
"imports": [
|
|
141
|
+
{
|
|
142
|
+
"path": "../core/config.js",
|
|
143
|
+
"kind": "import-statement",
|
|
144
|
+
"external": true
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"path": "child_process",
|
|
148
|
+
"kind": "dynamic-import",
|
|
149
|
+
"external": true
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"path": "util",
|
|
153
|
+
"kind": "dynamic-import",
|
|
154
|
+
"external": true
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"path": "fs/promises",
|
|
158
|
+
"kind": "dynamic-import",
|
|
159
|
+
"external": true
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"path": "os",
|
|
163
|
+
"kind": "dynamic-import",
|
|
164
|
+
"external": true
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"path": "child_process",
|
|
168
|
+
"kind": "dynamic-import",
|
|
169
|
+
"external": true
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"path": "util",
|
|
173
|
+
"kind": "dynamic-import",
|
|
174
|
+
"external": true
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"format": "esm"
|
|
178
|
+
},
|
|
179
|
+
"src/ui/width.ts": {
|
|
180
|
+
"bytes": 11061,
|
|
181
|
+
"imports": [
|
|
182
|
+
{
|
|
183
|
+
"path": "../core/config.js",
|
|
184
|
+
"kind": "import-statement",
|
|
185
|
+
"external": true
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"path": "child_process",
|
|
189
|
+
"kind": "dynamic-import",
|
|
190
|
+
"external": true
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"path": "util",
|
|
194
|
+
"kind": "dynamic-import",
|
|
195
|
+
"external": true
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"path": "child_process",
|
|
199
|
+
"kind": "dynamic-import",
|
|
200
|
+
"external": true
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"path": "util",
|
|
204
|
+
"kind": "dynamic-import",
|
|
205
|
+
"external": true
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"format": "esm"
|
|
209
|
+
},
|
|
210
|
+
"src/env/context.ts": {
|
|
211
|
+
"bytes": 9791,
|
|
212
|
+
"imports": [
|
|
213
|
+
{
|
|
214
|
+
"path": "../core/config.js",
|
|
215
|
+
"kind": "import-statement",
|
|
216
|
+
"external": true
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"path": "src/core/cache.ts",
|
|
220
|
+
"kind": "import-statement",
|
|
221
|
+
"original": "../core/cache.js"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"path": "../ui/symbols.js",
|
|
225
|
+
"kind": "import-statement",
|
|
226
|
+
"external": true
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"path": "child_process",
|
|
230
|
+
"kind": "dynamic-import",
|
|
231
|
+
"external": true
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"path": "util",
|
|
235
|
+
"kind": "dynamic-import",
|
|
236
|
+
"external": true
|
|
237
|
+
}
|
|
238
|
+
],
|
|
239
|
+
"format": "esm"
|
|
240
|
+
},
|
|
241
|
+
"src/index.ts": {
|
|
242
|
+
"bytes": 16968,
|
|
243
|
+
"imports": [
|
|
244
|
+
{
|
|
245
|
+
"path": "fs",
|
|
246
|
+
"kind": "import-statement",
|
|
247
|
+
"external": true
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"path": "src/core/config.ts",
|
|
251
|
+
"kind": "import-statement",
|
|
252
|
+
"original": "./core/config.js"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"path": "src/core/security.ts",
|
|
256
|
+
"kind": "import-statement",
|
|
257
|
+
"original": "./core/security.js"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"path": "src/core/cache.ts",
|
|
261
|
+
"kind": "import-statement",
|
|
262
|
+
"original": "./core/cache.js"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"path": "src/git/status.ts",
|
|
266
|
+
"kind": "import-statement",
|
|
267
|
+
"original": "./git/status.js"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"path": "src/ui/symbols.ts",
|
|
271
|
+
"kind": "import-statement",
|
|
272
|
+
"original": "./ui/symbols.js"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"path": "src/ui/width.ts",
|
|
276
|
+
"kind": "import-statement",
|
|
277
|
+
"original": "./ui/width.js"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"path": "src/env/context.ts",
|
|
281
|
+
"kind": "import-statement",
|
|
282
|
+
"original": "./env/context.js"
|
|
283
|
+
}
|
|
284
|
+
],
|
|
285
|
+
"format": "esm"
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"outputs": {
|
|
289
|
+
"dist/index.bundle.js.map": {
|
|
290
|
+
"imports": [],
|
|
291
|
+
"exports": [],
|
|
292
|
+
"inputs": {},
|
|
293
|
+
"bytes": 118861
|
|
294
|
+
},
|
|
295
|
+
"dist/index.bundle.js": {
|
|
296
|
+
"imports": [
|
|
297
|
+
{
|
|
298
|
+
"path": "fs",
|
|
299
|
+
"kind": "import-statement",
|
|
300
|
+
"external": true
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"path": "zod",
|
|
304
|
+
"kind": "import-statement",
|
|
305
|
+
"external": true
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"path": "fs",
|
|
309
|
+
"kind": "import-statement",
|
|
310
|
+
"external": true
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"path": "os",
|
|
314
|
+
"kind": "import-statement",
|
|
315
|
+
"external": true
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"path": "path",
|
|
319
|
+
"kind": "import-statement",
|
|
320
|
+
"external": true
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"path": "yaml",
|
|
324
|
+
"kind": "import-statement",
|
|
325
|
+
"external": true
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"path": "fs/promises",
|
|
329
|
+
"kind": "dynamic-import",
|
|
330
|
+
"external": true
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"path": "fs",
|
|
334
|
+
"kind": "dynamic-import",
|
|
335
|
+
"external": true
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"path": "fs/promises",
|
|
339
|
+
"kind": "import-statement",
|
|
340
|
+
"external": true
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"path": "fs",
|
|
344
|
+
"kind": "import-statement",
|
|
345
|
+
"external": true
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"path": "path",
|
|
349
|
+
"kind": "import-statement",
|
|
350
|
+
"external": true
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"path": "fs/promises",
|
|
354
|
+
"kind": "dynamic-import",
|
|
355
|
+
"external": true
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"path": "fs/promises",
|
|
359
|
+
"kind": "dynamic-import",
|
|
360
|
+
"external": true
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"path": "fs/promises",
|
|
364
|
+
"kind": "dynamic-import",
|
|
365
|
+
"external": true
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"path": "child_process",
|
|
369
|
+
"kind": "dynamic-import",
|
|
370
|
+
"external": true
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"path": "util",
|
|
374
|
+
"kind": "dynamic-import",
|
|
375
|
+
"external": true
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"path": "child_process",
|
|
379
|
+
"kind": "import-statement",
|
|
380
|
+
"external": true
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"path": "child_process",
|
|
384
|
+
"kind": "dynamic-import",
|
|
385
|
+
"external": true
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"path": "util",
|
|
389
|
+
"kind": "dynamic-import",
|
|
390
|
+
"external": true
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"path": "fs/promises",
|
|
394
|
+
"kind": "dynamic-import",
|
|
395
|
+
"external": true
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"path": "os",
|
|
399
|
+
"kind": "dynamic-import",
|
|
400
|
+
"external": true
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"path": "child_process",
|
|
404
|
+
"kind": "dynamic-import",
|
|
405
|
+
"external": true
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"path": "util",
|
|
409
|
+
"kind": "dynamic-import",
|
|
410
|
+
"external": true
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"path": "child_process",
|
|
414
|
+
"kind": "dynamic-import",
|
|
415
|
+
"external": true
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
"path": "util",
|
|
419
|
+
"kind": "dynamic-import",
|
|
420
|
+
"external": true
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"path": "child_process",
|
|
424
|
+
"kind": "dynamic-import",
|
|
425
|
+
"external": true
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"path": "util",
|
|
429
|
+
"kind": "dynamic-import",
|
|
430
|
+
"external": true
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"path": "child_process",
|
|
434
|
+
"kind": "dynamic-import",
|
|
435
|
+
"external": true
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
"path": "util",
|
|
439
|
+
"kind": "dynamic-import",
|
|
440
|
+
"external": true
|
|
441
|
+
}
|
|
442
|
+
],
|
|
443
|
+
"exports": [
|
|
444
|
+
"main"
|
|
445
|
+
],
|
|
446
|
+
"entryPoint": "src/index.ts",
|
|
447
|
+
"inputs": {
|
|
448
|
+
"src/index.ts": {
|
|
449
|
+
"bytesInOutput": 9921
|
|
450
|
+
},
|
|
451
|
+
"src/core/config.ts": {
|
|
452
|
+
"bytesInOutput": 4415
|
|
453
|
+
},
|
|
454
|
+
"src/core/security.ts": {
|
|
455
|
+
"bytesInOutput": 2344
|
|
456
|
+
},
|
|
457
|
+
"src/core/cache.ts": {
|
|
458
|
+
"bytesInOutput": 5638
|
|
459
|
+
},
|
|
460
|
+
"src/git/native.ts": {
|
|
461
|
+
"bytesInOutput": 2808
|
|
462
|
+
},
|
|
463
|
+
"src/git/status.ts": {
|
|
464
|
+
"bytesInOutput": 6430
|
|
465
|
+
},
|
|
466
|
+
"src/ui/symbols.ts": {
|
|
467
|
+
"bytesInOutput": 7286
|
|
468
|
+
},
|
|
469
|
+
"src/ui/width.ts": {
|
|
470
|
+
"bytesInOutput": 6321
|
|
471
|
+
},
|
|
472
|
+
"src/env/context.ts": {
|
|
473
|
+
"bytesInOutput": 7285
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
"bytes": 52741
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
package/dist/metafile.prod.json
CHANGED
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
"format": "esm"
|
|
240
240
|
},
|
|
241
241
|
"src/index.ts": {
|
|
242
|
-
"bytes":
|
|
242
|
+
"bytes": 16968,
|
|
243
243
|
"imports": [
|
|
244
244
|
{
|
|
245
245
|
"path": "fs",
|
|
@@ -440,7 +440,7 @@
|
|
|
440
440
|
"entryPoint": "src/index.ts",
|
|
441
441
|
"inputs": {
|
|
442
442
|
"src/index.ts": {
|
|
443
|
-
"bytesInOutput":
|
|
443
|
+
"bytesInOutput": 3563
|
|
444
444
|
},
|
|
445
445
|
"src/core/config.ts": {
|
|
446
446
|
"bytesInOutput": 2741
|
|
@@ -467,7 +467,7 @@
|
|
|
467
467
|
"bytesInOutput": 3027
|
|
468
468
|
}
|
|
469
469
|
},
|
|
470
|
-
"bytes":
|
|
470
|
+
"bytes": 22022
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-statusline",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Simple statusline for Claude Code with git indicators. TypeScript rewrite for performance and npm distribution.",
|
|
5
5
|
"main": "dist/index.bundle.js",
|
|
6
6
|
"bin": {
|
|
@@ -55,19 +55,19 @@
|
|
|
55
55
|
"bun": ">=1.0.0"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"yaml": "^2.
|
|
59
|
-
"zod": "^3.
|
|
58
|
+
"yaml": "^2.8.2",
|
|
59
|
+
"zod": "^3.25.76"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^22.
|
|
63
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
64
|
-
"@typescript-eslint/parser": "^8.
|
|
65
|
-
"esbuild": "^0.27.
|
|
66
|
-
"eslint": "^9.
|
|
67
|
-
"eslint-config-prettier": "^9.1.
|
|
68
|
-
"eslint-plugin-prettier": "^5.
|
|
69
|
-
"prettier": "^3.
|
|
70
|
-
"typescript": "^5.
|
|
62
|
+
"@types/node": "^22.19.7",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
64
|
+
"@typescript-eslint/parser": "^8.53.1",
|
|
65
|
+
"esbuild": "^0.27.2",
|
|
66
|
+
"eslint": "^9.39.2",
|
|
67
|
+
"eslint-config-prettier": "^9.1.2",
|
|
68
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
69
|
+
"prettier": "^3.8.1",
|
|
70
|
+
"typescript": "^5.9.3"
|
|
71
71
|
},
|
|
72
72
|
"files": [
|
|
73
73
|
"dist/",
|