@neilurk12/pi-clean-footer 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@ Shows a compact split footer:
20
20
 
21
21
  ## Install
22
22
 
23
- From npm (recommended):
23
+ From npm (recommended) | https://www.npmjs.com/package/@neilurk12/pi-clean-footer:
24
24
 
25
25
  ```bash
26
26
  pi install @neilurk12/pi-clean-footer
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import D from"path";import H from"os";import W from"path";import{existsSync as $,readFileSync as _}from"fs";var I=500,c={enabled:!0,showGit:!0,showTokens:!0,showCache:!0,showContext:!0,showDirectory:!0,showEffort:!0,gitRefreshDebounceMs:I,contextWarningPercent:70,contextDangerPercent:85,modelAliases:{},colors:{model:"accent",directory:"dim",git:"success",gitDirty:"warning",contextNormal:"success",contextWarning:"warning",contextDanger:"error",tokens:"muted",separator:"dim"}};function x(e,t){return L([e,t])}function L(e){let t=[],n={},r;for(let o of e)if($(o))try{let i=JSON.parse(_(o,"utf8"));n=j(n,i),t.push(o)}catch(i){r=`${o}: ${i instanceof Error?i.message:String(i)}`}return{config:A(n),loadedPaths:t,error:r}}function j(e,t){return{...e,...t,modelAliases:{...e.modelAliases??{},...t.modelAliases??{}},colors:{...e.colors??{},...t.colors??{}}}}function A(e){return{...c,...e,gitRefreshDebounceMs:G(e.gitRefreshDebounceMs,c.gitRefreshDebounceMs),contextWarningPercent:w(e.contextWarningPercent,c.contextWarningPercent),contextDangerPercent:w(e.contextDangerPercent,c.contextDangerPercent),modelAliases:{...c.modelAliases,...e.modelAliases??{}},colors:{...c.colors,...e.colors??{}}}}function G(e,t){return typeof e=="number"&&Number.isFinite(e)&&e>0?e:t}function w(e,t){return typeof e=="number"&&Number.isFinite(e)&&e>=0&&e<=100?e:t}import{execFile as N}from"child_process";import{promisify as U}from"util";var R=U(N);function m(e){let t={inRepo:!1,dirtyCount:0},n,r=[];e.onChange&&r.push(e.onChange);async function o(){if(!e.enabled){t={inRepo:!1,dirtyCount:0};return}try{let[d,s]=await Promise.all([R("git",["branch","--show-current"],{cwd:e.cwd,timeout:2e3}),R("git",["status","--porcelain"],{cwd:e.cwd,timeout:2e3})]),a=d.stdout.trim()||"detached",g=s.stdout.split(`
2
- `).filter(Boolean).length;t={inRepo:!0,branch:a,dirtyCount:g}}catch{t={inRepo:!1,dirtyCount:0}}for(let d of r)d()}function i(){l(),n=setTimeout(()=>{n=void 0,o()},e.debounceMs)}function l(){n&&(clearTimeout(n),n=void 0)}return{get state(){return t},schedule:i,clear:l,refresh:o,onChange(d){return r.push(d),()=>{let s=r.indexOf(d);s>=0&&r.splice(s,1)}}}}function P(e){var n,r,o,i,l;let t={input:0,output:0,cacheRead:0,cacheWrite:0};for(let d of e){if(d.type!=="message"||((n=d.message)==null?void 0:n.role)!=="assistant")continue;let s=d.message;t.input+=((r=s.usage)==null?void 0:r.input)??0,t.output+=((o=s.usage)==null?void 0:o.output)??0,t.cacheRead+=((i=s.usage)==null?void 0:i.cacheRead)??0,t.cacheWrite+=((l=s.usage)==null?void 0:l.cacheWrite)??0}return t}function p(e){if(typeof e!="string")return;let t=e.toLowerCase();if(t==="medium")return"med";if(t==="extra-high"||t==="extra_high"||t==="x-high")return"xhigh";if(["low","med","high","xhigh"].includes(t))return t}var C=class{#t;#r;#i;#e;#n;#s;#a;#d;#l;#o;constructor(t){this.#a=t.globalConfigPath,this.#d=t.getProjectConfigPath,this.#l=t.getThinkingLevel,this.#o=t.onRenderNeeded,this.#t=c,this.#r={config:this.#t,loadedPaths:[]},this.#i=void 0,this.#e=void 0,this.#n=!0,this.#s=""}async start(t){this.#s=t.cwd,this.#r=x(this.#a,this.#d(t.cwd)),this.#t=this.#r.config,this.#i=p(this.#l()),this.#n=this.#t.enabled,this.#n&&(this.#e=m({cwd:t.cwd,debounceMs:this.#t.gitRefreshDebounceMs,enabled:this.#t.showGit,onChange:()=>this.#o()}),await this.#e.refresh())}shutdown(){var t;(t=this.#e)==null||t.clear(),this.#e=void 0}onThinkingLevel(t){this.#i=p(t),this.#o()}onModelSelect(){this.#o()}onMessageEnd(t){t==="assistant"&&this.#o()}onToolEnd(t){var n;["bash","edit","write"].includes(t)&&((n=this.#e)==null||n.schedule()),this.#o()}onUserBash(){var t;(t=this.#e)==null||t.schedule()}async refresh(){var t;await((t=this.#e)==null?void 0:t.refresh())}async reload(t){var n;this.#r=x(this.#a,this.#d(t.cwd)),this.#t=this.#r.config,this.#n=this.#t.enabled,(n=this.#e)==null||n.clear(),this.#e=void 0,this.#n&&(this.#e=m({cwd:this.#s,debounceMs:this.#t.gitRefreshDebounceMs,enabled:this.#t.showGit,onChange:()=>this.#o()}),await this.#e.refresh()),this.#o()}async toggle(){var t;return this.#n=!this.#n,this.#n?(this.#i=p(this.#l()),this.#e=m({cwd:this.#s,debounceMs:this.#t.gitRefreshDebounceMs,enabled:this.#t.showGit,onChange:()=>this.#o()}),await this.#e.refresh()):((t=this.#e)==null||t.clear(),this.#e=void 0),this.#o(),this.#n}getFooterInput(t){var n,r,o,i,l,d;return{modelId:((n=t.model)==null?void 0:n.id)??"no-model",thinkingLevel:this.#i,directory:W.basename(t.cwd),gitBranch:(r=this.#e)==null?void 0:r.state.branch,gitDirtyCount:((o=this.#e)==null?void 0:o.state.dirtyCount)??0,contextUsed:((l=(i=t.getContextUsage)==null?void 0:i.call(t))==null?void 0:l.tokens)??0,contextMax:(d=t.model)==null?void 0:d.contextWindow,totals:P(t.sessionManager.getBranch()),config:this.#t}}get isEnabled(){return this.#n}get loadedError(){return this.#r.error}get loadedPaths(){return this.#r.loadedPaths}get config(){return this.#t}};import{truncateToWidth as u,visibleWidth as T}from"@earendil-works/pi-tui";function f(e){return!Number.isFinite(e)||e<=0?"0":e<1e3?`${Math.round(e)}`:e<1e6?`${(e/1e3).toFixed(e<1e4?1:0)}k`:`${(e/1e6).toFixed(1)}m`}function B(e,t){if(t[e])return t[e];let n=e.toLowerCase(),r=n.includes("/")?n.split("/").pop():n;if(t[r])return t[r];if(r.includes("claude")&&r.includes("sonnet"))return r.includes("4-5")||r.includes("4.5")?"sonnet-4.5":r.includes("4")?"sonnet-4":"sonnet";if(r.includes("claude")&&r.includes("opus"))return"opus";if(r.includes("claude")&&r.includes("haiku"))return"haiku";let o=r.match(/gpt-5(?:[.-][a-z0-9]+)*/);if(o)return o[0];let i=r.match(/gpt-4(?:[.-][a-z0-9]+)*/);if(i)return i[0];let l=r.match(/gemini-[a-z0-9.-]+/);return l?l[0].replace(/-preview.*/,""):r.length>24?`${r.slice(0,21)}\u2026`:r}function F(e,t,n,r,o,i){let l=B(e,n),d=r&&t?` \u2022 ${t}`:"";return o(i,`${l}${d}`)}function k(e,t,n){if(e)return t(n,e)}function v(e,t,n,r,o){if(!e)return;let i=n(r,e);return t<=0?i:`${i} ${n(o,`\u25CF${t}`)}`}function b(e,t,n,r,o,i){if(!n)return;let l=r?t:t==="full"?"no-cache":t,d=e.input+e.output,s;if(l==="total-only")s=`\u03A3${f(d)}`;else{let a=`\u2191${f(e.input)} \u2193${f(e.output)} \u03A3${f(d)}`;s=l==="full"?`${a} \u21AF${f(e.cacheRead)} \u21A5${f(e.cacheWrite)}`:a}return o(i,s)}function E(e,t,n,r,o,i){let l=`ctx ${f(e)}/${t?f(t):"--"}`;if(!t||t<=0)return o(i.dim,l);let d=e/t*100;return d>=r?o(i.danger,l):d>=n?o(i.warning,l):o(i.normal,l)}function O(e,t){let n=e.config,r=F(e.modelId,e.thinkingLevel,n.modelAliases,n.showEffort,t,n.colors.model),o=n.showDirectory?k(e.directory,t,n.colors.directory):void 0,i=n.showGit?v(e.gitBranch,e.gitDirtyCount,t,n.colors.git,n.colors.gitDirty):void 0,l=n.showContext?E(e.contextUsed,e.contextMax,n.contextWarningPercent,n.contextDangerPercent,t,{normal:n.colors.contextNormal,warning:n.colors.contextWarning,danger:n.colors.contextDanger,dim:"dim"}):void 0,d={};return n.showTokens&&(d.full=b(e.totals,"full",!0,n.showCache,t,n.colors.tokens),d.noCache=b(e.totals,"no-cache",!0,n.showCache,t,n.colors.tokens),d.totalOnly=b(e.totals,"total-only",!0,n.showCache,t,n.colors.tokens)),{model:r,dir:o,git:i,context:l,tokens:d}}function z(e,t,n){let r=[e.model,e.dir,e.git].filter(Boolean).join(t),o=e.model;if(n>=100){let i=[e.context,e.tokens.full].filter(Boolean).join(t);return[h(r,i,n)]}if(n>=80){let i=[e.context,e.tokens.noCache].filter(Boolean).join(t);return[h(r,i,n)]}if(n>=60){let i=[e.context,e.tokens.totalOnly].filter(Boolean).join(t);return[h(r,i,n)]}return n>=40?[h(r,e.context??"",n)]:[h(o,e.context??"",n)]}function S(e,t,n){let r=(l,d)=>t.fg(l,d),o=O(e,r),i=r(e.config.colors.separator," | ");return z(o,i,n)}function h(e,t,n){if(!t)return u(e,n);if(!e)return u(t,n);let r=n-T(e)-T(t);if(r>=1)return u(e+" ".repeat(r)+t,n);let o=Math.max(1,Math.floor((n-1)/2));return u(e,o)+" "+u(t,n-o-1)}function ue(e){let t=D.join(H.homedir(),".pi","agent","clean-footer.json"),n=s=>D.join(s,".pi","clean-footer.json"),r=()=>{},o=new C({globalConfigPath:t,getProjectConfigPath:n,getThinkingLevel:()=>{var s;return(s=e.getThinkingLevel)==null?void 0:s.call(e)},onRenderNeeded:()=>r()});e.registerCommand("footer",{description:"Toggle, refresh, or configure the clean footer",handler:async(s,a)=>{let g=s.trim();if(g==="refresh"){await o.refresh(),a.hasUI&&a.ui.notify("Footer refreshed","info");return}if(g==="reload"){await o.reload(a),a.hasUI&&o.isEnabled&&i(a),a.hasUI&&!o.isEnabled&&a.ui.setFooter(void 0),r(),l(a);return}if(g==="config"){d(a);return}let y=await o.toggle();a.hasUI&&(y?(i(a),a.ui.notify("Clean footer enabled","info")):(a.ui.setFooter(void 0),a.ui.notify("Default footer restored","info")))}}),e.on("session_start",async(s,a)=>{await o.start(a),a.hasUI&&o.loadedError&&o.isEnabled&&a.ui.notify(`Config error: ${o.loadedError}`,"error"),a.hasUI&&o.isEnabled&&i(a)}),e.on("session_shutdown",(s,a)=>{o.shutdown(),r=()=>{},a.hasUI&&a.ui.setFooter(void 0)}),e.on("thinking_level_select",s=>{o.onThinkingLevel(s.level)}),e.on("model_select",()=>{o.onModelSelect()}),e.on("message_end",s=>{o.onMessageEnd(s.message.role)}),e.on("tool_execution_end",s=>{o.onToolEnd(s.toolName)}),e.on("user_bash",()=>{o.onUserBash()});function i(s){s.hasUI&&s.ui.setFooter((a,g)=>(r=()=>a.requestRender(),{invalidate(){},render(y){let M=o.getFooterInput(s);return S(M,g,y)}}))}function l(s){s.hasUI&&(o.loadedError?s.ui.notify(`Clean footer config error: ${o.loadedError}`,"error"):s.ui.notify("Clean footer config loaded","info"))}function d(s){if(!s.hasUI)return;let a=o.loadedPaths.length?o.loadedPaths.join(`
3
- `):"none",g=n(s.cwd);s.ui.notify(["Clean footer config",`global: ${t}`,`project: ${g}`,`loaded:
4
- ${a}`,o.loadedError?`error: ${o.loadedError}`:"error: none",`resolved: ${JSON.stringify(o.config)}`].join(`
1
+ import T from"path";import H from"os";import N from"path";import{existsSync as M,readFileSync as $}from"fs";var D=500,f={enabled:!0,showGit:!0,showTokens:!0,showCache:!0,showContext:!0,showDirectory:!0,showEffort:!0,gitRefreshDebounceMs:D,contextWarningPercent:70,contextDangerPercent:85,modelAliases:{},colors:{model:"accent",directory:"dim",git:"success",gitDirty:"warning",contextNormal:"success",contextWarning:"warning",contextDanger:"error",tokens:"muted",separator:"dim"}};function p(e,t){return S([e,t])}function S(e){let t=[],o={},n;for(let r of e)if(M(r))try{let s=JSON.parse($(r,"utf8"));o=I(o,s),t.push(r)}catch(s){n=`${r}: ${s instanceof Error?s.message:String(s)}`}return{config:_(o),loadedPaths:t,error:n}}function I(e,t){return{...e,...t,modelAliases:{...e.modelAliases??{},...t.modelAliases??{}},colors:{...e.colors??{},...t.colors??{}}}}function _(e){return{...f,...e,gitRefreshDebounceMs:L(e.gitRefreshDebounceMs,f.gitRefreshDebounceMs),contextWarningPercent:x(e.contextWarningPercent,f.contextWarningPercent),contextDangerPercent:x(e.contextDangerPercent,f.contextDangerPercent),modelAliases:{...f.modelAliases,...e.modelAliases??{}},colors:{...f.colors,...e.colors??{}}}}function L(e,t){return typeof e=="number"&&Number.isFinite(e)&&e>0?e:t}function x(e,t){return typeof e=="number"&&Number.isFinite(e)&&e>=0&&e<=100?e:t}import{execFile as j}from"child_process";import{promisify as A}from"util";var w=A(j);function F(e){let t={inRepo:!1,dirtyCount:0},o,n=[];e.onChange&&n.push(e.onChange);async function r(){if(!e.enabled){t={inRepo:!1,dirtyCount:0};return}try{let[l,i]=await Promise.all([w("git",["branch","--show-current"],{cwd:e.cwd,timeout:2e3}),w("git",["status","--porcelain"],{cwd:e.cwd,timeout:2e3})]),a=l.stdout.trim()||"detached",d=i.stdout.split(`
2
+ `).filter(Boolean).length;t={inRepo:!0,branch:a,dirtyCount:d}}catch{t={inRepo:!1,dirtyCount:0}}for(let l of n)l()}function s(){c(),o=setTimeout(()=>{o=void 0,r()},e.debounceMs)}function c(){o&&(clearTimeout(o),o=void 0)}return{get state(){return t},schedule:s,clear:c,refresh:r,onChange(l){return n.push(l),()=>{let i=n.indexOf(l);i>=0&&n.splice(i,1)}}}}function P(e){var o,n,r,s,c;let t={input:0,output:0,cacheRead:0,cacheWrite:0};for(let l of e){if(l.type!=="message"||((o=l.message)==null?void 0:o.role)!=="assistant")continue;let i=l.message;t.input+=((n=i.usage)==null?void 0:n.input)??0,t.output+=((r=i.usage)==null?void 0:r.output)??0,t.cacheRead+=((s=i.usage)==null?void 0:s.cacheRead)??0,t.cacheWrite+=((c=i.usage)==null?void 0:c.cacheWrite)??0}return t}function m(e){if(typeof e!="string")return;let t=e.toLowerCase();if(t==="medium")return"med";if(t==="extra-high"||t==="extra_high"||t==="x-high")return"xhigh";if(["low","med","high","xhigh"].includes(t))return t}var C=class{#t;#r;#i;#e;#o;#s;#a;#l;#c;#n;constructor(t){this.#a=t.globalConfigPath,this.#l=t.getProjectConfigPath,this.#c=t.getThinkingLevel,this.#n=t.onRenderNeeded,this.#t=f,this.#r={config:this.#t,loadedPaths:[]},this.#i=void 0,this.#e=void 0,this.#o=!0,this.#s=""}async start(t){this.#s=t.cwd,this.#r=p(this.#a,this.#l(t.cwd)),this.#t=this.#r.config,this.#i=m(this.#c()),this.#o=this.#t.enabled,this.#o&&(this.#d(t.cwd),await this.#e.refresh())}shutdown(){var t;(t=this.#e)==null||t.clear(),this.#e=void 0}#d(t){this.#e=F({cwd:t,debounceMs:this.#t.gitRefreshDebounceMs,enabled:this.#t.showGit,onChange:()=>this.#n()})}onThinkingLevel(t){this.#i=m(t),this.#n()}onModelSelect(){this.#n()}onMessageEnd(t){t==="assistant"&&this.#n()}onToolEnd(t){var o;["bash","edit","write"].includes(t)&&((o=this.#e)==null||o.schedule()),this.#n()}onUserBash(){var t;(t=this.#e)==null||t.schedule()}async refresh(){var t;await((t=this.#e)==null?void 0:t.refresh())}async reload(t){var o;this.#r=p(this.#a,this.#l(t.cwd)),this.#t=this.#r.config,this.#o=this.#t.enabled,(o=this.#e)==null||o.clear(),this.#e=void 0,this.#o&&(this.#d(this.#s),await this.#e.refresh()),this.#n()}async toggle(){var t;return this.#o=!this.#o,this.#o?(this.#i=m(this.#c()),this.#d(this.#s),await this.#e.refresh()):((t=this.#e)==null||t.clear(),this.#e=void 0),this.#n(),this.#o}getFooterInput(t){var o,n,r,s,c,l;return{modelId:((o=t.model)==null?void 0:o.id)??"no-model",thinkingLevel:this.#i,directory:N.basename(t.cwd),gitBranch:(n=this.#e)==null?void 0:n.state.branch,gitDirtyCount:((r=this.#e)==null?void 0:r.state.dirtyCount)??0,contextUsed:((c=(s=t.getContextUsage)==null?void 0:s.call(t))==null?void 0:c.tokens)??0,contextMax:(l=t.model)==null?void 0:l.contextWindow,totals:P(t.sessionManager.getBranch()),config:this.#t}}get isEnabled(){return this.#o}get loadedError(){return this.#r.error}get loadedPaths(){return this.#r.loadedPaths}get config(){return this.#t}};import{truncateToWidth as u,visibleWidth as k}from"@earendil-works/pi-tui";function R(e,t){if(t[e])return t[e];let o=e.toLowerCase(),n=o.includes("/")?o.split("/").pop():o;if(t[n])return t[n];if(n.includes("claude")&&n.includes("sonnet"))return n.includes("4-5")||n.includes("4.5")?"sonnet-4.5":n.includes("4")?"sonnet-4":"sonnet";if(n.includes("claude")&&n.includes("opus"))return"opus";if(n.includes("claude")&&n.includes("haiku"))return"haiku";let r=n.match(/gpt-5(?:[.-][a-z0-9]+)*/);if(r)return r[0];let s=n.match(/gpt-4(?:[.-][a-z0-9]+)*/);if(s)return s[0];let c=n.match(/gemini-[a-z0-9.-]+/);return c?c[0].replace(/-preview.*/,""):n.length>24?`${n.slice(0,21)}\u2026`:n}function v(e,t,o){let n=(c,l)=>t.fg(c,l),r=U(e,n),s=n(e.config.colors.separator," | ");return z(r,s,o)}function U(e,t){let o=e.config,n=W(e,t),r=o.showDirectory?G(e,t):void 0,s=o.showGit?B(e,t):void 0,c=o.showContext?O(e,t):void 0,l={};return o.showTokens&&(l.full=b(e.totals,"full",o.showCache,t,o.colors.tokens),l.noCache=b(e.totals,"no-cache",o.showCache,t,o.colors.tokens),l.totalOnly=b(e.totals,"total-only",o.showCache,t,o.colors.tokens)),{model:n,dir:r,git:s,context:c,tokens:l}}function g(e){return!Number.isFinite(e)||e<=0?"0":e<1e3?`${Math.round(e)}`:e<1e6?`${(e/1e3).toFixed(e<1e4?1:0)}k`:`${(e/1e6).toFixed(1)}m`}function W(e,t){let o=R(e.modelId,e.config.modelAliases),n=e.config.showEffort&&e.thinkingLevel?` \u2022 ${e.thinkingLevel}`:"";return t(e.config.colors.model,`${o}${n}`)}function G(e,t){if(e.directory)return t(e.config.colors.directory,e.directory)}function B(e,t){if(!e.gitBranch)return;let o=t(e.config.colors.git,e.gitBranch);return e.gitDirtyCount<=0?o:`${o} ${t(e.config.colors.gitDirty,`\u25CF${e.gitDirtyCount}`)}`}function b(e,t,o,n,r){let s=o?t:t==="full"?"no-cache":t,c=e.input+e.output,l;if(s==="total-only")l=`\u03A3${g(c)}`;else{let i=`\u2191${g(e.input)} \u2193${g(e.output)} \u03A3${g(c)}`;l=s==="full"?`${i} \u21AF${g(e.cacheRead)} \u21A5${g(e.cacheWrite)}`:i}return n(r,l)}function O(e,t){let o=`ctx ${g(e.contextUsed)}/${e.contextMax?g(e.contextMax):"--"}`;if(!e.contextMax||e.contextMax<=0)return t("dim",o);let n=e.contextUsed/e.contextMax*100;return n>=e.config.contextDangerPercent?t(e.config.colors.contextDanger,o):n>=e.config.contextWarningPercent?t(e.config.colors.contextWarning,o):t(e.config.colors.contextNormal,o)}function z(e,t,o){let n=[e.model,e.dir,e.git].filter(Boolean).join(t),r=e.model;if(o>=100){let s=[e.context,e.tokens.full].filter(Boolean).join(t);return[h(n,s,o)]}if(o>=80){let s=[e.context,e.tokens.noCache].filter(Boolean).join(t);return[h(n,s,o)]}if(o>=60){let s=[e.context,e.tokens.totalOnly].filter(Boolean).join(t);return[h(n,s,o)]}return o>=40?[h(n,e.context??"",o)]:[h(r,e.context??"",o)]}function h(e,t,o){if(!t)return u(e,o);if(!e)return u(t,o);let n=o-k(e)-k(t);if(n>=1)return u(e+" ".repeat(n)+t,o);let r=Math.max(1,Math.floor((o-1)/2));return u(e,r)+" "+u(t,o-r-1)}function ue(e){let t=T.join(H.homedir(),".pi","agent","clean-footer.json"),o=i=>T.join(i,".pi","clean-footer.json"),n=()=>{},r=new C({globalConfigPath:t,getProjectConfigPath:o,getThinkingLevel:()=>{var i;return(i=e.getThinkingLevel)==null?void 0:i.call(e)},onRenderNeeded:()=>n()});e.registerCommand("footer",{description:"Toggle, refresh, or configure the clean footer",handler:async(i,a)=>{let d=i.trim();if(d==="refresh"){await r.refresh(),a.hasUI&&a.ui.notify("Footer refreshed","info");return}if(d==="reload"){await r.reload(a),a.hasUI&&r.isEnabled&&s(a),a.hasUI&&!r.isEnabled&&a.ui.setFooter(void 0),n(),c(a);return}if(d==="config"){l(a);return}let y=await r.toggle();a.hasUI&&(y?(s(a),a.ui.notify("Clean footer enabled","info")):(a.ui.setFooter(void 0),a.ui.notify("Default footer restored","info")))}}),e.on("session_start",async(i,a)=>{await r.start(a),a.hasUI&&r.loadedError&&r.isEnabled&&a.ui.notify(`Config error: ${r.loadedError}`,"error"),a.hasUI&&r.isEnabled&&s(a)}),e.on("session_shutdown",(i,a)=>{r.shutdown(),n=()=>{},a.hasUI&&a.ui.setFooter(void 0)}),e.on("thinking_level_select",i=>{r.onThinkingLevel(i.level)}),e.on("model_select",()=>{r.onModelSelect()}),e.on("message_end",i=>{r.onMessageEnd(i.message.role)}),e.on("tool_execution_end",i=>{r.onToolEnd(i.toolName)}),e.on("user_bash",()=>{r.onUserBash()});function s(i){i.hasUI&&i.ui.setFooter((a,d)=>(n=()=>a.requestRender(),{invalidate(){},render(y){let E=r.getFooterInput(i);return v(E,d,y)}}))}function c(i){i.hasUI&&(r.loadedError?i.ui.notify(`Clean footer config error: ${r.loadedError}`,"error"):i.ui.notify("Clean footer config loaded","info"))}function l(i){if(!i.hasUI)return;let a=r.loadedPaths.length?r.loadedPaths.join(`
3
+ `):"none",d=o(i.cwd);i.ui.notify(["Clean footer config",`global: ${t}`,`project: ${d}`,`loaded:
4
+ ${a}`,r.loadedError?`error: ${r.loadedError}`:"error: none",`resolved: ${JSON.stringify(r.config)}`].join(`
5
5
  `),"info")}}export{ue as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neilurk12/pi-clean-footer",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Clean, minimal, and lightweight powerline-style footer extension for pi coding agent.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -31,7 +31,9 @@
31
31
  },
32
32
  "scripts": {
33
33
  "build": "tsup",
34
- "dev": "tsup --watch"
34
+ "dev": "tsup --watch",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
35
37
  },
36
38
  "peerDependencies": {
37
39
  "@earendil-works/pi-ai": "*",
@@ -40,7 +42,8 @@
40
42
  },
41
43
  "devDependencies": {
42
44
  "tsup": "^8.5.1",
43
- "typescript": "^6.0.3"
45
+ "typescript": "^6.0.3",
46
+ "vitest": "^4.1.6"
44
47
  },
45
48
  "pnpm": {
46
49
  "onlyBuiltDependencies": [