ccpet
Version:
A Claude Code status line script that displays a virtual pet
17 lines (15 loc) • 33.6 kB
JavaScript
"use strict";var Z=Object.create;var O=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,se=Object.prototype.hasOwnProperty;var ne=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),ie=(i,e)=>{for(var t in e)O(i,t,{get:e[t],enumerable:!0})},H=(i,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of te(e))!se.call(i,s)&&s!==t&&O(i,s,{get:()=>e[s],enumerable:!(o=ee(e,s))||o.enumerable});return i};var d=(i,e,t)=>(t=i!=null?Z(oe(i)):{},H(e||!i||!i.__esModule?O(t,"default",{value:i,enumerable:!0}):t,i)),re=i=>H(O({},"__esModule",{value:!0}),i);var W=ne((qe,he)=>{he.exports={name:"ccpet",version:"1.1.2",description:"A Claude Code status line script that displays a virtual pet",main:"dist/ccpet.js",bin:{ccpet:"dist/cli.js"},files:["/dist","/bin"],scripts:{build:"node esbuild.config.js",watch:"node esbuild.config.js --watch",test:"vitest","test:unit":"vitest run src/core src/ui src/services","test:coverage":"vitest run --coverage",prepublishOnly:"npm run build && tsc --noEmit && npm test",version:"npm run build",postversion:"git push && git push --tags","release:patch":"npm version patch","release:minor":"npm version minor","release:major":"npm version major"},devDependencies:{"@types/node":"20.10.5","@vitest/coverage-v8":"^3.2.4",esbuild:"0.20.2",prettier:"3.1.1",typescript:"5.3.3",vitest:"^3.2.4"},engines:{node:">=20.0.0",npm:">=9.0.0"},keywords:["claude-code","status-line","ccpet","pet","cli","virtual-pet","productivity"],author:"Claude Code Team",license:"MIT",homepage:"https://github.com/terryso/ccpet#readme",repository:{type:"git",url:"git+https://github.com/terryso/ccpet.git"},bugs:{url:"https://github.com/terryso/ccpet/issues"}}});var Se={};ie(Se,{main:()=>z});module.exports=re(Se);function ae(){let i=process.env.COLORTERM,e=process.env.TERM;return!!(i==="truecolor"||i==="24bit"||e&&(["iterm","iterm2","alacritty","kitty","wezterm"].some(o=>e.toLowerCase().includes(o))||e.includes("256color"))||process.env.WT_SESSION)}function ce(i){let e=i.replace("#",""),t=parseInt(e.substring(0,2),16),o=parseInt(e.substring(2,4),16),s=parseInt(e.substring(4,6),16);return{r:t,g:o,b:s}}function le(i,e,t){let o=[{r:0,g:0,b:0},{r:128,g:0,b:0},{r:0,g:128,b:0},{r:128,g:128,b:0},{r:0,g:0,b:128},{r:128,g:0,b:128},{r:0,g:128,b:128},{r:192,g:192,b:192},{r:128,g:128,b:128},{r:255,g:0,b:0},{r:0,g:255,b:0},{r:255,g:255,b:0},{r:0,g:0,b:255},{r:255,g:0,b:255},{r:0,g:255,b:255},{r:255,g:255,b:255}],s=0,n=1/0;for(let r=0;r<o.length;r++){let a=o[r],l=Math.sqrt(Math.pow(i-a.r,2)+Math.pow(e-a.g,2)+Math.pow(t-a.b,2));l<n&&(n=l,s=r)}for(let r=0;r<216;r++){let a=16+r,l=Math.floor(r/36)*51,E=Math.floor(r%36/6)*51,F=r%6*51,C=Math.sqrt(Math.pow(i-l,2)+Math.pow(e-E,2)+Math.pow(t-F,2));C<n&&(n=C,s=a)}for(let r=0;r<24;r++){let a=232+r,l=8+r*10,E=Math.sqrt(Math.pow(i-l,2)+Math.pow(e-l,2)+Math.pow(t-l,2));E<n&&(n=E,s=a)}return s}function ue(i,e,t){return`\x1B[38;2;${i};${e};${t}m`}function pe(i,e=!1,t=!1){if(i==="RESET")return"\x1B[0m";let{r:o,g:s,b:n}=ce(i);if(ae()){let l=ue(o,s,n);return t?`\x1B[1m${l}`:l}let r=le(o,s,n);if(e&&r<8)return`\x1B[1;3${r}m`;let a=`\x1B[38;5;${r}m`;return t?`\x1B[1m${a}`:a}function j(i){let e={};for(let[t,o]of Object.entries(i))if(t==="RESET")e[t]="\x1B[0m";else{let s=o.split(":"),n=s[0],r=s.includes("bright"),a=s.includes("bold");e[t]=pe(n,r,a)}return e}var h=d(require("fs")),D=d(require("path")),Y=d(require("os")),m={colors:{petExpression:"#FFFF00:bright:bold",energyBar:"#00FF00",energyValue:"#00FFFF",accumulatedTokens:"#778899",lifetimeTokens:"#FF00FF",sessionInput:"#00FF00",sessionOutput:"#FFFF00",sessionCached:"#F4A460",sessionTotal:"#FFFFFF",contextLength:"#00DDFF",contextPercentage:"#0099DD",contextPercentageUsable:"#90EE90",cost:"#FFD700"},pet:{animationEnabled:!0,decayRate:.0231,emojiEnabled:!0},display:{maxLines:3,line2:{enabled:!0,items:["input","output","cached","total"]},line3:{enabled:!0,items:["context-length","context-percentage","context-percentage-usable","cost"]}}},f=class{configDir;configFile;cachedConfig=null;constructor(){this.configDir=D.join(Y.homedir(),".claude-pet"),this.configFile=D.join(this.configDir,"config.json")}ensureConfigDir(){h.existsSync(this.configDir)||h.mkdirSync(this.configDir,{recursive:!0})}loadConfig(){if(this.cachedConfig)return this.cachedConfig;if(this.ensureConfigDir(),!h.existsSync(this.configFile))return this.saveConfig(m),this.cachedConfig=m,m;try{let e=h.readFileSync(this.configFile,"utf8"),t=JSON.parse(e);return this.cachedConfig=this.mergeWithDefaults(t),this.cachedConfig}catch(e){let t=e instanceof Error?e.message:"Unknown error";return console.warn("Failed to load config, using defaults:",t),this.cachedConfig=m,m}}mergeWithDefaults(e){return{colors:{...m.colors,...e.colors},pet:{...m.pet,...e.pet},display:{...m.display,...e.display,line2:{...m.display.line2,...e.display?.line2},line3:{...m.display.line3,...e.display?.line3}}}}saveConfig(e){this.ensureConfigDir(),h.writeFileSync(this.configFile,JSON.stringify(e,null,2),"utf8"),this.cachedConfig=e}getConfig(){return this.loadConfig()}setColorConfig(e,t){let o=this.loadConfig();o.colors[e]=t,this.saveConfig(o)}setPetConfig(e,t){let o=this.loadConfig();o.pet[e]=t,this.saveConfig(o)}setDisplayConfig(e,t){let o=this.loadConfig();e==="maxLines"?o.display.maxLines=Math.min(3,Math.max(1,Number(t))):e==="line2.enabled"?o.display.line2.enabled=!!t:e==="line2.items"?o.display.line2.items=Array.isArray(t)?t:t.split(",").map(s=>s.trim()):e==="line3.enabled"?o.display.line3.enabled=!!t:e==="line3.items"&&(o.display.line3.items=Array.isArray(t)?t:t.split(",").map(s=>s.trim())),this.saveConfig(o)}resetConfig(){this.saveConfig(m)}listConfig(){let e=this.getConfig();return JSON.stringify(e,null,2)}getConfigPath(){return this.configFile}};var v=(n=>(n.CAT="cat",n.DOG="dog",n.RABBIT="rabbit",n.PANDA="panda",n.FOX="fox",n))(v||{});function ge(){try{let e=new f().getConfig();return{PET_EXPRESSION:e.colors.petExpression||"#FFFF00:bright:bold",ENERGY_BAR:e.colors.energyBar||"#00FF00",ENERGY_VALUE:e.colors.energyValue||"#00FFFF",ACCUMULATED_TOKENS:e.colors.accumulatedTokens||"#778899",LIFETIME_TOKENS:e.colors.lifetimeTokens||"#FF00FF",SESSION_INPUT:e.colors.sessionInput||"#00FF00",SESSION_OUTPUT:e.colors.sessionOutput||"#FFFF00",SESSION_CACHED:e.colors.sessionCached||"#F4A460",SESSION_TOTAL:e.colors.sessionTotal||"#FFFFFF",CONTEXT_LENGTH:e.colors.contextLength||"#00DDFF",CONTEXT_PERCENTAGE:e.colors.contextPercentage||"#0099DD",CONTEXT_PERCENTAGE_USABLE:e.colors.contextPercentageUsable||"#90EE90",COST:e.colors.cost||"#FFD700",RESET:"RESET"}}catch{return{PET_EXPRESSION:"#FFFF00:bright:bold",ENERGY_BAR:"#00FF00",ENERGY_VALUE:"#00FFFF",ACCUMULATED_TOKENS:"#778899",LIFETIME_TOKENS:"#FF00FF",SESSION_INPUT:"#00FF00",SESSION_OUTPUT:"#FFFF00",SESSION_CACHED:"#F4A460",SESSION_TOTAL:"#FFFFFF",CONTEXT_LENGTH:"#00DDFF",CONTEXT_PERCENTAGE:"#0099DD",CONTEXT_PERCENTAGE_USABLE:"#90EE90",COST:"#FFD700",RESET:"RESET"}}}var L={cat:{id:"cat",name:"\u732B",emoji:"\u{1F431}"},dog:{id:"dog",name:"\u72D7",emoji:"\u{1F436}"},rabbit:{id:"rabbit",name:"\u5154\u5B50",emoji:"\u{1F430}"},panda:{id:"panda",name:"\u718A\u732B",emoji:"\u{1F43C}"},fox:{id:"fox",name:"\u72D0\u72F8",emoji:"\u{1F98A}"}},c={INITIAL_ENERGY:100,HAPPY_EXPRESSION_THRESHOLD:80,HAPPY_EXPRESSION:"(^_^)",ENERGY_BAR_LENGTH:10,STATUS_BAR_PRIORITY:100,FILLED_BAR_CHAR:"\u25CF",EMPTY_BAR_CHAR:"\u25CB",STATE_THRESHOLDS:{HAPPY:80,HUNGRY:40,SICK:10,DEAD:0},STATE_EXPRESSIONS:{HAPPY:"(^_^)",HUNGRY:"(o_o)",SICK:"(u_u)",DEAD:"(x_x)"},ANIMATED_EXPRESSIONS:{HAPPY:["(^_^)","(^o^)","(^_^)","(^v^)"],HUNGRY:["(o_o)","(O_O)","(o_o)","(-_-)"],SICK:["(u_u)","(T_T)","(u_u)","(>_<)"],DEAD:["(x_x)","(X_X)","(x_x)","(+_+)"]},TIME_DECAY:{DECAY_CHECK_INTERVAL:6e4,DECAY_RATE:.0231,MINIMUM_DECAY_INTERVAL:6e4},FEEDING:{TOKENS_PER_ENERGY:1e6},ANIMAL:{DEFAULT_TYPE:"cat"},COLORS:j(ge())};var x=class i{state;deps;observers=[];constructor(e,t){this.state={...e},this.deps=t,this._updateExpression()}getState(){return{...this.state}}subscribe(e){return this.observers.push(e),()=>{let t=this.observers.indexOf(e);t>-1&&this.observers.splice(t,1)}}feed(e){try{let t=this.state.accumulatedTokens+e,{TOKENS_PER_ENERGY:o}=this.deps.config.FEEDING,s=Math.floor(t/o),n=t%o;this.state={...this.state,accumulatedTokens:n,lastFeedTime:new Date,totalTokensConsumed:this.state.totalTokensConsumed+e,totalLifetimeTokens:this.state.totalLifetimeTokens+e},s>0&&this.addEnergy(s)}catch(t){console.error("Pet feeding failed:",t)}}applyTimeDecay(){try{let e=new Date,{TIME_DECAY:t}=this.deps.config,o=this.state.lastDecayTime||this.state.lastFeedTime,s=(e.getTime()-o.getTime())/(1e3*60);if(s>0){let n=t?t.DECAY_RATE/(t.DECAY_CHECK_INTERVAL/6e4):.023148148148148147,r=s*n,a=t?t.MINIMUM_DECAY_INTERVAL/(1e3*60):0;r>0&&s>=a&&(this.decreaseEnergy(r),this.state={...this.state,lastDecayTime:e})}}catch(e){console.error("Pet time decay failed:",e)}}addEnergy(e){try{if(typeof e!="number"||e<0||isNaN(e))throw new Error(`Invalid energy amount: ${e}. Must be a non-negative number.`);let t=new Date;this.state={...this.state,energy:Math.min(100,this.state.energy+e),lastFeedTime:t,lastDecayTime:t},this._updateExpression(),this._notify()}catch(t){throw console.error("Pet addEnergy failed:",t),t}}decreaseEnergy(e){try{if(typeof e!="number"||e<0||isNaN(e))throw new Error(`Invalid energy amount: ${e}. Must be a non-negative number.`);this.state={...this.state,energy:Math.max(0,this.state.energy-e)},this._updateExpression(),this._notify()}catch(t){throw console.error("Pet decreaseEnergy failed:",t),t}}getCurrentEnergy(){return this.state.energy}getCurrentAnimalType(){return this.state.animalType}static getRandomAnimalType(){let e=Object.values(v),t=Math.floor(Math.random()*e.length);return e[t]}getAnimalEmoji(){return L[this.state.animalType]?.emoji||L.cat.emoji}isDead(){return this.state.energy===0}resetToInitialState(){try{let e=new Date,t=i.getRandomAnimalType();this.state={energy:this.deps.config.INITIAL_ENERGY,expression:this.deps.config.STATE_EXPRESSIONS.HAPPY,animalType:t,birthTime:e,lastFeedTime:e,totalTokensConsumed:0,accumulatedTokens:0,totalLifetimeTokens:0,lastDecayTime:e,sessionTotalInputTokens:0,sessionTotalOutputTokens:0,sessionTotalCachedTokens:0},console.log(`Pet reborn as ${t} type`),this._updateExpression(),this._notify()}catch(e){throw console.error("Pet resetToInitialState failed:",e),e}}_updateExpression(){if(!this.deps?.config)return;let{STATE_THRESHOLDS:e,STATE_EXPRESSIONS:t}=this.deps.config;this.state.energy>=e.HAPPY?this.state.expression=t.HAPPY:this.state.energy>=e.HUNGRY?this.state.expression=t.HUNGRY:this.state.energy>=e.SICK?this.state.expression=t.SICK:this.state.expression=t.DEAD}getAnimatedExpression(e=!1,t=0,o=!0){let{STATE_THRESHOLDS:s,ANIMATED_EXPRESSIONS:n}=this.deps.config,r;if(!e||!n)r=this.state.expression;else{let a;this.state.energy>=s.HAPPY?a=n.HAPPY:this.state.energy>=s.HUNGRY?a=n.HUNGRY:this.state.energy>=s.SICK?a=n.SICK:a=n.DEAD;let l=t%a.length;r=a[l]}return o?`${this.getAnimalEmoji()}${r}`:r}_notify(){this.observers.forEach(e=>{try{e(this.getState())}catch(t){console.error("Observer notification failed:",t)}})}};var _=class{testMode;configService;constructor(e=!1,t){this.testMode=e,this.configService=t||new f}formatPetDisplay(e,t){try{let o=this.configService.getConfig(),s=[],n=this.formatPetLine(e,t);s.push(n);let r=this.getSessionData(e);if(o.display.line2?.enabled&&(o.display.maxLines||2)>=2){let a=this.formatConfigurableLine(o.display.line2.items||[],r);a&&s.push(a)}if(o.display.line3?.enabled&&(o.display.maxLines||2)>=3){let a=this.formatConfigurableLine(o.display.line3.items||[],r);a&&s.push(a)}return s.join((this.testMode,`
`))}catch(o){return console.error("Failed to format pet display:",o),console.error("Error stack:",o instanceof Error?o.stack:"No stack trace"),"(?) ERROR"}}formatPetLine(e,t){let o=this.generateEnergyBar(e.energy),s=e.energy.toFixed(2),n=this.formatTokenCount(e.accumulatedTokens),r=this.formatTokenCount(e.totalLifetimeTokens),a=t||e.expression;return this.testMode?`${a} ${o} ${s} (${n}) \u{1F496}${r}`:`${c.COLORS.PET_EXPRESSION}${a}${c.COLORS.RESET} ${c.COLORS.ENERGY_BAR}${o}${c.COLORS.RESET} ${c.COLORS.ENERGY_VALUE}${s}${c.COLORS.RESET} ${c.COLORS.ACCUMULATED_TOKENS}(${n})${c.COLORS.RESET} ${c.COLORS.LIFETIME_TOKENS}\u{1F496}${r}${c.COLORS.RESET}`}getSessionData(e){let t={};if(e.sessionTotalInputTokens!==void 0&&(t.input={value:this.formatTokenCount(e.sessionTotalInputTokens),color:c.COLORS.SESSION_INPUT}),e.sessionTotalOutputTokens!==void 0&&(t.output={value:this.formatTokenCount(e.sessionTotalOutputTokens),color:c.COLORS.SESSION_OUTPUT}),e.sessionTotalCachedTokens!==void 0&&(t.cached={value:this.formatTokenCount(e.sessionTotalCachedTokens),color:c.COLORS.SESSION_CACHED}),e.sessionTotalInputTokens!==void 0&&e.sessionTotalOutputTokens!==void 0&&e.sessionTotalCachedTokens!==void 0){let o=e.sessionTotalInputTokens+e.sessionTotalOutputTokens+e.sessionTotalCachedTokens;t.total={value:this.formatTokenCount(o),color:c.COLORS.SESSION_TOTAL}}return e.sessionTotalCostUsd!==void 0&&(t.cost={value:`$${e.sessionTotalCostUsd.toFixed(2)}`,color:c.COLORS.COST}),e.contextLength!==void 0&&(t["context-length"]={value:this.formatTokenCount(e.contextLength),color:c.COLORS.CONTEXT_LENGTH}),e.contextPercentage!==void 0&&(t["context-percentage"]={value:isNaN(e.contextPercentage)?"0.0%":`${e.contextPercentage.toFixed(1)}%`,color:c.COLORS.CONTEXT_PERCENTAGE}),e.contextPercentageUsable!==void 0&&(t["context-percentage-usable"]={value:isNaN(e.contextPercentageUsable)?"0.0%":`${e.contextPercentageUsable.toFixed(1)}%`,color:c.COLORS.CONTEXT_PERCENTAGE_USABLE}),t}formatConfigurableLine(e,t){let o=[];for(let s of e)if(t[s]){let n=t[s],r;s==="context-length"||s==="context-percentage"?r="Ctx":s==="context-percentage-usable"?r="Ctx(u)":s==="cost"?r="Cost":r=s.charAt(0).toUpperCase()+s.slice(1),this.testMode?o.push(`${r}: ${n.value}`):o.push(`${n.color}${r}: ${n.value}${c.COLORS.RESET}`)}return o.length>0?o.join(" "):""}generateEnergyBar(e){try{if(isNaN(e))return"??????????";let t=Math.max(0,Math.min(100,e)),o=Math.round(t/100*c.ENERGY_BAR_LENGTH),s=c.ENERGY_BAR_LENGTH-o;return c.FILLED_BAR_CHAR.repeat(o)+c.EMPTY_BAR_CHAR.repeat(s)}catch(t){return console.error("Failed to generate energy bar:",t),"??????????"}}formatTokenCount(e){try{return isNaN(e)?"?":e>=1e6?`${(e/1e6).toFixed(2)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toString()}catch(t){return console.error("Failed to format token count:",t),"?"}}};var T=d(require("fs")),M=d(require("path")),B=d(require("os")),w=class{stateFilePath;constructor(){let e=B.homedir(),t=M.join(e,".claude-pet");this.stateFilePath=M.join(t,"pet-state.json"),this.ensureDirectoryExists(t)}loadState(){try{if(!T.existsSync(this.stateFilePath))return null;let e=T.readFileSync(this.stateFilePath,"utf8"),t=JSON.parse(e);return t.lastFeedTime&&(t.lastFeedTime=new Date(t.lastFeedTime)),t.lastDecayTime&&(t.lastDecayTime=new Date(t.lastDecayTime)),t.birthTime&&(t.birthTime=new Date(t.birthTime)),t.totalLifetimeTokens===void 0&&(t.totalLifetimeTokens=t.totalTokensConsumed||0),t.animalType===void 0&&(t.animalType=c.ANIMAL.DEFAULT_TYPE,console.log(`Migrating existing pet to default animal type: ${t.animalType}`)),Object.values(v).includes(t.animalType)||(console.warn(`Invalid animal type found: ${t.animalType}, using default`),t.animalType=c.ANIMAL.DEFAULT_TYPE),t.birthTime===void 0&&(t.birthTime=t.lastFeedTime||new Date,console.log(`Adding birthTime for existing pet: ${t.birthTime.toISOString()}`)),t}catch(e){return console.error("Failed to load pet state:",e),null}}saveState(e){try{let t=JSON.stringify(e,null,2);T.writeFileSync(this.stateFilePath,t,"utf8")}catch(t){console.error("Failed to save pet state:",t)}}ensureDirectoryExists(e){try{T.existsSync(e)||T.mkdirSync(e,{recursive:!0})}catch(t){console.error("Failed to create pet storage directory:",t)}}};var p=d(require("fs")),X=d(require("readline")),A=d(require("path")),b=A.join(process.env.HOME||"",".claude-pet","session-tracker.json");function de(i){try{if(!p.existsSync(b))return null;let e=p.readFileSync(b,"utf8");return JSON.parse(e)[i]||null}catch{return null}}function me(i){try{let e=A.dirname(b);p.existsSync(e)||p.mkdirSync(e,{recursive:!0});let t={};if(p.existsSync(b)){let o=p.readFileSync(b,"utf8");t=JSON.parse(o)}t[i.sessionId]=i,p.writeFileSync(b,JSON.stringify(t,null,2))}catch(e){console.error("Failed to save session tracker:",e)}}async function K(i){let e=0,t=0,o=0,s=0,n=0,r=0,a=0,l="",E="",F="";try{if(!p.existsSync(i))return{inputTokens:0,outputTokens:0,cachedTokens:0,totalTokens:0,sessionTotalInputTokens:0,sessionTotalOutputTokens:0,sessionTotalCachedTokens:0,contextLength:0};let C=p.createReadStream(i),Q=X.createInterface({input:C,crlfDelay:1/0}),$=[];for await(let g of Q)if(g.trim()!=="")try{let u=JSON.parse(g);u.sessionId&&(l=u.sessionId),$.push(u)}catch{continue}if(!l)return{inputTokens:0,outputTokens:0,cachedTokens:0,totalTokens:0,sessionTotalInputTokens:0,sessionTotalOutputTokens:0,sessionTotalCachedTokens:0,contextLength:0};let I=de(l),G=!I;for(let g of $){let u=g.usage||g.message&&g.message.usage;if(u&&(s+=u.input_tokens||0,n+=u.output_tokens||0,r+=(u.cache_creation_input_tokens||0)+(u.cache_read_input_tokens||0),a=(u.input_tokens||0)+(u.cache_read_input_tokens||0)+(u.cache_creation_input_tokens||0)),I&&!G){if(g.uuid===I.lastProcessedUuid){G=!0;continue}continue}u&&(e+=u.input_tokens||0,t+=u.output_tokens||0,o+=(u.cache_creation_input_tokens||0)+(u.cache_read_input_tokens||0)),g.uuid&&(E=g.uuid),g.timestamp&&(F=g.timestamp)}if(E){let g={sessionId:l,lastProcessedUuid:E,lastProcessedTimestamp:F,totalProcessedTokens:(I?.totalProcessedTokens||0)+e+t+o};me(g)}return{inputTokens:e,outputTokens:t,cachedTokens:o,totalTokens:e+t+o,sessionTotalInputTokens:s,sessionTotalOutputTokens:n,sessionTotalCachedTokens:r,contextLength:a}}catch(C){return console.error("Failed to process JSONL transcript:",C),{inputTokens:0,outputTokens:0,cachedTokens:0,totalTokens:0,sessionTotalInputTokens:0,sessionTotalOutputTokens:0,sessionTotalCachedTokens:0,contextLength:0}}}var U=class{callCount=0;testMode;COUNTER_FILE=require("path").join(require("os").homedir(),".claude-pet","animation-counter.json");constructor(e=!1){this.testMode=e,e||this.loadCounter()}loadCounter(){try{let e=require("fs");if(e.existsSync(this.COUNTER_FILE)){let t=JSON.parse(e.readFileSync(this.COUNTER_FILE,"utf8"));this.callCount=t.callCount||0}}catch{this.callCount=0}}saveCounter(){try{let e=require("fs"),o=require("path").dirname(this.COUNTER_FILE);e.existsSync(o)||e.mkdirSync(o,{recursive:!0});let s={callCount:this.callCount,lastUpdate:Date.now()};e.writeFileSync(this.COUNTER_FILE,JSON.stringify(s))}catch{}}recordCall(){this.testMode||(this.callCount++,this.saveCounter())}shouldEnableAnimation(){return!this.testMode}getFrameIndex(){return this.callCount}},y=class{pet;formatter;storage;configService;animationCounter;constructor(e=!1,t){this.animationCounter=new U(e),this.storage=new w,this.configService=t||new f,this.formatter=new _(e,t);let o=this.storage.loadState(),s=new Date,n=o||{energy:c.INITIAL_ENERGY,expression:c.HAPPY_EXPRESSION,animalType:x.getRandomAnimalType(),birthTime:s,lastFeedTime:s,totalTokensConsumed:0,accumulatedTokens:0,totalLifetimeTokens:0};this.pet=new x(n,{config:c}),o&&this.pet.applyTimeDecay()}async processTokensAndGetStatusDisplay(e){try{this.animationCounter.recordCall(),this.pet.applyTimeDecay();let t=await K(e.transcript_path);t.totalTokens>0&&this.pet.feed(t.totalTokens);let o=this.pet.getState();o.sessionTotalInputTokens=t.sessionTotalInputTokens,o.sessionTotalOutputTokens=t.sessionTotalOutputTokens,o.sessionTotalCachedTokens=t.sessionTotalCachedTokens,o.sessionTotalCostUsd=e.cost.total_cost_usd,o.contextLength=t.contextLength,t.contextLength!==void 0&&(o.contextPercentage=Math.min(100,t.contextLength/2e5*100),o.contextPercentageUsable=Math.min(100,t.contextLength/16e4*100));let s=this.animationCounter.shouldEnableAnimation(),n=this.animationCounter.getFrameIndex(),a=this.configService.getConfig().pet.emojiEnabled??!0,l=this.pet.getAnimatedExpression(s,n,a);return this.formatter.formatPetDisplay(o,l)}catch(t){console.error("Token processing failed:",t),this.pet.applyTimeDecay();let o=this.pet.getState();return this.formatter.formatPetDisplay(o)}}getStatusDisplay(){this.animationCounter.recordCall(),this.pet.applyTimeDecay();let e=this.pet.getState(),t=this.animationCounter.shouldEnableAnimation(),o=this.animationCounter.getFrameIndex(),n=this.configService.getConfig().pet.emojiEnabled??!0,r=this.pet.getAnimatedExpression(t,o,n);return this.formatter.formatPetDisplay(e,r)}saveState(){this.storage.saveState(this.pet.getState())}adoptNewPet(){this.pet.isDead()&&(this.pet.resetToInitialState(),this.saveState(),typeof window<"u"&&window.vscode?.postMessage&&window.vscode.postMessage({command:"showInformationMessage",text:"Successfully adopted a new pet! Your pet is now happy and full of energy."}))}isPetDead(){return this.pet.isDead()}};function fe(){return new Promise(i=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t}),process.stdin.on("end",()=>{i(e.trim())})})}async function J(){try{let i=await fe();if(!i){let s=new y,n=s.getStatusDisplay();s.saveState(),process.stdout.write(n);return}let e;try{e=JSON.parse(i)}catch{let n=new y,r=n.getStatusDisplay();n.saveState(),process.stdout.write(r);return}let t=new y,o=await t.processTokensAndGetStatusDisplay(e);t.saveState(),process.stdout.write(o)}catch(i){process.stdout.write("(?) ERROR"),process.stderr.write(`Pet status error: ${i}
`),process.exit(1)}}var P=class{name="check";description="Manually check pet status without consuming Claude Code tokens";countdownInterval=null;previousState=null;errorCount=0;MAX_ERRORS=3;countdownSeconds=0;refreshIntervalSeconds=60;async execute(e){let t=this.parseArguments(e);t.watch?await this.startWatchMode(t.interval||60):await this.executeOnce()}parseArguments(e){let t={};for(let o=0;o<e.length;o++){let s=e[o];if(s==="--watch"||s==="-w")t.watch=!0;else if(s==="--interval"){let n=parseInt(e[o+1]);isNaN(n)||n<10||n>300?(console.error("\u274C \u95F4\u9694\u65F6\u95F4\u5FC5\u987B\u5728 10-300 \u79D2\u4E4B\u95F4"),console.error("\u4F7F\u7528\u9ED8\u8BA4\u95F4\u9694 60 \u79D2"),t.interval=60):t.interval=n,o++}else s==="--help"||s==="-h"?(this.showHelp(),process.exit(0)):s.startsWith("--")&&(console.error(`\u274C \u672A\u77E5\u53C2\u6570: ${s}`),this.showHelp(),process.exit(1))}return t}async startWatchMode(e){this.refreshIntervalSeconds=e,this.countdownSeconds=e,this.setupSignalHandlers(),await this.executeOnceForWatch(),this.countdownInterval=setInterval(async()=>{this.countdownSeconds--,this.countdownSeconds<=0?(this.countdownSeconds=this.refreshIntervalSeconds,await this.executeOnceForWatch()):await this.updateCountdown()},1e3)}async executeOnceForWatch(){try{let e=new y,t=e.getStatusDisplay(),o=e.pet?e.pet.getState():null;this.previousState&&process.stdout.write("\x1B[3A\x1B[0J");let s="";if(s+=t+`
`,o&&o.lastFeedTime){let n=Date.now()-new Date(o.lastFeedTime).getTime(),r=Math.floor(n/(1e3*60)),a=Math.floor(r/60);a>0?s+=`\u23F0 \u8DDD\u79BB\u4E0A\u6B21\u5582\u98DF: ${a}\u5C0F\u65F6${r%60}\u5206\u949F\u524D
`:s+=`\u23F0 \u8DDD\u79BB\u4E0A\u6B21\u5582\u98DF: ${r}\u5206\u949F\u524D
`}else s+=`\u23F0 \u8DDD\u79BB\u4E0A\u6B21\u5582\u98DF: \u672A\u77E5
`;s+=`\u23F3 \u4E0B\u6B21\u66F4\u65B0: ${this.countdownSeconds}\u79D2
`,process.stdout.write(s),e.saveState(),this.previousState=o?{...o}:null,this.errorCount=0}catch(e){this.handleWatchError(e)}}async updateCountdown(){try{process.stdout.write("\x1B[1A\x1B[2K"),process.stdout.write(`\u23F3 \u4E0B\u6B21\u66F4\u65B0: ${this.countdownSeconds}\u79D2
`)}catch{}}async executeOnce(){try{console.log(`\u{1F43E} \u68C0\u67E5\u5BA0\u7269\u72B6\u6001...
`);let e=new y,t=e.getStatusDisplay();e.saveState(),console.log(t),console.log(`
\u{1F4A1} \u63D0\u793A: \u8FD9\u6B21\u67E5\u770B\u4E0D\u6D88\u8017Claude Code token`),console.log("\u{1F4DD} \u5728Claude Code\u4E2D\u6D3B\u8DC3\u4F7F\u7528\u53EF\u4EE5\u5582\u517B\u4F60\u7684\u5BA0\u7269");let o=e.pet?e.pet.getState():null;this.showTimeInfo(o)}catch(e){let t=e instanceof Error?e.message:"Unknown error";console.error("\u274C \u68C0\u67E5\u5BA0\u7269\u72B6\u6001\u5931\u8D25:",t),process.exit(1)}}showTimeInfo(e){if(e&&e.lastFeedTime){let t=Date.now()-new Date(e.lastFeedTime).getTime(),o=Math.floor(t/(1e3*60)),s=Math.floor(o/60);s>0?console.log(`\u23F0 \u8DDD\u79BB\u4E0A\u6B21\u5582\u98DF: ${s}\u5C0F\u65F6${o%60}\u5206\u949F\u524D`):console.log(`\u23F0 \u8DDD\u79BB\u4E0A\u6B21\u5582\u98DF: ${o}\u5206\u949F\u524D`)}}handleWatchError(e){this.errorCount++;let t=e instanceof Error?e.message:"Unknown error";console.error(`\u274C \u83B7\u53D6\u72B6\u6001\u5931\u8D25 (${this.errorCount}/${this.MAX_ERRORS}): ${t}`),this.errorCount>=this.MAX_ERRORS&&(console.log(`
\u26A0\uFE0F \u8FDE\u7EED\u5931\u8D25\u6B21\u6570\u8FC7\u591A\uFF0C\u662F\u5426\u7EE7\u7EED\u76D1\u63A7\uFF1F`),console.log("\u8F93\u5165 y \u7EE7\u7EED\uFF0C\u4EFB\u4F55\u5176\u4ED6\u952E\u9000\u51FA\u76D1\u63A7"),console.log("\u8FDE\u7EED\u5931\u8D25\uFF0C\u9000\u51FA\u76D1\u63A7\u6A21\u5F0F"),this.cleanup(),process.exit(1))}setupSignalHandlers(){process.on("SIGINT",()=>{console.log(`
\u{1F44B} \u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6B63\u5728\u505C\u6B62\u76D1\u63A7...`),this.cleanup(),console.log("\u2705 \u76D1\u63A7\u5DF2\u505C\u6B62\uFF0C\u518D\u89C1\uFF01"),process.exit(0)})}cleanup(){this.countdownInterval&&(clearInterval(this.countdownInterval),this.countdownInterval=null)}showHelp(){console.log("ccpet check - \u68C0\u67E5\u5BA0\u7269\u72B6\u6001"),console.log(""),console.log("\u7528\u6CD5: ccpet check [options]"),console.log(""),console.log("\u9009\u9879:"),console.log(" -w, --watch \u5F00\u542F\u6301\u7EED\u76D1\u63A7\u6A21\u5F0F"),console.log(" --interval <seconds> \u8BBE\u7F6E\u76D1\u63A7\u95F4\u9694 (10-300\u79D2\uFF0C\u9ED8\u8BA460\u79D2)"),console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),console.log(""),console.log("\u793A\u4F8B:"),console.log(" ccpet check \u5355\u6B21\u68C0\u67E5\u5BA0\u7269\u72B6\u6001"),console.log(" ccpet check --watch \u5F00\u542F\u6301\u7EED\u76D1\u63A7 (60\u79D2\u95F4\u9694)"),console.log(" ccpet check -w --interval 30 \u6301\u7EED\u76D1\u63A7\uFF0C30\u79D2\u95F4\u9694"),console.log(""),console.log("\u6CE8\u610F:"),console.log(" \u2022 \u6301\u7EED\u76D1\u63A7\u6A21\u5F0F\u4E0B\u6309 Ctrl+C \u9000\u51FA"),console.log(" \u2022 \u76D1\u63A7\u95F4\u9694\u5FC5\u987B\u5728 10-300 \u79D2\u4E4B\u95F4"),console.log(" \u2022 \u72B6\u6001\u53D8\u5316\u4F1A\u88AB\u9AD8\u4EAE\u663E\u793A")}};var N=class{name="config";description="Manage ccpet configuration";configService=new f;async execute(e){if(e.length===0){this.showHelp();return}let t=e[0];switch(t){case"list":await this.listConfig();break;case"set":await this.setConfig(e.slice(1));break;case"reset":await this.resetConfig();break;case"path":await this.showConfigPath();break;default:console.error(`Unknown config command: ${t}`),this.showHelp(),process.exit(1)}}showHelp(){console.log("ccpet config - Configuration management"),console.log(""),console.log("Usage: ccpet config <subcommand> [options]"),console.log(""),console.log("Subcommands:"),console.log(" list List current configuration"),console.log(" set <key> <value> Set configuration value"),console.log(" reset Reset to default configuration"),console.log(" path Show configuration file path"),console.log(""),console.log("Configuration keys:"),console.log(" colors.petExpression Pet expression color"),console.log(" colors.energyBar Energy bar color"),console.log(" colors.energyValue Energy value color"),console.log(" colors.accumulatedTokens Accumulated tokens color"),console.log(" colors.lifetimeTokens Lifetime tokens color"),console.log(" colors.sessionInput Session input color"),console.log(" colors.sessionOutput Session output color"),console.log(" colors.sessionCached Session cached color"),console.log(" colors.sessionTotal Session total color"),console.log(" colors.contextLength Context length color"),console.log(" colors.contextPercentage Context percentage color"),console.log(" colors.contextPercentageUsable Context percentage usable color"),console.log(" pet.animationEnabled Enable/disable animations (true/false)"),console.log(" pet.decayRate Energy decay rate per minute"),console.log(" display.maxLines Maximum lines to display (1-3)"),console.log(" display.line2.enabled Enable/disable line 2 (true/false)"),console.log(" display.line2.items Items to show on line 2 (comma-separated)"),console.log(" display.line3.enabled Enable/disable line 3 (true/false)"),console.log(" display.line3.items Items to show on line 3 (comma-separated)"),console.log(""),console.log("Available display items: input, output, cached, total, context-length, context-percentage, context-percentage-usable"),console.log(""),console.log("Examples:"),console.log(' ccpet config set colors.petExpression "#FF0000:bright"'),console.log(" ccpet config set pet.animationEnabled false"),console.log(" ccpet config set pet.decayRate 0.05"),console.log(" ccpet config set display.maxLines 3"),console.log(' ccpet config set display.line2.items "input,output"'),console.log(' ccpet config set display.line3.items "total"')}async listConfig(){try{let e=this.configService.listConfig();console.log("Current configuration:"),console.log(e)}catch(e){let t=e instanceof Error?e.message:"Unknown error";console.error("Failed to list configuration:",t),process.exit(1)}}async setConfig(e){e.length!==2&&(console.error("Usage: ccpet config set <key> <value>"),process.exit(1));let[t,o]=e;try{if(t.startsWith("colors.")){let s=t.replace("colors.","");this.configService.setColorConfig(s,o),console.log(`\u2705 Set ${t} = ${o}`)}else if(t.startsWith("pet.")){let s=t.replace("pet.",""),n=o;o==="true"?n=!0:o==="false"?n=!1:isNaN(Number(o))||(n=Number(o)),this.configService.setPetConfig(s,n),console.log(`\u2705 Set ${t} = ${n}`)}else if(t.startsWith("display.")){let s=t.replace("display.",""),n=o;o==="true"?n=!0:o==="false"?n=!1:isNaN(Number(o))||(n=Number(o)),this.configService.setDisplayConfig(s,n),console.log(`\u2705 Set ${t} = ${n}`)}else console.error(`Unknown configuration key: ${t}`),console.error('Run "ccpet config" to see available keys.'),process.exit(1)}catch(s){let n=s instanceof Error?s.message:"Unknown error";console.error("Failed to set configuration:",n),process.exit(1)}}async resetConfig(){try{this.configService.resetConfig(),console.log("\u2705 Configuration reset to defaults")}catch(e){let t=e instanceof Error?e.message:"Unknown error";console.error("Failed to reset configuration:",t),process.exit(1)}}async showConfigPath(){try{let e=this.configService.getConfigPath();console.log(`Configuration file: ${e}`)}catch(e){let t=e instanceof Error?e.message:"Unknown error";console.error("Failed to get configuration path:",t),process.exit(1)}}};var S=d(require("fs")),k=d(require("path")),V=d(require("os")),R=class{name="reset";description="Reset pet to initial state";async execute(e){try{let t=k.join(V.homedir(),".claude-pet"),o=k.join(t,"pet-state.json"),s=k.join(t,"animation-counter.json"),n=k.join(t,"session-tracker.json"),r=0;S.existsSync(o)&&(S.unlinkSync(o),r++,console.log("\u{1F5D1}\uFE0F Removed pet-state.json")),S.existsSync(s)&&(S.unlinkSync(s),r++,console.log("\u{1F5D1}\uFE0F Removed animation-counter.json")),S.existsSync(n)&&(S.unlinkSync(n),r++,console.log("\u{1F5D1}\uFE0F Removed session-tracker.json")),r===0?console.log("\u2139\uFE0F No pet state files found to reset"):(console.log(`\u2705 Pet reset complete! Removed ${r} state file(s)`),console.log("\u{1F423} Your pet will be reborn on next use"))}catch(t){let o=t instanceof Error?t.message:"Unknown error";console.error("\u274C Failed to reset pet:",o),process.exit(1)}}};var Te=W(),q=[new P,new N,new R];function Ee(){console.log(`ccpet v${Te.version}`)}function ye(){console.log("ccpet - Claude Code Pet CLI"),console.log(""),console.log("Usage: ccpet [command] [options]"),console.log(""),console.log("Commands:");for(let i of q)console.log(` ${i.name.padEnd(12)} ${i.description}`);console.log(""),console.log("Options:"),console.log(" -h, --help Show help information"),console.log(" -v, --version Show version number"),console.log(""),console.log("Examples:"),console.log(" ccpet # Show status line (for Claude Code)"),console.log(" ccpet check # Manually check pet status"),console.log(" ccpet config list # List current configuration"),console.log(' ccpet config set colors.petExpression "#FF0000"'),console.log(" ccpet reset # Reset pet to initial state")}async function z(){let i=process.argv.slice(2);if(i.length===0){await J();return}let e=i[0];if(e==="--help"||e==="-h"){ye();return}if(e==="--version"||e==="-v"){Ee();return}let t=q.find(o=>o.name===e);t||(console.error(`Unknown command: ${e}`),console.error('Run "ccpet --help" for usage information.'),process.exit(1));try{await t.execute(i.slice(1))}catch(o){console.error(`Error executing command: ${o.message}`),process.exit(1)}}require.main===module&&z().catch(i=>{console.error("Unexpected error:",i),process.exit(1)});0&&(module.exports={main});
//# sourceMappingURL=cli.js.map