@promptctl/cc-candybar 1.106.0 → 1.107.0
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 +4 -0
- package/dist/index.mjs +3 -3
- package/package.json +18 -10
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
+
**[Try the live bar in your browser →](https://promptctl.github.io/cc-candybar/)** The real daemon, compiled for the page, replays a few turns of a Claude Code session; every click in the bar is real.
|
|
16
|
+
|
|
15
17
|
## What it is
|
|
16
18
|
|
|
17
19
|
CCCandybar is a statusline renderer for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). It shows session cost, context usage, git status, model info, rate-limit utilization, and more, configured through a JSON5 DSL with hot-reloading.
|
|
@@ -146,6 +148,8 @@ Run the install once to stage the runtime, then point `~/.claude/settings.json`
|
|
|
146
148
|
|
|
147
149
|
`just deploy` builds `dist/index.mjs` and stages the native binary at `bin/cc-candybar-native` — point your statusline command at that path. On a machine without cargo, `pnpm install && pnpm build` builds only the bundle — point your statusline at the committed `bin/cc-candybar` node entry instead. Either way the bar renders HEAD; the daemon watches the built bundle and respawns itself on rebuild.
|
|
148
150
|
|
|
151
|
+
`pnpm bar:web` serves the bar at http://127.0.0.1:7317/ in a browser terminal you can click: an isolated daemon (`--config my.json5` starts it from a copy of your config, `--ssh` shows the host segment). `pnpm site:build` builds the GitHub Pages version into `site/dist`, the same page with the daemon running inside it against a simulated machine (`site/`).
|
|
152
|
+
|
|
149
153
|
### Config file
|
|
150
154
|
|
|
151
155
|
Customization lives in `.cc-candybar.json5`. See the [Customization](#customization) section above for the resolution order. Saved edits hot-reload — no restart needed.
|
package/dist/index.mjs
CHANGED
|
@@ -162,7 +162,7 @@ Config tooling:
|
|
|
162
162
|
Single-row example: root: { h: ["seg1", "seg2"] }`,line:W(e.source,[`layout`])}),t.root!==void 0&&(r.root=ud(e,`root`,t.root)),t.actions!==void 0&&(r.actions=VC(e,t.actions)),t.looks!==void 0&&e.issues.push({path:`looks`,message:`"looks" was renamed "styles" — move the block under styles: { … } (and globals.look to globals.style)`,line:W(e.source,[`looks`])}),t.styles!==void 0&&(r.styles=jw(e,t.styles)),t.presets!==void 0&&(r.presets=Nw(e,t.presets)),t.editGlobals!==void 0&&(r.editGlobals=El(e,`editGlobals`,t.editGlobals)),t.helpers!==void 0&&(r.helpers=Pw(e,t.helpers)),vd(e,r),z_(e,r),tv(e,r),wu(e,r,K,`the global settings menu`),r}const wT=new Set([`globals`,`variables`,`segments`,`layout`,`looks`,`root`,`actions`,`styles`,`presets`,`editGlobals`,`helpers`]);function TT(e){let t=AT(e.termCols),n=AT(e.termRows),r=jT(e.ssh),i=OT(e.tmux),a=DT(e.configEnv),o=ET(e.claudeConfigDir);return{...t!==void 0&&{termCols:t},...n!==void 0&&{termRows:n},...r!==void 0&&{ssh:r},...i!==void 0&&{tmux:i},...a!==void 0&&{configEnv:a},...o!==void 0&&{claudeConfigDir:o}}}function ET(e){return typeof e==`string`&&c.isAbsolute(e)?e:void 0}function DT(e){return typeof e==`string`&&e!==``?sT(e):void 0}function OT(e){if(e===null)return null;if(typeof e!=`object`)return;let{socket:t,pane:n,truecolor:r}=e;if(!(typeof t!=`string`||t===``)&&!(typeof n!=`string`||n===``)&&!(r!==null&&(typeof r!=`string`||r===``)))return{socket:t,pane:n,truecolor:r}}const kT=1e4;function AT(e){if(typeof e!=`number`||!Number.isFinite(e))return;let t=Math.floor(e);if(!(t<=0))return t>kT?kT:t}function jT(e){return typeof e==`boolean`?e:void 0}var MT=class extends Error{constructor(e){super(e),this.name=`ProtocolError`}};function NT(e){let t=Buffer.from(JSON.stringify(e),`utf8`),n=Buffer.alloc(4);return n.writeUInt32BE(t.length,0),Buffer.concat([n,t])}function PT(e,t){let n=Buffer.alloc(0);return function(r){for(n=Buffer.concat([n,r]);n.length>=4;){let r=n.readUInt32BE(0);if(r>16777216){t(new MT(`frame too large: ${r}`));return}if(n.length<4+r)return;let i=n.subarray(4,4+r);n=n.subarray(4+r);try{e(JSON.parse(i.toString(`utf8`)))}catch(e){let n=new MT(e instanceof Error?e.message:String(e));e instanceof Error&&(n.cause=e),t(n);return}}}}function FT(e,t,n){return new Promise((r,i)=>{let a=!1,o=t=>{if(!a){a=!0,clearTimeout(s),e.removeAllListeners();try{t()}catch{}}},s=setTimeout(()=>{o(()=>{e.destroy(),i(Error(`TIMEOUT`))})},n),c=PT(e=>o(()=>r(e)),e=>o(()=>i(e)));e.on(`data`,c),e.on(`error`,e=>o(()=>i(e))),e.on(`close`,()=>o(()=>i(Error(`socket closed before response`)))),e.write(NT(t))})}async function IT(e,t,n){let r=null;try{r=await VT(Fe(),t.connectMs);let i=await FT(r,{v:3,...e},t.budgetMs);return zT(e.kind,i,n)}catch(e){return BT(e)}finally{r&&r.destroy()}}function LT(e,t){return typeof e==`string`?e:t}function RT(e){return typeof e==`number`&&Number.isInteger(e)&&e>=0?e:0}function zT(e,t,n){let r=t;if(r.ok===!0){let r=n(t);return r===void 0?{kind:`permanent`,cause:`malformed_response`,message:`ok response without payload for "${e}" request`}:{kind:`ok`,value:r}}let i=LT(r.error,`(no error message)`);switch(r.code){case`VERSION_MISMATCH`:return{kind:`permanent`,cause:`version_mismatch`,clientV:3,daemonV:RT(r.daemonV)};case`TIMEOUT`:return{kind:`transient`,cause:`timeout`,message:i};case`BAD_REQUEST`:return{kind:`permanent`,cause:`bad_request`,message:i};case`RENDER_FAILED`:return{kind:`permanent`,cause:`render_failed`,message:i};default:return{kind:`permanent`,cause:`malformed_response`,message:`unknown error code: ${String(r.code)}`}}}function BT(e){if(e instanceof MT||e instanceof SyntaxError)return{kind:`permanent`,cause:`malformed_response`,message:e instanceof Error?e.message:String(e)};let t=e instanceof Error?e.message:String(e);return t===`CONNECT_TIMEOUT`||t===`TIMEOUT`?{kind:`transient`,cause:`timeout`,message:t}:t.includes(`ECONNREFUSED`)||t.includes(`ENOENT`)||t.includes(`ENOTSOCK`)?{kind:`transient`,cause:`unreachable`,message:t}:{kind:`transient`,cause:`io_error`,message:t}}function VT(e,t){return new Promise((n,r)=>{let i=y.createConnection({path:e}),a=setTimeout(()=>{i.destroy(),r(Error(`CONNECT_TIMEOUT`))},t);i.once(`connect`,()=>{clearTimeout(a),n(i)}),i.once(`error`,e=>{clearTimeout(a),r(e)})})}function HT(e){if(e.kind===`transient`)return`daemon unavailable (${e.cause}: ${e.message})\nHint: daemon may not be running. Run \`cc-candybar\` once to spawn it.`;switch(e.cause){case`version_mismatch`:{let t=e.daemonV===0?`unknown`:`v${e.daemonV}`;return`daemon protocol mismatch (client v${e.clientV} ≠ daemon ${t})`}case`bad_request`:case`render_failed`:case`malformed_response`:return`daemon error (${e.cause}): ${e.message}`}}const UT={connectMs:50,budgetMs:150},WT={connectMs:50,budgetMs:200};function GT(e){let t=e.output;return typeof t==`string`?t:void 0}function KT(e,t,n,r){return IT({kind:`render`,hookData:e,args:t,cwd:n,...r},UT,GT)}function qT(e,t){return IT({kind:`click`,verb:e,value:t},WT,GT)}let JT=null;function YT(e){if(JT!==null)return JT;r.mkdirSync(c.dirname(e),{recursive:!0});try{JT=r.statSync(e).size}catch{JT=0}return JT}function XT(e){for(let t=2;t>=1;t--){let n=`${e}.${t}`,i=`${e}.${t+1}`;try{r.renameSync(n,i)}catch{}}try{r.renameSync(e,`${e}.1`)}catch{}JT=0}function Q(e,t){let n=`${new Date().toISOString()} [${e}] ${t}\n`;try{let e=qe(),t=YT(e);r.appendFileSync(e,n),JT=t+Buffer.byteLength(n,`utf8`),JT>=5242880&&XT(e)}catch(e){JT=null;try{process.stderr.write(`${n}cc-candybar: daemon.log unwritable: ${e.message}\n`)}catch{}}}function ZT(e){let t=[];for(let n of e){let e=n.read();if(e.kind===`text`)return`# memory report from: ${n.name}\n${e.text}`;t.push(`# ${n.name}: unavailable — ${e.reason}`)}return[`# memory report: no probe answered`,...t.length>0?t:[`# no probe is known for this platform`]].join(`
|
|
163
163
|
`)}function QT(e,t){return e===`darwin`?[$T(`footprint`,[`-p`,String(t)]),$T(`vmmap`,[`--summary`,String(t)])]:e===`linux`?[eE(`/proc/self/smaps_rollup`),eE(`/proc/self/status`)]:[]}function $T(e,t){return{name:`${e} ${t.join(` `)}`,read:()=>{let n=Oe({bin:e,args:[...t],timeoutMs:5e3,category:`limits.memory-report`});return n.ok?n.stdout.trim().length>0?{kind:`text`,text:n.stdout}:{kind:`unavailable`,reason:`exited 0 but printed nothing`}:{kind:`unavailable`,reason:`${n.reason}${n.error===void 0?``:`: ${n.error}`}${tE(n.stderr)}`}}}}function eE(e){return{name:e,read:()=>{try{let t=r.readFileSync(e,`utf8`);return t.trim().length>0?{kind:`text`,text:t}:{kind:`unavailable`,reason:`empty file`}}catch(e){return{kind:`unavailable`,reason:e.message}}}}}function tE(e){let t=e.split(`
|
|
164
164
|
`).map(e=>e.trim()).find(e=>e.length>0);return t===void 0?``:` (${t})`}const nE=`CC_CANDYBAR_RSS_LIMIT_MB`;function rE(e){let t=e[nE];if(t===void 0)return 512;let n=/^\d+$/.test(t)?Number(t):NaN;if(!Number.isSafeInteger(n)||n<=0)throw Error(`${nE} must be a positive integer (MB), got ${JSON.stringify(t)}`);return n}function iE(e){return rE(e)*2}const aE=1024*1024;function oE(e){return rE(e)*aE}const sE={memoryReport:{prefix:`memory-`,suffix:`.txt`},heapSnapshot:{prefix:`heap-`,suffix:`.heapsnapshot`}};function cE(e,t,n){let{prefix:r,suffix:i}=sE[t];return c.join(e,`${r}${n}${i}`)}function lE(e){for(let t of Object.keys(sE)){let{prefix:n,suffix:r}=sE[t];if(e.startsWith(n)&&e.endsWith(r))return t}return null}function uE(e){let t=e.rssLimitBytes??512*aE,n=e.snapshotsKeep??3,r=!1;function i(){if(r)return!0;let{rss:i,heapTotal:a}=e.memoryBytes();if(i<=t)return!1;r=!0,e.log(`warn`,`RSS ${i} > limit ${t} (v8 heap ${a}); recording memory then shutting down`);let o=`${new Date(e.now()).toISOString().replace(/[:.]/g,`-`)}-${e.pid}`;return dE(e.log,`memory report`,()=>{let t=cE(e.snapshotDir,`memoryReport`,o);e.writeMemoryReport(t,e.captureMemoryReport()),e.log(`info`,`memory report written: ${t}`)}),dE(e.log,`heap snapshot`,()=>{let t=cE(e.snapshotDir,`heapSnapshot`,o);e.log(`info`,`heap snapshot written: ${e.writeHeapSnapshot(t)}`)}),dE(e.log,`artifact rotation`,()=>{pE(e.listArtifacts(),n,e.removeFile)}),e.shutdown(0),!0}function a(){let{rss:n,heapTotal:r}=e.memoryBytes();return n>t*.75?`rss ${n} approaching limit ${t} (v8 heap ${r})`:null}function o(e=6e4){let t=setInterval(()=>{i()},e);return t.unref(),{disarm:()=>clearInterval(t)}}return{checkRss:i,describeNextRestart:a,arm:o}}function dE(e,t,n){try{n()}catch(n){e(`warn`,`${t} failed: ${n.message}`)}}function fE(e){let t=e.slice(e.lastIndexOf(`/`)+1),n=lE(t);if(n===null)return t;let{prefix:r,suffix:i}=sE[n];return t.slice(r.length,t.length-i.length)}function pE(e,t,n){let r=new Map;for(let t of e){let e=fE(t),n=r.get(e);n===void 0?r.set(e,[t]):n.push(t)}let i=[...r.keys()].sort((e,t)=>t.localeCompare(e));for(let e of i.slice(t))for(let t of r.get(e)??[])try{n(t)}catch{}}function mE(e,t,n={}){let i=Pe();return{now:()=>Date.now(),pid:process.pid,snapshotDir:i,log:Q,memoryBytes:()=>{let e=process.memoryUsage();return{rss:e.rss,heapTotal:e.heapTotal}},captureMemoryReport:()=>ZT(QT(process.platform,process.pid)),writeMemoryReport:(e,t)=>r.writeFileSync(e,t,{mode:384}),writeHeapSnapshot:e=>ne.writeHeapSnapshot(e),listArtifacts:()=>{try{return r.readdirSync(i).filter(e=>lE(e)!==null).map(e=>c.join(i,e))}catch{return[]}},removeFile:e=>r.unlinkSync(e),shutdown:t,startedAtMs:e,...n}}function hE(e={}){if(jE()!==null)return;let n=e.spawn??ME,r=OE();if(r.kind===`contended`){let e=_E();e!==null&&e>2e3&&(t.stderr.write(`cc-candybar: spawn-lock held ${e}ms (likely crashed holder) — spawning unlocked\n`),gE(n));return}if(r.kind===`error`){t.stderr.write(`cc-candybar: spawn-lock unavailable (${r.reason}) — spawning unlocked\n`),gE(n);return}try{gE(n)}finally{AE()}}function gE(e){wE()&&vE(e)}function _E(){try{let e=r.statSync(Ue());return Date.now()-e.mtimeMs}catch{return null}}function vE(e){try{e()||t.stderr.write(`cc-candybar: daemon spawn returned false (unable to resolve script path?)
|
|
165
|
-
`)}catch(e){t.stderr.write(`cc-candybar: daemon spawn failed: ${e.message}\n`)}}function yE(e,t){return e===null?{kind:`allow`}:e<-1e4?{kind:`allow-future-garbage`,futureMs:-e}:e<t?{kind:`deny`}:{kind:`allow`}}function bE(e){return Math.min(3e3*2**Math.min(Math.max(e,0),5),6e4)}function xE(e){try{let t=r.readFileSync(e,`utf8`).trim(),n=Number(t);return!Number.isInteger(n)||n<0?0:Math.min(n,5)}catch{return 0}}function SE(e,n){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,String(n),{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.backoff: ${e.message}\n`)}}function CE(){try{r.unlinkSync(Ge())}catch(e){e.code!==`ENOENT`&&t.stderr.write(`cc-candybar: could not reset spawn.backoff: ${e.message}\n`)}}function wE(){let e=We(),n=Ge(),r=xE(n),i=yE(TE(e),bE(r));return i.kind===`deny`?!1:(i.kind===`allow-future-garbage`&&t.stderr.write(`cc-candybar: spawn.cooldown mtime is ${i.futureMs}ms in the future — ignoring and spawning\n`),EE(e),SE(n,Math.min(r+1,5)),!0)}function TE(e){try{return Date.now()-r.statSync(e).mtimeMs}catch{return null}}function EE(e){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,`${t.pid} ${Date.now()}\n`,{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.cooldown: ${e.message}\n`)}}let DE=null;function OE(){let e=Ue();for(let n=0;n<2;n++){try{let n=r.openSync(e,`wx`,384);try{r.writeSync(n,JSON.stringify({pid:t.pid,ts:Date.now()}))}catch{}return DE={fd:n,path:e},{kind:`held`}}catch(t){let n=t.code;if(n!==`EEXIST`)return{kind:`error`,reason:`openSync(${e}): ${n??t.message}`}}if(!kE(e))return{kind:`contended`};try{r.unlinkSync(e)}catch(e){if(e.code!==`ENOENT`)return{kind:`error`,reason:`unlink stale spawn.lock: ${e.message}`}}}return{kind:`contended`}}function kE(e){try{let t=r.statSync(e);return Date.now()-t.mtimeMs>1e4}catch{return!0}}function AE(){if(!DE)return;let{fd:e,path:t}=DE;DE=null;try{r.closeSync(e)}catch{}try{r.unlinkSync(t)}catch{}}function jE(){try{return r.mkdirSync(Pe(),{recursive:!0}),null}catch(e){return`mkdir ${Pe()}: ${e.message}`}}function ME(){let e=t.execPath,n=t.argv[1];return n?ke({bin:e,args:[`--max-old-space-size=${iE(t.env)}`,n,`daemon`],category:`daemon-spawn`}).ok:!1}const NE=`cc-candybar`,PE=`dispatch`,FE=`set-state`,IE=`step-state`,LE=`copy`,RE=`open-vscode`,zE=`toolbar-toggle`,BE=`show-config-error`,VE=`show-config-warning`,HE=`set-config`,UE=`step-config`,WE=`save`,GE=`save-preset`,KE=`delete-preset`,qE=`reset-config`,JE=`apply-layout-op`,YE=`undo`,XE=`redo`,ZE=`back`,QE=`rewind`,$E=`apply-update`,eD=`doctor-run`,tD=`doctor-fix`,nD=`ceiling`,rD=`slash`;function iD(e){return e.map(encodeURIComponent).join(`/`)}function aD(e){return e.length===0?[]:e.split(`/`).map(decodeURIComponent)}function oD(e){return`${NE}://${PE}/${e.map(e=>`e=${encodeURIComponent(`${e.verb}/${iD(e.args)}`)}`).join(`&`)}`}function sD(e){return new w(e).getAll(`e`).map(dD)}const cD=new Set([FE,qE]);function lD(e){return e.reduce((e,t)=>{let n=e.at(-1),r=n&&uD(n,t);return r?[...e.slice(0,-1),r]:[...e,t]},[])}function uD(e,t){if(e.verb!==t.verb||!cD.has(e.verb))return;let[n,r]=[dD(e.value),dD(t.value)];return n.verb===r.verb?{verb:e.verb,value:`${n.verb}/${n.value}/${r.value}`}:void 0}function dD(e){let t=e.indexOf(`/`);return t===-1?{verb:e,value:``}:{verb:e.slice(0,t),value:e.slice(t+1)}}const fD=`1.
|
|
165
|
+
`)}catch(e){t.stderr.write(`cc-candybar: daemon spawn failed: ${e.message}\n`)}}function yE(e,t){return e===null?{kind:`allow`}:e<-1e4?{kind:`allow-future-garbage`,futureMs:-e}:e<t?{kind:`deny`}:{kind:`allow`}}function bE(e){return Math.min(3e3*2**Math.min(Math.max(e,0),5),6e4)}function xE(e){try{let t=r.readFileSync(e,`utf8`).trim(),n=Number(t);return!Number.isInteger(n)||n<0?0:Math.min(n,5)}catch{return 0}}function SE(e,n){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,String(n),{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.backoff: ${e.message}\n`)}}function CE(){try{r.unlinkSync(Ge())}catch(e){e.code!==`ENOENT`&&t.stderr.write(`cc-candybar: could not reset spawn.backoff: ${e.message}\n`)}}function wE(){let e=We(),n=Ge(),r=xE(n),i=yE(TE(e),bE(r));return i.kind===`deny`?!1:(i.kind===`allow-future-garbage`&&t.stderr.write(`cc-candybar: spawn.cooldown mtime is ${i.futureMs}ms in the future — ignoring and spawning\n`),EE(e),SE(n,Math.min(r+1,5)),!0)}function TE(e){try{return Date.now()-r.statSync(e).mtimeMs}catch{return null}}function EE(e){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,`${t.pid} ${Date.now()}\n`,{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.cooldown: ${e.message}\n`)}}let DE=null;function OE(){let e=Ue();for(let n=0;n<2;n++){try{let n=r.openSync(e,`wx`,384);try{r.writeSync(n,JSON.stringify({pid:t.pid,ts:Date.now()}))}catch{}return DE={fd:n,path:e},{kind:`held`}}catch(t){let n=t.code;if(n!==`EEXIST`)return{kind:`error`,reason:`openSync(${e}): ${n??t.message}`}}if(!kE(e))return{kind:`contended`};try{r.unlinkSync(e)}catch(e){if(e.code!==`ENOENT`)return{kind:`error`,reason:`unlink stale spawn.lock: ${e.message}`}}}return{kind:`contended`}}function kE(e){try{let t=r.statSync(e);return Date.now()-t.mtimeMs>1e4}catch{return!0}}function AE(){if(!DE)return;let{fd:e,path:t}=DE;DE=null;try{r.closeSync(e)}catch{}try{r.unlinkSync(t)}catch{}}function jE(){try{return r.mkdirSync(Pe(),{recursive:!0}),null}catch(e){return`mkdir ${Pe()}: ${e.message}`}}function ME(){let e=t.execPath,n=t.argv[1];return n?ke({bin:e,args:[`--max-old-space-size=${iE(t.env)}`,n,`daemon`],category:`daemon-spawn`}).ok:!1}const NE=`cc-candybar`,PE=`dispatch`,FE=`set-state`,IE=`step-state`,LE=`copy`,RE=`open-vscode`,zE=`toolbar-toggle`,BE=`show-config-error`,VE=`show-config-warning`,HE=`set-config`,UE=`step-config`,WE=`save`,GE=`save-preset`,KE=`delete-preset`,qE=`reset-config`,JE=`apply-layout-op`,YE=`undo`,XE=`redo`,ZE=`back`,QE=`rewind`,$E=`apply-update`,eD=`doctor-run`,tD=`doctor-fix`,nD=`ceiling`,rD=`slash`;function iD(e){return e.map(encodeURIComponent).join(`/`)}function aD(e){return e.length===0?[]:e.split(`/`).map(decodeURIComponent)}function oD(e){return`${NE}://${PE}/${e.map(e=>`e=${encodeURIComponent(`${e.verb}/${iD(e.args)}`)}`).join(`&`)}`}function sD(e){return new w(e).getAll(`e`).map(dD)}const cD=new Set([FE,qE]);function lD(e){return e.reduce((e,t)=>{let n=e.at(-1),r=n&&uD(n,t);return r?[...e.slice(0,-1),r]:[...e,t]},[])}function uD(e,t){if(e.verb!==t.verb||!cD.has(e.verb))return;let[n,r]=[dD(e.value),dD(t.value)];return n.verb===r.verb?{verb:e.verb,value:`${n.verb}/${n.value}/${r.value}`}:void 0}function dD(e){let t=e.indexOf(`/`);return t===-1?{verb:e,value:``}:{verb:e.slice(0,t),value:e.slice(t+1)}}const fD=`1.107.0`;function pD(e,t){let n=(e.CLAUDE_CONFIG_DIR??``).split(`,`)[0].trim();return n===``?void 0:c.resolve(t,n)}function mD(e){return e??c.join(p.homedir(),`.claude`)}function hD(e){return c.join(e,`settings.json`)}function gD(e){return c.join(e,`plugins`,`installed_plugins.json`)}function _D(e){return r.existsSync(e)?r.readFileSync(e,`utf8`):``}function vD(e){let t;try{let n=_D(e);if(/^\s*$/.test(n))return{};t=Ko.parse(n)}catch(t){throw Error(`cannot read ${e}: ${yD(t)}`,{cause:t})}if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`cannot read ${e}: not a JSON object`);return t}const yD=e=>e instanceof Error?e.message:String(e),bD=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;function xD(e){let t=bD.exec(e);return t?{kind:`ok`,value:[Number(t[1]),Number(t[2]),Number(t[3])]}:{kind:`failed`,reason:`"${e}" is not a release version (expected MAJOR.MINOR.PATCH)`}}function SD(e){return e.join(`.`)}function CD([e,t,n],[r,i,a]){return e-r||t-i||n-a}const wD=`@promptctl/cc-candybar`;async function TD(e,t,n){let r=`${n}/-/package/${encodeURIComponent(e)}/dist-tags`;try{let e=await t(r,{signal:AbortSignal.timeout(5e3)});if(!e.ok)return X(`registry responded ${e.status} for ${r}`);let n=await e.json();return typeof n.latest==`string`?xD(n.latest):Y}catch(e){return X(e instanceof Error?e.message:String(e))}}function ED(e,t){let n=xD(e);if(n.kind===`failed`)return{kind:`unchecked`,installed:e,reason:n.reason};switch(t.kind){case`failed`:return{kind:`unchecked`,installed:e,reason:t.reason};case`absent`:return{kind:`unchecked`,installed:e,reason:"the registry lists no `latest` dist-tag"};case`ok`:{let e=CD(n.value,t.value);return e<0?{kind:`stale`,installed:n.value,latest:t.value}:e>0?{kind:`ahead`,installed:n.value,latest:t.value}:{kind:`current`,installed:n.value}}}}function DD(e,t){switch(t.kind){case`current`:return{stream:`stdout`,text:`✓ cc-candybar ${SD(t.installed)} is the latest release.\n`};case`ahead`:return{stream:`stdout`,text:`cc-candybar ${SD(t.installed)} is newer than the registry's latest release (${SD(t.latest)}): an unpublished build.\n`};case`stale`:{let n=SD(t.latest);return{stream:`stderr`,text:`⚠ cc-candybar ${SD(t.installed)} was staged, but the latest release is ${n}.\n pnpm's release-age gate (minimumReleaseAge) and its dlx cache can both\n resolve \`@latest\` to an older release without saying so.\n To install ${n} now, name it explicitly:\n pnpm dlx ${e}@${n} install\n`}}case`unchecked`:return{stream:`stderr`,text:`⚠ Could not check for a cc-candybar release newer than ${t.installed} (${t.reason}); the registry check was skipped.\n`}}}const OD=`CCCandybarURLHandler`,kD=[],AD={"darwin-arm64":`@promptctl/cc-candybar-darwin-arm64`,"darwin-x64":`@promptctl/cc-candybar-darwin-x64`,"linux-x64":`@promptctl/cc-candybar-linux-x64`,"linux-arm64":`@promptctl/cc-candybar-linux-arm64`};function jD(e){return/^[A-Za-z0-9_./=,:-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function MD(e,t){return[e,...t].map(jD).join(` `)}function ND(){return c.join(p.homedir(),`Applications`,`${OD}.app`)}function PD(){if(process.platform!==`darwin`)throw Error(`URL handler installation requires macOS (found platform: ${process.platform}).`)}function FD(){if(process.platform===`darwin`)return c.join(p.homedir(),`Library`,`Application Support`,`CCCandybar`);let e=process.env.XDG_DATA_HOME??c.join(p.homedir(),`.local`,`share`);return c.join(e,`cc-candybar`)}function ID(){return c.join(FD(),`bin`,`cc-candybar`)}function LD(){return c.join(FD(),`dist`,`index.mjs`)}function RD(e,t){return[`on open location L`,`\tdo shell script "'${e.replace(/"/g,`\\"`)}' '${t.replace(/"/g,`\\"`)}' url-handle " & quoted form of L`,`end open location`].join(`
|
|
166
166
|
`)}function zD(e){if(!e)throw Error(`install: process.argv[1] not set`);return e.endsWith(`.mjs`)||e.endsWith(`.js`)?e:c.resolve(c.dirname(e),`..`,`dist`,`index.mjs`)}function BD(t){let n=AD[`${process.platform}-${process.arch}`];if(n){let r=e(t);try{return{kind:`native`,sourcePath:r.resolve(`${n}/bin/cc-candybar`)}}catch{}}return{kind:`node-shim`,sourcePath:c.resolve(c.dirname(t),`..`,`bin`,`cc-candybar`)}}function VD(e,t){c.resolve(e)!==c.resolve(t)&&r.copyFileSync(e,t)}function HD(e){let t=r.openSync(e,`r`);try{let n=Buffer.alloc(2),i=r.readSync(t,n,0,2,0);if(i<2)throw Error(`install: staged render entry at ${e} is truncated (${i} byte(s)). Re-run: pnpm dlx ${wD}@latest install`);return n.toString(`latin1`)===`#!`?`node-shim`:`native`}finally{r.closeSync(t)}}function UD(){let e=zD(process.argv[1]);if(!r.existsSync(e))throw Error(`install: bundled dist not found at ${e}. Reinstall the package.`);let t=BD(e);if(!r.existsSync(t.sourcePath))throw Error(`install: render entry not found at ${t.sourcePath}. Reinstall the package.`);r.mkdirSync(c.dirname(LD()),{recursive:!0}),r.mkdirSync(c.dirname(ID()),{recursive:!0}),VD(e,LD()),VD(t.sourcePath,ID()),r.chmodSync(ID(),493),r.rmSync(c.join(FD(),`url-handler.mjs`),{force:!0});let n=HD(ID());return process.stdout.write(`Staged cc-candybar v${fD} runtime at ${FD()}\n`+(n===`native`?` render entry: native binary (${process.platform}-${process.arch})\n`:` render entry: node shim (no native binary for ${process.platform}-${process.arch}; renders are correct but pay node startup)\n`)),{binPath:ID(),distPath:LD(),entryKind:n}}function WD(){return[{key:`CFBundleIdentifier`,xml:`<string>com.cccandybar.url-handler</string>`},{key:`CFBundleURLTypes`,xml:[`<array>`,` <dict>`,` <key>CFBundleURLName</key>`,` <string>Claude Powerline Click Action</string>`,` <key>CFBundleURLSchemes</key>`,` <array>`,` <string>${NE}</string>`,` </array>`,` </dict>`,`</array>`].join(`
|
|
167
167
|
`)}]}function GD(e){let t=ND();r.mkdirSync(c.dirname(t),{recursive:!0}),r.existsSync(t)&&r.rmSync(t,{recursive:!0,force:!0}),process.stdout.write(`Building ${t}\n`);let n=Oe({bin:`/usr/bin/osacompile`,args:[`-o`,t,`-e`,RD(process.execPath,e)],category:`install.osacompile`});if(!n.ok)throw process.stderr.write(n.stderr),Error(`osacompile failed (${n.reason})`);let i=c.join(t,`Contents`,`Info.plist`);for(let{key:e}of WD())Oe({bin:`/usr/bin/plutil`,args:[`-remove`,e,i],category:`install.plutil`});for(let{key:e,xml:t}of WD()){let n=Oe({bin:`/usr/bin/plutil`,args:[`-insert`,e,`-xml`,t,i],category:`install.plutil`});if(!n.ok)throw process.stderr.write(n.stderr),Error(`plutil -insert ${e} failed (${n.reason})`)}process.stdout.write(`Registering ${NE}:// with Launch Services\n`);let a=Oe({bin:`/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister`,args:[`-f`,t],category:`install.lsregister`});if(!a.ok)throw process.stderr.write(a.stderr),Error(`lsregister failed (${a.reason})`);process.stdout.write(`✓ ${OD}.app installed and registered.\n`),process.stdout.write(` Test: open '${NE}://hello-world' && pbpaste\n`)}function KD(){PD(),GD(UD().distPath)}function qD(e,t=NE){let n=`${t}://`;if(!e.startsWith(n))throw Error(`expected ${n} scheme, got: ${e}`);let r=e.slice(n.length),i=r.indexOf(`/`);return i===-1?{verb:LE,value:r}:{verb:decodeURIComponent(r.slice(0,i)),value:r.slice(i+1)}}async function JD(e){e||(process.stderr.write(`url-handle: missing URL argument.
|
|
168
168
|
`),process.exit(1));let t;try{t=qD(e)}catch(e){process.stderr.write(`url-handle: ${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let n=await qT(t.verb,t.value);n.kind===`ok`&&process.exit(0),n.kind===`transient`&&(hE(),process.stderr.write(`url-handle: daemon unavailable (${n.cause}: ${n.message})\n`),process.exit(1)),process.stderr.write(YD(n)+`
|
|
@@ -173,7 +173,7 @@ Config tooling:
|
|
|
173
173
|
`))throw Error(`renderStripCells: rich-js strip output did not end its last line`);return i.slice(0,-1)}function RO(e){return Math.min(20,e??20)}const zO={heading:`ERROR`,glyph:`⚠`,colors:OO},BO={heading:`WARNING`,glyph:`⚠`,colors:kO},VO={heading:`UPDATE`,glyph:`⬆`,colors:kO};function HO(e,t){return{text:CO(e),link:t}}function UO(e,t,n){let[r,...i]=[WO(e,zO,BE),t,WO(n,BO,VE)].flat();return r===void 0?null:{channels:[r,...i]}}function WO(e,t,n){let r=oD([{verb:n,args:[e]}]),[i,...a]=e.split(/\r\n|\r|\n/).map(e=>HO(e,r)).filter(e=>e.text!==``).map(e=>[e]);return i===void 0?[]:[{severity:t,message:e,lines:[i,...a]}]}function GO(e){return e.channels.map(e=>`${e.severity.heading}\n${e.message}\n`).join(`
|
|
174
174
|
`)}function KO(e,t,n,r){if(t===null)return e;let i=qO(r),a=t.channels.flatMap(e=>JO(e,i)),o=n.failedConfigFile!==null||a.length>r.rowCap,s=a.slice(0,r.rowCap-Number(o)),c=o?[YO(t,n,a.length-s.length,i)]:[],l=[...s,...c].join(`
|
|
175
175
|
`);return e?`${l}\n${e}`:l}function qO(e){return{endcaps:`plain`,separator:``,width:e.width,wrap:!0,padding:0,charset:`unicode`,colorCompatibility:e.colorCompatibility}}function JO(e,t){let n=new B({bgcolor:e.severity.colors.bg,color:e.severity.colors.fg}),r=Rt(Math.max(2,t.width-1)),i=(e,t)=>new H(`${e} `,{style:t,end:``,overflow:`ignore`});return e.lines.flatMap((a,o)=>LO([i(o===0?e.severity.glyph:` `,n.withLink(a[0].link)),...a.flatMap(e=>{let t=n.withLink(e.link);return e.text.split(` `).flatMap(e=>Ht(e,r)).map(e=>i(e,t))})],t).split(`
|
|
176
|
-
`))}function YO(e,t,n,r){let{colors:i}=e.channels[0].severity,{fullText:a,failedConfigFile:o}=t,s=new B({bgcolor:i.bg,color:i.fg}),c=(e,t)=>new H(e,{style:t,end:``,overflow:`ignore`}),l=n>0?[c(`${n} more rows · `,s),a.kind===`file`?c(`open full text`,s.withLink(T(a.path).href)):c(`full text unavailable: ${CO(a.reason)}`,s)]:[],u=o===null?[]:[c(`${l.length>0?` · `:``}open `,s),c(CO(o),s.withLink(T(o).href))],d=[c(`↳ `,s),...l,...u.slice(0,-1)],f=d.reduce((e,t)=>e+t.cellLength,0),p=u.slice(-1).map(e=>e.truncate(Math.max(1,r.width-f),{mode:`middle`})),m=H.fromFragments([...d,...p]).truncate(r.width);return m.overflow=`ignore`,LO([m],r)}const XO=e=>!e.startsWith(`.`)&&!e.endsWith(`~`);function ZO(e,t){return t.isSymbolicLink()?Buffer.from(r.readlinkSync(e)):r.readFileSync(e)}function QO(e,t){return r.readdirSync(t).filter(XO).sort().flatMap(n=>{let i=c.join(t,n),a=r.lstatSync(i,{throwIfNoEntry:!1});return a===void 0?[]:a.isDirectory()?QO(e,i):[[c.relative(e,i).split(c.sep).join(`/`),ZO(i,a)]]})}function $O(e){let t=E.createHash(`sha256`);for(let[n,r]of QO(e,e))t.update(n).update(`\0`).update(r).update(`\0`);return t.digest(`hex`)}const ek=e=>e.slice(0,7);function tk(e){return c.dirname(c.dirname(e))}function nk(){return{version:fD,digest:`7695747a2bbe55dd5856f57bcbff7d9df16cc90c2109b0ed676cafb97c63e1f2`}}function rk(e){let t=JSON.parse(r.readFileSync(c.join(e,`package.json`),`utf8`)),n=typeof t==`object`&&t?t.version:void 0;if(typeof n!=`string`)throw Error(`${c.join(e,`package.json`)} has no version string`);return n}function ik(e,t){try{let n=tk(ie(e)),i=c.join(n,`src`);if(!r.existsSync(i))return{kind:`not-source-checkout`};let a=t(),o=$O(i);return o===a.digest?{kind:`current`,root:n,stamp:a}:{kind:`stale`,root:n,source:{version:rk(n),digest:o},running:a}}catch(e){return{kind:`unchecked`,reason:e.message}}}var $=class extends Error{constructor(e){super(e),this.name=`BadVerbArgs`}};function ak(e){return e.op===`remove`?`remove:${e.target}`:`insert:${e.segment}:${e.anchor}:${e.relation}`}function ok(e){let t=e.split(`:`);return t[0]===`remove`&&t.length===2&&t[1]?{op:`remove`,target:t[1]}:t[0]===`insert`&&t.length===4&&t[1]&&t[2]&&(t[3]===`before`||t[3]===`after`)?{op:`insert`,segment:t[1],anchor:t[2],relation:t[3]}:null}function sk(e,t,n){let r=As(e,new Set(n.map(ks).filter(e=>e.includes(t)).flat()));return r===e?{seg:e}:{seg:e,id:r}}const ck=/^-?\d+$/;function lk(e,t,n=`set-state`){let r=e.filter(e=>e.includes(`/`));if(r.length>0)throw Error(`makeAllowListValidator(${t}): values contain "/" — the ${n} wire shape splits values on "/" so slash-bearing options cannot be addressed. Offending values: ${r.join(`, `)}`);if(e.includes(``))throw Error(`makeAllowListValidator(${t}): empty string is not a writable option — the validator rejects empty input before the allow-list check, so an "" in the allowed list could be rendered but never delivered. Remove "" from the allowed list.`);let i=new Set(e),a=[...e];return e=>e?i.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown ${t} "${e}" (have: ${a.join(`, `)})`}:{ok:!1,reason:`${t} value is required`}}function uk(e){return t=>{if(!t)return{ok:!1,reason:`${e} value is required`};if(!ck.test(t))return{ok:!1,reason:`${e} must be an integer, got "${t}"`};let n=t[0]===`-`,r=(n?t.slice(1):t).replace(/^0+/,``);return r===``?{ok:!0,value:`0`}:{ok:!0,value:n?`-${r}`:r}}}function dk(e,t,n){return r=>r?ck.test(r)?{ok:!0,value:String(Math.max(e,Math.min(t,parseInt(r,10))))}:{ok:!1,reason:`${n} must be an integer, got "${r}"`}:{ok:!1,reason:`${n} value is required`}}function fk(e,t,n=`state`){let r=t.filter(e=>e.kind===`range`),i=t.some(e=>e.kind===`int`),a=t.flatMap(e=>e.kind===`allow-list`?e.allowed:[]);if(r.length===0&&!i)return{kind:`allow-list`,allowed:[...new Set(a)]};let o=a.filter(e=>!ck.test(e));if(o.length>0)throw Error(`${n} action table: key "${e}" is an integer spec (a paged cursor or a bounded value) but a click writes non-integer value(s) to it (${o.join(`, `)}). A ${n} key has one key shape — point that click at a distinct key, or write an integer.`);if(i&&r.length>0)throw Error(`${n} action table: key "${e}" is declared as both a paged cursor (int) and a bounded value (range) — a ${n} key has one key shape. Use distinct keys.`);if(r.length>0){let t=Math.min(...r.map(e=>e.min)),i=Math.max(...r.map(e=>e.max)),o=a.filter(e=>{let n=parseInt(e,10);return n<t||n>i});if(o.length>0)throw Error(`${n} action table: key "${e}" is a bounded range [${t},${i}] but a click writes out-of-range value(s) to it (${o.join(`, `)}). The range gate would clamp them, storing a different value than the click renders — write an in-range integer, or point that click at a distinct key.`);return{kind:`range`,min:t,max:i}}return{kind:`int`}}function pk(e){return e===`config`?`set-config`:`set-state`}function mk(e,t,n){return t.kind===`int`?uk(`menu page "${e}"`):t.kind===`range`?dk(t.min,t.max,`${n} stepper "${e}"`):lk(t.allowed,`${n} "${e}"`,pk(n))}function hk(e,t=`state`){let n=new Map;for(let{key:t,spec:r}of e){let e=n.get(t);e?e.push(r):n.set(t,[r])}return[...n].map(([e,n])=>({key:e,spec:fk(e,n,t)}))}function gk(e,t=`state`){let n=new Map(Object.entries(e).map(([e,t])=>[e,{validator:t,permanent:!0}]));function r(){let e=[];for(let[t,r]of n)r.permanent&&e.push(t);return e}return{register(e,i){if(!e)throw Error(`register: key is required`);if(e.includes(`/`))throw Error(`register: key "${e}" contains "/" — the wire shape splits on "/" so a slash-bearing key cannot be addressed. Use a slash-free key.`);let a=n.get(e);if(a){if(a.permanent)throw Error(`register: key "${e}" is a built-in ${t} key and cannot be re-claimed (built-in keys: ${[...r()].join(`, `)})`);let n=fk(e,[...a.specs,i],t);a.specs.push(i),a.merged=n,a.validator=mk(e,n,t)}else{let r=fk(e,[i],t);n.set(e,{permanent:!1,specs:[i],merged:r,validator:mk(e,r,t)})}let o=!0;return()=>{if(!o)return;o=!1;let r=n.get(e);if(!r||r.permanent)return;let a=r.specs.indexOf(i);a>=0&&r.specs.splice(a,1),r.specs.length===0?n.delete(e):(r.merged=fk(e,r.specs,t),r.validator=mk(e,r.merged,t))}},validate(e,r){let i=n.get(e);return i?i.validator(r):{ok:!1,reason:`unknown ${t} key "${e}" (have: ${[...n.keys()].join(`, `)})`}},listKeys(){return[...n.keys()]},listBaselineKeys(){return r()},rangeParamsFor(e){let t=n.get(e);if(!t||t.permanent||t.merged.kind!==`range`)return null;let{min:r,max:i}=t.merged;return{min:r,max:i}}}}const _k=gk({},`config`);function vk(){return _k.listKeys()}function yk(e,t){return _k.validate(e,t)}function bk(e){return _k.rangeParamsFor(e)}function xk(e,t){return`persist`in e?`to`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[e.to]}}]:`from`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:Zb(e.from,t).members}}]:`cycle`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:e.cycle}}]:`removeSegment`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[ak({op:`remove`,target:e.removeSegment})]}}]:`insertSegment`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[ak({op:`insert`,segment:e.insertSegment,anchor:e.anchor,relation:e.relation})]}}]:`insertSegmentFrom`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:Zb(e.insertSegmentFrom,t).members.map(t=>ak({op:`insert`,segment:t,anchor:e.anchor,relation:e.relation}))}}]:[{key:e.persist,spec:{kind:`range`,min:e.min,max:e.max}}]:[]}function Sk(e,t){let n=jl(e).get(t);return n===void 0?null:String(n)}function Ck(e){let t=new Set;for(let n of Object.values(e.actions)){`reset`in n&&t.add(n.reset);let e=`persist`in n?ox(n.persist):null;e?.scope===`preset-root`&&t.add(ix(e.preset))}return[...t].map(e=>({key:e,spec:{kind:`allow-list`,allowed:[]}}))}function wk(e){let t=new Map([...Yb(e),...xC(e)]);return[...Ck(e),...Object.values(e.actions).flatMap(e=>xk(e,t))]}function Tk(e){return hk(wk(e),`config`)}function Ek(e,t){return _k.register(e,t)}const Dk=Array.from({length:10},(e,t)=>(t+1)*1e5),Ok=Dk[0],kk=Dk[Dk.length-1];function Ak(e){let t;try{t=vD(e)}catch(e){return X(e instanceof Error?e.message:String(e))}let n=t.autoCompactWindow;return n===void 0?J(`auto`):typeof n==`number`&&Number.isInteger(n)&&n>=Ok&&n<=kk?J(n):X(`${e}: autoCompactWindow is ${JSON.stringify(n)}, not a window /autocompact accepts (${Ok}–${kk} tokens)`)}function jk(e,t){let n=Math.min(t??kk,kk),r=e===`auto`?n:Math.min(e,n);return{window:e===`auto`?0:e,applied:e===`auto`?0:r,lower:Dk.filter(e=>e<r).at(-1)??0,higher:Dk.find(e=>e>r&&e<=n)??0}}const Mk=Vx(`commands.`),Nk=`trimPrefix "/" (trimPrefix .project_dir .current_dir)`,Pk=`{{ \$dir := .current_dir }}{{ if and (ne .home "") (or (eq .home .current_dir) (hasPrefix (printf "%s/" .home) .current_dir)) }}{{ \$dir = printf "~%s" (trimPrefix .home .current_dir) }}{{ else }}{{ if or (eq .project_dir .current_dir) (hasPrefix (printf "%s/" .project_dir) .current_dir) }}{{ $dir = ternary (${Nk}) (basename .project_dir) (ne (${Nk}) "") }}{{ end }}{{ end }}{{ abbreviatePath \$dir }}`,Fk=`{{ ${yx} }}`,Ik={min:0,max:100,step:5},Lk={warnAt:{label:`warning at %`,domain:Ik,default:50},errorAt:{label:`error at %`,domain:{...Ik,atLeast:`warnAt`},default:80}};function Rk(e){return{budget:{label:`budget $`,domain:{min:0,max:1e4,step:5},default:e},warnAt:{label:`warning at %`,domain:Ik,default:80}}}const zk={globals:{palette:`tokyo-night`},variables:{...Mk.variables,...Db,current_dir:{kind:`input`,path:`workspace.current_dir`,default:`?`},"model.display_name":{kind:`input`,path:`model.display_name`,default:``},version:{kind:`input`,path:`version`,default:``},home:{kind:`input`,path:`home`,default:``},"tmux.session":{kind:`input`,path:`tmux.session`,default:``},"host.name":{kind:`input`,path:`host.name`,default:``},"host.user":{kind:`input`,path:`host.user`,default:``},"host.ssh":{kind:`input`,path:`host.ssh`,type:`boolean`,default:!1},"git.repoName":{kind:`input`,path:`git.repoName`,default:``},"git.branch":{kind:`input`,path:`git.branch`,default:``},"git.sha":{kind:`input`,path:`git.sha`,default:``},"git.ahead":{kind:`input`,path:`git.ahead`,type:`number`,default:0},"git.behind":{kind:`input`,path:`git.behind`,type:`number`,default:0},"git.staged":{kind:`input`,path:`git.staged`,type:`number`,default:0},"git.unstaged":{kind:`input`,path:`git.unstaged`,type:`number`,default:0},"git.untracked":{kind:`input`,path:`git.untracked`,type:`number`,default:0},"git.conflicts":{kind:`input`,path:`git.conflicts`,type:`number`,default:0},"git.upstream":{kind:`input`,path:`git.upstream`,default:``},"git.stash":{kind:`input`,path:`git.stash`,type:`number`,default:0},"git.status":{kind:`input`,path:`git.status`,default:`clean`},"git.operation":{kind:`input`,path:`git.operation`,default:``},"git.timeSinceCommit":{kind:`input`,path:`git.timeSinceCommit`,type:`number`,default:0},"git.color.branch":{kind:`literal`,value:`primary`},"git.color.staged":{kind:`literal`,value:`success`},"git.color.unstaged":{kind:`literal`,value:`warning`},"git.color.untracked":{kind:`literal`,value:`accent`},"git.color.conflicts":{kind:`literal`,value:`error`},"git.color.ahead":{kind:`literal`,value:`success`},"git.color.behind":{kind:`literal`,value:`warning`},"git.color.stash":{kind:`literal`,value:`accent`},"git.detail":{kind:`state`,key:`git-detail`,default:`collapsed`},"git.prNumber":{kind:`input`,path:`git.prNumber`,type:`number`,default:0},"git.prState":{kind:`input`,path:`git.prState`,default:``},"git.prUrl":{kind:`input`,path:`git.prUrl`,default:``},"git.prError":{kind:`input`,path:`git.prError`,default:``},"cache.expiresAt":{kind:`input`,path:`cache.expiresAt`,type:`number`,default:0},"session.cost":{kind:`input`,path:`session.cost`,type:`number`,default:0},"session.tokens":{kind:`input`,path:`session.tokens`,type:`number`,default:0},"today.cost":{kind:`input`,path:`today.cost`,type:`number`,default:0},"today.tokens":{kind:`input`,path:`today.tokens`,type:`number`,default:0},"block.nativeUtilization":{kind:`input`,path:`block.nativeUtilization`,type:`number`,default:0},"block.resetsAt":{kind:`input`,path:`block.resetsAt`,type:`number`,default:0},"weekly.percentage":{kind:`input`,path:`weekly.percentage`,type:`number`,default:0},"weekly.resetsAt":{kind:`input`,path:`weekly.resetsAt`,type:`number`,default:0},"burn.costPerHour":{kind:`input`,path:`burn.costPerHour`,type:`number`,default:-1},"block.etaMinutes":{kind:`input`,path:`block.etaMinutes`,type:`number`,default:-1},"weekly.etaMinutes":{kind:`input`,path:`weekly.etaMinutes`,type:`number`,default:-1},"speed.input":{kind:`input`,path:`speed.input`,type:`number`,default:-1},"speed.output":{kind:`input`,path:`speed.output`,type:`number`,default:-1},"speed.total":{kind:`input`,path:`speed.total`,type:`number`,default:-1},"speed.history":{kind:`input`,path:`speed.history`,type:`string`,default:``},"context.totalTokens":{kind:`input`,path:`context.totalTokens`,type:`number`,default:0},"context.contextLeft":{kind:`input`,path:`context.contextLeft`,type:`number`,default:100},"memento.ceiling":{kind:`input`,path:`memento.ceiling`,type:`number`,default:-1},"memento.off":{kind:`input`,path:`memento.off`,type:`boolean`,default:!1},"memento.session":{kind:`input`,path:`memento.session`,default:``},"memento.error":{kind:`input`,path:`memento.error`,default:``},"autocompact.window":{kind:`input`,path:`autocompact.window`,type:`number`,default:-1},...Object.fromEntries([`applied`,`lower`,`higher`].map(e=>[`autocompact.${e}`,{kind:`input`,path:`autocompact.${e}`,type:`number`,default:0}])),"autocompact.error":{kind:`input`,path:`autocompact.error`,default:``},"metrics.lastResponseTime":{kind:`input`,path:`metrics.lastResponseTime`,type:`number`,default:0},"metrics.responseTime":{kind:`input`,path:`metrics.responseTime`,type:`number`,default:0},"metrics.sessionDuration":{kind:`input`,path:`metrics.sessionDuration`,type:`number`,default:0},"metrics.messageCount":{kind:`input`,path:`metrics.messageCount`,type:`number`,default:0},"metrics.linesAdded":{kind:`input`,path:`metrics.linesAdded`,type:`number`,default:0},"metrics.linesRemoved":{kind:`input`,path:`metrics.linesRemoved`,type:`number`,default:0},"activity.command":{kind:`input`,path:`activity.command`,type:`string`,default:``},"activity.todo.total":{kind:`input`,path:`activity.todo.total`,type:`number`,default:0},"activity.todo.completed":{kind:`input`,path:`activity.todo.completed`,type:`number`,default:0},"activity.todo.position":{kind:`input`,path:`activity.todo.position`,type:`number`,default:0},"activity.todo.active":{kind:`input`,path:`activity.todo.active`,type:`string`,default:``},"activity.tool.running":{kind:`input`,path:`activity.tool.running`,type:`string`,default:``},"activity.tool.done":{kind:`input`,path:`activity.tool.done`,type:`string`,default:``}},segments:{directory:{group:`location`,description:"The current directory, shortened fish-style — `~` under home, project-relative inside the project.",template:Pk},model:{group:`model-context`,description:`The active model's display name.`,template:`✱ {{ formatModelName .model.display_name }}`,when:`{{ ne .model.display_name "" }}`},sessionId:{group:`session-tools`,description:`The session id, truncated to 8 characters.`,template:`⌗{{ trunc 8 .session.id }}`,when:`{{ ne .session.id "" }}`},version:{group:`model-context`,description:`The Claude Code version reported in the hook payload.`,template:`◈ v{{ .version }}`,when:`{{ ne .version "" }}`},tmux:{group:`location`,description:`The tmux session name; hidden when not inside tmux.`,template:`tmux:{{ .tmux.session | default "none" }}`,when:`{{ ne .tmux.session "" }}`},host:{group:`location`,description:`user@host on a warning background, shown only over SSH.`,template:`⇄ {{ .host.user | default "?" }}@{{ .host.name | default "?" }}`,bg:`warning`,when:`{{ .host.ssh }}`},gitaculous:{group:`git`,description:`The git state: a summary (branch, ahead/behind, S/U/? flags) that the arrow at its right edge expands to every fact — repo, in-progress operation, sha, upstream ±, stash count, time since the last commit.`,template:`{{ if eq .git.detail "expanded" }}{{ template "gitExpanded" . }}{{ else }}{{ template "gitCollapsed" . }}{{ end }} {{ action "gitDetail" "▸" "◂" }}`,fg:Fk,when:`{{ ne .git.branch "" }}`,settings:{aheadBehind:{label:`ahead/behind`,domain:`bool`,default:!0},flags:{label:`dirty flags`,domain:`bool`,default:!0},operation:{label:`operation`,domain:`bool`,default:!0},repo:{label:`repo name`,domain:`bool`,default:!0},sha:{label:`commit hash`,domain:`bool`,default:!0},stash:{label:`stash`,domain:`bool`,default:!0},upstream:{label:`upstream`,domain:`bool`,default:!0},age:{label:`time since commit`,domain:`bool`,default:!0}}},gitPr:{group:`git`,description:"The pull request open for this branch, as a link; `⚠ PR` when the forge lookup failed.",template:`{{ if ne .git.prUrl "" }}{{ link .git.prUrl (printf "⇆ #%v" .git.prNumber) }}{{ else }}⚠ PR{{ end }}`,when:`{{ or (ne .git.prUrl "") (ne .git.prError "") }}`},toolbar:{group:`session-tools`,description:`Quick actions: copy the session id, and open the project, transcript or repo.`,template:Ax(``).template},commands:{group:`session-tools`,description:`Type /compact, /model or /clear into this session; /clear asks for a second click.`,template:Mk.template},themeSwitcher:{group:`session-tools`,description:"`◀ <theme> ▶`: the theme the bar is wearing; ◀ and ▶ switch this session to the previous or next theme, wrapping at the ends.",template:`{{ carousel "stepTheme" 0 }}`},session:{group:`cost-limits`,description:`This session's cost and token total, with a budget warning once a budget is configured.`,template:`§ {{ template "formatCost" .session.cost }} ({{ template "formatTokens" .session.tokens }}){{ template "budgetStatus" (dict "cost" .session.cost "budget" .settings.budget "warn" .settings.warnAt) }}`,settings:Rk(0)},today:{group:`cost-limits`,description:`Today's cost and tokens across every session, with a budget warning once a budget is configured.`,template:`☉ {{ template "formatCost" .today.cost }} ({{ template "formatTokens" .today.tokens }}){{ template "budgetStatus" (dict "cost" .today.cost "budget" .settings.budget "warn" .settings.warnAt) }}`,settings:Rk(50)},block:{group:`cost-limits`,description:`The 5-hour rate-limit block: percent used and time to reset, heating to warning then error.`,template:`◱ {{ round .block.nativeUtilization }}% ({{ template "formatResetCountdown" .block.resetsAt }})`,bg:`{{ ramp (round .block.nativeUtilization) "step" 0 (tint) .settings.warnAt "warning" .settings.errorAt "error" }}`,settings:Lk,when:`{{ gt .block.resetsAt 0 }}`},weekly:{group:`cost-limits`,description:`The weekly rate-limit quota: percent used and time to reset, heating to warning then error.`,template:`◑ {{ round .weekly.percentage }}% ({{ template "formatResetCountdown" .weekly.resetsAt }})`,bg:`{{ ramp (round .weekly.percentage) "step" 0 (tint) .settings.warnAt "warning" .settings.errorAt "error" }}`,settings:Lk,when:`{{ gt .weekly.resetsAt 0 }}`},burnrate:{group:`cost-limits`,description:`Spend per hour, with the projected time to the 5-hour and weekly limits.`,template:`⚡ {{ template "formatRate" .burn.costPerHour }} · {{ template "formatEta" .block.etaMinutes }} to 5h · {{ template "formatEta" .weekly.etaMinutes }} to wk`,bg:`{{ ramp .block.etaMinutes "step" -1 (tint) 0 "error" .settings.errorWithin "warning" .settings.warnWithin (tint) }}`,settings:{errorWithin:{label:`error within (min)`,domain:{min:0,max:300,step:5},default:30},warnWithin:{label:`warning within (min)`,domain:{min:0,max:300,step:5,atLeast:`errorWithin`},default:60}},when:`{{ or (gt .block.resetsAt 0) (gt .weekly.resetsAt 0) }}`},speed:{group:`activity`,description:`Token throughput for the latest exchange: output, input, and total.`,template:`⇅ out {{ template "formatSpeed" .speed.output }} · in {{ template "formatSpeed" .speed.input }} · tot {{ template "formatSpeed" .speed.total }}`,when:`{{ gt .session.tokens 0 }}`},tokenSparkline:{group:`activity`,description:`A sparkline of recent token throughput.`,template:`⚡ {{ sparkline .speed.history 24 }}`,when:`{{ ne .speed.history "" }}`},cacheTimer:{group:`activity`,description:"Minutes until the prompt cache expires, or `cold` once it has.",template:`◴ {{ if le (minutesUntilReset .cache.expiresAt) 0 }}cold{{ else }}{{ minutesUntilReset .cache.expiresAt }}m{{ end }}`,fg:`{{ readableOn (color (cascade (minutesUntilReset .cache.expiresAt) "0:error" "9:warning" "21:foreground")) (bgOf) ${wa} }}`,when:`{{ gt .cache.expiresAt 0 }}`},context:{group:`model-context`,description:`Context used, in tokens and percent remaining, heating as it fills.`,template:`◔ {{ formatInteger .context.totalTokens }} ({{ .context.contextLeft }}%)`,bg:`{{ ramp .context.contextLeft "step" 0 "error" 21 "warning" 41 (tint) }}`,when:`{{ gt .context.totalTokens 0 }}`},ceiling:{group:`model-context`,description:`The memento plugin's context ceiling for this session: − and + move it by 100K, ∞ lifts it, ↺ drops this session's own setting.`,template:`{{ if ne .memento.error "" }}⌈ ⚠ {{ .memento.error }} {{ action "ceiling.clear" "↺" }}{{ else }}⌈ {{ if .memento.off }}off{{ else }}{{ template "formatTokenCount" .memento.ceiling }} {{ action "ceiling.lower" "−" }} {{ action "ceiling.raise" "+" }} {{ action "ceiling.off" "∞" }}{{ end }}{{ if ne .memento.session "" }} {{ action "ceiling.clear" "↺" }}{{ end }}{{ end }}`,bg:`{{ if ne .memento.error "" }}{{ color "error" }}{{ else }}{{ tint }}{{ end }}`,when:`{{ or (ge .memento.ceiling 0) (ne .memento.error "") }}`},autocompact:{group:`model-context`,description:`Claude Code's auto-compact window: − and + move it by 100K, ↺ returns it to auto. Clicks type /autocompact into this session.`,template:`{{ if ne .autocompact.error "" }}⇲ ⚠ {{ .autocompact.error }}{{ else }}⇲ {{ if eq .autocompact.window 0 }}auto{{ else }}{{ template "formatTokenCount" .autocompact.applied }}{{ end }}{{ if gt .autocompact.lower 0 }} {{ action (printf "autocompact.%d" .autocompact.lower) "−" }}{{ end }}{{ if gt .autocompact.higher 0 }} {{ action (printf "autocompact.%d" .autocompact.higher) "+" }}{{ end }}{{ if gt .autocompact.window 0 }} {{ action "autocompact.auto" "↺" }}{{ end }}{{ end }}`,bg:`{{ if ne .autocompact.error "" }}{{ color "error" }}{{ else }}{{ tint }}{{ end }}`,when:`{{ or (ge .autocompact.window 0) (ne .autocompact.error "") }}`},metrics:{group:`activity`,description:`Response times, session duration, message count, and lines added/removed.`,template:`{{ if .metrics.lastResponseTime }} Δ {{ template "formatResponseTime" .metrics.lastResponseTime }}{{ end }}{{ if .metrics.responseTime }} ⧖ {{ template "formatResponseTime" .metrics.responseTime }}{{ end }}{{ if .metrics.sessionDuration }} ⧗ {{ template "formatDuration" .metrics.sessionDuration }}{{ end }}{{ if .metrics.messageCount }} ◆ {{ .metrics.messageCount }}{{ end }}{{ if .metrics.linesAdded }} + {{ .metrics.linesAdded }}{{ end }}{{ if .metrics.linesRemoved }} - {{ .metrics.linesRemoved }}{{ end }} `,when:`{{ or (gt .metrics.lastResponseTime 0.0) (gt .metrics.responseTime 0.0) (gt .metrics.sessionDuration 0.0) (gt .metrics.messageCount 0) (gt .metrics.linesAdded 0) (gt .metrics.linesRemoved 0) }}`},activity:{group:`activity`,description:`What Claude is doing: the slash command that opened the turn, the in-progress todo, and the tools in flight.`,template:`{{ if .activity.command }} ⌘ {{ .activity.command }}{{ end }}{{ if .activity.todo.total }}{{ if .activity.todo.active }} ☐ {{ .activity.todo.position }}/{{ .activity.todo.total }} {{ abbrev 32 .activity.todo.active }}{{ else }} ☑ {{ .activity.todo.completed }}/{{ .activity.todo.total }}{{ end }}{{ end }}{{ if .activity.tool.running }} ⟳ {{ template "formatToolTally" .activity.tool.running }}{{ end }}{{ if .activity.tool.done }} ✓ {{ template "formatToolTally" .activity.tool.done }}{{ end }} `,when:`{{ or (ne .activity.command "") (gt .activity.todo.total 0) (ne .activity.tool.running "") (ne .activity.tool.done "") }}`}},root:{rows:{identity:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`}]},status:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`activity`}]}}},actions:{...Ax(``).actions,...Mk.actions,copyDir:{copy:`{{ .current_dir }}`},stepTheme:{set:`theme`,from:`themes`},gitDetail:{set:`git-detail`,cycle:[`collapsed`,`expanded`]},"ceiling.raise":{ceiling:`set`,to:`+100_000`},"ceiling.lower":{ceiling:`set`,to:`-100_000`},"ceiling.off":{ceiling:`set`,to:`off`},"ceiling.clear":{ceiling:`clear`},"autocompact.auto":{slash:Rx(`/autocompact auto`)},...Object.fromEntries(Dk.map(e=>[`autocompact.${e}`,{slash:Rx(`/autocompact ${e}`)}]))},styles:{none:{hueShift:0,chromaScale:1,lightnessScale:1,lightnessShift:0},vivid:{hueShift:0,chromaScale:1.35,lightnessScale:1,lightnessShift:0},muted:{hueShift:0,chromaScale:.55,lightnessScale:1,lightnessShift:0},dim:{hueShift:0,chromaScale:1,lightnessScale:.85,lightnessShift:0},bright:{hueShift:0,chromaScale:1,lightnessScale:1,lightnessShift:.08},inverted:{hueShift:0,chromaScale:1,lightnessScale:-1,lightnessShift:1}},presets:{default:{},compact:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`context`}]},globals:{padding:0}},verbose:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`gitPr`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`burnrate`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`speed`},{kind:`segment`,name:`tokenSparkline`}]}]}},zen:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`context`}]},globals:{endcaps:`plain`,style:`dim`}},git:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`gitPr`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`segment`,name:`context`},{kind:`segment`,name:`activity`}]}]}},usage:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`burnrate`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`session`},{kind:`segment`,name:`today`},{kind:`segment`,name:`speed`},{kind:`segment`,name:`tokenSparkline`}]}]}},dense:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`session`},{kind:`segment`,name:`activity`}]},globals:{padding:0}}},editGlobals:{endcaps:`plain`,default_separator:` | `},helpers:{gitPaint:`{{ fg (readableOn (color .color) (bgOf) ${wa}) .text }}`,gitCollapsed:`{{ template "gitBranch" . }}{{ template "gitAheadBehind" . }}{{ template "gitFlags" . }}`,gitExpanded:`(git){{ template "gitRepo" . }}{{ template "gitOperation" . }}{{ template "gitSha" . }}{{ template "gitFlags" . }} {{ template "gitBranch" . }}{{ template "gitUpstream" . }}{{ template "gitStash" . }}{{ template "gitAge" . }}`,gitBranch:`⎇ {{ template "gitPaint" (dict "color" .git.color.branch "text" .git.branch) }}`,gitRepo:`{{ if and .settings.repo (ne .git.repoName "") }} {{ .git.repoName }}{{ end }}`,gitOperation:`{{ if and .settings.operation (ne .git.operation "") }} [{{ .git.operation }}]{{ end }}`,gitSha:`{{ if and .settings.sha (ne .git.sha "") }} {{ .git.sha }}{{ end }}`,gitFlags:`{{ if and .settings.flags (or (gt .git.staged 0) (gt .git.unstaged 0) (gt .git.untracked 0) (gt .git.conflicts 0)) }} {{ if gt .git.staged 0 }}{{ template "gitPaint" (dict "color" .git.color.staged "text" "S") }}{{ end }}{{ if gt .git.unstaged 0 }}{{ template "gitPaint" (dict "color" .git.color.unstaged "text" "U") }}{{ end }}{{ if gt .git.untracked 0 }}{{ template "gitPaint" (dict "color" .git.color.untracked "text" "?") }}{{ end }}{{ if gt .git.conflicts 0 }}{{ template "gitPaint" (dict "color" .git.color.conflicts "text" (printf "!%v" .git.conflicts)) }}{{ end }}{{ end }}`,gitAheadBehind:`{{ if and .settings.aheadBehind (or (gt .git.ahead 0) (gt .git.behind 0)) }} {{ if gt .git.ahead 0 }}{{ template "gitPaint" (dict "color" .git.color.ahead "text" (printf "+%v" .git.ahead)) }}{{ end }}{{ if and (gt .git.ahead 0) (gt .git.behind 0) }}/{{ end }}{{ if gt .git.behind 0 }}{{ template "gitPaint" (dict "color" .git.color.behind "text" (printf "-%v" .git.behind)) }}{{ end }}{{ end }}`,gitUpstream:`{{ if and .settings.upstream (ne .git.upstream "") }} [{{ .git.upstream }}{{ template "gitAheadBehind" . }}]{{ end }}`,gitStash:`{{ if and .settings.stash (gt .git.stash 0) }} {{ template "gitPaint" (dict "color" .git.color.stash "text" (printf "(%v stashed)" .git.stash)) }}{{ end }}`,gitAge:`{{ if and .settings.age (gt .git.timeSinceCommit 0) }} ◷ {{ template "formatTimeSince" .git.timeSinceCommit }}{{ end }}`,formatCost:'{{ if lt . 0.01 }}<$0.01{{ else }}${{ printf "%.2f" . }}{{ end }}',formatTokenCount:`{{ if ge . 1000000 }}{{ printf "%.1f" (divf . 1000000) }}M{{ else if ge . 1000 }}{{ printf "%.1f" (divf . 1000) }}K{{ else }}{{ . }}{{ end }}`,formatTokens:`{{ template "formatTokenCount" . }} tokens`,formatToolTally:`{{ $names := splitList "," . }}{{ range $i, $pair := $names }}{{ if lt $i 2 }}{{ if $i }} {{ end }}{{ $kv := splitList ":" $pair }}{{ index $kv 0 }}{{ if ne (index $kv 1) "1" }}×{{ index $kv 1 }}{{ end }}{{ end }}{{ end }}{{ if gt (len $names) 2 }} +{{ sub (len $names) 2 }}{{ end }}`,formatRate:`{{ if lt . 0 }}—/hr{{ else }}{{ template "formatCost" . }}/hr{{ end }}`,formatEta:`{{ if lt . 0 }}—{{ else }}{{ template "formatLongTimeRemaining" . }}{{ end }}`,formatSpeed:`{{ if lt . 0 }}—{{ else }}{{ template "formatTokenCount" (round .) }}/s{{ end }}`,formatTokenBreakdown:`{{ $first := true }}{{ if gt .input 0 }}{{ template "formatTokenCount" .input }} in{{ $first = false }}{{ end }}{{ if gt .output 0 }}{{ if not $first }} + {{ end }}{{ template "formatTokenCount" .output }} out{{ $first = false }}{{ end }}{{ if or (gt .cacheCreation 0) (gt .cacheRead 0) }}{{ if not $first }} + {{ end }}{{ template "formatTokenCount" (add .cacheCreation .cacheRead) }} cached{{ $first = false }}{{ end }}{{ if $first }}0 tokens{{ end }}`,budgetStatus:`{{ if or (le .budget 0) (lt .cost 0) }}{{ else }}{{ $pct := minf 100 (mulf (divf .cost .budget) 100) }}{{ $p := printf "%.0f%%" $pct }}{{ if ge $pct .warn }} !{{ $p }}{{ else }}{{ if ge $pct 50 }} +{{ $p }}{{ else }} {{ $p }}{{ end }}{{ end }}{{ end }}`,formatTimeSince:`{{ if lt . 60 }}{{ . }}s{{ else if lt . 3600 }}{{ div . 60 }}m{{ else if lt . 86400 }}{{ div . 3600 }}h{{ else if lt . 604800 }}{{ div . 86400 }}d{{ else }}{{ div . 604800 }}w{{ end }}`,formatDuration:`{{ if lt . 60 }}{{ printf "%.0f" . }}s{{ else if lt . 3600 }}{{ printf "%.0f" (divf . 60) }}m{{ else if lt . 86400 }}{{ printf "%.1f" (divf . 3600) }}h{{ else }}{{ printf "%.1f" (divf . 86400) }}d{{ end }}`,formatResponseTime:`{{ if lt . 60 }}{{ printf "%.1f" . }}s{{ else }}{{ printf "%.1f" (divf . 60) }}m{{ end }}`,formatLongTimeRemaining:`{{ if ge . 1440 }}{{ $d := div . 1440 }}{{ $h := div (mod . 1440) 60 }}{{ if gt $h 0 }}{{ $d }}d {{ $h }}h{{ else }}{{ $d }}d{{ end }}{{ else if ge . 60 }}{{ $h := div . 60 }}{{ $m := mod . 60 }}{{ if gt $m 0 }}{{ $h }}h {{ $m }}m{{ else }}{{ $h }}h{{ end }}{{ else }}{{ . }}m{{ end }}`,formatResetCountdown:`{{ template "formatLongTimeRemaining" (add 1 (minutesUntilReset .)) }}`}},Bk=new Set([zk.globals.palette,...Object.values(zk.segments).map(e=>e.palette)].filter(e=>e!==void 0)),Vk=Bc(yT(`<default>`,JSON.stringify(zk),Bk),zk),Hk=T_(Vk.presets);function Uk(e){return Hk.includes(e)}function Wk(e){if(!e)return 0;try{return o(e).mtimeMs}catch{return 0}}const Gk=new class{slots;head=null;tail=null;constructor(e){this.slots=e}async run(e){await this.acquire();try{return await e()}finally{this.release()}}async acquire(){if(this.slots>0){this.slots--;return}await new Promise(e=>{let t={wake:e,next:null};this.tail?this.tail.next=t:this.head=t,this.tail=t})}release(){let e=this.head;if(!e){this.slots++;return}this.head=e.next,this.head||(this.tail=null),e.wake()}}(8);function Kk(e){return((...t)=>Gk.run(()=>e(...t)))}const qk=Kk(S),Jk=Kk(x),Yk=Kk(C);async function Xk(e,t){return Gk.run(async()=>{let n=null;try{n=await b(e,`r`);let{size:r,mtimeMs:i,ino:a}=await n.stat(),o=t!==void 0&&(a!==t.ino||r<t.offset),s=o||t===void 0?0:t.offset;if(s>=r)return J({buf:Buffer.alloc(0),start:s,size:r,mtimeMs:i,ino:a,reset:o});let c=Buffer.alloc(r-s),l=0;for(;l<c.length;){let{bytesRead:e}=await n.read(c,l,c.length-l,s+l);if(e===0)break;l+=e}return J({buf:l===c.length?c:c.subarray(0,l),start:s,size:r,mtimeMs:i,ino:a,reset:o})}catch(t){return t.code===`ENOENT`?Y:X(`readAppended ${e}: ${t instanceof Error?t.message:String(t)}`)}finally{await n?.close().catch(e=>{O(`transcript-fs: close failed: ${e instanceof Error?e.message:String(e)}`)})}})}async function Zk(e,t){return Gk.run(async()=>{let n=null;try{n=await b(e,`r`);let{size:r}=await n.stat(),i=Math.max(0,r-t),a=Buffer.alloc(r-i),o=0;for(;o<a.length;){let{bytesRead:e}=await n.read(a,o,a.length-o,i+o);if(e===0)break;o+=e}return J({buf:o===a.length?a:a.subarray(0,o),fromStart:i===0})}catch(t){return t.code===`ENOENT`?Y:X(`readTail ${e}: ${t instanceof Error?t.message:String(t)}`)}finally{await n?.close().catch(e=>{O(`transcript-fs: close failed: ${e instanceof Error?e.message:String(e)}`)})}})}const Qk=/"(?:cache_read_input_tokens|cache_creation_input_tokens)":[1-9]/;function $k(e){let t;try{t=JSON.parse(e)}catch{return null}let n=t.message?.usage;if(!((n?.cache_read_input_tokens??0)>0||(n?.cache_creation_input_tokens??0)>0))return null;let r=t.timestamp==null?NaN:Date.parse(t.timestamp);return Number.isNaN(r)?null:r}async function eA(e){let t=await tA(e);return t.kind===`ok`?J(Math.floor((t.value+36e5)/1e3)):t}async function tA(e){for(let t of[65536,1048576]){let n=await Zk(e,t);if(n.kind!==`ok`)return n;let r=nA(n.value.buf,n.value.fromStart);if(r!=null)return J(r);if(n.value.fromStart)return Y}return Y}function nA(e,t){let n=e.toString(`utf8`).split(`
|
|
176
|
+
`))}function YO(e,t,n,r){let{colors:i}=e.channels[0].severity,{fullText:a,failedConfigFile:o}=t,s=new B({bgcolor:i.bg,color:i.fg}),c=(e,t)=>new H(e,{style:t,end:``,overflow:`ignore`}),l=n>0?[c(`${n} more rows · `,s),a.kind===`file`?c(`open full text`,s.withLink(T(a.path).href)):c(`full text unavailable: ${CO(a.reason)}`,s)]:[],u=o===null?[]:[c(`${l.length>0?` · `:``}open `,s),c(CO(o),s.withLink(T(o).href))],d=[c(`↳ `,s),...l,...u.slice(0,-1)],f=d.reduce((e,t)=>e+t.cellLength,0),p=u.slice(-1).map(e=>e.truncate(Math.max(1,r.width-f),{mode:`middle`})),m=H.fromFragments([...d,...p]).truncate(r.width);return m.overflow=`ignore`,LO([m],r)}const XO=e=>!e.startsWith(`.`)&&!e.endsWith(`~`);function ZO(e,t){return t.isSymbolicLink()?Buffer.from(r.readlinkSync(e)):r.readFileSync(e)}function QO(e,t){return r.readdirSync(t).filter(XO).sort().flatMap(n=>{let i=c.join(t,n),a=r.lstatSync(i,{throwIfNoEntry:!1});return a===void 0?[]:a.isDirectory()?QO(e,i):[[c.relative(e,i).split(c.sep).join(`/`),ZO(i,a)]]})}function $O(e){let t=E.createHash(`sha256`);for(let[n,r]of QO(e,e))t.update(n).update(`\0`).update(r).update(`\0`);return t.digest(`hex`)}const ek=e=>e.slice(0,7);function tk(e){return c.dirname(c.dirname(e))}function nk(){return{version:fD,digest:`6152ae199b27eac3e64f56a39c6617220789d8e4595966bbfe9c83717190b61d`}}function rk(e){let t=JSON.parse(r.readFileSync(c.join(e,`package.json`),`utf8`)),n=typeof t==`object`&&t?t.version:void 0;if(typeof n!=`string`)throw Error(`${c.join(e,`package.json`)} has no version string`);return n}function ik(e,t){try{let n=tk(ie(e)),i=c.join(n,`src`);if(!r.existsSync(i))return{kind:`not-source-checkout`};let a=t(),o=$O(i);return o===a.digest?{kind:`current`,root:n,stamp:a}:{kind:`stale`,root:n,source:{version:rk(n),digest:o},running:a}}catch(e){return{kind:`unchecked`,reason:e.message}}}var $=class extends Error{constructor(e){super(e),this.name=`BadVerbArgs`}};function ak(e){return e.op===`remove`?`remove:${e.target}`:`insert:${e.segment}:${e.anchor}:${e.relation}`}function ok(e){let t=e.split(`:`);return t[0]===`remove`&&t.length===2&&t[1]?{op:`remove`,target:t[1]}:t[0]===`insert`&&t.length===4&&t[1]&&t[2]&&(t[3]===`before`||t[3]===`after`)?{op:`insert`,segment:t[1],anchor:t[2],relation:t[3]}:null}function sk(e,t,n){let r=As(e,new Set(n.map(ks).filter(e=>e.includes(t)).flat()));return r===e?{seg:e}:{seg:e,id:r}}const ck=/^-?\d+$/;function lk(e,t,n=`set-state`){let r=e.filter(e=>e.includes(`/`));if(r.length>0)throw Error(`makeAllowListValidator(${t}): values contain "/" — the ${n} wire shape splits values on "/" so slash-bearing options cannot be addressed. Offending values: ${r.join(`, `)}`);if(e.includes(``))throw Error(`makeAllowListValidator(${t}): empty string is not a writable option — the validator rejects empty input before the allow-list check, so an "" in the allowed list could be rendered but never delivered. Remove "" from the allowed list.`);let i=new Set(e),a=[...e];return e=>e?i.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown ${t} "${e}" (have: ${a.join(`, `)})`}:{ok:!1,reason:`${t} value is required`}}function uk(e){return t=>{if(!t)return{ok:!1,reason:`${e} value is required`};if(!ck.test(t))return{ok:!1,reason:`${e} must be an integer, got "${t}"`};let n=t[0]===`-`,r=(n?t.slice(1):t).replace(/^0+/,``);return r===``?{ok:!0,value:`0`}:{ok:!0,value:n?`-${r}`:r}}}function dk(e,t,n){return r=>r?ck.test(r)?{ok:!0,value:String(Math.max(e,Math.min(t,parseInt(r,10))))}:{ok:!1,reason:`${n} must be an integer, got "${r}"`}:{ok:!1,reason:`${n} value is required`}}function fk(e,t,n=`state`){let r=t.filter(e=>e.kind===`range`),i=t.some(e=>e.kind===`int`),a=t.flatMap(e=>e.kind===`allow-list`?e.allowed:[]);if(r.length===0&&!i)return{kind:`allow-list`,allowed:[...new Set(a)]};let o=a.filter(e=>!ck.test(e));if(o.length>0)throw Error(`${n} action table: key "${e}" is an integer spec (a paged cursor or a bounded value) but a click writes non-integer value(s) to it (${o.join(`, `)}). A ${n} key has one key shape — point that click at a distinct key, or write an integer.`);if(i&&r.length>0)throw Error(`${n} action table: key "${e}" is declared as both a paged cursor (int) and a bounded value (range) — a ${n} key has one key shape. Use distinct keys.`);if(r.length>0){let t=Math.min(...r.map(e=>e.min)),i=Math.max(...r.map(e=>e.max)),o=a.filter(e=>{let n=parseInt(e,10);return n<t||n>i});if(o.length>0)throw Error(`${n} action table: key "${e}" is a bounded range [${t},${i}] but a click writes out-of-range value(s) to it (${o.join(`, `)}). The range gate would clamp them, storing a different value than the click renders — write an in-range integer, or point that click at a distinct key.`);return{kind:`range`,min:t,max:i}}return{kind:`int`}}function pk(e){return e===`config`?`set-config`:`set-state`}function mk(e,t,n){return t.kind===`int`?uk(`menu page "${e}"`):t.kind===`range`?dk(t.min,t.max,`${n} stepper "${e}"`):lk(t.allowed,`${n} "${e}"`,pk(n))}function hk(e,t=`state`){let n=new Map;for(let{key:t,spec:r}of e){let e=n.get(t);e?e.push(r):n.set(t,[r])}return[...n].map(([e,n])=>({key:e,spec:fk(e,n,t)}))}function gk(e,t=`state`){let n=new Map(Object.entries(e).map(([e,t])=>[e,{validator:t,permanent:!0}]));function r(){let e=[];for(let[t,r]of n)r.permanent&&e.push(t);return e}return{register(e,i){if(!e)throw Error(`register: key is required`);if(e.includes(`/`))throw Error(`register: key "${e}" contains "/" — the wire shape splits on "/" so a slash-bearing key cannot be addressed. Use a slash-free key.`);let a=n.get(e);if(a){if(a.permanent)throw Error(`register: key "${e}" is a built-in ${t} key and cannot be re-claimed (built-in keys: ${[...r()].join(`, `)})`);let n=fk(e,[...a.specs,i],t);a.specs.push(i),a.merged=n,a.validator=mk(e,n,t)}else{let r=fk(e,[i],t);n.set(e,{permanent:!1,specs:[i],merged:r,validator:mk(e,r,t)})}let o=!0;return()=>{if(!o)return;o=!1;let r=n.get(e);if(!r||r.permanent)return;let a=r.specs.indexOf(i);a>=0&&r.specs.splice(a,1),r.specs.length===0?n.delete(e):(r.merged=fk(e,r.specs,t),r.validator=mk(e,r.merged,t))}},validate(e,r){let i=n.get(e);return i?i.validator(r):{ok:!1,reason:`unknown ${t} key "${e}" (have: ${[...n.keys()].join(`, `)})`}},listKeys(){return[...n.keys()]},listBaselineKeys(){return r()},rangeParamsFor(e){let t=n.get(e);if(!t||t.permanent||t.merged.kind!==`range`)return null;let{min:r,max:i}=t.merged;return{min:r,max:i}}}}const _k=gk({},`config`);function vk(){return _k.listKeys()}function yk(e,t){return _k.validate(e,t)}function bk(e){return _k.rangeParamsFor(e)}function xk(e,t){return`persist`in e?`to`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[e.to]}}]:`from`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:Zb(e.from,t).members}}]:`cycle`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:e.cycle}}]:`removeSegment`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[ak({op:`remove`,target:e.removeSegment})]}}]:`insertSegment`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:[ak({op:`insert`,segment:e.insertSegment,anchor:e.anchor,relation:e.relation})]}}]:`insertSegmentFrom`in e?[{key:e.persist,spec:{kind:`allow-list`,allowed:Zb(e.insertSegmentFrom,t).members.map(t=>ak({op:`insert`,segment:t,anchor:e.anchor,relation:e.relation}))}}]:[{key:e.persist,spec:{kind:`range`,min:e.min,max:e.max}}]:[]}function Sk(e,t){let n=jl(e).get(t);return n===void 0?null:String(n)}function Ck(e){let t=new Set;for(let n of Object.values(e.actions)){`reset`in n&&t.add(n.reset);let e=`persist`in n?ox(n.persist):null;e?.scope===`preset-root`&&t.add(ix(e.preset))}return[...t].map(e=>({key:e,spec:{kind:`allow-list`,allowed:[]}}))}function wk(e){let t=new Map([...Yb(e),...xC(e)]);return[...Ck(e),...Object.values(e.actions).flatMap(e=>xk(e,t))]}function Tk(e){return hk(wk(e),`config`)}function Ek(e,t){return _k.register(e,t)}const Dk=Array.from({length:10},(e,t)=>(t+1)*1e5),Ok=Dk[0],kk=Dk[Dk.length-1];function Ak(e){let t;try{t=vD(e)}catch(e){return X(e instanceof Error?e.message:String(e))}let n=t.autoCompactWindow;return n===void 0?J(`auto`):typeof n==`number`&&Number.isInteger(n)&&n>=Ok&&n<=kk?J(n):X(`${e}: autoCompactWindow is ${JSON.stringify(n)}, not a window /autocompact accepts (${Ok}–${kk} tokens)`)}function jk(e,t){let n=Math.min(t??kk,kk),r=e===`auto`?n:Math.min(e,n);return{window:e===`auto`?0:e,applied:e===`auto`?0:r,lower:Dk.filter(e=>e<r).at(-1)??0,higher:Dk.find(e=>e>r&&e<=n)??0}}const Mk=Vx(`commands.`),Nk=`trimPrefix "/" (trimPrefix .project_dir .current_dir)`,Pk=`{{ \$dir := .current_dir }}{{ if and (ne .home "") (or (eq .home .current_dir) (hasPrefix (printf "%s/" .home) .current_dir)) }}{{ \$dir = printf "~%s" (trimPrefix .home .current_dir) }}{{ else }}{{ if or (eq .project_dir .current_dir) (hasPrefix (printf "%s/" .project_dir) .current_dir) }}{{ $dir = ternary (${Nk}) (basename .project_dir) (ne (${Nk}) "") }}{{ end }}{{ end }}{{ abbreviatePath \$dir }}`,Fk=`{{ ${yx} }}`,Ik={min:0,max:100,step:5},Lk={warnAt:{label:`warning at %`,domain:Ik,default:50},errorAt:{label:`error at %`,domain:{...Ik,atLeast:`warnAt`},default:80}};function Rk(e){return{budget:{label:`budget $`,domain:{min:0,max:1e4,step:5},default:e},warnAt:{label:`warning at %`,domain:Ik,default:80}}}const zk={globals:{palette:`tokyo-night`},variables:{...Mk.variables,...Db,current_dir:{kind:`input`,path:`workspace.current_dir`,default:`?`},"model.display_name":{kind:`input`,path:`model.display_name`,default:``},version:{kind:`input`,path:`version`,default:``},home:{kind:`input`,path:`home`,default:``},"tmux.session":{kind:`input`,path:`tmux.session`,default:``},"host.name":{kind:`input`,path:`host.name`,default:``},"host.user":{kind:`input`,path:`host.user`,default:``},"host.ssh":{kind:`input`,path:`host.ssh`,type:`boolean`,default:!1},"git.repoName":{kind:`input`,path:`git.repoName`,default:``},"git.branch":{kind:`input`,path:`git.branch`,default:``},"git.sha":{kind:`input`,path:`git.sha`,default:``},"git.ahead":{kind:`input`,path:`git.ahead`,type:`number`,default:0},"git.behind":{kind:`input`,path:`git.behind`,type:`number`,default:0},"git.staged":{kind:`input`,path:`git.staged`,type:`number`,default:0},"git.unstaged":{kind:`input`,path:`git.unstaged`,type:`number`,default:0},"git.untracked":{kind:`input`,path:`git.untracked`,type:`number`,default:0},"git.conflicts":{kind:`input`,path:`git.conflicts`,type:`number`,default:0},"git.upstream":{kind:`input`,path:`git.upstream`,default:``},"git.stash":{kind:`input`,path:`git.stash`,type:`number`,default:0},"git.status":{kind:`input`,path:`git.status`,default:`clean`},"git.operation":{kind:`input`,path:`git.operation`,default:``},"git.timeSinceCommit":{kind:`input`,path:`git.timeSinceCommit`,type:`number`,default:0},"git.color.branch":{kind:`literal`,value:`primary`},"git.color.staged":{kind:`literal`,value:`success`},"git.color.unstaged":{kind:`literal`,value:`warning`},"git.color.untracked":{kind:`literal`,value:`accent`},"git.color.conflicts":{kind:`literal`,value:`error`},"git.color.ahead":{kind:`literal`,value:`success`},"git.color.behind":{kind:`literal`,value:`warning`},"git.color.stash":{kind:`literal`,value:`accent`},"git.detail":{kind:`state`,key:`git-detail`,default:`collapsed`},"git.prNumber":{kind:`input`,path:`git.prNumber`,type:`number`,default:0},"git.prState":{kind:`input`,path:`git.prState`,default:``},"git.prUrl":{kind:`input`,path:`git.prUrl`,default:``},"git.prError":{kind:`input`,path:`git.prError`,default:``},"cache.expiresAt":{kind:`input`,path:`cache.expiresAt`,type:`number`,default:0},"session.cost":{kind:`input`,path:`session.cost`,type:`number`,default:0},"session.tokens":{kind:`input`,path:`session.tokens`,type:`number`,default:0},"today.cost":{kind:`input`,path:`today.cost`,type:`number`,default:0},"today.tokens":{kind:`input`,path:`today.tokens`,type:`number`,default:0},"block.nativeUtilization":{kind:`input`,path:`block.nativeUtilization`,type:`number`,default:0},"block.resetsAt":{kind:`input`,path:`block.resetsAt`,type:`number`,default:0},"weekly.percentage":{kind:`input`,path:`weekly.percentage`,type:`number`,default:0},"weekly.resetsAt":{kind:`input`,path:`weekly.resetsAt`,type:`number`,default:0},"burn.costPerHour":{kind:`input`,path:`burn.costPerHour`,type:`number`,default:-1},"block.etaMinutes":{kind:`input`,path:`block.etaMinutes`,type:`number`,default:-1},"weekly.etaMinutes":{kind:`input`,path:`weekly.etaMinutes`,type:`number`,default:-1},"speed.input":{kind:`input`,path:`speed.input`,type:`number`,default:-1},"speed.output":{kind:`input`,path:`speed.output`,type:`number`,default:-1},"speed.total":{kind:`input`,path:`speed.total`,type:`number`,default:-1},"speed.history":{kind:`input`,path:`speed.history`,type:`string`,default:``},"context.totalTokens":{kind:`input`,path:`context.totalTokens`,type:`number`,default:0},"context.contextLeft":{kind:`input`,path:`context.contextLeft`,type:`number`,default:100},"memento.ceiling":{kind:`input`,path:`memento.ceiling`,type:`number`,default:-1},"memento.off":{kind:`input`,path:`memento.off`,type:`boolean`,default:!1},"memento.session":{kind:`input`,path:`memento.session`,default:``},"memento.error":{kind:`input`,path:`memento.error`,default:``},"autocompact.window":{kind:`input`,path:`autocompact.window`,type:`number`,default:-1},...Object.fromEntries([`applied`,`lower`,`higher`].map(e=>[`autocompact.${e}`,{kind:`input`,path:`autocompact.${e}`,type:`number`,default:0}])),"autocompact.error":{kind:`input`,path:`autocompact.error`,default:``},"metrics.lastResponseTime":{kind:`input`,path:`metrics.lastResponseTime`,type:`number`,default:0},"metrics.responseTime":{kind:`input`,path:`metrics.responseTime`,type:`number`,default:0},"metrics.sessionDuration":{kind:`input`,path:`metrics.sessionDuration`,type:`number`,default:0},"metrics.messageCount":{kind:`input`,path:`metrics.messageCount`,type:`number`,default:0},"metrics.linesAdded":{kind:`input`,path:`metrics.linesAdded`,type:`number`,default:0},"metrics.linesRemoved":{kind:`input`,path:`metrics.linesRemoved`,type:`number`,default:0},"activity.command":{kind:`input`,path:`activity.command`,type:`string`,default:``},"activity.todo.total":{kind:`input`,path:`activity.todo.total`,type:`number`,default:0},"activity.todo.completed":{kind:`input`,path:`activity.todo.completed`,type:`number`,default:0},"activity.todo.position":{kind:`input`,path:`activity.todo.position`,type:`number`,default:0},"activity.todo.active":{kind:`input`,path:`activity.todo.active`,type:`string`,default:``},"activity.tool.running":{kind:`input`,path:`activity.tool.running`,type:`string`,default:``},"activity.tool.done":{kind:`input`,path:`activity.tool.done`,type:`string`,default:``}},segments:{directory:{group:`location`,description:"The current directory, shortened fish-style — `~` under home, project-relative inside the project.",template:Pk},model:{group:`model-context`,description:`The active model's display name.`,template:`✱ {{ formatModelName .model.display_name }}`,when:`{{ ne .model.display_name "" }}`},sessionId:{group:`session-tools`,description:`The session id, truncated to 8 characters.`,template:`⌗{{ trunc 8 .session.id }}`,when:`{{ ne .session.id "" }}`},version:{group:`model-context`,description:`The Claude Code version reported in the hook payload.`,template:`◈ v{{ .version }}`,when:`{{ ne .version "" }}`},tmux:{group:`location`,description:`The tmux session name; hidden when not inside tmux.`,template:`tmux:{{ .tmux.session | default "none" }}`,when:`{{ ne .tmux.session "" }}`},host:{group:`location`,description:`user@host on a warning background, shown only over SSH.`,template:`⇄ {{ .host.user | default "?" }}@{{ .host.name | default "?" }}`,bg:`warning`,when:`{{ .host.ssh }}`},gitaculous:{group:`git`,description:`The git state: a summary (branch, ahead/behind, S/U/? flags) that the arrow at its right edge expands to every fact — repo, in-progress operation, sha, upstream ±, stash count, time since the last commit.`,template:`{{ if eq .git.detail "expanded" }}{{ template "gitExpanded" . }}{{ else }}{{ template "gitCollapsed" . }}{{ end }} {{ action "gitDetail" "▸" "◂" }}`,fg:Fk,when:`{{ ne .git.branch "" }}`,settings:{aheadBehind:{label:`ahead/behind`,domain:`bool`,default:!0},flags:{label:`dirty flags`,domain:`bool`,default:!0},operation:{label:`operation`,domain:`bool`,default:!0},repo:{label:`repo name`,domain:`bool`,default:!0},sha:{label:`commit hash`,domain:`bool`,default:!0},stash:{label:`stash`,domain:`bool`,default:!0},upstream:{label:`upstream`,domain:`bool`,default:!0},age:{label:`time since commit`,domain:`bool`,default:!0}}},gitPr:{group:`git`,description:"The pull request open for this branch, as a link; `⚠ PR` when the forge lookup failed.",template:`{{ if ne .git.prUrl "" }}{{ link .git.prUrl (printf "⇆ #%v" .git.prNumber) }}{{ else }}⚠ PR{{ end }}`,when:`{{ or (ne .git.prUrl "") (ne .git.prError "") }}`},toolbar:{group:`session-tools`,description:`Quick actions: copy the session id, and open the project, transcript or repo.`,template:Ax(``).template},commands:{group:`session-tools`,description:`Type /compact, /model or /clear into this session; /clear asks for a second click.`,template:Mk.template},themeSwitcher:{group:`session-tools`,description:"`◀ <theme> ▶`: the theme the bar is wearing; ◀ and ▶ switch this session to the previous or next theme, wrapping at the ends.",template:`{{ carousel "stepTheme" 0 }}`},session:{group:`cost-limits`,description:`This session's cost and token total, with a budget warning once a budget is configured.`,template:`§ {{ template "formatCost" .session.cost }} ({{ template "formatTokens" .session.tokens }}){{ template "budgetStatus" (dict "cost" .session.cost "budget" .settings.budget "warn" .settings.warnAt) }}`,settings:Rk(0)},today:{group:`cost-limits`,description:`Today's cost and tokens across every session, with a budget warning once a budget is configured.`,template:`☉ {{ template "formatCost" .today.cost }} ({{ template "formatTokens" .today.tokens }}){{ template "budgetStatus" (dict "cost" .today.cost "budget" .settings.budget "warn" .settings.warnAt) }}`,settings:Rk(50)},block:{group:`cost-limits`,description:`The 5-hour rate-limit block: percent used and time to reset, heating to warning then error.`,template:`◱ {{ round .block.nativeUtilization }}% ({{ template "formatResetCountdown" .block.resetsAt }})`,bg:`{{ ramp (round .block.nativeUtilization) "step" 0 (tint) .settings.warnAt "warning" .settings.errorAt "error" }}`,settings:Lk,when:`{{ gt .block.resetsAt 0 }}`},weekly:{group:`cost-limits`,description:`The weekly rate-limit quota: percent used and time to reset, heating to warning then error.`,template:`◑ {{ round .weekly.percentage }}% ({{ template "formatResetCountdown" .weekly.resetsAt }})`,bg:`{{ ramp (round .weekly.percentage) "step" 0 (tint) .settings.warnAt "warning" .settings.errorAt "error" }}`,settings:Lk,when:`{{ gt .weekly.resetsAt 0 }}`},burnrate:{group:`cost-limits`,description:`Spend per hour, with the projected time to the 5-hour and weekly limits.`,template:`⚡ {{ template "formatRate" .burn.costPerHour }} · {{ template "formatEta" .block.etaMinutes }} to 5h · {{ template "formatEta" .weekly.etaMinutes }} to wk`,bg:`{{ ramp .block.etaMinutes "step" -1 (tint) 0 "error" .settings.errorWithin "warning" .settings.warnWithin (tint) }}`,settings:{errorWithin:{label:`error within (min)`,domain:{min:0,max:300,step:5},default:30},warnWithin:{label:`warning within (min)`,domain:{min:0,max:300,step:5,atLeast:`errorWithin`},default:60}},when:`{{ or (gt .block.resetsAt 0) (gt .weekly.resetsAt 0) }}`},speed:{group:`activity`,description:`Token throughput for the latest exchange: output, input, and total.`,template:`⇅ out {{ template "formatSpeed" .speed.output }} · in {{ template "formatSpeed" .speed.input }} · tot {{ template "formatSpeed" .speed.total }}`,when:`{{ gt .session.tokens 0 }}`},tokenSparkline:{group:`activity`,description:`A sparkline of recent token throughput.`,template:`⚡ {{ sparkline .speed.history 24 }}`,when:`{{ ne .speed.history "" }}`},cacheTimer:{group:`activity`,description:"Minutes until the prompt cache expires, or `cold` once it has.",template:`◴ {{ if le (minutesUntilReset .cache.expiresAt) 0 }}cold{{ else }}{{ minutesUntilReset .cache.expiresAt }}m{{ end }}`,fg:`{{ readableOn (color (cascade (minutesUntilReset .cache.expiresAt) "0:error" "9:warning" "21:foreground")) (bgOf) ${wa} }}`,when:`{{ gt .cache.expiresAt 0 }}`},context:{group:`model-context`,description:`Context used, in tokens and percent remaining, heating as it fills.`,template:`◔ {{ formatInteger .context.totalTokens }} ({{ .context.contextLeft }}%)`,bg:`{{ ramp .context.contextLeft "step" 0 "error" 21 "warning" 41 (tint) }}`,when:`{{ gt .context.totalTokens 0 }}`},ceiling:{group:`model-context`,description:`The memento plugin's context ceiling for this session: − and + move it by 100K, ∞ lifts it, ↺ drops this session's own setting.`,template:`{{ if ne .memento.error "" }}⌈ ⚠ {{ .memento.error }} {{ action "ceiling.clear" "↺" }}{{ else }}⌈ {{ if .memento.off }}off{{ else }}{{ template "formatTokenCount" .memento.ceiling }} {{ action "ceiling.lower" "−" }} {{ action "ceiling.raise" "+" }} {{ action "ceiling.off" "∞" }}{{ end }}{{ if ne .memento.session "" }} {{ action "ceiling.clear" "↺" }}{{ end }}{{ end }}`,bg:`{{ if ne .memento.error "" }}{{ color "error" }}{{ else }}{{ tint }}{{ end }}`,when:`{{ or (ge .memento.ceiling 0) (ne .memento.error "") }}`},autocompact:{group:`model-context`,description:`Claude Code's auto-compact window: − and + move it by 100K, ↺ returns it to auto. Clicks type /autocompact into this session.`,template:`{{ if ne .autocompact.error "" }}⇲ ⚠ {{ .autocompact.error }}{{ else }}⇲ {{ if eq .autocompact.window 0 }}auto{{ else }}{{ template "formatTokenCount" .autocompact.applied }}{{ end }}{{ if gt .autocompact.lower 0 }} {{ action (printf "autocompact.%d" .autocompact.lower) "−" }}{{ end }}{{ if gt .autocompact.higher 0 }} {{ action (printf "autocompact.%d" .autocompact.higher) "+" }}{{ end }}{{ if gt .autocompact.window 0 }} {{ action "autocompact.auto" "↺" }}{{ end }}{{ end }}`,bg:`{{ if ne .autocompact.error "" }}{{ color "error" }}{{ else }}{{ tint }}{{ end }}`,when:`{{ or (ge .autocompact.window 0) (ne .autocompact.error "") }}`},metrics:{group:`activity`,description:`Response times, session duration, message count, and lines added/removed.`,template:`{{ if .metrics.lastResponseTime }} Δ {{ template "formatResponseTime" .metrics.lastResponseTime }}{{ end }}{{ if .metrics.responseTime }} ⧖ {{ template "formatResponseTime" .metrics.responseTime }}{{ end }}{{ if .metrics.sessionDuration }} ⧗ {{ template "formatDuration" .metrics.sessionDuration }}{{ end }}{{ if .metrics.messageCount }} ◆ {{ .metrics.messageCount }}{{ end }}{{ if .metrics.linesAdded }} + {{ .metrics.linesAdded }}{{ end }}{{ if .metrics.linesRemoved }} - {{ .metrics.linesRemoved }}{{ end }} `,when:`{{ or (gt .metrics.lastResponseTime 0.0) (gt .metrics.responseTime 0.0) (gt .metrics.sessionDuration 0.0) (gt .metrics.messageCount 0) (gt .metrics.linesAdded 0) (gt .metrics.linesRemoved 0) }}`},activity:{group:`activity`,description:`What Claude is doing: the slash command that opened the turn, the in-progress todo, and the tools in flight.`,template:`{{ if .activity.command }} ⌘ {{ .activity.command }}{{ end }}{{ if .activity.todo.total }}{{ if .activity.todo.active }} ☐ {{ .activity.todo.position }}/{{ .activity.todo.total }} {{ abbrev 32 .activity.todo.active }}{{ else }} ☑ {{ .activity.todo.completed }}/{{ .activity.todo.total }}{{ end }}{{ end }}{{ if .activity.tool.running }} ⟳ {{ template "formatToolTally" .activity.tool.running }}{{ end }}{{ if .activity.tool.done }} ✓ {{ template "formatToolTally" .activity.tool.done }}{{ end }} `,when:`{{ or (ne .activity.command "") (gt .activity.todo.total 0) (ne .activity.tool.running "") (ne .activity.tool.done "") }}`}},root:{rows:{identity:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`}]},status:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`activity`}]}}},actions:{...Ax(``).actions,...Mk.actions,copyDir:{copy:`{{ .current_dir }}`},stepTheme:{set:`theme`,from:`themes`},gitDetail:{set:`git-detail`,cycle:[`collapsed`,`expanded`]},"ceiling.raise":{ceiling:`set`,to:`+100_000`},"ceiling.lower":{ceiling:`set`,to:`-100_000`},"ceiling.off":{ceiling:`set`,to:`off`},"ceiling.clear":{ceiling:`clear`},"autocompact.auto":{slash:Rx(`/autocompact auto`)},...Object.fromEntries(Dk.map(e=>[`autocompact.${e}`,{slash:Rx(`/autocompact ${e}`)}]))},styles:{none:{hueShift:0,chromaScale:1,lightnessScale:1,lightnessShift:0},vivid:{hueShift:0,chromaScale:1.35,lightnessScale:1,lightnessShift:0},muted:{hueShift:0,chromaScale:.55,lightnessScale:1,lightnessShift:0},dim:{hueShift:0,chromaScale:1,lightnessScale:.85,lightnessShift:0},bright:{hueShift:0,chromaScale:1,lightnessScale:1,lightnessShift:.08},inverted:{hueShift:0,chromaScale:1,lightnessScale:-1,lightnessShift:1}},presets:{default:{},compact:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`context`}]},globals:{padding:0}},verbose:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`gitPr`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`burnrate`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`speed`},{kind:`segment`,name:`tokenSparkline`}]}]}},zen:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`directory`},{kind:`segment`,name:`context`}]},globals:{endcaps:`plain`,style:`dim`}},git:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`gitPr`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`segment`,name:`context`},{kind:`segment`,name:`activity`}]}]}},usage:{root:{kind:`container`,direction:`vertical`,children:[{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`burnrate`}]},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`session`},{kind:`segment`,name:`today`},{kind:`segment`,name:`speed`},{kind:`segment`,name:`tokenSparkline`}]}]}},dense:{root:{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`host`},{kind:`segment`,name:`directory`},{kind:`segment`,name:`gitaculous`},{kind:`segment`,name:`model`},{kind:`container`,direction:`horizontal`,children:[{kind:`segment`,name:`context`},{kind:`segment`,name:`ceiling`},{kind:`segment`,name:`autocompact`}]},{kind:`segment`,name:`cacheTimer`},{kind:`segment`,name:`block`},{kind:`segment`,name:`weekly`},{kind:`segment`,name:`session`},{kind:`segment`,name:`activity`}]},globals:{padding:0}}},editGlobals:{endcaps:`plain`,default_separator:` | `},helpers:{gitPaint:`{{ fg (readableOn (color .color) (bgOf) ${wa}) .text }}`,gitCollapsed:`{{ template "gitBranch" . }}{{ template "gitAheadBehind" . }}{{ template "gitFlags" . }}`,gitExpanded:`(git){{ template "gitRepo" . }}{{ template "gitOperation" . }}{{ template "gitSha" . }}{{ template "gitFlags" . }} {{ template "gitBranch" . }}{{ template "gitUpstream" . }}{{ template "gitStash" . }}{{ template "gitAge" . }}`,gitBranch:`⎇ {{ template "gitPaint" (dict "color" .git.color.branch "text" .git.branch) }}`,gitRepo:`{{ if and .settings.repo (ne .git.repoName "") }} {{ .git.repoName }}{{ end }}`,gitOperation:`{{ if and .settings.operation (ne .git.operation "") }} [{{ .git.operation }}]{{ end }}`,gitSha:`{{ if and .settings.sha (ne .git.sha "") }} {{ .git.sha }}{{ end }}`,gitFlags:`{{ if and .settings.flags (or (gt .git.staged 0) (gt .git.unstaged 0) (gt .git.untracked 0) (gt .git.conflicts 0)) }} {{ if gt .git.staged 0 }}{{ template "gitPaint" (dict "color" .git.color.staged "text" "S") }}{{ end }}{{ if gt .git.unstaged 0 }}{{ template "gitPaint" (dict "color" .git.color.unstaged "text" "U") }}{{ end }}{{ if gt .git.untracked 0 }}{{ template "gitPaint" (dict "color" .git.color.untracked "text" "?") }}{{ end }}{{ if gt .git.conflicts 0 }}{{ template "gitPaint" (dict "color" .git.color.conflicts "text" (printf "!%v" .git.conflicts)) }}{{ end }}{{ end }}`,gitAheadBehind:`{{ if and .settings.aheadBehind (or (gt .git.ahead 0) (gt .git.behind 0)) }} {{ if gt .git.ahead 0 }}{{ template "gitPaint" (dict "color" .git.color.ahead "text" (printf "+%v" .git.ahead)) }}{{ end }}{{ if and (gt .git.ahead 0) (gt .git.behind 0) }}/{{ end }}{{ if gt .git.behind 0 }}{{ template "gitPaint" (dict "color" .git.color.behind "text" (printf "-%v" .git.behind)) }}{{ end }}{{ end }}`,gitUpstream:`{{ if and .settings.upstream (ne .git.upstream "") }} [{{ .git.upstream }}{{ template "gitAheadBehind" . }}]{{ end }}`,gitStash:`{{ if and .settings.stash (gt .git.stash 0) }} {{ template "gitPaint" (dict "color" .git.color.stash "text" (printf "(%v stashed)" .git.stash)) }}{{ end }}`,gitAge:`{{ if and .settings.age (gt .git.timeSinceCommit 0) }} ◷ {{ template "formatTimeSince" .git.timeSinceCommit }}{{ end }}`,formatCost:'{{ if lt . 0.01 }}<$0.01{{ else }}${{ printf "%.2f" . }}{{ end }}',formatTokenCount:`{{ if ge . 1000000 }}{{ printf "%.1f" (divf . 1000000) }}M{{ else if ge . 1000 }}{{ printf "%.1f" (divf . 1000) }}K{{ else }}{{ . }}{{ end }}`,formatTokens:`{{ template "formatTokenCount" . }} tokens`,formatToolTally:`{{ $names := splitList "," . }}{{ range $i, $pair := $names }}{{ if lt $i 2 }}{{ if $i }} {{ end }}{{ $kv := splitList ":" $pair }}{{ index $kv 0 }}{{ if ne (index $kv 1) "1" }}×{{ index $kv 1 }}{{ end }}{{ end }}{{ end }}{{ if gt (len $names) 2 }} +{{ sub (len $names) 2 }}{{ end }}`,formatRate:`{{ if lt . 0 }}—/hr{{ else }}{{ template "formatCost" . }}/hr{{ end }}`,formatEta:`{{ if lt . 0 }}—{{ else }}{{ template "formatLongTimeRemaining" . }}{{ end }}`,formatSpeed:`{{ if lt . 0 }}—{{ else }}{{ template "formatTokenCount" (round .) }}/s{{ end }}`,formatTokenBreakdown:`{{ $first := true }}{{ if gt .input 0 }}{{ template "formatTokenCount" .input }} in{{ $first = false }}{{ end }}{{ if gt .output 0 }}{{ if not $first }} + {{ end }}{{ template "formatTokenCount" .output }} out{{ $first = false }}{{ end }}{{ if or (gt .cacheCreation 0) (gt .cacheRead 0) }}{{ if not $first }} + {{ end }}{{ template "formatTokenCount" (add .cacheCreation .cacheRead) }} cached{{ $first = false }}{{ end }}{{ if $first }}0 tokens{{ end }}`,budgetStatus:`{{ if or (le .budget 0) (lt .cost 0) }}{{ else }}{{ $pct := minf 100 (mulf (divf .cost .budget) 100) }}{{ $p := printf "%.0f%%" $pct }}{{ if ge $pct .warn }} !{{ $p }}{{ else }}{{ if ge $pct 50 }} +{{ $p }}{{ else }} {{ $p }}{{ end }}{{ end }}{{ end }}`,formatTimeSince:`{{ if lt . 60 }}{{ . }}s{{ else if lt . 3600 }}{{ div . 60 }}m{{ else if lt . 86400 }}{{ div . 3600 }}h{{ else if lt . 604800 }}{{ div . 86400 }}d{{ else }}{{ div . 604800 }}w{{ end }}`,formatDuration:`{{ if lt . 60 }}{{ printf "%.0f" . }}s{{ else if lt . 3600 }}{{ printf "%.0f" (divf . 60) }}m{{ else if lt . 86400 }}{{ printf "%.1f" (divf . 3600) }}h{{ else }}{{ printf "%.1f" (divf . 86400) }}d{{ end }}`,formatResponseTime:`{{ if lt . 60 }}{{ printf "%.1f" . }}s{{ else }}{{ printf "%.1f" (divf . 60) }}m{{ end }}`,formatLongTimeRemaining:`{{ if ge . 1440 }}{{ $d := div . 1440 }}{{ $h := div (mod . 1440) 60 }}{{ if gt $h 0 }}{{ $d }}d {{ $h }}h{{ else }}{{ $d }}d{{ end }}{{ else if ge . 60 }}{{ $h := div . 60 }}{{ $m := mod . 60 }}{{ if gt $m 0 }}{{ $h }}h {{ $m }}m{{ else }}{{ $h }}h{{ end }}{{ else }}{{ . }}m{{ end }}`,formatResetCountdown:`{{ template "formatLongTimeRemaining" (add 1 (minutesUntilReset .)) }}`}},Bk=new Set([zk.globals.palette,...Object.values(zk.segments).map(e=>e.palette)].filter(e=>e!==void 0)),Vk=Bc(yT(`<default>`,JSON.stringify(zk),Bk),zk),Hk=T_(Vk.presets);function Uk(e){return Hk.includes(e)}function Wk(e){if(!e)return 0;try{return o(e).mtimeMs}catch{return 0}}const Gk=new class{slots;head=null;tail=null;constructor(e){this.slots=e}async run(e){await this.acquire();try{return await e()}finally{this.release()}}async acquire(){if(this.slots>0){this.slots--;return}await new Promise(e=>{let t={wake:e,next:null};this.tail?this.tail.next=t:this.head=t,this.tail=t})}release(){let e=this.head;if(!e){this.slots++;return}this.head=e.next,this.head||(this.tail=null),e.wake()}}(8);function Kk(e){return((...t)=>Gk.run(()=>e(...t)))}const qk=Kk(S),Jk=Kk(x),Yk=Kk(C);async function Xk(e,t){return Gk.run(async()=>{let n=null;try{n=await b(e,`r`);let{size:r,mtimeMs:i,ino:a}=await n.stat(),o=t!==void 0&&(a!==t.ino||r<t.offset),s=o||t===void 0?0:t.offset;if(s>=r)return J({buf:Buffer.alloc(0),start:s,size:r,mtimeMs:i,ino:a,reset:o});let c=Buffer.alloc(r-s),l=0;for(;l<c.length;){let{bytesRead:e}=await n.read(c,l,c.length-l,s+l);if(e===0)break;l+=e}return J({buf:l===c.length?c:c.subarray(0,l),start:s,size:r,mtimeMs:i,ino:a,reset:o})}catch(t){return t.code===`ENOENT`?Y:X(`readAppended ${e}: ${t instanceof Error?t.message:String(t)}`)}finally{await n?.close().catch(e=>{O(`transcript-fs: close failed: ${e instanceof Error?e.message:String(e)}`)})}})}async function Zk(e,t){return Gk.run(async()=>{let n=null;try{n=await b(e,`r`);let{size:r}=await n.stat(),i=Math.max(0,r-t),a=Buffer.alloc(r-i),o=0;for(;o<a.length;){let{bytesRead:e}=await n.read(a,o,a.length-o,i+o);if(e===0)break;o+=e}return J({buf:o===a.length?a:a.subarray(0,o),fromStart:i===0})}catch(t){return t.code===`ENOENT`?Y:X(`readTail ${e}: ${t instanceof Error?t.message:String(t)}`)}finally{await n?.close().catch(e=>{O(`transcript-fs: close failed: ${e instanceof Error?e.message:String(e)}`)})}})}const Qk=/"(?:cache_read_input_tokens|cache_creation_input_tokens)":[1-9]/;function $k(e){let t;try{t=JSON.parse(e)}catch{return null}let n=t.message?.usage;if(!((n?.cache_read_input_tokens??0)>0||(n?.cache_creation_input_tokens??0)>0))return null;let r=t.timestamp==null?NaN:Date.parse(t.timestamp);return Number.isNaN(r)?null:r}async function eA(e){let t=await tA(e);return t.kind===`ok`?J(Math.floor((t.value+36e5)/1e3)):t}async function tA(e){for(let t of[65536,1048576]){let n=await Zk(e,t);if(n.kind!==`ok`)return n;let r=nA(n.value.buf,n.value.fromStart);if(r!=null)return J(r);if(n.value.fromStart)return Y}return Y}function nA(e,t){let n=e.toString(`utf8`).split(`
|
|
177
177
|
`),r=+!t;for(let e=n.length-1;e>=r;e--){let t=n[e];if(!t||!Qk.test(t))continue;let r=$k(t);if(r!=null)return r}return null}function rA(e,t,n){let r=E_(t(`preset`),e.globals.preset,e.presets),i=k_(e,r),a=t(`edit.mode`)===`arrange`?e.editGlobals:{};return{preset:r,presetCustomized:n(r),theme:Ub(a.palette,t(`theme`),i.palette),style:ao(a.style,t(`style`),i.style,e.styles),endcaps:co(a.endcaps,t(`endcaps`),i.endcaps),variation:xo(a.variation,t(`variation`),i.variation),separator:a.default_separator??i.default_separator,autoWrap:Oo(a.autoWrap,t(`autoWrap`),i.autoWrap),padding:Ao(a.padding,t(`padding`),i.padding),charset:po(a.charset,t(`charset`),i.charset),updateNotice:ko(a.updateNotice,t(`updateNotice`),i.updateNotice),colorCompatibility:_o(a.colorCompatibility,t(`colorCompatibility`),i.colorCompatibility)}}function iA(e,t){return{endcaps:e.endcaps,separator:e.separator,colorCompatibility:e.colorCompatibility,wrap:e.autoWrap,padding:e.padding,charset:e.charset,width:t}}function aA(e){return{theme:e.theme,style:e.style,preset:e.preset,variation:e.variation}}function oA(e){return{preset:{effective:e.preset,customized:e.presetCustomized,bundled:Uk(e.preset)},endcaps:{effective:e.endcaps},variation:{effective:e.variation},charset:{effective:e.charset},colorCompatibility:{effective:e.colorCompatibility},autoWrap:{effective:e.autoWrap},padding:{effective:e.padding},updateNotice:{effective:e.updateNotice}}}const sA=10*1e3;function cA(e,t,n,r){let i=n-(t*1e3-r);if(i<3e5||e<=0)return;let a=e/i,o=(100-e)/a;return Math.max(0,Math.round(o/6e4))}function lA(e,t){if(!(t<60))return e*3600/t}function uA(e,t,n,r){let i=r-t;if(i<50||i>sA)return;let a=n-e;if(!(a<=0))return a*1e3/i}function dA(e){let{prev:t,cur:n}=e;if(t===void 0)return;let r=uA(t.input,t.atMs,n.input,n.atMs),i=uA(t.output,t.atMs,n.output,n.atMs),a=uA(t.total,t.atMs,n.total,n.atMs);if(!(r===void 0&&i===void 0&&a===void 0))return{...r!==void 0&&{input:r},...i!==void 0&&{output:i},...a!==void 0&&{total:a}}}function fA(e){let{samples:t}=e,n=[];for(let e=1;e<t.length;e++){let r=t[e-1],i=t[e],a=i.atMs-r.atMs;if(a<50||a>sA)continue;let o=uA(r.total,r.atMs,i.total,i.atMs);n.push(o??0)}if(n.length!==0)return n.join(`,`)}function pA(e){let t=e.indexOf(`.`);return t<0?e:e.slice(0,t)}function mA(e){let t=[],n=(e,n)=>{try{let e=n();return e===``?void 0:e}catch(n){t.push(`host.${e}: ${String(n)}`);return}},r=n(`name`,()=>pA(p.hostname())),i=n(`user`,()=>p.userInfo().username);return{host:{...r!==void 0&&{name:r},...i!==void 0&&{user:i},...e.ssh!==void 0&&{ssh:e.ssh}},failures:t}}function hA(e,t){let n=new Map;for(let[t,r]of Object.entries(e.variables))n.set(t,r);for(let[t,r]of Object.entries(e.segments))if(r.vars)for(let[e,i]of Object.entries(r.vars))n.set(`${t}.${e}`,i);let r=[],i=new Set,a=t=>hv(t,e.helpers).keys(),o=k_(e,t);for(let e of Qa){let t=o[e];if($a(t))for(let e of a(t))r.push(e)}for(let n of Ms(O_(e,t).node)){if(n.when)for(let e of a(n.when))r.push(e);if(n.kind!==`segment`)continue;let t=e.segments[n.name];if(t){for(let e of[t.template,t.when,t.bg,t.fg])if(e)for(let t of a(e))r.push(t)}}let s=new Set;for(;r.length>0;){let e=r.pop();for(let t of _A(n,e)){if(i.has(t))continue;i.add(t);let e=n.get(t);if(e){if(e.kind===`input`)s.add(e.path);else if(e.kind===`template`)for(let t of a(e.template))r.push(t)}}}return s}function gA(e){let t=new Map;return n=>{let r=t.get(n);if(r!==void 0)return r;let i=hA(e,n);return t.set(n,i),i}}function _A(e,t){let n=t;for(;n.length>0;){if(e.has(n))return[n];let t=n.lastIndexOf(`.`);if(t<0)break;n=n.slice(0,t)}let r=`${t}.`,i=[];for(let t of e.keys())t.startsWith(r)&&i.push(t);return i}function vA(e,t){for(let n of e)if(n===t||n.startsWith(t+`.`))return!0;return!1}function yA(e){let t=t=>e.has(t),n=t(`git.staged`)||t(`git.unstaged`)||t(`git.untracked`)||t(`git.conflicts`);return{...t(`git.sha`)&&{showSha:!0},...n&&{showWorkingTree:!0},...t(`git.stash`)&&{showStashCount:!0},...t(`git.upstream`)&&{showUpstream:!0},...t(`git.repoName`)&&{showRepoName:!0},...t(`git.repoUrl`)&&{showRepoUrl:!0},...t(`git.operation`)&&{showOperation:!0},...t(`git.timeSinceCommit`)&&{showTimeSinceCommit:!0},...(t(`git.prNumber`)||t(`git.prState`)||t(`git.prUrl`)||t(`git.prError`))&&{showPullRequest:!0}}}async function bA(e,t,n,r,i,a,o){let s=e=>vA(r,e),c=(t.clock??(()=>new Date))().getTime(),l=(e,t,n)=>t?n().catch(t=>X(`${e}: ${String(t)}`)):Promise.resolve(Y),[u,d,f,p,m,h,g,_,v,y,b]=await Promise.all([l(`git`,s(`git`),()=>t.gitProvider.getGitInfo(n??e.workspace?.current_dir,yA(r),e.workspace?.project_dir)),l(`session`,s(`session.cost`)||s(`session.tokens`)||s(`burn`),()=>t.usageStore.getUsageInfo(e.session_id,e)),l(`today`,s(`today`),()=>t.usageStore.getTodayInfo(e)),l(`context`,s(`context`)||s(`autocompact`),()=>t.contextProvider.getContextInfo(e)),l(`metrics`,s(`metrics`)||s(`burn`),()=>t.metricsProvider.getMetricsInfo(e.session_id,e)),l(`activity`,s(`activity`),()=>t.activityProvider.getActivityInfo(e.session_id,e)),l(`tmux`,s(`tmux`),()=>t.tmuxService.getSessionId()),l(`cache`,s(`cache`),()=>eA(e.transcript_path)),l(`speed`,s(`speed`),()=>t.usageStore.observeSpeed(e.session_id,e.transcript_path,c)),l(`memento`,s(`memento`),()=>t.mementoProvider.getCeiling({sessionId:e.session_id,projectDir:e.workspace?.project_dir??``,cwd:n??e.workspace?.current_dir??``})),l(`autocompact`,s(`autocompact`),()=>Promise.resolve(t.autoCompact(hD(mD(a.claudeConfigDir)))))]),x=[],S=e=>{if(e.kind===`failed`){x.push(e.reason);return}return e.kind===`ok`?e.value:void 0},C=OA(u);x.push(...C.failures);let ee=mA(a);x.push(...ee.failures);let te=S(d),ne=S(f),re=S(p),w=S(m),ie=S(h),T=S(g),E=S(_),ae=CA(y);y.kind===`failed`&&x.push(`memento: ${y.reason}`);let oe=xA(b,re?.maxTokens);b.kind===`failed`&&x.push(`autocompact: ${b.reason}`);for(let e of x)t.log(`warn`,`provider fetch failed: ${e}`);let D=e.rate_limits?.five_hour,se=e.rate_limits?.seven_day,ce=D?cA(D.used_percentage,D.resets_at,18e6,c):void 0,le=se?cA(se.used_percentage,se.resets_at,6048e5,c):void 0,ue=te?.session.cost,de=w?.sessionDuration,fe=s(`burn`)&&ue!=null&&de!=null?lA(ue,de):void 0,pe=S(v),me=pe===void 0?void 0:dA(pe),he=pe===void 0?void 0:fA(pe),ge=me!==void 0||he!==void 0?{...me,...he!==void 0&&{history:he}}:void 0,O=DA(process.env.HOME??process.env.USERPROFILE),_e=e.workspace?{...e.workspace,current_dir:DA(e.workspace.current_dir)??``,project_dir:DA(e.workspace.project_dir)??``}:e.workspace,ve=te===void 0?void 0:EA({cost:te.session.cost,tokens:te.session.tokens}),ye=ne===void 0?void 0:{cost:ne.cost,tokens:ne.tokens},be=w===void 0?void 0:EA({lastResponseTime:w.lastResponseTime,responseTime:w.responseTime,sessionDuration:w.sessionDuration,messageCount:w.messageCount,linesAdded:w.linesAdded,linesRemoved:w.linesRemoved}),xe=ie===void 0?void 0:wA(ie);return{...e,..._e!==void 0&&{workspace:_e},...O!==void 0&&{home:O},...C.git!==void 0&&{git:C.git},...T!==void 0&&{tmux:{session:T}},host:ee.host,...oA(i),history:t.history(e.session_id),navigation:{back:t.navigation(e.session_id)},...o,...ve!==void 0&&{session:ve},...ye!==void 0&&{today:ye},...fe!==void 0&&{burn:{costPerHour:fe}},...ge!==void 0&&{speed:ge},...s(`block`)&&D!==void 0&&{block:{nativeUtilization:D.used_percentage,resetsAt:D.resets_at,...ce!==void 0&&{etaMinutes:ce}}},...se!==void 0&&{weekly:{percentage:se.used_percentage,resetsAt:se.resets_at,...le!==void 0&&{etaMinutes:le}}},...E!==void 0&&{cache:{expiresAt:E}},...re!==void 0&&{context:{totalTokens:re.totalTokens,contextLeft:re.contextLeftPercentage}},...be!==void 0&&{metrics:be},...xe!==void 0&&{activity:xe},...ae!==void 0&&{memento:ae},...oe!==void 0&&{autocompact:oe}}}function xA(e,t){switch(e.kind){case`absent`:return;case`failed`:return{error:e.reason};case`ok`:return jk(e.value,t)}}const SA=e=>e.trim().split(`
|
|
178
178
|
`).at(-1).trim();function CA(e){switch(e.kind){case`absent`:return;case`failed`:return{error:SA(e.reason)};case`ok`:{let{ceiling:t,session:n}=e.value;return{ceiling:t===`off`?0:t,off:t===`off`,session:n??``}}}}function wA(e){let t=e.todos.findIndex(e=>e.active),n=e.todos.length===0?void 0:{total:e.todos.length,completed:e.todos.filter(e=>e.done).length,...t>=0&&{position:t+1,active:e.todos[t].text}},r=TA(e.running),i=TA(e.done),a=r===void 0&&i===void 0?void 0:{...r!==void 0&&{running:r},...i!==void 0&&{done:i}};if(!(e.command===null&&n===void 0&&a===void 0))return{...e.command!==null&&{command:e.command},...n!==void 0&&{todo:n},...a!==void 0&&{tool:a}}}function TA(e){return e.length===0?void 0:e.map(e=>`${e.name}:${e.count}`).join(`,`)}function EA(e){let t={},n=!1;for(let r of Object.keys(e)){let i=e[r];i!=null&&(t[r]=i,n=!0)}return n?t:void 0}function DA(e){return e===void 0||e.length===0||c.sep!==`\\`?e:e.replace(/\\/g,`/`)}function OA(e){if(e.kind===`absent`)return{failures:[]};if(e.kind===`failed`)return{failures:[e.reason]};let t=e.value,n=[],r=(e,t)=>{if(!(t===void 0||t.kind===`absent`)){if(t.kind===`failed`){n.push(`git.${e}: ${t.reason}`);return}return t.value}},i=r(`aheadBehind`,t.aheadBehind),a=r(`sha`,t.sha),o=r(`operation`,t.operation),s=r(`timeSinceCommit`,t.timeSinceCommit),c=r(`stash`,t.stashCount),l=r(`upstream`,t.upstream),u=r(`repoName`,t.repoName),d=r(`repoUrl`,t.repoUrl),f=t.pullRequest,p={};return f?.kind===`ok`?(p.prNumber=f.value.number,p.prState=f.value.state,p.prUrl=f.value.url):f?.kind===`failed`&&(n.push(`git.pr: ${f.reason}`),p.prError=f.reason),{git:{branch:t.branch,status:t.status,...i!==void 0&&{ahead:i.ahead,behind:i.behind},...t.workingTree!==void 0&&{staged:t.workingTree.staged,unstaged:t.workingTree.unstaged,untracked:t.workingTree.untracked,conflicts:t.workingTree.conflicts},...a!==void 0&&{sha:a},...o!==void 0&&{operation:o},...s!==void 0&&{timeSinceCommit:s},...c!==void 0&&{stash:c},...l!==void 0&&{upstream:l},...u!==void 0&&{repoName:u},...d!==void 0&&{repoUrl:d},...p},failures:n}}const kA={theme:e=>e.theme.kind===`decided`?e.theme.name:null,preset:e=>e.preset,style:e=>e.style.kind===`decided`?e.style.name:null,endcaps:e=>e.endcaps,variation:e=>e.variation,charset:e=>e.charset,colorCompatibility:e=>e.colorCompatibility,autoWrap:e=>e.autoWrap?So:Co,padding:e=>String(e.padding),updateNotice:e=>e.updateNotice?So:Co},AA=Object.entries(Ob),jA=new Set(kb.map(e=>e.sessionKey)),MA=()=>!1;function NA(e,t){return rA(e,e=>jA.has(e)?t(e):null,MA)}function PA(e,t,n,r){return e.flatMap(([e,i])=>{let a=kA[e](t);return a===null||a===kA[e](n(e))?[]:[{...i,value:a,target:r(i)}]})}function FA(e,t,n){return kA[n](NA(e,t))}function IA(e,t){let n=NA(e,t),r=rA(e,()=>null,MA),i=rA(e,e=>e===Ob.preset.sessionKey?n.preset:null,MA);return PA(AA,n,e=>e===`preset`?r:i,t=>LA(e,n.preset,t.configKey))}function LA(e,t,n){return n in(D_(e.presets,t).globals??{})?ax(t,n):n}function RA(e,t,n){let r=E_(t(Ob.preset.sessionKey),e.globals.preset,e.presets),i=ox(n);return{key:i?.scope===`globals`?LA(e,r,i.field):n,globals:k_(e,r)}}function zA(e,t){let{preset:n}=NA(e,t);return HA(e,n).flatMap(({id:e,setting:r,key:i,decl:a,saved:o})=>{let s=t(i),c=s===null?void 0:Js(a,s);return c===void 0||qs(c)===qs(o)?[]:[{preset:n,id:e,setting:r,key:i,value:c}]})}function BA(e,t,n){let r=new Map(n.map(e=>[e.key,e.value]));return T_(e.presets).flatMap(n=>{let i=HA(e,n);return[...new Set(i.filter(e=>r.has(e.key)).map(e=>e.id))].flatMap(e=>{let n=i.filter(t=>t.id===e);return Gs(Object.fromEntries(n.map(e=>[e.setting,e.decl])),Object.fromEntries(n.map(e=>{let n=r.get(e.key)??t(e.key),i=n===null?void 0:Js(e.decl,n);return[e.setting,i??e.saved]}))).map(({message:t})=>`placement "${e}": ${t}`)})})}const VA=new WeakMap;function HA(e,t){let n=VA.get(e)??new Map;VA.set(e,n);let r=n.get(t);if(r!==void 0)return r;let i=[...Ms(O_(e,t).node)].flatMap(t=>t.kind!==`segment`||t.drafts===void 0?[]:Object.entries(t.drafts).map(([n,{id:r,key:i}])=>{let a=Us(e.segments[t.name])[n];return{id:r,setting:n,key:i,decl:a,saved:t.settings?.[n]??a.default}})),a=[...new Map(i.map(e=>[e.key,e])).values()];return n.set(t,a),a}function UA(e,t){let n=NA(e,t),r=rA(e,e=>e===Ob.preset.sessionKey?n.preset:null,MA);return{from:n.preset,globals:D_(e.presets,n.preset).globals??{},picks:PA(AA.filter(([e])=>e!==`preset`),n,()=>r,e=>e.configKey),placements:zA(e,t)}}function WA(e){return{sessionKeys:kb.filter(t=>t.configKey===e).map(e=>e.sessionKey),fileKeys:[e,...xl(e)?Hk.map(t=>ax(t,e)):[]]}}function GA(e){return new Set(kb.map(e=>e.configKey).filter(t=>WA(t).fileKeys.some(t=>JA(e,qA(t)))))}function KA(e,t,n){let r=IA(e,n);return{unsaved:r.length+zA(e,n).length,resettable:new Set([...r.map(e=>e.configKey),...t]).size}}function qA(e){let t=ox(e);if(t===null||t.scope===`preset-root`)throw Error(`reset layer "${e}" is not a value path`);return sx(t)}function JA(e,t){let[n,...r]=t;return n===void 0?e!==void 0:typeof e==`object`&&!!e&&JA(e[n],r)}const YA=qa(),XA=new Set(YA),ZA=new Set(oo),QA=e=>e?XA.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown theme "${e}" (have: ${YA.join(`, `)})`}:{ok:!1,reason:`theme name is required`},$A=e=>e?ZA.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown endcaps "${e}" (have: ${oo.join(`, `)})`}:{ok:!1,reason:`endcaps name is required`},ej=new Set([`1`,`true`]),tj=new Set([`0`,`false`]),nj=gk({endcaps:$A,theme:QA,"toolbar-expanded":e=>ej.has(e)?{ok:!0,value:`1`}:tj.has(e)?{ok:!0,value:``}:{ok:!1,reason:`expected boolean-ish (1, 0, true, false), got "${e}"`}});function rj(){return nj.listKeys()}function ij(e,t){return nj.register(e,t)}function aj(e,t){return nj.validate(e,t)}function oj(e){return nj.rangeParamsFor(e)}function sj(e,t){return`set`in e?`to`in e?[{key:e.set,spec:{kind:`allow-list`,allowed:[e.to]}}]:`from`in e?[{key:e.set,spec:{kind:`allow-list`,allowed:Zb(e.from,t).members}}]:`int`in e?[{key:e.set,spec:{kind:`int`}}]:`cycle`in e?[{key:e.set,spec:{kind:`allow-list`,allowed:e.cycle}}]:[{key:e.set,spec:{kind:`range`,min:e.min,max:e.max}}]:[]}function cj(e){let t=new Set(nj.listBaselineKeys());return e.filter(e=>e.spec.kind!==`allow-list`||!t.has(e.key))}function lj(e,t,n){let r=Mb.get(n);if(r!==void 0)return FA(e,t,r);let i=Object.values(e.variables).find(e=>e.kind===`state`&&e.key===n);return i?.kind===`state`?i.default??null:null}function uj(e){let t=Yb(e);return cj(Object.values(e.actions).flatMap(e=>sj(e,t)))}function dj(e){return hk(uj(e))}const fj=`update.dismissed`,pj=`updateNotice`,mj=Ob.updateNotice.sessionKey;function hj(e){return e.kind===`source`?e.newer.digest:SD(e.newer)}const gj=e=>`${e.version} [${ek(e.digest)}]`;function _j(e){switch(e.kind){case`source`:return{headline:`Newer source`,newer:gj(e.newer),running:gj(e.running),act:`rebuild`,busy:`rebuilding…`,command:{bin:`pnpm`,args:[`build`],cwd:e.root}};case`release`:return{headline:`Newer release`,newer:SD(e.newer),running:SD(e.running),act:`upgrade`,busy:`upgrading…`,command:{bin:`pnpm`,args:[`dlx`,`${wD}@${SD(e.newer)}`,`install`]}}}}const vj={kind:`idle`},yj={kind:`running`};function bj(e,t,n){if(e===null)return[];let r=hj(e);if(!n.enabled||n.dismissed===r)return[];let i=_j(e),a=`${i.headline}: ${i.newer}. You're on ${i.running}.`,o=t.kind===`failed`&&t.identity===r?[`${i.act} failed: ${t.reason}`]:[],s=[a,...o].join(`
|
|
179
179
|
`),c=oD([{verb:VE,args:[s]}]),l=t.kind===`running`?HO(`[${i.busy}]`,c):HO(`[${i.act}]`,oD([{verb:$E,args:[n.sessionId]}]));return[{severity:VO,message:s,lines:[[HO(a,c),l,HO(`[dismiss]`,oD([{verb:FE,args:[n.sessionId,fj,r]}])),HO(`[disable]`,oD([{verb:HE,args:[n.sessionId,pj,`false`]},{verb:FE,args:[n.sessionId,mj,`false`]}]))],...o.map(e=>[HO(e,c)])]}]}function xj(e,t){return e.kind===`stale`?{kind:`source`,root:e.root,newer:e.source,running:e.running}:e.kind===`not-source-checkout`&&t!==null&&t.kind===`stale`?{kind:`release`,newer:t.latest,running:t.installed}:null}function Sj(e){switch(e.kind){case`current`:return[`info`,`build: current ${gj(e.stamp)}`];case`stale`:return[`info`,`build: stale — source ${gj(e.source)}, running ${gj(e.running)}`];case`not-source-checkout`:return[`info`,`build: not a source checkout`];case`unchecked`:return[`warn`,`build: unchecked: ${e.reason}`]}}function Cj(e){switch(e.kind){case`current`:return[`info`,`release: current ${SD(e.installed)}`];case`stale`:return[`info`,`release: stale — latest ${SD(e.latest)}, running ${SD(e.installed)}`];case`ahead`:return[`info`,`release: ahead — running ${SD(e.installed)}, latest ${SD(e.latest)}`];case`unchecked`:return[`warn`,`release: unchecked: ${e.reason}`]}}function wj(e){let t=null;return([n,r])=>{r!==t&&(t=r,e(n,r))}}const Tj=e=>e.split(/\r?\n/).map(e=>e.trim()).filter(e=>e!==``).at(-1);function Ej(e){let t=e.exitCode===null?``:` (exit ${e.exitCode})`,n=Tj(e.stderr)??e.error??Tj(e.stdout)??`no output`;return`${e.reason}${t}: ${n}`}function Dj(e){let{entryUrl:t,intervalMs:n,releaseIntervalMs:r,registryUrl:i,fetchImpl:a,onApplied:o,log:s}=e,c={kind:`unchecked`,reason:`not sampled yet`},l=null,u=vj,d=null,f=wj(s),p=wj(s),m=()=>xj(c,l);function h(){let e=m(),t=e===null?null:hj(e);(d===null?null:d.identity)!==t&&(d?.dispose(),d=t===null?null:{identity:t,dispose:ij(fj,{kind:`allow-list`,allowed:[t]})})}function g(){c=ik(t,nk),f(Sj(c)),h()}async function _(){l=ED(fD,await TD(wD,a,i)),p(Cj(l)),h()}return{arm(){Ek(pj,{kind:`allow-list`,allowed:[`false`]}),ij(mj,{kind:`allow-list`,allowed:[`false`]}),g(),setInterval(g,n).unref(),c.kind===`not-source-checkout`&&(_(),setInterval(()=>void _(),r).unref())},notice:e=>bj(m(),u,e),act(){let e=m();if(e===null)throw new $(`apply-update: nothing newer is known to apply`);let t=_j(e);if(u.kind===`running`)throw new $(`apply-update: already ${t.busy}`);u=yj,s(`info`,`apply-update: ${t.act} — ${t.command.bin} ${t.command.args?.join(` `)??``}`),De({...t.command,category:`update.apply`,timeoutMs:6e5}).then(n=>{if(n.ok){u=vj,s(`info`,`apply-update: ${t.act} succeeded`),g(),o();return}let r=Ej(n);u={kind:`failed`,identity:hj(e),reason:r},s(`error`,`apply-update: ${t.act} failed: ${r}`)})}}}var Oj=class{static CACHE_DIR=Ne();static USAGE_CACHE_DIR=c.join(this.CACHE_DIR,`usage`);static LOCKS_DIR=c.join(this.CACHE_DIR,`locks`);static isLocked(e){let t=c.join(this.LOCKS_DIR,e);if(!r.existsSync(t))return!1;try{let n=r.readFileSync(t,`utf-8`),i=parseInt(n.trim(),10);if(isNaN(i))return O(`Invalid PID in lock file ${e}, removing stale lock`),r.unlinkSync(t),!1;try{return process.kill(i,0),!0}catch(n){return n.code===`ESRCH`?(O(`Removing stale lock file ${e} for dead process ${i}`),r.unlinkSync(t),!1):(O(`Error checking process ${i} for lock ${e}:`,n),!0)}}catch(t){return O(`Error reading lock file ${e}:`,t),!0}}static async acquireLock(e,t=5e3){await this.ensureCacheDirectories();let n=c.join(this.LOCKS_DIR,e),i=Date.now(),a=String(process.pid);for(;Date.now()-i<t;)try{return await r.promises.writeFile(n,a,{flag:`wx`}),O(`Lock acquired for ${e}`),!0}catch(e){if(e.code===`EEXIST`)await D(50);else throw e}return O(`Failed to acquire lock for ${e} within ${t}ms`),!1}static async releaseLock(e){let t=c.join(this.LOCKS_DIR,e);try{await r.promises.unlink(t),O(`Lock released for ${e}`)}catch(t){t.code!==`ENOENT`&&O(`Error releasing lock for ${e}:`,t)}}static async ensureCacheDirectories(){try{await Promise.all([r.promises.mkdir(this.CACHE_DIR,{recursive:!0}),r.promises.mkdir(this.USAGE_CACHE_DIR,{recursive:!0}),r.promises.mkdir(this.LOCKS_DIR,{recursive:!0})])}catch(e){O(`Failed to create cache directories:`,e)}}static createProjectHash(e){return ae(`md5`).update(e).digest(`hex`).substring(0,8)}static async getUsageCache(e,t){await this.ensureCacheDirectories();let n=c.join(this.USAGE_CACHE_DIR,`${e}.json`),i=`${e}.usage.lock`;for(let a=0;a<3;a++){if(this.isLocked(i)){O(`Cache for ${e} is locked, waiting...`),await D(75);continue}try{let i=await r.promises.readFile(n,`utf-8`),a=JSON.parse(i);return!t||a.timestamp>=t?(O(`[CACHE-HIT] ${e} disk cache: found`),this.deserializeDates(a.data)):(O(`${e} cache outdated: cache=${a.timestamp}, latest=${t}`),null)}catch(t){if(t.code===`ENOENT`)return O(`No shared ${e} usage cache found`),null;O(`Attempt ${a+1} failed to read ${e} cache: ${t.message}. Retrying...`),await D(75)}}return O(`Failed to read ${e} cache after 3 attempts.`),null}static deserializeDates(e){return Array.isArray(e)?e.map(e=>({...e,timestamp:new Date(e.timestamp)})):e}static async setUsageCache(e,t,n){let i=`${e}.usage.lock`;if(!await this.acquireLock(i)){O(`Could not acquire lock to set usage cache for ${e}`);return}try{await this.ensureCacheDirectories();let i=c.join(this.USAGE_CACHE_DIR,`${e}.json`),a=JSON.stringify({data:t,timestamp:n||Date.now()});await r.promises.writeFile(i,a,`utf-8`),O(`[CACHE-SET] ${e} disk cache stored`)}catch(t){O(`Failed to save ${e} usage cache:`,t)}finally{await this.releaseLock(i)}}};const kj={"claude-haiku-4-5-20251001":{name:`Claude Haiku 4.5`,input:1,output:5,cache_write_5m:1.25,cache_write_1h:2,cache_read:.1},"claude-haiku-4-5":{name:`Claude Haiku 4.5`,input:1,output:5,cache_write_5m:1.25,cache_write_1h:2,cache_read:.1},"claude-opus-4-20250514":{name:`Claude Opus 4`,input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-opus-4-1":{name:`Claude Opus 4.1`,input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-opus-4-1-20250805":{name:`Claude Opus 4.1`,input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-sonnet-4-20250514":{name:`Claude Sonnet 4`,input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-4-opus-20250514":{name:`Claude 4 Opus`,input:15,output:75,cache_write_5m:18.75,cache_write_1h:30,cache_read:1.5},"claude-4-sonnet-20250514":{name:`Claude 4 Sonnet`,input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-sonnet-4-5":{name:`Claude Sonnet 4.5`,input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-sonnet-4-5-20250929":{name:`Claude Sonnet 4.5`,input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3},"claude-opus-4-5":{name:`Claude Opus 4.5`,input:5,output:25,cache_write_5m:6.25,cache_write_1h:10,cache_read:.5},"claude-opus-4-5-20251101":{name:`Claude Opus 4.5`,input:5,output:25,cache_write_5m:6.25,cache_write_1h:10,cache_read:.5},"claude-opus-4-6":{name:`Claude Opus 4.6`,input:5,output:25,cache_write_5m:6.25,cache_write_1h:10,cache_read:.5},"claude-opus-4-6-20260205":{name:`Claude Opus 4.6`,input:5,output:25,cache_write_5m:6.25,cache_write_1h:10,cache_read:.5},"claude-sonnet-4-6":{name:`Claude Sonnet 4.6`,input:3,output:15,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3}};var Aj=class{static executionCache=null;static modelPricingCache=new Map;static GITHUB_PRICING_URL=`https://raw.githubusercontent.com/promptctl/cc-candybar/main/pricing.json`;static async loadDiskCache(){let e=Date.now()-1440*60*1e3;return await Oj.getUsageCache(`pricing`,e)}static async saveDiskCache(e){await Oj.setUsageCache(`pricing`,e)}static async fetchPricingData(){return new Promise(e=>{let t=new re(this.GITHUB_PRICING_URL),n=oe({hostname:t.hostname,path:t.pathname,headers:{"User-Agent":`cc-candybar`,"Cache-Control":`no-cache`},timeout:5e3},t=>{if(t.statusCode!==200){O(`HTTP ${t.statusCode}: ${t.statusMessage}`),e(null);return}let r=``,i=0;t.on(`data`,t=>{if(i+=t.length,i>1048576){O(`Response too large`),n.destroy(),e(null);return}r+=t}),t.on(`end`,()=>{try{let t=JSON.parse(r),n=t._meta,i={};for(let[e,n]of Object.entries(t))e!==`_meta`&&(i[e]=n);this.validatePricingData(i)?(O(`Fetched fresh pricing from GitHub for ${Object.keys(i).length} models`),O(`Pricing last updated: ${n?.updated||`unknown`}`),e(i)):(O(`Invalid pricing data structure`),e(null))}catch(t){O(`Failed to parse JSON:`,t),e(null)}}),t.on(`error`,t=>{O(`Response error:`,t),e(null)})});n.on(`error`,t=>{O(`Request error:`,t),e(null)}),n.on(`timeout`,()=>{O(`Request timeout`),n.destroy(),e(null)}),n.end()})}static async getCurrentPricing(){if(this.executionCache!==null)return O(`[CACHE-HIT] Pricing execution cache: ${Object.keys(this.executionCache).length} models`),this.executionCache;let e=await this.loadDiskCache();if(e)return O(`[CACHE-HIT] Pricing disk cache: ${Object.keys(e).length} models`),this.executionCache=e,O(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(e).length} models`),e;let t=await this.fetchPricingData();return t?(await this.saveDiskCache(t),O(`[CACHE-SET] Pricing disk cache stored: ${Object.keys(t).length} models`),this.executionCache=t,O(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(t).length} models`),t):(O(`[CACHE-FALLBACK] Using offline pricing data: ${Object.keys(kj).length} models`),this.executionCache=kj,O(`[CACHE-SET] Pricing execution cache stored: ${Object.keys(kj).length} models`),kj)}static validatePricingData(e){if(!e||typeof e!=`object`)return!1;for(let[,t]of Object.entries(e)){if(!t||typeof t!=`object`)return!1;let e=t;if(typeof e.input!=`number`||typeof e.output!=`number`||typeof e.cache_read!=`number`)return!1}return!0}static async getModelPricing(e){if(this.modelPricingCache.has(e))return O(`[CACHE-HIT] Model pricing cache: ${e}`),this.modelPricingCache.get(e);let t=await this.getCurrentPricing(),n;return n=t[e]?t[e]:this.fuzzyMatchModel(e,t),this.modelPricingCache.set(e,n),O(`[CACHE-SET] Model pricing cache: ${e}`),n}static fuzzyMatchModel(e,t){let n=e.toLowerCase();for(let[e,r]of Object.entries(t))if(e.toLowerCase()===n)return r;for(let{pattern:e,fallback:r}of[{pattern:[`opus-4-6`,`claude-opus-4-6`],fallback:`claude-opus-4-6-20260205`},{pattern:[`opus-4-5`,`claude-opus-4-5`],fallback:`claude-opus-4-5-20251101`},{pattern:[`opus-4-1`,`claude-opus-4-1`],fallback:`claude-opus-4-1-20250805`},{pattern:[`opus-4`,`claude-opus-4`],fallback:`claude-opus-4-20250514`},{pattern:[`sonnet-4-6`,`sonnet-4.6`,`claude-sonnet-4-6`],fallback:`claude-sonnet-4-6`},{pattern:[`sonnet-4.5`,`4-5-sonnet`,`sonnet-4-5`],fallback:`claude-sonnet-4-5-20250929`},{pattern:[`sonnet-4`,`claude-sonnet-4`],fallback:`claude-sonnet-4-20250514`},{pattern:[`haiku-4.5`,`4-5-haiku`,`haiku-4-5`],fallback:`claude-haiku-4-5-20251001`},{pattern:[`haiku`],fallback:`claude-haiku-4-5-20251001`},{pattern:[`opus`],fallback:`claude-opus-4-20250514`},{pattern:[`sonnet`],fallback:`claude-sonnet-4-5-20250929`}])if(e.some(e=>n.includes(e))&&t[r])return t[r];return t[`claude-sonnet-4-5-20250929`]||{name:`${e} (Unknown Model)`,input:3,cache_write_5m:3.75,cache_write_1h:6,cache_read:.3,output:15}}static async calculateCostForEntry(e){let t=e.message?.usage;if(!t)return 0;let n=this.extractModelId(e),r=await this.getModelPricing(n),i=t.input_tokens||0,a=t.output_tokens||0,o=t.cache_creation_input_tokens||0,s=t.cache_read_input_tokens||0,c=i/1e6*r.input,l=a/1e6*r.output,u=s/1e6*r.cache_read,d=o/1e6*r.cache_write_5m;return c+l+d+u}static extractModelId(e){if(e.model&&typeof e.model==`string`)return e.model;let t=e.message;if(t?.model){let e=t.model;if(typeof e==`string`)return e;let n=e;return(typeof n?.id==`string`?n.id:null)||`claude-sonnet-4-5-20250929`}return e.model_id&&typeof e.model_id==`string`?e.model_id:`claude-sonnet-4-5-20250929`}};const jj=/<command-name>\s*([^<\s][^<]*?)\s*<\/command-name>/;function Mj(e){if(typeof e==`string`)return jj.exec(e)?.[1]}function Nj(e){let t=e?.todos;if(!Array.isArray(t))return;let n=[];for(let e of t){if(typeof e!=`object`||!e)continue;let{content:t,activeForm:r,status:i}=e,a=i===`in_progress`,o=a&&typeof r==`string`?r:t;typeof o==`string`&&n.push({text:o,active:a,done:i===`completed`})}return n}function Pj(e){let t=e.message?.content,n=e.type===`user`,r=[],i=[],a,o;if(typeof t==`string`)o=t;else if(Array.isArray(t))for(let e of t){if(typeof e!=`object`||!e)continue;let t=e;switch(t.type){case`tool_use`:{let{id:e,name:n}=t;if(typeof e!=`string`||typeof n!=`string`)break;r.push({id:e,name:n}),n===`TodoWrite`&&(a=Nj(t.input)??a);break}case`tool_result`:{let e=t.tool_use_id;typeof e==`string`&&i.push(e);break}case`text`:o??=t.text;break;default:break}}let s=n?Mj(o):void 0;if(!(r.length===0&&i.length===0&&a===void 0&&s===void 0))return{...r.length>0&&{started:r},...i.length>0&&{finished:i},...a!==void 0&&{todos:a},...s!==void 0&&{command:s}}}function Fj(){let e=[],t=process.env.CLAUDE_CONFIG_DIR;if(t&&t.split(`,`).forEach(t=>{let n=t.trim();a(n)&&e.push(n)}),e.length===0){let t=m(),n=f(t,`.config`,`claude`),r=f(t,`.claude`);a(n)&&e.push(n),a(r)&&e.push(r)}return e}async function Ij(e){let t=[];for(let n of e){let e=f(n,`projects`);if(a(e))try{let n=await qk(e,{withFileTypes:!0});for(let r of n)if(r.isDirectory()){let n=f(e,r.name);t.push(n)}}catch(t){O(`Failed to read projects directory ${e}:`,t)}}return t}async function Lj(e,t,n){let r=[],i=f(t,e,`subagents`);try{let t=(await qk(i)).filter(e=>e.startsWith(`agent-`)&&e.endsWith(`.jsonl`));for(let a of t){let t=f(i,a);if(n?.has(t)){r.push(t);continue}try{let n=(await Jk(t,`utf-8`)).split(`
|
|
@@ -198,7 +198,7 @@ print(json.dumps({"ceiling": "off" if ceiling == math.inf else ceiling,
|
|
|
198
198
|
`,c.join(e,`lib`),t.sessionId,t.cwd],env:kL(t),timeoutMs:3e3,category:`memento.read`});return n.ok?jL(n.stdout):X(AL(n))}function NL(e,t,n){let r=Oe({bin:c.join(e,TL),args:n.kind===`set`?[`set`,`session`,n.to]:[`clear`,`session`],env:kL(t),timeoutMs:5e3,category:`memento.move`});if(!r.ok)throw Error(AL(r))}function PL(){let e=gD(mD(pD(process.env,process.cwd())));return{locate:t=>OL(e,t),read:ML,move:NL}}var FL=class{written=new Map;constructor(e){this.dir=e}pathFor(e){return c.join(this.dir,`${encodeURIComponent(e)}.txt`)}sync(e,t){let n=this.pathFor(e);if(t===(this.written.get(e)??null))return null;try{return t===null?(r.rmSync(n,{force:!0}),this.written.delete(e)):(r.mkdirSync(this.dir,{recursive:!0,mode:448}),r.writeFileSync(n,t,{mode:384}),this.written.set(e,t)),null}catch(e){return`${n}: ${e.message}`}}reset(){this.written.clear();try{return r.rmSync(this.dir,{recursive:!0,force:!0}),null}catch(e){return`${this.dir}: ${e.message}`}}};const IL=new tP;Te(IL.launchStats);const LL=new Yy({counters:IL,logger:Q}),RL=new rb({watchers:LL,logger:Q}),zL=new nM,BL=new aP,VL=new iF(BL,Q),HL=new EF,UL=new FL(Ke()),WL=new cL,GL=new pL,KL=new vL,qL=new xL,JL=new CL(PL()),YL=new $N({gitService:RL,sessionState:BL,watchers:LL},{observers:{onReload:e=>Q(`info`,`config loaded projectDir=${e.projectDir} cwd=${e.cwd} file=${e.configFilePath??`<bundled default>`} error=${e.lastError===null?`none`:JSON.stringify(e.lastError)} warning=${e.lastWarning===null?`none`:JSON.stringify(e.lastWarning)}`)}}),XL=60*1e3;function ZL(){let e=import.meta.url,n=[];e.startsWith(`file://`)&&n.push(ie(e)),t.argv[1]&&n.push(t.argv[1]);let i=new Map;for(let e of n)try{i.set(e,r.statSync(e).mtimeMs)}catch{}let a=null,o=()=>{for(let[e,t]of i)try{if(r.statSync(e).mtimeMs!==t){Q(`info`,`binary mtime changed (${e}); shutting down`),a&&clearInterval(a),pR(0);return}}catch(e){Q(`warn`,`bin stat failed: ${e.message}`)}};return{arm(){i.size!==0&&(a=setInterval(o,XL),a.unref())},checkNow:o}}const QL=ZL(),$L=Dj({entryUrl:import.meta.url,intervalMs:XL,releaseIntervalMs:216e5,registryUrl:t.env.CC_CANDYBAR_REGISTRY_URL??`https://registry.npmjs.org`,fetchImpl:fetch,onApplied:()=>QL.checkNow(),log:Q});let eR=null,tR=null,nR=0;function rR(){t.on(`uncaughtException`,e=>{Q(`error`,`uncaughtException: ${e.stack||e.message}`),pR(1)}),t.on(`unhandledRejection`,e=>{Q(`error`,`unhandledRejection: ${String(e)}`),pR(1)});for(let e of[`SIGINT`,`SIGTERM`,`SIGHUP`])t.on(e,()=>{Q(`info`,`received ${e}, shutting down`),pR(0)});try{nR=oE(t.env)}catch(e){Q(`error`,`refusing to boot: ${e.message}`),pR(1);return}eR=lO(t.pid);let e=yO(xO(eR));if(!e.decision.allow){Q(`warn`,`fork-bomb breaker: ${e.decision.reason}; refusing to boot`),pR(1);return}tR=e.registryPath,r.mkdirSync(Pe(),{recursive:!0}),Le(Fe()),BL.useStorage(new cP(Be(),500,Q)),VL.useStorage(wF(Ve(),Q)),fO({anchor:dO(t.env),isAlive:pO,onOrphaned:e=>{Q(`info`,`parent watchdog: ${e}; shutting down`),pR(0)}}),iR(y.createServer({allowHalfOpen:!1},e=>{mR(e)}),Fe(),!1)}function iR(e,n,r){e.removeAllListeners(`error`),e.removeAllListeners(`listening`),e.once(`error`,i=>{if(i.code!==`EADDRINUSE`){Q(`error`,`server error: ${i.message}`),pR(1);return}if(r){Q(`info`,`lost rebind race; another daemon is alive — exiting`),t.exit(0);return}aR(e,n)}),e.listen(n,()=>oR(n))}function aR(e,n){let i=$D(eO(Re(n)),(e,t)=>cO(e,t,{readStartTime:sO,pidAlive:pO}));if(i.kind===`attach-and-exit`){Q(`info`,`EADDRINUSE: ${i.reason} — exiting`),t.exit(0);return}Q(`warn`,`EADDRINUSE: ${i.reason} — unlinking stale socket and rebinding`);try{r.unlinkSync(n)}catch(e){if(e.code!==`ENOENT`){Q(`error`,`cannot unlink stale socket ${n}: ${e.message}`),pR(1);return}}iR(e,n,!0)}function oR(e){let n=rO(e);if(n.kind!==`present`){Q(`warn`,`no ownable socket at bind callback (${n.kind}); exiting`),pR(0);return}uR(e);try{r.chmodSync(e,384)}catch(e){Q(`warn`,`chmod socket failed: ${e.message}`)}Q(`info`,`daemon up: pid=${t.pid} v=3 sock=${e} heapCap=${Math.round(ne.getHeapStatistics().heap_size_limit/1048576)}MB rssLimit=${Math.round(nR/1048576)}MB`),CE();let i=UL.reset();i!==null&&Q(`warn`,`diagnostic dump wipe failed: ${i}`),QL.arm(),$L.arm(),lR(),sR(e,n.identity)}function sR(e,n){oO({bound:n,myPid:t.pid,readIdentity:()=>rO(e),readLease:()=>eO(Re(e)),shutdown:e=>pR(e),log:Q}).arm()}let cR=null;function lR(){cR=uE(mE(IL.startedAt.getTime(),e=>pR(e),{rssLimitBytes:nR})),cR.arm()}function uR(e){let n=tO(Re(e),{pid:t.pid,version:3,binPath:t.argv[1],startTime:eR});n!==null&&Q(`warn`,`lease write failed: ${n}`)}let dR=0,fR=!1;function pR(e){if(!fR){fR=!0,setTimeout(()=>t.kill(t.pid,`SIGKILL`),500);try{RL.close()}catch(e){Q(`warn`,`gitService close failed: ${e.message}`)}try{zL.close()}catch(e){Q(`warn`,`usageStore close failed: ${e.message}`)}try{LL.closeAll()}catch(e){Q(`warn`,`watcherRegistry close failed: ${e.message}`)}try{BL.flush()}catch(e){Q(`warn`,`sessionState flush failed: ${e.message}`)}nO(ze(),t.pid),tR!==null&&bO(tR,t.pid,_O,e=>r.unlinkSync(e)),t.exit(e)}}function mR(e){dR++,IL.inFlight=dR;let t=!1,n=(n,r)=>{if(t){r!==null&&Q(`warn`,`exit-after-flush dropped: an earlier responder settled this socket`);return}t=!0;let i=r===null?void 0:()=>pR(r);try{e.end(NT(n),i)}catch(e){Q(`warn`,`response write failed: ${e.message}`),i?.()}},r=setTimeout(()=>{IL.requestsTimedOut++,n({ok:!1,error:`request exceeded 200ms`,code:`TIMEOUT`,daemonV:3},null)},200),i=PT(e=>{gR(e).then(e=>n(e.resp,e.exitAfterFlush)).catch(e=>{Q(`error`,`handler threw: ${e?.stack||e}`),n({ok:!1,error:String(e?.message||e),code:`RENDER_FAILED`,daemonV:3},null)})},e=>{Q(`warn`,`frame parse failed: ${e.message}`),n({ok:!1,error:e.message,code:`BAD_REQUEST`,daemonV:3},null)});e.on(`data`,i),e.on(`error`,e=>{Q(`warn`,`socket error: ${e.message}`)}),e.on(`close`,()=>{clearTimeout(r),dR=Math.max(0,dR-1),IL.inFlight=dR})}const hR=e=>({resp:e,exitAfterFlush:null});async function gR(e){if(!e||typeof e!=`object`||typeof e.v!=`number`)return hR({ok:!1,error:`malformed request`,code:`BAD_REQUEST`,daemonV:3});if(e.v!==3)return e.v>3?Q(`info`,`version mismatch: client=${e.v} > daemon=3; binary likely upgraded — exiting after the response flushes`):Q(`info`,`version mismatch: client=${e.v} < daemon=3; client is stale — staying up`),{resp:{ok:!1,error:`protocol v${e.v} not supported (daemon at v3)`,code:`VERSION_MISMATCH`,daemonV:3},exitAfterFlush:e.v>3?0:null};if(e.kind===`shutdown`)return{resp:{ok:!0,output:``},exitAfterFlush:0};if(e.kind===`stats`)return hR({ok:!0,stats:IL.snapshot({gitCache:RL.getStats(),usageCache:zL.getStats(),renderCacheSize:YL.size,watchersActive:LL.size(),nextRestartReason:cR?.describeNextRestart()??null})});if(e.kind===`render`){IL.requestsTotal++;let t=Date.now();try{let{report:n}=GI(e.hookData);for(let e of n.unknownTopLevelFields)Q(`info`,`schema: unknown field '${e}' — Anthropic may have added it`);let r=[];for(let e of n.missingRequired)r.push(`missing required field '${e}'`);for(let{path:e,expected:t,got:i}of n.typeMismatches)r.push(`field '${e}' expected ${t}, got ${i}`);if(e.cwd===``&&r.push(`request 'cwd' is empty`),r.length>0)return IL.requestsErrored++,Q(`warn`,`BAD_REQUEST: ${r.join(`; `)}`),hR({ok:!1,error:`malformed hookData: ${r.join(`; `)}`,code:`BAD_REQUEST`,daemonV:3});let i=e.hookData.workspace.project_dir,{configFile:a,unknownFlagsError:o}=_R(e.args),s=e.hookData.session_id,c=TT(e),l=JSON.stringify(c);BL.get(s,`client-hints`)!==l&&BL.set(s,AI,l);let u=BL.get(s,`config-override`)??a??c.configEnv,d=YL.getOrCreate(i,e.cwd,u),f=cI({projectDir:i,cwd:e.cwd,configFile:u??null});BL.get(s,`render-origin`)!==f&&BL.set(s,sI,f);let p=c.termCols,m=sL(p??120),h=RO(c.termRows),{authoredRoots:g}=d.state,_=t=>BL.get(e.hookData.session_id,t),v=rA(d.state.config,_,e=>g.has(e)),y=await bA(e.hookData,SR,e.cwd,d.state.neededInputPaths(v.preset),v,c,KA(d.state.config,d.state.fileHeldSettings,_)),b=[],x=iA(v,m),S=zN(d.state.config,d.state.compiled,d.state.store,d.state.registry,y,x,{perSegmentSink:d.state.lastRenderCellsBySegment,onRenderWarning:e=>b.push(e)},aA(v)),C=BL.get(e.hookData.session_id,`click.error`);C&&BL.clear(e.hookData.session_id,`click.error`);let ee=[o,d.lastError,C].filter(Boolean).join(`
|
|
199
199
|
`),te=$L.notice({sessionId:s,dismissed:BL.get(s,fj),enabled:v.updateNotice}),ne=d.lastError===null?null:d.configFilePath,re=UO(ee,te,[d.lastWarning??``,...b].filter(Boolean).join(`
|
|
200
200
|
`)),w=UL.sync(s,re===null?null:GO(re));w!==null&&Q(`warn`,`diagnostic dump failed: ${w}`);let ie=KO(S,re,{fullText:w===null?{kind:`file`,path:UL.pathFor(s)}:{kind:`unavailable`,reason:w},failedConfigFile:ne},{width:m,rowCap:h,colorCompatibility:v.colorCompatibility}),T=Date.now()-t,E=RL.getStats(),ae=zL.getStats();return Q(`info`,`render sid=${e.hookData.session_id??`?`} took=${T}ms termCols=${p??`?`} termRows=${c.termRows??`?`} width=${m} git=${E.size}/${E.hits}h/${E.misses}m usage=${ae.size}/${ae.hits}h/${ae.misses}m err=${ee?`Y`:`N`} upd=${te.length} warn=${d.lastWarning?`Y`:`N`}`),hR({ok:!0,output:ie+`
|
|
201
|
-
`})}catch(e){throw IL.requestsErrored++,e}}if(e.kind===`click`)return hR(await CR(e.verb,e.value));if(e.kind===`debug`){if(!oL(e.what))return hR({ok:!1,error:`unknown debug 'what': ${String(e.what)} (have: ${aL.join(`, `)})`,code:`BAD_REQUEST`,daemonV:3});let t=YL.firstState(),n=t===null?null:{store:t.store,registry:t.registry,config:t.config,compiled:t.compiled,lastRenderBySegment:e.what===`segments`?xR(t.lastRenderCellsBySegment,t.config.globals.charset??`unicode`,t.config.globals.colorCompatibility??`truecolor`):bR};return hR({ok:!0,debug:JI(e.what,n)})}return hR({ok:!1,error:`unknown kind`,code:`BAD_REQUEST`,daemonV:3})}function _R(e){let{values:t,tokens:n}=_({args:e.slice(1),options:{config:{type:`string`}},strict:!1,tokens:!0,allowPositionals:!0}),r=[...new Set((n??[]).filter(e=>e.kind===`option`&&e.name!==`config`).map(e=>`--${e.name}`))];return{configFile:DT(t.config),unknownFlagsError:r.length>0?`Unknown flags: ${r.join(`, `)}`:null}}const vR={sessionState:BL,dlog:Q,applyUpdate:()=>$L.act(),doctor:kF(),memento:JL,claudeInput:WF(),history:VL,navigation:HL,configFor:e=>YL.getOrCreate(e.projectDir,e.cwd,e.configFile??void 0).state.config,reloadConfig:e=>YL.reload(e.projectDir,e.cwd,e.configFile??void 0)}
|
|
201
|
+
`})}catch(e){throw IL.requestsErrored++,e}}if(e.kind===`click`)return hR(await CR(e.verb,e.value));if(e.kind===`debug`){if(!oL(e.what))return hR({ok:!1,error:`unknown debug 'what': ${String(e.what)} (have: ${aL.join(`, `)})`,code:`BAD_REQUEST`,daemonV:3});let t=YL.firstState(),n=t===null?null:{store:t.store,registry:t.registry,config:t.config,compiled:t.compiled,lastRenderBySegment:e.what===`segments`?xR(t.lastRenderCellsBySegment,t.config.globals.charset??`unicode`,t.config.globals.colorCompatibility??`truecolor`):bR};return hR({ok:!0,debug:JI(e.what,n)})}return hR({ok:!1,error:`unknown kind`,code:`BAD_REQUEST`,daemonV:3})}function _R(e){let{values:t,tokens:n}=_({args:e.slice(1),options:{config:{type:`string`}},strict:!1,tokens:!0,allowPositionals:!0}),r=[...new Set((n??[]).filter(e=>e.kind===`option`&&e.name!==`config`).map(e=>`--${e.name}`))];return{configFile:DT(t.config),unknownFlagsError:r.length>0?`Unknown flags: ${r.join(`, `)}`:null}}const vR={sessionState:BL,dlog:Q,applyUpdate:()=>$L.act(),doctor:kF(),memento:JL,claudeInput:WF(),history:VL,navigation:HL,configFor:e=>YL.getOrCreate(e.projectDir,e.cwd,e.configFile??void 0).state.config,reloadConfig:e=>YL.reload(e.projectDir,e.cwd,e.configFile??void 0)};vR.reloadConfig;const yR={endcaps:`powerline`,colorCompatibility:ho,wrap:!0,padding:1,charset:uo,width:1/0},bR=new Map;function xR(e,t,n){let r=new Map;for(let[i,a]of e)r.set(i,LO(a,{...yR,charset:t,colorCompatibility:n}));return r}const SR={gitProvider:RL,usageStore:zL,contextProvider:WL,metricsProvider:GL,activityProvider:KL,tmuxService:qL,mementoProvider:JL,autoCompact:Ak,log:Q,clock:()=>new Date,history:e=>VL.depth(e),navigation:e=>HL.depth(e,BL)};function CR(e,t){let n=HI.get(e);if(!n)return{ok:!1,error:`unknown click verb: ${e}`,code:`BAD_REQUEST`,daemonV:3};try{return n(t,vR),{ok:!0,output:``}}catch(e){let t=e instanceof $?`BAD_REQUEST`:`RENDER_FAILED`;return{ok:!1,error:String(e instanceof Error?e.message:e),code:t,daemonV:3}}}const wR={connectMs:200,budgetMs:500};async function TR(e){let n=e.includes(`--json`),r=await ER();if(r.kind!==`ok`&&(t.stderr.write(`daemon-stats: ${HT(r)}\n`),t.exit(1)),n){t.stdout.write(JSON.stringify(r.value,null,2)+`
|
|
202
202
|
`);return}t.stdout.write(AR(r.value))}function ER(){return IT({kind:`stats`},wR,e=>`stats`in e?e.stats:void 0)}function DR(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function OR(e,t){let n=e+t;return n===0?`n/a`:`${(e/n*100).toFixed(1)}%`}function kR(e){return e<60?`${e}s`:e<3600?`${Math.floor(e/60)}m${e%60}s`:`${Math.floor(e/3600)}h${Math.floor(e%3600/60)}m`}function AR(e){let t=[];t.push(`cc-candybar daemon stats`),t.push(``),t.push(`process`),t.push(` pid ${e.pid}`),t.push(` version ${e.version}`),t.push(` protocol ${e.protocolVersion}`),t.push(` startedAt ${e.startedAt}`),t.push(` uptime ${kR(e.uptimeSec)}`),t.push(` rss ${DR(e.rssBytes)}`),t.push(` heapUsed ${DR(e.heapUsedBytes)}`),t.push(` heapTotal ${DR(e.heapTotalBytes)}`),t.push(` external ${DR(e.externalBytes)}`),t.push(` arrayBuffers ${DR(e.arrayBuffersBytes)}`),t.push(``),t.push(`requests`),t.push(` total ${e.requests.total}`),t.push(` errored ${e.requests.errored}`),t.push(` timedOut ${e.requests.timedOut}`),t.push(` inFlight ${e.requests.inFlight}`),t.push(``),t.push(`gitCache`),t.push(` size ${e.gitCache.size}`),t.push(` hit rate ${OR(e.gitCache.hits,e.gitCache.misses)} (${e.gitCache.hits} / ${e.gitCache.hits+e.gitCache.misses})`),t.push(` invalidations ${e.gitCache.invalidations}`),t.push(``),t.push(`usageCache`),t.push(` size ${e.usageCache.size}`),t.push(` hit rate ${OR(e.usageCache.hits,e.usageCache.misses)} (${e.usageCache.hits} / ${e.usageCache.hits+e.usageCache.misses})`),t.push(` sweeps ${e.usageCache.sweeps}`),t.push(``),t.push(`renderCache`),t.push(` size ${e.renderCache.size}`),t.push(`watchers`),t.push(` active ${e.watchers.active}`),t.push(` opened ${e.watchers.opened}`),t.push(` closed ${e.watchers.closed}`),t.push(` evicted ${e.watchers.evicted}`),t.push(``),t.push(`subprocesses`),t.push(` total ${e.subprocesses.total}`),t.push(` inFlight ${e.subprocesses.inFlight}`),t.push(` lastMinute ${e.subprocesses.lastMinute}`);let n=Object.entries(e.subprocesses.byCategory),r=n.reduce((e,[t])=>Math.max(e,t.length),13);for(let[i,a]of n){let n=e.subprocesses.p50DurationMs[i],o=e.subprocesses.p99DurationMs[i],s=n!==void 0&&o!==void 0?` (p50 ${n}ms · p99 ${o}ms)`:``;t.push(` ${i.padEnd(r)} ${a}${s}`)}return e.nextRestartReason&&(t.push(``),t.push(`nextRestart ${e.nextRestartReason}`)),t.join(`
|
|
203
203
|
`)+`
|
|
204
204
|
`}const jR={connectMs:200,budgetMs:500};async function MR(e,n){let r=n.includes(`--json`),i=await NR(e);if(i.kind!==`ok`&&(t.stderr.write(`${e}: ${HT(i)}\n`),t.exit(1)),r){t.stdout.write(JSON.stringify(i.value,null,2)+`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptctl/cc-candybar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.107.0",
|
|
4
4
|
"description": "Statusline renderer for Claude Code — a JSON5-configurable DSL with daemon-cached data sources, byte-clean palette-aware composition, and OSC8 click verbs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"gallery": "tsx src/demo/gallery.ts",
|
|
27
27
|
"bar": "node --require ./scripts/version-stamp.cjs --import tsx scripts/drive-bar.ts",
|
|
28
28
|
"bar:web": "node --require ./scripts/version-stamp.cjs --import tsx scripts/bar-web.ts",
|
|
29
|
+
"site:build": "node site/build.mjs",
|
|
29
30
|
"benchmark:timing": "scripts/benchmark_timing.sh",
|
|
30
31
|
"preloadtest": "pnpm build",
|
|
31
32
|
"loadtest": "node --import tsx scripts/daemon-load-harness.ts",
|
|
@@ -69,6 +70,9 @@
|
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@eslint/js": "^9.33.0",
|
|
73
|
+
"@pkgjs/parseargs": "0.11.0",
|
|
74
|
+
"@promptctl/go-template-js": "^0.10.0",
|
|
75
|
+
"@promptctl/rich-js": "^0.18.1",
|
|
72
76
|
"@semantic-release/changelog": "^6.0.3",
|
|
73
77
|
"@semantic-release/exec": "^7.0.3",
|
|
74
78
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -77,25 +81,29 @@
|
|
|
77
81
|
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
|
78
82
|
"@typescript-eslint/parser": "^8.39.0",
|
|
79
83
|
"ajv": "^8.20.0",
|
|
84
|
+
"buffer": "6.0.3",
|
|
85
|
+
"esbuild": "0.28.2",
|
|
80
86
|
"eslint": "^9.33.0",
|
|
81
87
|
"eslint-config-prettier": "^10.1.8",
|
|
82
88
|
"eslint-plugin-prettier": "^5.5.4",
|
|
89
|
+
"events": "3.3.0",
|
|
83
90
|
"jest": "^30.0.5",
|
|
91
|
+
"json5": "^2.2.3",
|
|
92
|
+
"memfs": "4.80.0",
|
|
93
|
+
"mobx": "^6.15.0",
|
|
94
|
+
"path-browserify": "1.0.1",
|
|
84
95
|
"prettier": "^3.6.2",
|
|
96
|
+
"readable-stream": "4.7.0",
|
|
85
97
|
"semantic-release": "^25.0.2",
|
|
86
98
|
"ts-jest": "^29.4.1",
|
|
87
99
|
"tsdown": "^0.21.4",
|
|
88
100
|
"tsx": "^4.21.0",
|
|
89
|
-
"typescript": "^5.0.0"
|
|
90
|
-
"@promptctl/go-template-js": "^0.10.0",
|
|
91
|
-
"@promptctl/rich-js": "^0.18.1",
|
|
92
|
-
"json5": "^2.2.3",
|
|
93
|
-
"mobx": "^6.15.0"
|
|
101
|
+
"typescript": "^5.0.0"
|
|
94
102
|
},
|
|
95
103
|
"optionalDependencies": {
|
|
96
|
-
"@promptctl/cc-candybar-darwin-arm64": "1.
|
|
97
|
-
"@promptctl/cc-candybar-darwin-x64": "1.
|
|
98
|
-
"@promptctl/cc-candybar-linux-x64": "1.
|
|
99
|
-
"@promptctl/cc-candybar-linux-arm64": "1.
|
|
104
|
+
"@promptctl/cc-candybar-darwin-arm64": "1.107.0",
|
|
105
|
+
"@promptctl/cc-candybar-darwin-x64": "1.107.0",
|
|
106
|
+
"@promptctl/cc-candybar-linux-x64": "1.107.0",
|
|
107
|
+
"@promptctl/cc-candybar-linux-arm64": "1.107.0"
|
|
100
108
|
}
|
|
101
109
|
}
|