@promptctl/cc-candybar 1.8.3 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +23 -23
- package/package.json +5 -5
- package/src/dsl/render.ts +17 -2
- package/src/render/action.ts +12 -1
- package/src/render/picker.ts +18 -1
- package/src/render/strip.ts +29 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import e from"node:process";import{json as t}from"node:stream/consumers";import n,{createReadStream as r,existsSync as i,watch as a}from"node:fs";import o,{basename as s,dirname as c,join as l}from"node:path";import u,{homedir as d}from"node:os";import{spawn as f,spawnSync as p}from"node:child_process";import m from"node:net";import{URL as h,URLSearchParams as g,fileURLToPath as _}from"node:url";import{parseArgs as v}from"node:util";import{get as y}from"node:https";import{createHash as b}from"node:crypto";import{setTimeout as x}from"node:timers/promises";import{open as S,readFile as C,readdir as ee,stat as te}from"node:fs/promises";import{createInterface as w}from"node:readline";import{clearInterval as ne,setInterval as re}from"node:timers";import ie from"node:v8";var T=Object.create,E=Object.defineProperty,ae=Object.getOwnPropertyDescriptor,oe=Object.getOwnPropertyNames,se=Object.getPrototypeOf,ce=Object.prototype.hasOwnProperty,D=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),le=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=oe(t),a=0,o=i.length,s;a<o;a++)s=i[a],!ce.call(e,s)&&s!==n&&E(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=ae(t,s))||r.enumerable});return e},ue=(e,t,n)=>(n=e==null?{}:T(se(e)),le(t||!e||!e.__esModule?E(n,`default`,{value:e,enumerable:!0}):n,e));function O(e,...t){process.env.CC_CANDYBAR_DEBUG&&console.error(`[DEBUG] ${e}`,...t)}const de={"click.pbcopy":1e3,"click.open":1e3},fe=new Map;function pe(e){let t=de[e];if(t===void 0)return{allowed:!0};let n=fe.get(e);if(n===void 0)return{allowed:!0};let r=Date.now()-n;return r>=t?{allowed:!0}:{allowed:!1,minIntervalMs:t,sinceLastMs:r}}function me(e){fe.set(e,Date.now())}function he(e,t,n){return{ok:!1,reason:`rate-limited`,stdout:``,stderr:``,exitCode:null,signal:null,error:`rate-limited: ${e} min interval ${t}ms, last start ${n}ms ago`}}let ge=null;function k(e){ge=e}async function _e(e){let t=pe(e.category);if(!t.allowed)return he(e.category,t.minIntervalMs,t.sinceLastMs);me(e.category);let n=Date.now();return ge?.onStart(e.category),new Promise(t=>{let r;try{r=f(e.bin,e.args??[],{cwd:e.cwd,env:e.env,stdio:[`pipe`,`pipe`,`pipe`]})}catch(r){ge?.onEnd(e.category,Date.now()-n),t({ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:r instanceof Error?r.message:String(r)});return}let i=``,a=``,o=!1,s=null,c=null,l=!1,u=r=>{o||(o=!0,s&&clearTimeout(s),c&&clearTimeout(c),ge?.onEnd(e.category,Date.now()-n),t(r))};r.stdout?.on(`data`,e=>{i+=e.toString(`utf8`)}),r.stderr?.on(`data`,e=>{a+=e.toString(`utf8`)}),r.on(`error`,e=>{u({ok:!1,reason:`spawn-error`,stdout:i,stderr:a,exitCode:null,signal:null,error:e.message})}),r.on(`close`,(e,t)=>{if(l){u({ok:!1,reason:`timeout`,stdout:i,stderr:a,exitCode:e,signal:t});return}if(e===0){u({ok:!0,stdout:i,stderr:a,exitCode:e});return}u({ok:!1,reason:t?`signal`:`non-zero`,stdout:i,stderr:a,exitCode:e,signal:t})}),e.timeoutMs&&e.timeoutMs>0&&(s=setTimeout(()=>{l=!0,r.pid!==void 0&&(r.kill(`SIGTERM`),c=setTimeout(()=>{r.kill(`SIGKILL`)},250))},e.timeoutMs)),e.stdinInput!==void 0&&r.stdin?r.stdin.end(e.stdinInput):r.stdin&&r.stdin.end()})}function ve(e){let t=pe(e.category);if(!t.allowed)return he(e.category,t.minIntervalMs,t.sinceLastMs);me(e.category);let n=Date.now();ge?.onStart(e.category);let r=[`pipe`,`pipe`,`pipe`];try{let t=p(e.bin,e.args??[],{cwd:e.cwd,env:e.env,input:e.stdinInput,timeout:e.timeoutMs&&e.timeoutMs>0?e.timeoutMs:void 0,stdio:r,encoding:`utf8`});ge?.onEnd(e.category,Date.now()-n);let i=typeof t.stdout==`string`?t.stdout:``,a=typeof t.stderr==`string`?t.stderr:``;if(t.error)return{ok:!1,reason:t.error.code===`ETIMEDOUT`?`timeout`:`spawn-error`,stdout:i,stderr:a,exitCode:null,signal:t.signal??null,error:t.error.message};if(t.status===0)return{ok:!0,stdout:i,stderr:a,exitCode:t.status};let o=e.timeoutMs!==void 0&&e.timeoutMs>0;return{ok:!1,reason:t.signal?o&&t.signal===`SIGTERM`?`timeout`:`signal`:`non-zero`,stdout:i,stderr:a,exitCode:t.status,signal:t.signal??null}}catch(t){return ge?.onEnd(e.category,Date.now()-n),{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:t instanceof Error?t.message:String(t)}}}function ye(e){let t=pe(e.category);if(!t.allowed)return he(e.category,t.minIntervalMs,t.sinceLastMs);me(e.category);let n=Date.now();ge?.onStart(e.category);let r=be(e);return ge?.onEnd(e.category,Date.now()-n),r}function be(e){let t;try{t=f(e.bin,e.args??[],{cwd:e.cwd,env:e.env,detached:!0,stdio:`ignore`})}catch(e){return{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:e instanceof Error?e.message:String(e)}}return t.once(`error`,()=>{}),t.pid===void 0?{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:`spawn(${e.bin}): no pid (binary not found or unexecutable)`}:(t.unref(),{ok:!0,stdout:``,stderr:``,exitCode:null})}function xe(e){let t=process.env[e];return t&&t.length>0?t:void 0}function Se(){let e=xe(`XDG_STATE_HOME`)??o.join(u.homedir(),`.local`,`state`);return o.join(e,`cc-candybar`)}function Ce(){let e=xe(`XDG_CACHE_HOME`)??o.join(u.homedir(),`.cache`);return o.join(e,`cc-candybar`)}function we(){return Se()}function Te(){let e=process.env.CC_CANDYBAR_SOCKET;if(e)return e;let t=u.userInfo().uid;return o.join(`/tmp`,`cc-candybar-${t}`,`socket`)}function Ee(e){let t=o.dirname(e);n.mkdirSync(t,{recursive:!0,mode:448});let r=n.lstatSync(t);if(r.isSymbolicLink())throw Error(`socket parent is a symlink: ${t}`);if(!r.isDirectory())throw Error(`socket parent is not a directory: ${t}`);let i=u.userInfo().uid;if(typeof i==`number`&&r.uid!==i)throw Error(`socket parent is not owned by uid ${i}: ${t} (owner uid=${r.uid})`);if(r.mode&63)throw Error(`socket parent has unsafe permissions: ${t} (mode=${(r.mode&511).toString(8)}, expected 0700)`);try{if(n.lstatSync(e).isSymbolicLink())throw Error(`socket path is a symlink: ${e}`)}catch(e){if(e.code!==`ENOENT`)throw e}}function De(){return o.join(Se(),`pid`)}function Oe(){return o.join(Se(),`session-state.json`)}function ke(){return o.join(Se(),`spawn.lock`)}function A(){return o.join(Se(),`daemon.log`)}const Ae=1e4;function je(e){if(typeof e!=`number`||!Number.isFinite(e))return;let t=Math.floor(e);if(!(t<=0))return t>Ae?Ae:t}var Me=class extends Error{constructor(e){super(e),this.name=`ProtocolError`}};function Ne(e){let t=Buffer.from(JSON.stringify(e),`utf8`),n=Buffer.alloc(4);return n.writeUInt32BE(t.length,0),Buffer.concat([n,t])}function Pe(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 Me(`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 Me(e instanceof Error?e.message:String(e));e instanceof Error&&(n.cause=e),t(n);return}}}}function Fe(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=Pe(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(Ne(t))})}async function Ie(e,t,n){let r=null;try{r=await Ve(Te(),t.connectMs);let i=await Fe(r,{v:3,...e},t.budgetMs);return ze(e.kind,i,n)}catch(e){return Be(e)}finally{r&&r.destroy()}}function Le(e,t){return typeof e==`string`?e:t}function Re(e){return typeof e==`number`&&Number.isInteger(e)&&e>=0?e:0}function ze(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=Le(r.error,`(no error message)`);switch(r.code){case`VERSION_MISMATCH`:return{kind:`permanent`,cause:`version_mismatch`,clientV:3,daemonV:Re(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 Be(e){if(e instanceof Me||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 Ve(e,t){return new Promise((n,r)=>{let i=m.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 He(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 Ue={connectMs:50,budgetMs:150},We={connectMs:50,budgetMs:200};function Ge(e){let t=e.output;return typeof t==`string`?t:void 0}function Ke(e,t,n,r){return Ie({kind:`render`,hookData:e,args:t,cwd:n,termCols:r},Ue,Ge)}function qe(e,t){return Ie({kind:`click`,verb:e,value:t},We,Ge)}function Je(t={}){if(tt()!==null)return;let n=t.spawn??nt,r=Qe();if(r.kind===`contended`){let t=Ye();t!==null&&t>2e3&&(e.stderr.write(`cc-candybar: spawn-lock held ${t}ms (likely crashed holder) — spawning unlocked\n`),Xe(n));return}if(r.kind===`error`){e.stderr.write(`cc-candybar: spawn-lock unavailable (${r.reason}) — spawning unlocked\n`),Xe(n);return}try{Xe(n)}finally{et()}}function Ye(){try{let e=n.statSync(ke());return Date.now()-e.mtimeMs}catch{return null}}function Xe(t){try{t()||e.stderr.write(`cc-candybar: daemon spawn returned false (unable to resolve script path?)
|
|
3
|
-
`)}catch(t){e.stderr.write(`cc-candybar: daemon spawn failed: ${t.message}\n`)}}let Ze=null;function Qe(){let t=ke();for(let r=0;r<2;r++){try{let r=n.openSync(t,`wx`,384);try{n.writeSync(r,JSON.stringify({pid:e.pid,ts:Date.now()}))}catch{}return Ze={fd:r,path:t},{kind:`held`}}catch(e){let n=e.code;if(n!==`EEXIST`)return{kind:`error`,reason:`openSync(${t}): ${n??e.message}`}}if(!$e(t))return{kind:`contended`};try{n.unlinkSync(t)}catch(e){if(e.code!==`ENOENT`)return{kind:`error`,reason:`unlink stale spawn.lock: ${e.message}`}}}return{kind:`contended`}}function $e(e){try{let t=n.statSync(e);return Date.now()-t.mtimeMs>1e4}catch{return!0}}function et(){if(!Ze)return;let{fd:e,path:t}=Ze;Ze=null;try{n.closeSync(e)}catch{}try{n.unlinkSync(t)}catch{}}function tt(){try{return n.mkdirSync(we(),{recursive:!0}),null}catch(e){return`mkdir ${we()}: ${e.message}`}}function nt(){let t=e.execPath,n=e.argv[1];return n?ye({bin:t,args:[`--max-old-space-size=400`,n,`daemon`],category:`daemon-spawn`}).ok:!1}const rt=`cc-candybar`,it=`dispatch`,at=`set-state`,ot=`step-state`,st=`copy`,ct=`open-vscode`,lt=`show-config-error`,ut=`show-config-warning`;function dt(e){return e.map(encodeURIComponent).join(`/`)}function ft(e){return e.length===0?[]:e.split(`/`).map(decodeURIComponent)}function pt(e){return`${rt}://${it}/${e.map(e=>`e=${encodeURIComponent(`${e.verb}/${dt(e.args)}`)}`).join(`&`)}`}function mt(e){return new g(e).getAll(`e`).map(ht)}function ht(e){let t=e.indexOf(`/`);return t===-1?{verb:e,value:``}:{verb:e.slice(0,t),value:e.slice(t+1)}}const gt=`@promptctl/cc-candybar`,_t=`CCCandybarURLHandler`,vt=[];function yt(e){return/^[A-Za-z0-9_./=,:-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function bt(e){return[`pnpm`,`dlx`,`${gt}@1.8.
|
|
3
|
+
`)}catch(t){e.stderr.write(`cc-candybar: daemon spawn failed: ${t.message}\n`)}}let Ze=null;function Qe(){let t=ke();for(let r=0;r<2;r++){try{let r=n.openSync(t,`wx`,384);try{n.writeSync(r,JSON.stringify({pid:e.pid,ts:Date.now()}))}catch{}return Ze={fd:r,path:t},{kind:`held`}}catch(e){let n=e.code;if(n!==`EEXIST`)return{kind:`error`,reason:`openSync(${t}): ${n??e.message}`}}if(!$e(t))return{kind:`contended`};try{n.unlinkSync(t)}catch(e){if(e.code!==`ENOENT`)return{kind:`error`,reason:`unlink stale spawn.lock: ${e.message}`}}}return{kind:`contended`}}function $e(e){try{let t=n.statSync(e);return Date.now()-t.mtimeMs>1e4}catch{return!0}}function et(){if(!Ze)return;let{fd:e,path:t}=Ze;Ze=null;try{n.closeSync(e)}catch{}try{n.unlinkSync(t)}catch{}}function tt(){try{return n.mkdirSync(we(),{recursive:!0}),null}catch(e){return`mkdir ${we()}: ${e.message}`}}function nt(){let t=e.execPath,n=e.argv[1];return n?ye({bin:t,args:[`--max-old-space-size=400`,n,`daemon`],category:`daemon-spawn`}).ok:!1}const rt=`cc-candybar`,it=`dispatch`,at=`set-state`,ot=`step-state`,st=`copy`,ct=`open-vscode`,lt=`show-config-error`,ut=`show-config-warning`;function dt(e){return e.map(encodeURIComponent).join(`/`)}function ft(e){return e.length===0?[]:e.split(`/`).map(decodeURIComponent)}function pt(e){return`${rt}://${it}/${e.map(e=>`e=${encodeURIComponent(`${e.verb}/${dt(e.args)}`)}`).join(`&`)}`}function mt(e){return new g(e).getAll(`e`).map(ht)}function ht(e){let t=e.indexOf(`/`);return t===-1?{verb:e,value:``}:{verb:e.slice(0,t),value:e.slice(t+1)}}const gt=`@promptctl/cc-candybar`,_t=`CCCandybarURLHandler`,vt=[];function yt(e){return/^[A-Za-z0-9_./=,:-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function bt(e){return[`pnpm`,`dlx`,`${gt}@1.8.4`,...e.map(yt)].join(` `)}function xt(){return o.join(u.homedir(),`Applications`,`${_t}.app`)}function St(){return o.join(u.homedir(),`.claude`,`settings.json`)}function Ct(){if(process.platform!==`darwin`)throw Error(`URL handler installation requires macOS (found platform: ${process.platform}).`)}function wt(){return o.join(u.homedir(),`Library`,`Application Support`,`CCCandybar`)}function Tt(){return o.join(wt(),`url-handler.mjs`)}function Et(e,t,n){let r=e.replace(/"/g,`\\"`),i=t.replace(/"/g,`\\"`);return[`on open location L`,`\tdo shell script "NODE_PATH='${n.replace(/"/g,`\\"`)}' '${r}' '${i}' url-handle " & quoted form of L`,`end open location`].join(`
|
|
4
4
|
`)}function Dt(e){if(!e)throw Error(`install-url-handler: process.argv[1] not set`);return e.endsWith(`.mjs`)||e.endsWith(`.js`)?e:o.resolve(o.dirname(e),`..`,`dist`,`index.mjs`)}function Ot(){let e=Dt(process.argv[1]);if(!n.existsSync(e))throw Error(`install-url-handler: bundled dist not found at ${e}. Reinstall the package.`);n.mkdirSync(wt(),{recursive:!0});let t=Tt();return n.copyFileSync(e,t),t}function kt(){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>${rt}</string>`,` </array>`,` </dict>`,`</array>`].join(`
|
|
5
5
|
`)}]}function At(){Ct();let e=Ot();process.stdout.write(`Copied dist to ${e}\n`);let t=Dt(process.argv[1]),r=o.join(o.dirname(t),`..`,`node_modules`);if(!n.existsSync(r))throw Error(`install-url-handler: node_modules not found at ${r}. Install deps first.`);let i=xt();n.mkdirSync(o.dirname(i),{recursive:!0}),n.existsSync(i)&&n.rmSync(i,{recursive:!0,force:!0}),process.stdout.write(`Building ${i}\n`);let a=ve({bin:`/usr/bin/osacompile`,args:[`-o`,i,`-e`,Et(process.execPath,e,r)],category:`install.osacompile`});if(!a.ok)throw process.stderr.write(a.stderr),Error(`osacompile failed (${a.reason})`);let s=o.join(i,`Contents`,`Info.plist`);for(let{key:e}of kt())ve({bin:`/usr/bin/plutil`,args:[`-remove`,e,s],category:`install.plutil`});for(let{key:e,xml:t}of kt()){let n=ve({bin:`/usr/bin/plutil`,args:[`-insert`,e,`-xml`,t,s],category:`install.plutil`});if(!n.ok)throw process.stderr.write(n.stderr),Error(`plutil -insert ${e} failed (${n.reason})`)}process.stdout.write(`Registering ${rt}:// with Launch Services\n`);let c=ve({bin:`/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister`,args:[`-f`,i],category:`install.lsregister`});if(!c.ok)throw process.stderr.write(c.stderr),Error(`lsregister failed (${c.reason})`);process.stdout.write(`✓ ${_t}.app installed and registered.\n`),process.stdout.write(` Test: open '${rt}://hello-world' && pbpaste\n`)}function jt(e,t=rt){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:st,value:r}:{verb:decodeURIComponent(r.slice(0,i)),value:r.slice(i+1)}}async function Mt(e){e||(process.stderr.write(`url-handle: missing URL argument.
|
|
6
6
|
`),process.exit(1));let t;try{t=jt(e)}catch(e){process.stderr.write(`url-handle: ${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let n=await qe(t.verb,t.value);n.kind===`ok`&&process.exit(0),n.kind===`transient`&&(Je(),process.stderr.write(`url-handle: daemon unavailable (${n.cause}: ${n.message})\n`),process.exit(1)),process.stderr.write(Nt(n)+`
|
|
@@ -98,34 +98,34 @@ Use 'override' annotation for methods overridden by subclass.`)}}var $i=aa(0),ea
|
|
|
98
98
|
With: root: { v: [{ h: ["seg1", "seg2"] }, "seg3"] }
|
|
99
99
|
Single-row example: root: { h: ["seg1", "seg2"] }`,line:Q(e.source,[`layout`])}),t.root!==void 0&&(n.root=Oc(e,`root`,t.root)),t.actions!==void 0&&(n.actions=Fm(e,t.actions)),t.helpers!==void 0&&(n.helpers=ih(e,t.helpers)),Bc(e,n),jm(e,n),n}const Ph=new Set([`globals`,`variables`,`segments`,`layout`,`root`,`actions`,`helpers`]),Fh=/"(?:cache_read_input_tokens|cache_creation_input_tokens)":[1-9]/;function Ih(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 Lh(e){let t=await Rh(e);return t.kind===`ok`?P(Math.floor((t.value+36e5)/1e3)):t}async function Rh(e){for(let t of[65536,1048576]){let n=await fn(e,t);if(n.kind!==`ok`)return n;let r=zh(n.value.buf,n.value.fromStart);if(r!=null)return P(r);if(n.value.fromStart)return F}return F}function zh(e,t){let n=e.toString(`utf8`).split(`
|
|
100
100
|
`),r=+!t;for(let e=n.length-1;e>=r;e--){let t=n[e];if(!t||!Fh.test(t))continue;let r=Ih(t);if(r!=null)return r}return null}const Bh=10*1e3;function Vh(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 Hh(e,t){if(!(t<60))return e*3600/t}function Uh(e,t,n,r){let i=r-t;if(i<50||i>Bh)return;let a=n-e;if(!(a<=0))return a*1e3/i}function Wh(e){let{prev:t,cur:n}=e;if(t===void 0)return;let r=Uh(t.input,t.atMs,n.input,n.atMs),i=Uh(t.output,t.atMs,n.output,n.atMs),a=Uh(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 Gh(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>Bh)continue;let o=Uh(r.total,r.atMs,i.total,i.atMs);n.push(o??0)}if(n.length!==0)return n.join(`,`)}function Kh(e){let t=new Map;for(let[n,r]of Object.entries(e.variables))t.set(n,r);for(let[n,r]of Object.entries(e.segments))if(r.vars)for(let[e,i]of Object.entries(r.vars))t.set(`${n}.${e}`,i);let n=[],r=new Set;for(let t of Nn(e.root)){if(t.when)for(let e of ch(t.when))n.push(e);if(t.kind!==`segment`)continue;let r=e.segments[t.name];if(r){for(let e of[r.template,r.when,r.bg,r.fg])if(e)for(let t of ch(e))n.push(t)}}let i=new Set;for(;n.length>0;){let e=n.pop();for(let a of qh(t,e)){if(r.has(a))continue;r.add(a);let e=t.get(a);if(e){if(e.kind===`input`)i.add(e.path);else if(e.kind===`template`)for(let t of ch(e.template))n.push(t)}}}return i}function qh(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 Jh(e,t){for(let n of e)if(n===t||n.startsWith(t+`.`))return!0;return!1}function Yh(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.operation`)&&{showOperation:!0},...t(`git.timeSinceCommit`)&&{showTimeSinceCommit:!0},...(t(`git.prNumber`)||t(`git.prState`)||t(`git.prUrl`)||t(`git.prError`))&&{showPullRequest:!0}}}async function Xh(e,t,n,r){let i=e=>Jh(r,e),a=(t.clock??(()=>new Date))().getTime(),o=(e,t,n)=>t?n().catch(t=>I(`${e}: ${String(t)}`)):Promise.resolve(F),[s,c,l,u,d,f,p,m]=await Promise.all([o(`git`,i(`git`),()=>t.gitProvider.getGitInfo(n??e.workspace?.current_dir,Yh(r),e.workspace?.project_dir)),o(`session`,i(`session.cost`)||i(`session.tokens`)||i(`burn`),()=>t.usageStore.getUsageInfo(e.session_id,e)),o(`today`,i(`today`),()=>t.usageStore.getTodayInfo(e)),o(`context`,i(`context`),()=>t.contextProvider.getContextInfo(e)),o(`metrics`,i(`metrics`)||i(`burn`),()=>t.metricsProvider.getMetricsInfo(e.session_id,e)),o(`tmux`,i(`tmux`),()=>t.tmuxService.getSessionId()),o(`cache`,i(`cache`),()=>Lh(e.transcript_path)),o(`speed`,i(`speed`),()=>t.usageStore.observeSpeed(e.session_id,e.transcript_path,a))]),h=[],g=e=>{if(e.kind===`failed`){h.push(e.reason);return}return e.kind===`ok`?e.value:void 0},_=$h(s);h.push(..._.failures);let v=g(c),y=g(l),b=g(u),x=g(d),S=g(f),C=g(p);for(let e of h)t.log(`warn`,`provider fetch failed: ${e}`);let ee=e.rate_limits?.five_hour,te=e.rate_limits?.seven_day,w=ee?Vh(ee.used_percentage,ee.resets_at,18e6,a):void 0,ne=te?Vh(te.used_percentage,te.resets_at,6048e5,a):void 0,re=v?.session.cost,ie=x?.sessionDuration,T=i(`burn`)&&re!=null&&ie!=null?Hh(re,ie):void 0,E=g(m),ae=E===void 0?void 0:Wh(E),oe=E===void 0?void 0:Gh(E),se=ae!==void 0||oe!==void 0?{...ae,...oe!==void 0&&{history:oe}}:void 0,ce=i(`theme`)?t.sessionState.get(e.session_id,`theme`):void 0,D=typeof ce==`string`?ce:void 0,le=Qh(process.env.HOME??process.env.USERPROFILE),ue=e.workspace?{...e.workspace,current_dir:Qh(e.workspace.current_dir)??``,project_dir:Qh(e.workspace.project_dir)??``}:e.workspace,O=v===void 0?void 0:Zh({cost:v.session.cost,tokens:v.session.tokens}),de=y===void 0?void 0:{cost:y.cost,tokens:y.tokens},fe=x===void 0?void 0:Zh({lastResponseTime:x.lastResponseTime,responseTime:x.responseTime,sessionDuration:x.sessionDuration,messageCount:x.messageCount,linesAdded:x.linesAdded,linesRemoved:x.linesRemoved});return{...e,...ue!==void 0&&{workspace:ue},...le!==void 0&&{home:le},..._.git!==void 0&&{git:_.git},...S!==void 0&&{tmux:{session:S}},...D!==void 0&&{theme:D},...O!==void 0&&{session:O},...de!==void 0&&{today:de},...T!==void 0&&{burn:{costPerHour:T}},...se!==void 0&&{speed:se},...i(`block`)&&ee!==void 0&&{block:{nativeUtilization:ee.used_percentage,resetsAt:ee.resets_at,...w!==void 0&&{etaMinutes:w}}},...te!==void 0&&{weekly:{percentage:te.used_percentage,resetsAt:te.resets_at,...ne!==void 0&&{etaMinutes:ne}}},...C!==void 0&&{cache:{expiresAt:C}},...b!==void 0&&{context:{totalTokens:b.totalTokens,contextLeft:b.contextLeftPercentage}},...fe!==void 0&&{metrics:fe}}}function Zh(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 Qh(e){return e===void 0||e.length===0||o.sep!==`\\`?e:e.replace(/\\/g,`/`)}function $h(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=t.pullRequest,f={};return d?.kind===`ok`?(f.prNumber=d.value.number,f.prState=d.value.state,f.prUrl=d.value.url):d?.kind===`failed`&&(n.push(`git.pr: ${d.reason}`),f.prError=d.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},...f},failures:n}}function eg(e){let t=typeof e;if(t===`string`||t===`number`||t===`boolean`)return t;throw TypeError(`Variable values must be string|number|boolean (got ${t})`)}function tg(e){return typeof e==`string`?e:String(e)}function ng(e){if(typeof e==`number`)return e;if(typeof e==`boolean`)return+!!e;let t=e.trim();if(t===``)throw TypeError(`Cannot cast empty string to number`);let n=Number(t);if(!Number.isFinite(n))throw TypeError(`Cannot cast ${JSON.stringify(e)} to number`);return n}function rg(e){if(typeof e==`boolean`)return e;if(typeof e==`number`){if(e===0||e===1)return e===1;throw TypeError(`Cannot cast number ${e} to bool (only 0 and 1 are accepted)`)}if(e===`true`)return!0;if(e===`false`)return!1;throw TypeError(`Cannot cast ${JSON.stringify(e)} to bool (expected "true" or "false")`)}const ig=/^(?:(?:global|apac|au|eu|us|us-east-\d|us-west-\d|eu-west-\d|eu-central-\d)\.)?(?:anthropic\.|azure_ai\/|bedrock\/|vertex_ai\/)?claude-(?:(?<family>opus|sonnet|haiku)-(?<newMajor>\d+)(?:-(?<newMinor>\d))?|(?<oldMajor>\d+)(?:-(?<oldMinor>\d))?-(?<oldFamily>opus|sonnet|haiku))(?:[-@]\d{8})?(?:-v\d+:\d+)?(?:-latest)?$/i,ag=/^(?<family>opus|sonnet|haiku)\s+(?<major>\d+)(?:\.(?<minor>\d))?$/i;function og(e){if(!e)return`Claude`;let t=e.trim().replace(/\s*\([^)]*\)\s*$/,``).replace(/\s*\[[^\]]*\]\s*$/,``).trim(),n=t.match(ig);if(n?.groups){let{family:e,newMajor:t,newMinor:r,oldMajor:i,oldMinor:a,oldFamily:o}=n.groups,s=e||o,c=t||i,l=r||a;if(s&&c)return`${s.charAt(0).toUpperCase()+s.slice(1).toLowerCase()} ${l?`${c}.${l}`:c}`}let r=t.match(ag);if(r?.groups){let e=r.groups.family,t=r.groups.major,n=r.groups.minor;return`${e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()} ${n?`${t}.${n}`:t}`}return t||e}function sg(e){let t=e.match(ag);if(!t?.groups)return e;let n=t.groups.family,r=t.groups.major,i=t.groups.minor;return`${n.charAt(0).toUpperCase()}${i?`${r}.${i}`:r}`}function cg(e){return e.toLocaleString()}const lg=[`▁`,`▂`,`▃`,`▄`,`▅`,`▆`,`▇`,`█`],ug=lg.length;function dg(e,t){let n=t===void 0?e:t<=0?[]:e.slice(-t);if(n.length===0)return``;let r=n[0],i=n[0];for(let e of n)e<r&&(r=e),e>i&&(i=e);let a=i-r,o=``;for(let e of n){let t=a===0?0:Math.round((e-r)/a*(ug-1));o+=lg[t]}return o}function fg(e){let t=[];for(let n of e.split(`,`)){let e=n.trim();if(e===``)continue;let r=Number(e);if(!Number.isFinite(r))throw TypeError(`sparkline: non-numeric series element ${JSON.stringify(n)}`);t.push(r)}return t}const pg=rs(),mg=[...is];function hg(){return{basename:{fn:e=>s(e),argTypes:[`string`]},dirname:{fn:e=>c(e),argTypes:[`string`]},int:{fn:e=>ng(e),argTypes:[`value`]},string:{fn:e=>tg(e),argTypes:[`value`]},bool:{fn:e=>rg(e),argTypes:[`value`]},urlEncode:{fn:e=>encodeURIComponent(e),argTypes:[`string`]},themes:{fn:()=>pg,argTypes:[]},styles:{fn:()=>mg,argTypes:[]},sparkline:{fn:(e,t)=>dg(fg(e),t),argTypes:[`string`,`int`]}}}function gg(e=()=>new Date){return{minutesUntilReset:{fn:t=>Math.round(Math.max(0,t*1e3-e().getTime())/6e4),argTypes:[`int`]},formatInteger:{fn:e=>cg(e),argTypes:[`int`]},round:{fn:e=>Math.round(e),argTypes:[`float`]},formatModelName:{fn:e=>og(e),argTypes:[`string`]},shortenModelName:{fn:e=>sg(e),argTypes:[`string`]}}}function _g(e,t,n=()=>new Date){return bu({fromString:e=>new Ca(e),toString:e=>e.plain,clock:n,missingKey:`error`,funcs:{...df(),...bm(),...Xf(),...vp(),...nf(n),...Ku(),...wf(),...Qo(),...e===void 0?{}:Zo(e),...hg(),...gg(n),...t??{}}})}function vg(e){return yg(e,new Set(e.names()),``)}function yg(e,t,n){return new Proxy(Object.create(null),{has(e,r){if(typeof r!=`string`)return!1;let i=n?`${n}.${r}`:r;if(t.has(i))return!0;let a=`${i}.`;for(let e of t)if(e.startsWith(a))return!0;return!1},get(r,i){if(typeof i!=`string`)return;let a=n?`${n}.${i}`:i;if(t.has(a))return e.read(a);let o=`${a}.`;for(let n of t)if(n.startsWith(o))return yg(e,t,a)}})}function bg(e,t){return t.kind!==`ttl`||t.durationMs>=500?t:(O(`declareShell "${e}": ttl ${t.durationMs}ms below floor 500ms; clamping`),{kind:`ttl`,durationMs:500})}function xg(e){let t=/^(\d+(?:\.\d+)?)(ms|s|m|h)$/.exec(e);if(!t)throw RangeError(`Invalid duration: "${e}"`);let n=parseFloat(t[1]);switch(t[2]){case`ms`:return n;case`s`:return n*1e3;case`m`:return n*6e4;case`h`:return n*36e5;default:throw RangeError(`Unexpected duration unit: "${t[2]}"`)}}async function Sg(e){let t=await _e({bin:`/bin/sh`,args:[`-c`,e],category:`user-shell`});return t.ok?{stdout:t.stdout,exitCode:t.exitCode??0}:{stdout:t.stdout,exitCode:t.exitCode??1}}async function Cg(e,t,n){let r;try{r=await C(e,`utf8`)}catch{return{error:`file unreadable: ${e}`}}if(n!==void 0){let t=new RegExp(n).exec(r);return t?.[1]?{content:t[1].replace(/\n/g,` `)}:{error:`regex no-match in "${e}"`}}return t===`first-line`?{content:(r.split(`
|
|
101
|
-
`)[0]??``).trim()}:{content:r.replace(/\n/g,` `).trim()}}const wg=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],Tg=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],Eg=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],Dg=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`];function Og(e,t){let n=[[`2006`,e=>String(e.getFullYear())],[`January`,e=>wg[e.getMonth()]],[`Monday`,e=>Eg[e.getDay()]],[`Jan`,e=>Tg[e.getMonth()]],[`Mon`,e=>Dg[e.getDay()]],[`15`,e=>String(e.getHours()).padStart(2,`0`)],[`06`,e=>String(e.getFullYear()%100).padStart(2,`0`)],[`01`,e=>String(e.getMonth()+1).padStart(2,`0`)],[`02`,e=>String(e.getDate()).padStart(2,`0`)],[`04`,e=>String(e.getMinutes()).padStart(2,`0`)],[`05`,e=>String(e.getSeconds()).padStart(2,`0`)],[`PM`,e=>e.getHours()<12?`AM`:`PM`],[`pm`,e=>e.getHours()<12?`am`:`pm`],[`1`,e=>String(e.getMonth()+1)],[`2`,e=>String(e.getDate())],[`3`,e=>String(e.getHours()%12||12)],[`4`,e=>String(e.getMinutes())],[`5`,e=>String(e.getSeconds())]],r=``,i=0;for(;i<e.length;){let a=!1;for(let[o,s]of n)if(e.startsWith(o,i)){r+=s(t),i+=o.length,a=!0;break}a||(r+=e[i],i++)}return r}const kg={branch:`string`,sha:`string`,dirty:`boolean`,ahead:`number`,behind:`number`,stash:`number`};function Ag(e,t,n,r){if(e===null){if(n!==void 0)return n;let e=kg[t];try{return Pg(r,e)}catch{return Fg(e)}}switch(t){case`branch`:return e.branch===`detached`?``:e.branch;case`sha`:return zt(e.sha,``);case`dirty`:return e.status!==`clean`;case`ahead`:return zt(e.aheadBehind,{ahead:0,behind:0}).ahead;case`behind`:return zt(e.aheadBehind,{ahead:0,behind:0}).behind;case`stash`:return zt(e.stashCount,0)}}var jg=class{watchers=new Map;subscribe(e,t){let n=this.watchers.get(e);if(!n){let t=new Set,r;try{r=a(e,()=>{for(let e of t)e()})}catch{return()=>{}}n={watcher:r,callbacks:t},this.watchers.set(e,n)}return n.callbacks.add(t),()=>this.unsubscribe(e,t)}unsubscribe(e,t){let n=this.watchers.get(e);n&&(n.callbacks.delete(t),n.callbacks.size===0&&(n.watcher.close(),this.watchers.delete(e)))}dispose(){for(let{watcher:e}of this.watchers.values())e.close();this.watchers.clear()}size(){return this.watchers.size}},Mg=class{buckets=new Map;subscribe(e,t){let n=this.buckets.get(e);if(!n){let t=new Set;n={timer:re(()=>{for(let e of t)e()},e),callbacks:t},this.buckets.set(e,n)}return n.callbacks.add(t),()=>this.unsubscribe(e,t)}unsubscribe(e,t){let n=this.buckets.get(e);n&&(n.callbacks.delete(t),n.callbacks.size===0&&(ne(n.timer),this.buckets.delete(e)))}dispose(){for(let{timer:e}of this.buckets.values())ne(e);this.buckets.clear()}bucketCount(){return this.buckets.size}};function Ng(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n)return;n=n[e]}return n}function Pg(e,t){if(typeof e!=`string`&&typeof e!=`number`&&typeof e!=`boolean`)throw TypeError(`Expected string|number|boolean from payload, got ${typeof e}`);return t===`string`?tg(e):t===`number`?ng(e):rg(e)}function Fg(e){return e===`number`?0:e===`boolean`?!1:``}var Ig=class{inputMetas=new Map;lastErrors=new Map;watchMgr=new jg;ttlMgr=new Mg;gitSubscriptions=new Map;cleanups=[];inFlight=new Set;engine=_g();gitProvider;ownsGitProvider;sessionState;constructor(e,t=``,n,r){this.store=e,this.defaultEmptyValue=t,n?(this.gitProvider=n,this.ownsGitProvider=!1):(this.gitProvider=new rn({sanityIntervalMs:0}),this.ownsGitProvider=!0),this.sessionState=r}get variableStore(){return this.store}declareLiteral(e,t){this.store.defineBox(e,eg(t),t)}declareInput(e,t,n,r){let i=r===void 0?this.defaultFor(n):r;this.store.defineBox(e,n,i),this.inputMetas.set(e,{path:t,varDefault:r})}declareEnv(e,t,n){let r=process.env[t];if(r!==void 0){this.store.defineBox(e,`string`,r);return}let i=n===void 0?typeof this.defaultEmptyValue==`string`?this.defaultEmptyValue:``:n;this.store.defineBox(e,`string`,i),this.recordError(e,`env var "${t}" is not set`)}declareShell(e,t,n){let r=bg(e,n.cache);this.store.defineBox(e,`string`,this.stringInitial(n.varDefault));let i=()=>void this.updateFromShell(e,t,n.regex,n.varDefault);i(),this.registerCachePolicy(e,r,i)}declareFile(e,t,n){this.store.defineBox(e,`string`,this.stringInitial(n.varDefault));let r=()=>void this.updateFromFile(e,t,n.readMode,n.regex,n.varDefault);r(),this.registerCachePolicy(e,n.cache,r)}declareTemplate(e,t,n={}){let r=this.engine.parse(t);this.store.defineComputed(e,`string`,t=>{let i=vg(this.store);try{let t=r.evaluate(i).map(e=>e.plain).join(``);return this.lastErrors.delete(e),t}catch(t){return this.recordError(e,t instanceof Error?t.message:String(t)),this.stringInitial(n.varDefault)}}),this.store.read(e)}declareTime(e,t){let n=t.ttlMs??1e3;this.store.defineBox(e,`string`,(e=>{try{return Og(t.format,e)}catch{return this.stringInitial(t.varDefault)}})(new Date));let r=this.ttlMgr.subscribe(n,()=>{try{this.store.setBox(e,Og(t.format,new Date)),this.lastErrors.delete(e)}catch(n){this.applyFallback(e,`string`,t.varDefault,n instanceof Error?n.message:String(n))}});this.cleanups.push(r)}declareGit(e,t){let n=kg[t.field],r=t.varDefault===void 0?Fg(n):Pg(t.varDefault,n);this.store.defineBox(e,n,r);let i=this.gitSubscriptions.get(t.cwd);if(!i){let e=new Map;i={fieldSubs:e,unsubscribe:this.gitProvider.subscribe(t.cwd,t=>{this.store.runInAction(()=>{for(let[n,r]of e)for(let{name:e,varDefault:i}of r)this.store.setBox(e,Ag(t,n,i,this.defaultEmptyValue))})})},this.gitSubscriptions.set(t.cwd,i)}let a=i.fieldSubs.get(t.field);a||(a=[],i.fieldSubs.set(t.field,a)),a.push({name:e,varDefault:t.varDefault})}declareState(e,t){if(!this.sessionState)throw Error(`declareState("${e}"): SourceRegistry was constructed without a SessionState — state-kind variables require a SessionState (the daemon provides one; tests must supply one)`);let n=this.sessionState,r=t.varDefault??this.stringInitial(void 0);this.store.defineComputed(e,`string`,e=>{let i=e(`session.id`);if(typeof i!=`string`||!i)return r;let a=n.get(i,t.key);return a===null?r:a})}applyInput(e){this.store.runInAction(()=>{for(let[t,n]of this.inputMetas){let r=Ng(e,n.path),i=this.store.getType(t);if(r!==void 0)try{this.store.setBox(t,Pg(r,i)),this.lastErrors.delete(t)}catch(e){this.applyFallback(t,i,n.varDefault,e instanceof Error?e.message:String(e))}else this.applyFallback(t,i,n.varDefault,`input path "${n.path}" not found in payload`)}})}getLastError(e){return this.lastErrors.get(e)}dispose(){for(let e of this.cleanups)e();this.cleanups.length=0;for(let e of this.gitSubscriptions.values())e.unsubscribe();this.gitSubscriptions.clear(),this.watchMgr.dispose(),this.ttlMgr.dispose(),this.ownsGitProvider&&this.gitProvider.close()}registerCachePolicy(e,t,n){switch(t.kind){case`never`:break;case`ttl`:{let e=this.ttlMgr.subscribe(t.durationMs,n);this.cleanups.push(e);break}case`watch_file`:{let e=this.watchMgr.subscribe(t.path,n);this.cleanups.push(e);break}case`key`:{let e=this.engine.parse(t.template),r=(0,X.reaction)(()=>{let t=vg(this.store);try{return e.evaluate(t).map(e=>e.plain).join(``)}catch{return``}},n);this.cleanups.push(r);break}case`depends_on`:{let e=(0,X.reaction)(()=>t.varNames.map(e=>String(this.store.read(e))).join(`,`),n);this.cleanups.push(e);break}}}async updateFromShell(e,t,n,r){if(!this.inFlight.has(e)){this.inFlight.add(e);try{let{stdout:i,exitCode:a}=await Sg(t);if(a!==0){this.applyFallback(e,`string`,r,`shell "${t}" exited with code ${a}`);return}if(n!==void 0){let a=new RegExp(n).exec(i);if(!a?.[1]){this.applyFallback(e,`string`,r,`regex no-match in output of "${t}"`);return}this.store.setBox(e,a[1].replace(/\n/g,` `))}else this.store.setBox(e,i.replace(/\n/g,` `).trim());this.lastErrors.delete(e)}finally{this.inFlight.delete(e)}}}async updateFromFile(e,t,n,r,i){if(!this.inFlight.has(e)){this.inFlight.add(e);try{let a=await Cg(t,n,r);if(a.error!==void 0){this.applyFallback(e,`string`,i,a.error);return}this.store.setBox(e,a.content??``),this.lastErrors.delete(e)}finally{this.inFlight.delete(e)}}}applyFallback(e,t,n,r){if(this.recordError(e,r),n!==void 0){this.store.setBox(e,n);return}try{this.store.setBox(e,Pg(this.defaultEmptyValue,t))}catch{this.store.setBox(e,Fg(t))}}defaultFor(e){try{return Pg(this.defaultEmptyValue,e)}catch{return Fg(e)}}stringInitial(e){return e===void 0?typeof this.defaultEmptyValue==`string`?this.defaultEmptyValue:``:e}recordError(e,t){this.lastErrors.set(e,{timestamp:Date.now(),message:t})}};function Lg(e,t){switch(e){case`capsule`:return new Aa;case`plain`:return new ja(t===void 0?{}:{separator:t});case`powerline`:return new ka;default:return e}}function Rg(e,t){if(e.length===0)return``;let n=Lg(t.style,t.separator);if(Number.isFinite(t.width)){let r=Pa(new Ka([...e],{joiner:n}),{width:t.width,colorSystem:t.colorCompatibility});return r.endsWith(`
|
|
102
|
-
`)?r.slice(0,-1):r}return Pa(new wa([...e],n),{colorSystem:t.colorCompatibility})}const
|
|
101
|
+
`)[0]??``).trim()}:{content:r.replace(/\n/g,` `).trim()}}const wg=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],Tg=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],Eg=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],Dg=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`];function Og(e,t){let n=[[`2006`,e=>String(e.getFullYear())],[`January`,e=>wg[e.getMonth()]],[`Monday`,e=>Eg[e.getDay()]],[`Jan`,e=>Tg[e.getMonth()]],[`Mon`,e=>Dg[e.getDay()]],[`15`,e=>String(e.getHours()).padStart(2,`0`)],[`06`,e=>String(e.getFullYear()%100).padStart(2,`0`)],[`01`,e=>String(e.getMonth()+1).padStart(2,`0`)],[`02`,e=>String(e.getDate()).padStart(2,`0`)],[`04`,e=>String(e.getMinutes()).padStart(2,`0`)],[`05`,e=>String(e.getSeconds()).padStart(2,`0`)],[`PM`,e=>e.getHours()<12?`AM`:`PM`],[`pm`,e=>e.getHours()<12?`am`:`pm`],[`1`,e=>String(e.getMonth()+1)],[`2`,e=>String(e.getDate())],[`3`,e=>String(e.getHours()%12||12)],[`4`,e=>String(e.getMinutes())],[`5`,e=>String(e.getSeconds())]],r=``,i=0;for(;i<e.length;){let a=!1;for(let[o,s]of n)if(e.startsWith(o,i)){r+=s(t),i+=o.length,a=!0;break}a||(r+=e[i],i++)}return r}const kg={branch:`string`,sha:`string`,dirty:`boolean`,ahead:`number`,behind:`number`,stash:`number`};function Ag(e,t,n,r){if(e===null){if(n!==void 0)return n;let e=kg[t];try{return Pg(r,e)}catch{return Fg(e)}}switch(t){case`branch`:return e.branch===`detached`?``:e.branch;case`sha`:return zt(e.sha,``);case`dirty`:return e.status!==`clean`;case`ahead`:return zt(e.aheadBehind,{ahead:0,behind:0}).ahead;case`behind`:return zt(e.aheadBehind,{ahead:0,behind:0}).behind;case`stash`:return zt(e.stashCount,0)}}var jg=class{watchers=new Map;subscribe(e,t){let n=this.watchers.get(e);if(!n){let t=new Set,r;try{r=a(e,()=>{for(let e of t)e()})}catch{return()=>{}}n={watcher:r,callbacks:t},this.watchers.set(e,n)}return n.callbacks.add(t),()=>this.unsubscribe(e,t)}unsubscribe(e,t){let n=this.watchers.get(e);n&&(n.callbacks.delete(t),n.callbacks.size===0&&(n.watcher.close(),this.watchers.delete(e)))}dispose(){for(let{watcher:e}of this.watchers.values())e.close();this.watchers.clear()}size(){return this.watchers.size}},Mg=class{buckets=new Map;subscribe(e,t){let n=this.buckets.get(e);if(!n){let t=new Set;n={timer:re(()=>{for(let e of t)e()},e),callbacks:t},this.buckets.set(e,n)}return n.callbacks.add(t),()=>this.unsubscribe(e,t)}unsubscribe(e,t){let n=this.buckets.get(e);n&&(n.callbacks.delete(t),n.callbacks.size===0&&(ne(n.timer),this.buckets.delete(e)))}dispose(){for(let{timer:e}of this.buckets.values())ne(e);this.buckets.clear()}bucketCount(){return this.buckets.size}};function Ng(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n)return;n=n[e]}return n}function Pg(e,t){if(typeof e!=`string`&&typeof e!=`number`&&typeof e!=`boolean`)throw TypeError(`Expected string|number|boolean from payload, got ${typeof e}`);return t===`string`?tg(e):t===`number`?ng(e):rg(e)}function Fg(e){return e===`number`?0:e===`boolean`?!1:``}var Ig=class{inputMetas=new Map;lastErrors=new Map;watchMgr=new jg;ttlMgr=new Mg;gitSubscriptions=new Map;cleanups=[];inFlight=new Set;engine=_g();gitProvider;ownsGitProvider;sessionState;constructor(e,t=``,n,r){this.store=e,this.defaultEmptyValue=t,n?(this.gitProvider=n,this.ownsGitProvider=!1):(this.gitProvider=new rn({sanityIntervalMs:0}),this.ownsGitProvider=!0),this.sessionState=r}get variableStore(){return this.store}declareLiteral(e,t){this.store.defineBox(e,eg(t),t)}declareInput(e,t,n,r){let i=r===void 0?this.defaultFor(n):r;this.store.defineBox(e,n,i),this.inputMetas.set(e,{path:t,varDefault:r})}declareEnv(e,t,n){let r=process.env[t];if(r!==void 0){this.store.defineBox(e,`string`,r);return}let i=n===void 0?typeof this.defaultEmptyValue==`string`?this.defaultEmptyValue:``:n;this.store.defineBox(e,`string`,i),this.recordError(e,`env var "${t}" is not set`)}declareShell(e,t,n){let r=bg(e,n.cache);this.store.defineBox(e,`string`,this.stringInitial(n.varDefault));let i=()=>void this.updateFromShell(e,t,n.regex,n.varDefault);i(),this.registerCachePolicy(e,r,i)}declareFile(e,t,n){this.store.defineBox(e,`string`,this.stringInitial(n.varDefault));let r=()=>void this.updateFromFile(e,t,n.readMode,n.regex,n.varDefault);r(),this.registerCachePolicy(e,n.cache,r)}declareTemplate(e,t,n={}){let r=this.engine.parse(t);this.store.defineComputed(e,`string`,t=>{let i=vg(this.store);try{let t=r.evaluate(i).map(e=>e.plain).join(``);return this.lastErrors.delete(e),t}catch(t){return this.recordError(e,t instanceof Error?t.message:String(t)),this.stringInitial(n.varDefault)}}),this.store.read(e)}declareTime(e,t){let n=t.ttlMs??1e3;this.store.defineBox(e,`string`,(e=>{try{return Og(t.format,e)}catch{return this.stringInitial(t.varDefault)}})(new Date));let r=this.ttlMgr.subscribe(n,()=>{try{this.store.setBox(e,Og(t.format,new Date)),this.lastErrors.delete(e)}catch(n){this.applyFallback(e,`string`,t.varDefault,n instanceof Error?n.message:String(n))}});this.cleanups.push(r)}declareGit(e,t){let n=kg[t.field],r=t.varDefault===void 0?Fg(n):Pg(t.varDefault,n);this.store.defineBox(e,n,r);let i=this.gitSubscriptions.get(t.cwd);if(!i){let e=new Map;i={fieldSubs:e,unsubscribe:this.gitProvider.subscribe(t.cwd,t=>{this.store.runInAction(()=>{for(let[n,r]of e)for(let{name:e,varDefault:i}of r)this.store.setBox(e,Ag(t,n,i,this.defaultEmptyValue))})})},this.gitSubscriptions.set(t.cwd,i)}let a=i.fieldSubs.get(t.field);a||(a=[],i.fieldSubs.set(t.field,a)),a.push({name:e,varDefault:t.varDefault})}declareState(e,t){if(!this.sessionState)throw Error(`declareState("${e}"): SourceRegistry was constructed without a SessionState — state-kind variables require a SessionState (the daemon provides one; tests must supply one)`);let n=this.sessionState,r=t.varDefault??this.stringInitial(void 0);this.store.defineComputed(e,`string`,e=>{let i=e(`session.id`);if(typeof i!=`string`||!i)return r;let a=n.get(i,t.key);return a===null?r:a})}applyInput(e){this.store.runInAction(()=>{for(let[t,n]of this.inputMetas){let r=Ng(e,n.path),i=this.store.getType(t);if(r!==void 0)try{this.store.setBox(t,Pg(r,i)),this.lastErrors.delete(t)}catch(e){this.applyFallback(t,i,n.varDefault,e instanceof Error?e.message:String(e))}else this.applyFallback(t,i,n.varDefault,`input path "${n.path}" not found in payload`)}})}getLastError(e){return this.lastErrors.get(e)}dispose(){for(let e of this.cleanups)e();this.cleanups.length=0;for(let e of this.gitSubscriptions.values())e.unsubscribe();this.gitSubscriptions.clear(),this.watchMgr.dispose(),this.ttlMgr.dispose(),this.ownsGitProvider&&this.gitProvider.close()}registerCachePolicy(e,t,n){switch(t.kind){case`never`:break;case`ttl`:{let e=this.ttlMgr.subscribe(t.durationMs,n);this.cleanups.push(e);break}case`watch_file`:{let e=this.watchMgr.subscribe(t.path,n);this.cleanups.push(e);break}case`key`:{let e=this.engine.parse(t.template),r=(0,X.reaction)(()=>{let t=vg(this.store);try{return e.evaluate(t).map(e=>e.plain).join(``)}catch{return``}},n);this.cleanups.push(r);break}case`depends_on`:{let e=(0,X.reaction)(()=>t.varNames.map(e=>String(this.store.read(e))).join(`,`),n);this.cleanups.push(e);break}}}async updateFromShell(e,t,n,r){if(!this.inFlight.has(e)){this.inFlight.add(e);try{let{stdout:i,exitCode:a}=await Sg(t);if(a!==0){this.applyFallback(e,`string`,r,`shell "${t}" exited with code ${a}`);return}if(n!==void 0){let a=new RegExp(n).exec(i);if(!a?.[1]){this.applyFallback(e,`string`,r,`regex no-match in output of "${t}"`);return}this.store.setBox(e,a[1].replace(/\n/g,` `))}else this.store.setBox(e,i.replace(/\n/g,` `).trim());this.lastErrors.delete(e)}finally{this.inFlight.delete(e)}}}async updateFromFile(e,t,n,r,i){if(!this.inFlight.has(e)){this.inFlight.add(e);try{let a=await Cg(t,n,r);if(a.error!==void 0){this.applyFallback(e,`string`,i,a.error);return}this.store.setBox(e,a.content??``),this.lastErrors.delete(e)}finally{this.inFlight.delete(e)}}}applyFallback(e,t,n,r){if(this.recordError(e,r),n!==void 0){this.store.setBox(e,n);return}try{this.store.setBox(e,Pg(this.defaultEmptyValue,t))}catch{this.store.setBox(e,Fg(t))}}defaultFor(e){try{return Pg(this.defaultEmptyValue,e)}catch{return Fg(e)}}stringInitial(e){return e===void 0?typeof this.defaultEmptyValue==`string`?this.defaultEmptyValue:``:e}recordError(e,t){this.lastErrors.set(e,{timestamp:Date.now(),message:t})}};function Lg(e,t){switch(e){case`capsule`:return new Aa;case`plain`:return new ja(t===void 0?{}:{separator:t});case`powerline`:return new ka;default:return e}}function Rg(e){switch(e){case`powerline`:return 1;case`capsule`:return 2;case`plain`:return 0;default:return e}}function zg(e,t){if(e.length===0)return``;let n=Lg(t.style,t.separator);if(Number.isFinite(t.width)){let r=Pa(new Ka([...e],{joiner:n}),{width:t.width,colorSystem:t.colorCompatibility});return r.endsWith(`
|
|
102
|
+
`)?r.slice(0,-1):r}return Pa(new wa([...e],n),{colorSystem:t.colorCompatibility})}const Bg=new Map,Vg=new Map;function Hg(e){let t=es(e),n=Bg.get(t);if(n!==void 0)return n;let r=Vi(t);if(r===null)throw Error(`Palette "${e}" (resolved "${t}") did not resolve in the theme registry — allowed names and the registry are inconsistent`);let i=new Pi(r);return Bg.set(t,i),i}function Ug(e,t){let n=`${e.palette.name} ${t}`,r=Vg.get(n);if(r!==void 0)return r;let i={hueShift:t,chromaScale:1,lightnessScale:1,lightnessShift:0},a=new Pi($i(e.palette,i));return Vg.set(n,a),a}function Wg(e,t){let n=[],r=[],i=()=>{if(!r.length)return;let e=Gg(r,t);e.plain.length>0&&n.push(e),r=[]};for(let a of e)if(a.style.link){i();let e=Gg([a],t);e.plain.length>0&&n.push(e)}else r.push(a);return i(),n}function Gg(e,t){let n=t!==void 0&&!t.isNull?e.map(e=>Kg(e,t)):e,r=Ca.fromFragments(n);return r.end=``,r.noWrap=!0,n.length===1?r.style=n[0].style:t!==void 0&&!t.isNull&&(r.style=t),r}function Kg(e,t){let n=e.copy();return n.style=t.add(e.style),n}function qg(e,t){return e===void 0?!0:e.evaluate(t).map(e=>e.plain).join(``)!==`false`}function Jg(e,t){let n=Ca.fromFragments(e);return n.end=``,n.noWrap=!0,t!==void 0&&!t.isNull&&(n.style=t),n}function Yg(e,t){let{width:n,justify:r,truncate:i,truncateMarker:a=`…`,baseStyle:o}=t;if(e.length===0)return[];let s=Jg(e,o);return n===`auto`||(s.cellLength>n?s.truncate(n,{mode:i,marker:a}):s.cellLength<n&&s.align(r,n)),[s]}var Xg=class extends Error{constructor(e,t){super(`Invalid ${t} color spec: ${JSON.stringify(e)}`),this.name=`ColorSpecError`}};function Zg(e,t,n,r){let i=Qg(t,r),a=i===void 0?void 0:$g(e,i,void 0,`bg`),o=Qg(n,r),s=o===void 0?void 0:$g(e,o,a,`fg`);return new J({bgcolor:a===void 0?void 0:K.fromRgba(a),color:s===void 0?void 0:K.fromRgba(s)})}function Qg(e,t){if(e!==void 0)return e.evaluate(t).map(e=>e.plain).join(``)}function $g(e,t,n,r){let i=e.resolve(t.trim(),n===void 0?void 0:{against:n});if(i===null)throw new Xg(t,r);return i}function e_(e){return e===`themes`?rs():is}function t_(e,t,n){let r=new Map;for(let[i,a]of Object.entries(t))r.set(i,n_(e,i,a,n));return r}function n_(e,t,n,r){if(`set`in n){let e=r.get(n.set)??n.set;return`to`in n?{kind:`set-literal`,key:n.set,value:n.to,stateVar:e}:`from`in n?{kind:`set-option`,key:n.set,stateVar:e,options:[...e_(n.from)]}:`int`in n?{kind:`set-int`,key:n.set,stateVar:e}:`cycle`in n?{kind:`set-cycle`,key:n.set,stateVar:e,members:n.cycle}:{kind:`set-bounded`,key:n.set,by:n.by}}return`copy`in n?{kind:`copy`,text:r_(e,n.copy,t)}:{kind:`open`,target:r_(e,n.open,t)}}function r_(e,t,n){try{return e(t)}catch(e){throw Error(`Template parse error in actions.${n}: ${e.message}`,{cause:e})}}function i_(e,t){return e.has(t)?tg(e.read(t)):``}function a_(e,t){return e.evaluate(t).map(e=>e.plain).join(``)}function o_(e,t,n){let r=new Ca(e,{style:new J({link:t,bold:n})});return r.noWrap=!0,r.end=``,r}function s_(e,t){return Math.max(e.members.indexOf(i_(t,e.stateVar)),0)}function c_(e,t,n,r,i){switch(e.kind){case`set-literal`:{let t=i_(r,e.stateVar);return{effect:{verb:at,args:[i,e.key,e.value]},active:t===e.value}}case`set-option`:{let a=n??t,o=i_(r,e.stateVar);return{effect:{verb:at,args:[i,e.key,a]},active:o===a}}case`set-int`:{let a=n??t,o=i_(r,e.stateVar);return{effect:{verb:at,args:[i,e.key,a]},active:o===a}}case`set-cycle`:{let t=e.members[(s_(e,r)+1)%e.members.length];return{effect:{verb:at,args:[i,e.key,t]},active:!1}}case`set-bounded`:return{effect:{verb:ot,args:[i,e.key,String(e.by)]},active:!1};case`copy`:return{effect:{verb:st,args:[a_(e.text,vg(r))]},active:!1};case`open`:return{effect:{verb:ct,args:[a_(e.target,vg(r))]},active:!1}}}function l_(e,t,n,r){if(n.length===0)throw Error(`action "${e}" needs a display (the clickable text)`);if(t.kind===`set-cycle`){if(n.length!==1&&n.length!==t.members.length)throw Error(`action "${e}" cycles ${t.members.length} members; bind one display per member (${t.members.length}) or one static display, got ${n.length}`);return{display:n.length===1?n[0]:n[s_(t,r)],boundValue:void 0}}if(n.length>2)throw Error(`action "${e}" takes a display and an optional bound value, got ${n.length} arguments (per-state displays are a cycle action's form)`);return{display:n[0],boundValue:n[1]}}function u_(e,t,n){let r=n.compiled.get(e);if(!r)throw Error(`action "${e}" is not declared in this config`);let i=n.store,{display:a,boundValue:o}=l_(e,r,t,i),{effect:s,active:c}=c_(r,a,o,i,i_(i,`session.id`));return o_(a,pt([s]),c)}function d_(e){return{action:{fn:(t,...n)=>u_(t,n,e),argTypes:[`string`,`string`],returnType:`T`}}}function f_(e){return new Ca(e).cellLength}function p_(e,t,n){if(!Number.isFinite(t))return e.length>0?[e.map((e,t)=>t)]:[];let r=Math.max(1,t-n),i=[],a=[],o=0;for(let t=0;t<e.length;t++){let n=e[t];a.length===0?(a=[t],o=n):o+1+n<=r?(a.push(t),o+=1+n):(i.push(a),a=[t],o=n)}return a.length>0&&i.push(a),i}function m_(e,t){let n=[];for(let t of e)n.length>0&&n.push(new Ca(` `)),n.push(t);let r=Ca.fromFragments(n);return r.noWrap=t,r.end=``,r}function h_(e,t,n,r){let i=e.compiled.get(t);if(!i||i.kind!==n)throw Error(`picker references action "${t}" which must be ${r}, got ${i?`a ${i.kind} action`:`no such action`}`);return i}function g_(e,t,n,r,i){let a=h_(i,e,`set-option`,`a set-option action ({ set, from })`),o=h_(i,t,`set-int`,`an int action ({ set, int: true })`),s=i.store,c=i_(s,`session.id`),l=i_(s,a.stateVar),u=a.options.map(f_),d=r?Math.max(1,ng(s.read(`term.cols`))-Rg(i.stripStyle)):1/0,f=f_(`✕`)+1,p=f_(`←`)+1+f_(`→`)+1,m=p_(u,d,f),h=m.length>1?p_(u,d,f+p):m,g=parseInt(i_(s,o.stateVar),10),_=Number.isInteger(g)?Math.max(0,Math.min(g,h.length-1)):0,v=h[_]??[],y=e=>pt([{verb:at,args:[c,o.key,String(e)]}]),b=e=>pt([{verb:at,args:[c,a.key,e,...n?[o.key,`-1`]:[]]}]),x=[o_(`✕`,y(-1),!1)];_>0&&x.push(o_(`←`,y(_-1),!1));for(let e of v){let t=a.options[e];x.push(o_(t,b(t),t===l))}return _<h.length-1&&x.push(o_(`→`,y(_+1),!1)),m_(x,r)}function __(e){return{picker:{fn:(t,n,r,i)=>g_(t,n,r===!0,i===!0,e),argTypes:[`string`,`string`,`bool`,`bool`],returnType:`T`}}}const v_=Symbol(`cc-candybar.menuDrop`);function y_(e){return e.flatMap(e=>e[v_]??[])}function b_(e,t){let n=e.compiled.get(t);if(!n||n.kind!==`set-int`)throw Error(`{{ menu }} page action "${t}" must be an int action ({ set, int: true })`);return n.key}function x_(e,t,n,r,i,a){let o=a.current;if(o===null)throw Error(`{{ menu }} rendered with no active segment placement — the render walk must publish one before evaluating a segment template`);let s=a.action,c=Tm(o.segName,e,i),l=wm(e),u=i_(s.store,c)===l,d=i_(s.store,`session.id`),f=o_(u?`▾`:`▸`,pt([{verb:at,args:[d,c,u?Sm:l,b_(s,t),`0`]}]),!1);return f[v_]=u?[g_(e,t,n,r,s)]:[],f}function S_(e){return{menu:{fn:(t,n,r,i,a)=>x_(t,n,r===!0,i===!0,a,e),argTypes:[`string`,`string`,`bool`,`bool`,`string`],returnType:`T`}}}function C_(e){let t=[],n=[];for(let r of e){if(!r.contains(`
|
|
103
103
|
`)){n.push(r);continue}let e=r.split(`
|
|
104
|
-
`);n.push(e[0]);for(let r=1;r<e.length;r++)t.push(n),n=[e[r]]}return t.push(n),t}function
|
|
105
|
-
`)}const
|
|
104
|
+
`);n.push(e[0]);for(let r=1;r<e.length;r++)t.push(n),n=[e[r]]}return t.push(n),t}function w_(e,t){switch(e){case`vertical`:return t.flatMap(e=>e);case`horizontal`:return t.reduce((e,t)=>Math.max(e,t.length),0)===0?[]:[t.flatMap(e=>e[0]??[]),...t.flatMap(e=>e.slice(1))]}}const T_={container:{compile(e,t){return{kind:`container`,direction:e.direction,when:t.when,children:e.children.map((e,n)=>t.compileChild(e,`${t.path}.children[${n}]`))}},render(e,t){return w_(e.direction,e.children.map(e=>t.renderChild(e,t.visible)))}},segment:{compile(e,t){return{kind:`segment`,when:t.when,name:e.name}},render(e,t){let n=t.lookupSegment(e.name);if(!n)throw Error(`Layout segment "${e.name}" has no matching segment`);let{seg:r,compiled:i}=n,a=t.nextHueShift();if(!t.visible)return[];try{if(!qg(i.when,t.scope))return[];t.beginSegment(e.name);let n=i.template.evaluate(t.scope),o=t.collectDrops(n),s=Zg(Ug(i.paletteResolver??t.basePalette,a),i.bg,i.fg,t.scope),c=o.length>0?t.focusTint(s):s,l={width:r.width??`auto`,justify:r.justify??`left`,truncate:r.truncate??`right`,baseStyle:c},u=C_(Wg(n,c)).map(e=>Yg(e,l)),d=o.map(e=>Yg(Wg([e],c),l)),f=[...u,...d];return t.perSegmentSink!==void 0&&t.perSegmentSink.set(e.name,f.flat()),f}catch(t){return[[new Ca(`⚠ ${e.name}: ${t.message??String(t)}`)]]}}}};function E_(e){return T_[e]}function D_(e){if(`ttl`in e)return{kind:`ttl`,durationMs:xg(e.ttl)};if(`watch_file`in e)return{kind:`watch_file`,path:e.watch_file};if(`depends_on`in e)return{kind:`depends_on`,varNames:e.depends_on};if(`key`in e)return{kind:`key`,template:e.key};if(`never`in e)return{kind:`never`};throw Error(`Unknown CacheDecl discriminator — loader invariant violated: ${JSON.stringify(e)}`)}function O_(e,t,n,r){switch(n.kind){case`literal`:e.declareLiteral(t,n.value);break;case`input`:e.declareInput(t,n.path,n.type??`string`,n.default);break;case`env`:e.declareEnv(t,n.name,n.default);break;case`file`:e.declareFile(t,n.path,{readMode:n.readMode,regex:n.regex,cache:D_(n.cache),varDefault:n.default});break;case`shell`:e.declareShell(t,n.command,{regex:n.regex,cache:D_(n.cache),varDefault:n.default});break;case`template`:e.declareTemplate(t,n.template,{varDefault:n.default});break;case`time`:e.declareTime(t,{format:n.layout,ttlMs:n.cache?xg(n.cache.ttl):void 0,varDefault:n.default});break;case`git`:e.declareGit(t,{field:n.field,cwd:r,varDefault:n.default});break;case`state`:e.declareState(t,{key:n.key,...n.default!==void 0&&{varDefault:n.default}});break}}function k_(e,t){let n=``;for(let[r,i]of Object.entries(t)){let t=`{{ define "${r}" }}${i}{{ end }}`;try{e.parse(t)}catch(e){throw Error(`Template parse error in helpers.${r}: ${e.message}`,{cause:e})}n+=t}return n}function A_(e,t,n){let r=n?.cwd??process.cwd(),i={store:t.variableStore,compiled:new Map,stripStyle:`powerline`},a={action:i,current:null},o=_g(void 0,{...d_(i),...__(i),...S_(a)},n?.clock),s=k_(o,e.helpers),c=e=>o.parse(s+e),l=new Map;for(let[t,n]of Object.entries(e.variables))n.kind===`state`&&!l.has(n.key)&&l.set(n.key,t);for(let[t,n]of Object.entries(e.segments))if(n.vars)for(let[e,r]of Object.entries(n.vars))r.kind===`state`&&!l.has(r.key)&&l.set(r.key,`${t}.${e}`);i.compiled=t_(c,e.actions,l);let u=[];for(let[n,i]of Object.entries(e.variables))try{O_(t,n,i,r)}catch(e){u.push(`Variable "${n}": ${e.message??String(e)}`)}for(let[n,i]of Object.entries(e.segments))if(i.vars)for(let[e,a]of Object.entries(i.vars))try{O_(t,`${n}.${e}`,a,r)}catch(t){u.push(`Variable "${n}.${e}": ${t.message??String(t)}`)}let d=Object.create(null);for(let[t,n]of Object.entries(e.segments)){let e=(e,n)=>{try{return c(e)}catch(e){throw Error(`Template parse error in segments.${t}.${n}: ${e.message}`,{cause:e})}};d[t]={when:n.when===void 0?void 0:e(n.when,`when`),template:e(n.template,`template`),bg:n.bg===void 0?void 0:e(n.bg,`bg`),fg:n.fg===void 0?void 0:e(n.fg,`fg`),paletteResolver:n.palette===void 0?void 0:Hg(n.palette)}}let f=(e,t,n)=>{try{return c(e)}catch(e){throw Error(`Template parse error in ${t}.${n}: ${e.message}`,{cause:e})}},p=(e,t)=>{let n={path:t,when:e.when===void 0?void 0:f(e.when,t,`when`),compileChild:p};return E_(e.kind).compile(e,n)};return{segments:d,root:p(e.root,`root`),menuRuntime:a,loadWarnings:u}}function j_(e){let t=e.bgcolor;return t===void 0?e:new J({bgcolor:K.fromRgba(q(t.getTruecolor(),1)),color:e.color})}function M_(e,t,n,r,i,a,o,s){r.applyInput({...i,term:{cols:o.width}}),t.menuRuntime.action.stripStyle=o.style;let c=vg(n),l=n.has(`hue.step`)?Number(n.read(`hue.step`)):0,u=Number.isFinite(l)?l:0;s?.clear();let d={value:0},f=()=>{let e=d.value*u;return d.value+=1,e},p=n=>{let r=e.segments[n],i=t.segments[n];return r!==void 0&&i!==void 0?{seg:r,compiled:i}:void 0},m=e=>{t.menuRuntime.current={segName:e}},h=e=>(t.menuRuntime.current=null,y_(e)),g=(e,t)=>{let n={scope:c,basePalette:a,visible:t&&qg(e.when,c),nextHueShift:f,perSegmentSink:s,beginSegment:m,collectDrops:h,focusTint:j_,lookupSegment:p,renderChild:g};return E_(e.kind).render(e,n)};return g(t.root,!0).map(e=>zg(e,o)).join(`
|
|
105
|
+
`)}const N_=rs(),P_=new Set(N_),F_=new Set(is),I_=e=>e?P_.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown theme "${e}" (have: ${N_.join(`, `)})`}:{ok:!1,reason:`theme name is required`},L_=e=>e?F_.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown style "${e}" (have: ${is.join(`, `)})`}:{ok:!1,reason:`style name is required`},R_=new Set([`1`,`true`]),z_=new Set([`0`,`false`]),B_=new Map([[`style`,{validator:L_,permanent:!0}],[`theme`,{validator:I_,permanent:!0}],[`toolbar-expanded`,{validator:e=>R_.has(e)?{ok:!0,value:`1`}:z_.has(e)?{ok:!0,value:``}:{ok:!1,reason:`expected boolean-ish (1, 0, true, false), got "${e}"`},permanent:!0}]]);function V_(){return[...B_.keys()]}function H_(e,t,n){if(t===`int`)return q_(`menu page "${e}"`);if(t===`range`){let t=n.flatMap(e=>e.kind===`range`?[e.min]:[]),r=n.flatMap(e=>e.kind===`range`?[e.max]:[]);return J_(Math.min(...t),Math.max(...r),`stepper "${e}"`)}return G_([...new Set(n.flatMap(e=>e.kind===`allow-list`?e.allowed:[]))],`state "${e}"`)}function U_(e,t){if(!e)throw Error(`registerStateValidator: key is required`);if(e.includes(`/`))throw Error(`registerStateValidator: key "${e}" contains "/" — the set-state wire shape splits on "/" so a slash-bearing key cannot be addressed. Use a slash-free key.`);let n=B_.get(e);if(n){if(n.permanent)throw Error(`registerStateValidator: key "${e}" is a built-in state key and cannot be re-claimed (built-in keys: ${[...W_()].join(`, `)})`);if(n.kind!==t.kind)throw Error(`registerStateValidator: key "${e}" is already a ${n.kind} state key; cannot also register it as ${t.kind}. A state key has one key shape — a menu page index (int) and a button allow-list cannot share a key.`);n.specs.push(t),n.validator=H_(e,n.kind,n.specs)}else{let n=[t];B_.set(e,{permanent:!1,kind:t.kind,validator:H_(e,t.kind,n),specs:n})}let r=!0;return()=>{if(!r)return;r=!1;let n=B_.get(e);if(!n||n.permanent)return;let i=n.specs.indexOf(t);i>=0&&n.specs.splice(i,1),n.specs.length===0?B_.delete(e):n.validator=H_(e,n.kind,n.specs)}}function W_(){let e=[];for(let[t,n]of B_)n.permanent&&e.push(t);return e}function G_(e,t){let n=e.filter(e=>e.includes(`/`));if(n.length>0)throw Error(`makeAllowListValidator(${t}): values contain "/" — the set-state wire shape splits values on "/" so slash-bearing options cannot be addressed. Offending values: ${n.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 r=new Set(e),i=[...e];return e=>e?r.has(e)?{ok:!0,value:e}:{ok:!1,reason:`unknown ${t} "${e}" (have: ${i.join(`, `)})`}:{ok:!1,reason:`${t} value is required`}}const K_=/^-?\d+$/;function q_(e){return t=>{if(!t)return{ok:!1,reason:`${e} value is required`};if(!K_.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 J_(e,t,n){return r=>r?K_.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 Y_(e){return e===`themes`?N_:is}function X_(e,t){let n=t.filter(e=>e.kind===`range`),r=t.some(e=>e.kind===`int`),i=t.flatMap(e=>e.kind===`allow-list`?e.allowed:[]);if(n.length===0&&!r)return{kind:`allow-list`,allowed:[...new Set(i)]};let a=i.filter(e=>!K_.test(e));if(a.length>0)throw Error(`deriveActionValidators: key "${e}" is an integer spec (a paged cursor or a bounded value) but a click writes non-integer value(s) to it (${a.join(`, `)}). A state key has one key shape — point that click at a distinct key, or write an integer.`);if(r&&n.length>0)throw Error(`deriveActionValidators: key "${e}" is declared as both a paged cursor (int) and a bounded value (range) — a state key has one key shape. Use distinct keys.`);if(n.length>0){let t=Math.min(...n.map(e=>e.min)),r=Math.max(...n.map(e=>e.max)),a=i.filter(e=>{let n=parseInt(e,10);return n<t||n>r});if(a.length>0)throw Error(`deriveActionValidators: key "${e}" is a bounded range [${t},${r}] but a click writes out-of-range value(s) to it (${a.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:r,seed:ev(n[0].seed,t,r)}}return{kind:`int`}}function Z_(e){let t=new Set(W_());return e.filter(e=>e.spec.kind!==`allow-list`||!t.has(e.key))}function Q_(e){let t=new Map;for(let{key:n,spec:r}of e){let e=t.get(n);e?e.push(r):t.set(n,[r])}return[...t].map(([e,t])=>({key:e,spec:X_(e,t)}))}function $_(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:Y_(e.from)}}]:`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,seed:ev(t.get(e.set),e.min,e.max)}}]:[]}function ev(e,t,n){return e===void 0?t:Math.max(t,Math.min(n,e))}function tv(e){let t=new Map;for(let n of Object.values(e.variables)){if(n.kind!==`state`)continue;let e=n.default;e!==void 0&&K_.test(e)&&t.set(n.key,parseInt(e,10))}return t}function nv(e){let t=tv(e);return Z_(Object.values(e.actions).flatMap(e=>$_(e,t)))}function rv(e){return Q_(nv(e))}function iv(e,t){let n=B_.get(e);return n?n.validator(t):{ok:!1,reason:`unknown state key "${e}" (have: ${V_().join(`, `)})`}}function av(e){let t=B_.get(e);if(!t||t.permanent||t.kind!==`range`)return null;let n=t.specs.flatMap(e=>e.kind===`range`?[e]:[]);if(n.length===0)return null;let r=Math.min(...n.map(e=>e.min)),i=Math.max(...n.map(e=>e.max));return{min:r,max:i,seed:ev(n[0].seed,r,i)}}var ov=class{kind=`box`;cell;lastSetAt;constructor(e,t,n){this.name=e,this.type=t,cv(e,t,n,`initial value`),this.cell=X.observable.box(n,{deep:!1}),this.lastSetAt=Date.now()}read(){return this.cell.get()}set(e){cv(this.name,this.type,e,`set value`),this.cell.set(e),this.lastSetAt=Date.now()}lastUpdatedMs(){return this.lastSetAt}},sv=class{kind=`computed`;cell;constructor(e,t,n){this.name=e,this.type=t,this.cell=(0,X.computed)(()=>{let e=n();return cv(this.name,this.type,e,`computed result`),e},{keepAlive:!0})}read(){return this.cell.get()}lastUpdatedMs(){return null}};function cv(e,t,n,r){let i=eg(n);if(i!==t)throw TypeError(`Variable "${e}": ${r} type ${i} does not match declared type ${t}`)}var lv=class{nodes=new Map;defineBox(e,t,n){this.assertNotDefined(e),this.nodes.set(e,new ov(e,t,n))}defineComputed(e,t,n){this.assertNotDefined(e);let r=e=>this.read(e);this.nodes.set(e,new sv(e,t,()=>n(r)))}read(e){return this.requireNode(e).read()}setBox(e,t){let n=this.requireNode(e);if(n.kind!==`box`)throw TypeError(`Variable "${e}" is a ${n.kind}, not a box (use defineBox to create a settable variable)`);(0,X.runInAction)(()=>n.set(t))}runInAction(e){(0,X.runInAction)(e)}has(e){return this.nodes.has(e)}getType(e){return this.requireNode(e).type}getKind(e){return this.requireNode(e).kind}getNode(e){let t=this.requireNode(e);return{name:t.name,type:t.type,kind:t.kind,read:()=>t.read(),lastUpdatedMs:()=>t.lastUpdatedMs()}}names(){return[...this.nodes.keys()]}requireNode(e){let t=this.nodes.get(e);if(!t)throw ReferenceError(`Unknown variable "${e}"`);return t}assertNotDefined(e){if(this.nodes.has(e))throw Error(`Variable "${e}" is already declared`)}};function uv(e,t,n){return e+`\0`+t+`\0`+(n??``)}var dv=class{entries=new Map;deps;maxEntries;constructor(e,t={}){this.deps=e,this.maxEntries=t.maxEntries??256}getOrCreate(e,t,n){let r=uv(e,t,n),i=this.entries.get(r);if(i)return this.entries.delete(r),this.entries.set(r,i),i;let a={projectDir:e,cwd:t,configFile:n,configFilePath:null,lastError:null,lastWarning:null,state:null,watcher:null};if(this.reloadInto(a),this.entries.set(r,a),this.entries.size>this.maxEntries){let e=this.entries.keys().next().value;if(e!==void 0){let t=this.entries.get(e);t?.state?.registry.dispose(),t?.state?.validatorDisposers.forEach(e=>e()),t?.watcher?.release(),this.entries.delete(e)}}return a}reloadInto(e){let t=Dh(e.projectDir,e.cwd,e.configFile);e.lastWarning=Oh(e.projectDir,e.cwd);let n;try{n=this.buildState(e,t)}catch(n){e.lastError=n instanceof ss||n instanceof Error?n.message:String(n),this.refreshWatcher(e,t);return}if(e.state?.registry.dispose(),e.state?.validatorDisposers.forEach(e=>e()),e.lastError=null,e.state=n,n.compiled.loadWarnings.length>0){let t=n.compiled.loadWarnings.join(`
|
|
106
106
|
`);e.lastWarning=e.lastWarning?e.lastWarning+`
|
|
107
|
-
`+t:t}this.refreshWatcher(e,t)}buildState(e,t){let{config:n,source:r}=kh(t),i=Ah(n,t??`<default>`,r),a=new cv,o=new Ig(a,i.globals.default_empty_value??``,this.deps.gitService,this.deps.sessionState),s,c=[];try{s=k_(i,o,{cwd:e.cwd});for(let{key:e,spec:t}of nv(i))c.push(H_(e,t))}catch(e){for(let e of c)e();throw o.dispose(),e}return{config:i,store:a,registry:o,compiled:s,neededInputPaths:Kh(i),lastRenderCellsBySegment:new Map,validatorDisposers:c}}refreshWatcher(e,t){(t!==e.configFilePath||e.watcher===null)&&(e.configFilePath=t,this.rebindWatcher(e,t))}rebindWatcher(e,t){e.watcher&&=(e.watcher.release(),null);let r=Eh(e.projectDir,e.cwd,e.configFile),i=new Map;for(let e of r){let t=o.dirname(e);if(!n.existsSync(t))continue;let r=o.basename(e);i.has(t)||i.set(t,new Set),i.get(t).add(r)}let a=[...i.entries()].map(([e,t])=>({path:e,filenames:[...t]})),s=`config:${e.projectDir}:${e.cwd}:${e.configFile??``}:${t??`<none>`}`;e.watcher=this.deps.watchers.acquire(s,{files:t===null?[]:[t],dirs:a},()=>this.onConfigChanged(e))}onConfigChanged(e){N(`info`,`config change detected for entry projectDir=${e.projectDir} cwd=${e.cwd}`),this.reloadInto(e)}get size(){return this.entries.size}firstPopulatedState(){for(let e of this.entries.values())if(e.state!==null)return e.state;return null}};const dv=16384;var fv=class{startedAt=new Date;requestsTotal=0;requestsErrored=0;requestsTimedOut=0;inFlight=0;watchersOpened=0;watchersClosed=0;watchersEvicted=0;subprocessTotal=0;subprocessInFlight=0;subprocessCount=new Map;subprocessHistogram=new Map;subprocessHistogramRotator=new Map;rollingTimestamps=[];rollingHead=0;launchStats={onStart:e=>{this.subprocessTotal++,this.subprocessInFlight++,this.subprocessCount.set(e,(this.subprocessCount.get(e)??0)+1),this.recordRollingNow()},onEnd:(e,t)=>{this.subprocessInFlight=Math.max(0,this.subprocessInFlight-1),this.recordDuration(e,t)}};recordRollingNow(){let e=Date.now();if(this.rollingTimestamps.length<dv){this.rollingTimestamps.push(e);return}this.rollingTimestamps[this.rollingHead]=e,this.rollingHead=(this.rollingHead+1)%dv}recordDuration(e,t){let n=this.subprocessHistogram.get(e);if(n||(n=[],this.subprocessHistogram.set(e,n)),n.length<16){n.push(t);return}let r=(this.subprocessHistogramRotator.get(e)??0)%16;n[r]=t,this.subprocessHistogramRotator.set(e,r+1)}snapshotSubprocesses(){let e=Date.now()-6e4,t=0;for(let n of this.rollingTimestamps)n>=e&&t++;let n={};for(let[e,t]of this.subprocessCount)t>0&&(n[e]=t);let r={},i={};for(let[e,t]of this.subprocessHistogram){if(t.length===0)continue;let n=[...t].sort((e,t)=>e-t),a=Math.floor(n.length*.5),o=Math.min(n.length-1,Math.floor(n.length*.99)),s=n[a],c=n[o];s!==void 0&&(r[e]=s),c!==void 0&&(i[e]=c)}return{total:this.subprocessTotal,inFlight:this.subprocessInFlight,lastMinute:t,byCategory:n,p50DurationMs:r,p99DurationMs:i}}snapshot(e){let t=process.memoryUsage();return{pid:process.pid,version:3,startedAt:this.startedAt.toISOString(),uptimeSec:Math.floor((Date.now()-this.startedAt.getTime())/1e3),rssBytes:t.rss,heapUsedBytes:t.heapUsed,heapTotalBytes:t.heapTotal,externalBytes:t.external,arrayBuffersBytes:t.arrayBuffers,requests:{total:this.requestsTotal,errored:this.requestsErrored,timedOut:this.requestsTimedOut,inFlight:this.inFlight},gitCache:e.gitCache,usageCache:e.usageCache,renderCache:{size:e.renderCacheSize},watchers:{active:e.watchersActive,opened:this.watchersOpened,closed:this.watchersClosed,evicted:this.watchersEvicted},subprocesses:this.snapshotSubprocesses(),nextRestartReason:e.nextRestartReason??null}}};const pv=(parseInt(process.env.CC_CANDYBAR_RSS_LIMIT_MB??``,10)||512)*1024*1024;function mv(e){let t=e.rssLimitBytes??pv,n=e.snapshotsKeep??3,r=!1;function i(){if(r)return!0;let i=e.rssBytes();if(i<=t)return!1;r=!0,e.log(`warn`,`RSS ${i} > limit ${t}; writing heap snapshot then shutting down`);try{let t=new Date(e.now()).toISOString().replace(/[:.]/g,`-`),r=o.join(e.snapshotDir,`heap-${t}-${e.pid}.heapsnapshot`),i=e.writeHeapSnapshot(r);e.log(`info`,`heap snapshot written: ${i}`),hv(e.listSnapshots(),n,e.removeFile)}catch(t){e.log(`warn`,`heap snapshot failed: ${t.message}`)}return e.shutdown(0),!0}function a(){let n=e.rssBytes();return n>t*.75?`rss ${n} approaching limit ${t}`:null}function s(e=6e4){let t=setInterval(()=>{i()},e);return t.unref(),{disarm:()=>clearInterval(t)}}return{checkRss:i,describeNextRestart:a,arm:s}}function hv(e,t,n){let r=[...e].sort((e,t)=>{let n=e.slice(e.lastIndexOf(`/`)+1);return t.slice(t.lastIndexOf(`/`)+1).localeCompare(n)});for(let e of r.slice(t))try{n(e)}catch{}}function gv(e,t,r={}){let i=we();return{now:()=>Date.now(),pid:process.pid,snapshotDir:i,log:N,rssBytes:()=>process.memoryUsage().rss,writeHeapSnapshot:e=>ie.writeHeapSnapshot(e),listSnapshots:()=>{try{return n.readdirSync(i).filter(e=>e.startsWith(`heap-`)&&e.endsWith(`.heapsnapshot`)).map(e=>o.join(i,e))}catch{return[]}},removeFile:e=>n.unlinkSync(e),shutdown:t,startedAtMs:e,...r}}const _v=`CC_CANDYBAR_PARENT_PID`;function vv(e){let t=e[_v];if(t===void 0)return{kind:`outlives-nobody`};let n=Number.parseInt(t,10);if(!Number.isInteger(n)||n<=0)throw Error(`${_v} must be a positive integer pid, got ${JSON.stringify(t)}`);return{kind:`anchored`,pid:n}}function yv(e){if(e.anchor.kind===`outlives-nobody`)return{disarm:()=>{}};let{pid:t}=e.anchor,n=setInterval(()=>{e.isAlive(t)||e.onOrphaned(`spawner pid ${t} gone`)},e.intervalMs??1e3);return n.unref(),{disarm:()=>clearInterval(n)}}function bv(t){try{return e.kill(t,0),!0}catch(e){return e.code===`EPERM`}}const xv={load:()=>({}),save:()=>{},flush:()=>{}};function Sv(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,new Map(Object.entries(r)));return t}var Cv=class{sessions;storage;atom=(0,X.createAtom)(`SessionState`);constructor(e=xv,t=256){this.maxSessions=t,this.storage=e,this.sessions=new Map,this.hydrateFromStorage()}useStorage(e){this.storage=e,this.hydrateFromStorage()}hydrateFromStorage(){this.sessions=Sv(this.storage.load()),this.evictOldest(),this.persist()}get(e,t){this.atom.reportObserved();let n=this.sessions.get(e);return n?(this.touch(e,n),n.get(t)??null):null}set(e,t,n){this.setBatch(e,[{key:t,value:n}])}setBatch(e,t){t.length!==0&&(0,X.runInAction)(()=>{let n=this.sessions.get(e)??new Map;for(let{key:e,value:r}of t)n.set(e,r);this.touch(e,n),this.evictOldest(),this.persist(),this.atom.reportChanged()})}clear(e,t){(0,X.runInAction)(()=>{let n=this.sessions.get(e);n&&(n.delete(t),n.size===0?this.sessions.delete(e):this.touch(e,n)),this.persist(),this.atom.reportChanged()})}prune(e){(0,X.runInAction)(()=>{for(let t of this.sessions.keys())e.has(t)||this.sessions.delete(t);this.persist(),this.atom.reportChanged()})}touch(e,t){this.sessions.delete(e),this.sessions.set(e,t)}evictOldest(){let e=this.sessions.size-this.maxSessions;if(!(e<=0)){for(let t of this.sessions.keys())if(this.sessions.delete(t),--e===0)break}}flush(){this.storage.flush()}persist(){this.storage.save(this.serialize())}serialize(){let e=Object.create(null);for(let[t,n]of this.sessions)e[t]=Object.fromEntries(n);return e}};const wv=(e,t)=>O(t);function Tv(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;for(let t of Object.values(e)){if(typeof t!=`object`||!t||Array.isArray(t))return!1;for(let e of Object.values(t))if(typeof e!=`string`)return!1}return!0}var Ev=class{timer=null;pending=null;constructor(e,t=500,n=wv){this.filePath=e,this.debounceMs=t,this.logger=n}load(){let e;try{e=n.readFileSync(this.filePath,`utf8`)}catch(e){let t=e.code;return t!==`ENOENT`&&this.logger(`warn`,`session-state read failed (${t}); starting empty`),{}}try{let t=JSON.parse(e);return Tv(t)?t:(this.logger(`warn`,`session-state load: unexpected shape, starting empty`),{})}catch{return this.logger(`warn`,`session-state load: corrupt JSON, starting empty`),{}}}save(e){this.pending=e,!this.timer&&(this.timer=setTimeout(()=>this.flush(),this.debounceMs),this.timer.unref())}flush(){if(this.timer&&=(clearTimeout(this.timer),null),this.pending===null)return;let e=this.pending;try{n.mkdirSync(o.dirname(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp`;n.writeFileSync(t,JSON.stringify(e),{mode:384}),n.chmodSync(t,384),n.renameSync(t,this.filePath),this.pending=null}catch(e){this.logger(`warn`,`session-state save failed: ${e.message}`)}}},Dv=class extends Error{constructor(e){super(e),this.name=`BadVerbArgs`}};function Ov(e){if(!e)throw new Dv(`session id is required`);if(e.includes(`/`)||e.includes(`..`))throw new Dv(`invalid session id "${e}"`);return e}function kv(e){return Av(()=>decodeURIComponent(e))}function Av(e){try{return e()}catch(e){throw e instanceof URIError?new Dv(`malformed wire encoding: ${e.message}`):e}}function jv(e,t){let n=ve({bin:`/usr/bin/pbcopy`,stdinInput:e,category:`click.pbcopy`});if(!n.ok){if(n.reason===`rate-limited`){t.dlog(`warn`,`click.pbcopy rate-limited: ${n.error??``}`);return}throw Error(`pbcopy failed (${n.reason}, exit ${n.exitCode??`null`})`)}}const Mv=(e,t)=>jv(kv(e),t),Nv=(e,t)=>{let n=ve({bin:`/usr/bin/open`,args:[`-a`,`Visual Studio Code`,kv(e)],category:`click.open`});if(!n.ok){if(n.reason===`rate-limited`){t.dlog(`warn`,`click.open rate-limited: ${n.error??``}`);return}throw Error(`open -a "Visual Studio Code" failed (${n.reason}, exit ${n.exitCode??`null`})`)}},Pv=(e,t)=>jv(kv(e),t),Fv=(e,t)=>jv(kv(e),t),Iv=(e,t)=>{let n=Ov(kv(e));t.sessionState.get(n,`toolbar-expanded`)?t.sessionState.clear(n,`toolbar-expanded`):t.sessionState.set(n,`toolbar-expanded`,`1`)},Lv=(e,t)=>{let[n=``,...r]=Av(()=>ft(e)),i=Ov(n);if(r.length===0)throw new Dv(`set-state: <key>/<value> is required (have keys: ${B_().join(`, `)})`);if(r.length%2!=0)throw new Dv(`set-state: expected even-count <key>/<value> pairs, got ${r.length} segment(s) after session id (have keys: ${B_().join(`, `)})`);let a=[];for(let e=0;e<r.length;e+=2){let t=r[e],n=r[e+1];if(!t)throw new Dv(`set-state: empty key at pair ${e/2+1} (expected <sessionId>/<key>/<value>[/<key>/<value>...] segments)`);let i=rv(t,n);if(!i.ok)throw new Dv(`set-state: pair ${e/2+1}: ${i.reason}`);a.push({key:t,value:i.value})}t.sessionState.setBatch(i,a);let o=a.map(e=>`${e.key}=${e.value}`).join(` `);t.dlog(`info`,`set-state: ${o} (session=${i})`)},Rv=/^-?\d+$/;function zv(e,t,n){return e>n?t:e<t?n:e}const Bv=(e,t)=>{let[n=``,r=``,i=``]=Av(()=>ft(e)),a=Ov(n);if(!r)throw new Dv(`step-state: <key> is required (shape: <sessionId>/<key>/<by>)`);if(!Rv.test(i))throw new Dv(`step-state: delta must be an integer, got "${i}"`);let o=parseInt(i,10),s=iv(r);if(!s)throw new Dv(`step-state: key "${r}" is not a bounded (range) state key (have keys: ${B_().join(`, `)})`);let c=t.sessionState.get(a,r),l=c&&Rv.test(c)?Math.max(s.min,Math.min(s.max,parseInt(c,10))):s.seed,u=zv(l+o,s.min,s.max),d=rv(r,String(u));if(!d.ok)throw new Dv(`step-state: ${d.reason}`);t.sessionState.set(a,r,d.value),t.dlog(`info`,`step-state: ${r} ${l}→${d.value} (by ${o}, session=${a})`)},Vv=`config-override`,Hv=new Map([[st,Mv],[`load-config`,(e,t)=>{let n=e.indexOf(`/`);if(n===-1)throw new Dv(`load-config: expected <sessionId>/<path> (missing separator)`);let r=Ov(Av(()=>decodeURIComponent(e.slice(0,n)))),i=Av(()=>decodeURIComponent(e.slice(n+1))).trim();if(i!==``){if(!i.startsWith(`/`))throw new Dv(`load-config: path must be absolute, got "${i}"`);if(!/\.(json5?|json)$/.test(i))throw new Dv(`load-config: path must end with .json5 or .json, got "${i}"`)}i===``?(t.sessionState.clear(r,Vv),t.dlog(`info`,`load-config: override cleared (session=${r})`)):(t.sessionState.set(r,Vv,i),t.dlog(`info`,`load-config: ${i} (session=${r})`))}],[ct,Nv],[at,Lv],[ot,Bv],[lt,Pv],[ut,Fv],[`toolbar-toggle`,Iv]]),Uv=(e,t)=>{let n=[],r=!1,i=null;for(let{verb:a,value:o}of mt(e)){if(!i&&(a===`set-state`||a===`step-state`||a===`toolbar-toggle`)){let e=ft(o);e.length>0&&e[0]&&(i=e[0])}let e=Hv.get(a);if(!e){n.push(`unknown effect verb "${a}"`);continue}try{e(o,t)}catch(e){e instanceof Dv||(r=!0),n.push(`${a}: ${e instanceof Error?e.message:String(e)}`)}}if(n.length>0){i&&t.sessionState.set(i,`click.error`,n.join(`
|
|
108
|
-
`));let e=`dispatch: ${n.join(`; `)}`;throw r?Error(e):new Dv(e)}},Wv=new Map([...Hv,[it,Uv]]);Object.freeze([...Wv.keys()]);const Gv=new Set([`hook_event_name`,`session_id`,`session_name`,`transcript_path`,`cwd`,`model`,`workspace`,`version`,`output_style`,`cost`,`context_window`,`exceeds_200k_tokens`,`effort`,`thinking`,`rate_limits`,`vim`,`agent`,`worktree`]),Kv=[[`session_id`,`string`],[`transcript_path`,`string`],[`cwd`,`string`],[`model`,`object`],[`model.id`,`string`],[`model.display_name`,`string`],[`workspace`,`object`],[`workspace.current_dir`,`string`],[`workspace.project_dir`,`string`]];function qv(e){let t={missingRequired:[],typeMismatches:[],unknownTopLevelFields:[]},n=typeof e==`object`&&e&&!Array.isArray(e)?e:{};for(let[e,r]of Kv){let i=Jv(n,e);if(i==null)t.missingRequired.push(e);else{let n=Array.isArray(i)?`array`:typeof i;(r===`object`?n!==`object`:n!==r)&&t.typeMismatches.push({path:e,expected:r,got:n})}}for(let e of Object.keys(n))Gv.has(e)||t.unknownTopLevelFields.push(e);return{data:e,report:t}}function Jv(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n||Array.isArray(n))return;n=n[e]}return n}function Yv(e,t){switch(e){case`vars`:return{what:e,vars:Xv(t)};case`segments`:return{what:e,segments:ey(t)};case`config`:return{what:e,config:ry(t)}}}function Xv(e){if(e===null)return[];let{store:t,registry:n,config:r}=e,i=Qv(r),a=t.names().sort(),o=[];for(let e of a){let r=t.getNode(e),a=n.getLastError(e);o.push({name:e,source:i.get(e)??null,type:r.type,value:r.read(),lastError:a===void 0?null:{timestampMs:a.timestamp,message:a.message},ageMs:Zv(r.lastUpdatedMs())})}return o}function Zv(e){return e===null?null:Math.max(0,Date.now()-e)}function Qv(e){let t=new Map;for(let[n,r]of Object.entries(e.variables))t.set(n,$v(r));for(let[n,r]of Object.entries(e.segments))if(r.vars)for(let[e,i]of Object.entries(r.vars))t.set(`${n}.${e}`,$v(i));return t}function $v(e){return e.kind}function ey(e){if(e===null)return[];let{store:t,config:n,lastRenderBySegment:r}=e,i=new Set(t.names()),a=ty(n),o=[];for(let e of a){let t=n.segments[e];t&&o.push({name:e,template:t.template,referencedVars:ny(t.template,i),lastRender:r.get(e)??null})}return o}function ty(e){let t=[],n=new Set;for(let r of Nn(e.root))r.kind===`segment`&&e.segments[r.name]&&!n.has(r.name)&&(t.push(r.name),n.add(r.name));for(let r of Object.keys(e.segments))n.has(r)||(t.push(r),n.add(r));return t}function ny(e,t){let n=new Set;for(let r of ch(e)){if(t.has(r)){n.add(r);continue}let e=r.split(`.`);for(;e.length>1;){e.pop();let r=e.join(`.`);if(t.has(r)){n.add(r);break}}}return Array.from(n).sort()}function ry(e){return e===null?null:e.config}const iy=[`vars`,`segments`,`config`];function ay(e){return typeof e==`string`&&iy.includes(e)}function oy(e){return Math.max(1,e-2)}var sy=class{thresholds={LOW:50,MEDIUM:80};getContextUsageThresholds(){return this.thresholds}ratioPercentages(e,t){let n=Math.min(100,Math.max(0,Math.round(e/t*100)));return{percentage:n,contextLeftPercentage:Math.max(0,100-n)}}calculateContextFromHookData(e){let t=e.context_window;if(!t?.current_usage)return O(`No current_usage in hook data, falling back to transcript parsing`),null;let n=t.current_usage,r=t.context_window_size,i=(n.input_tokens||0)+(n.cache_creation_input_tokens||0)+(n.cache_read_input_tokens||0);O(`Native current_usage: input=${n.input_tokens}, cache_create=${n.cache_creation_input_tokens}, cache_read=${n.cache_read_input_tokens}, total=${i} (limit: ${r})`);let a=this.ratioPercentages(i,r);return{totalTokens:i,maxTokens:r,percentage:t.used_percentage==null?a.percentage:Math.round(t.used_percentage),contextLeftPercentage:t.remaining_percentage==null?a.contextLeftPercentage:Math.round(t.remaining_percentage)}}async calculateContextTokensFromTranscript(e,t){try{O(`Calculating context tokens from transcript: ${e}`);let n=await _n(e);if(n.length===0)return O(`No entries in transcript`),F;let r=null;for(let e=n.length-1;e>=0;e--){let t=n[e];if(t&&t.message?.usage?.input_tokens&&t.isSidechain!==!0){r=t,O(`Context segment: Found most recent entry at ${t.timestamp.toISOString()}, stopping search`);break}}if(r?.message?.usage){let e=r.message.usage,n=(e.input_tokens||0)+(e.cache_read_input_tokens||0)+(e.cache_creation_input_tokens||0);return O(`Most recent main chain context: ${n} tokens (limit: ${t})`),P({totalTokens:n,maxTokens:t,...this.ratioPercentages(n,t)})}return O(`No main chain entries with usage data found`),F}catch(e){return I(`context transcript: ${e instanceof Error?e.message:String(e)}`)}}async getContextInfo(e){let t=this.calculateContextFromHookData(e);if(t)return P(t);let n=e.context_window?.context_window_size??2e5;return this.calculateContextTokensFromTranscript(e.transcript_path,n)}};function cy(e){let t=e.type||e.message?.role||e.message?.type,n=e.type===`user`&&e.message?.firstContentType===`tool_result`;return t===`user`&&!n}var ly=class{calculateMessageCount(e){return e.filter(cy).length}calculateLastResponseTime(e){if(e.length===0)return null;let t=e.slice(-20),n=null,r=null;for(let e of t){let t=e.type||e.message?.role||e.message?.type;if(cy(e))n=e.timestamp;else if(t===`assistant`&&n){let t=(e.timestamp.getTime()-n.getTime())/1e3;t>.1&&t<300&&(r=t)}}return r}async getMetricsInfo(e,t){try{if(O(`Getting metrics from hook data for session: ${e}`),!t.cost)return F;let n=(await _n(t.transcript_path)).filter(e=>!e.isSidechain),r=this.calculateMessageCount(n),i=this.calculateLastResponseTime(n);return P({responseTime:t.cost.total_api_duration_ms/1e3,lastResponseTime:i,sessionDuration:t.cost.total_duration_ms/1e3,messageCount:r,linesAdded:t.cost.total_lines_added,linesRemoved:t.cost.total_lines_removed})}catch(t){return I(`metrics (${e}): ${t instanceof Error?t.message:String(t)}`)}}};const uy=new Map;function dy(e){if(!e)return``;let t=e.indexOf(`,`);return t<0?e:e.slice(0,t)}var fy=class{async getSessionId(){if(!process.env.TMUX_PANE)return F;let e=dy(process.env.TMUX),t=uy.get(e);if(t!==void 0)return t;O(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);let n=await _e({bin:`tmux`,args:[`display-message`,`-p`,`#S`],timeoutMs:1e3,category:`tmux`}),r=n.ok?n.stdout.trim()?P(n.stdout.trim()):F:I(`tmux display-message: ${n.reason}`);return uy.set(e,r),r}isInTmux(){return!!process.env.TMUX_PANE}};function py(e){return e<32||e===127||e>=128&&e<=159}function my(e,t){let n=``;for(let t of e)n+=py(t.codePointAt(0)??0)?` `:t;n=n.replace(/\s+/g,` `).trim();let r=``,i=0;for(let e of n){if(i===t)return r.replace(/.$/u,`…`);r+=e,i++}return r}const hy=`\x1B[38;2;255;255;255m`,gy=`\x1B[48;2;200;40;40m`,_y=`\x1B[0m`,vy=new fv;k(vy.launchStats);const yy=new Zt({counters:vy,logger:N}),by=new rn({watchers:yy,logger:N}),xy=new jn,Sy=new Cv,Cy=new sy,wy=new ly,Ty=new fy,Ey=new uv({gitService:by,sessionState:Sy,watchers:yy});function Dy(){n.mkdirSync(we(),{recursive:!0}),Ee(Te()),Sy.useStorage(new Ev(Oe(),500,N)),e.on(`uncaughtException`,e=>{N(`error`,`uncaughtException: ${e.stack||e.message}`),By(1)}),e.on(`unhandledRejection`,e=>{N(`error`,`unhandledRejection: ${String(e)}`),By(1)});for(let t of[`SIGINT`,`SIGTERM`,`SIGHUP`])e.on(t,()=>{N(`info`,`received ${t}, shutting down`),By(0)});yv({anchor:vv(e.env),isAlive:bv,onOrphaned:e=>{N(`info`,`parent watchdog: ${e}; shutting down`),By(0)}}),Oy(m.createServer({allowHalfOpen:!1},e=>{Vy(e)}),Te(),!1)}function Oy(t,n,r){t.removeAllListeners(`error`),t.once(`error`,i=>{if(i.code!==`EADDRINUSE`){N(`error`,`server error: ${i.message}`),By(1);return}if(r){N(`info`,`lost rebind race; another daemon is alive — exiting`),e.exit(0);return}ky(t,n)}),t.listen(n,()=>My(n))}async function ky(t,r){await jy(r)&&(N(`info`,`another daemon is listening on socket — exiting`),e.exit(0)),await jy(r)&&(N(`info`,`race: another daemon claimed the socket during recovery — exiting`),e.exit(0)),N(`warn`,`stale socket from crashed daemon — unlinking and rebinding`);try{n.unlinkSync(r)}catch(e){if(e.code!==`ENOENT`){N(`error`,`cannot unlink stale socket ${r}: ${e.message}`),By(1);return}}Oy(t,r,!0)}function Ay(e){return new Promise(t=>{let n=m.connect(e),r=!1,i=null,a=e=>{r||(r=!0,i&&clearTimeout(i),n.removeAllListeners(),n.destroy(),t(e))};n.once(`connect`,()=>a(`alive`)),n.once(`error`,e=>{let t=e.code;a(t===`ECONNREFUSED`||t===`ENOENT`||t===`ENOTSOCK`?`dead`:`unknown`)}),i=setTimeout(()=>a(`unknown`),50),i.unref()})}async function jy(e){return await Ay(e)!==`dead`}function My(t){try{n.chmodSync(t,384)}catch(e){N(`warn`,`chmod socket failed: ${e.message}`)}Iy(),N(`info`,`daemon up: pid=${e.pid} v=3 sock=${t}`),Ny(),Fy()}function Ny(){let t=import.meta.url,r=[];t.startsWith(`file://`)&&r.push(_(t)),e.argv[1]&&r.push(e.argv[1]);let i=new Map;for(let e of r)try{i.set(e,n.statSync(e).mtimeMs)}catch{}if(i.size===0)return;let a=setInterval(()=>{for(let[e,t]of i)try{if(n.statSync(e).mtimeMs!==t){N(`info`,`binary mtime changed (${e}); shutting down`),clearInterval(a),By(0);return}}catch(e){N(`warn`,`bin stat failed: ${e.message}`)}},6e4);a.unref()}let Py=null;function Fy(){Py=mv(gv(vy.startedAt.getTime(),e=>By(e))),Py.arm()}function Iy(){let t=JSON.stringify({pid:e.pid,version:3,binPath:e.argv[1],startedAt:new Date().toISOString()});try{n.writeFileSync(De(),t,{mode:384}),n.chmodSync(De(),384)}catch(e){N(`warn`,`pidfile write failed: ${e.message}`)}}function Ly(){try{n.unlinkSync(De())}catch{}}let Ry=0,zy=!1;function By(t){if(!zy){zy=!0,setTimeout(()=>e.kill(e.pid,`SIGKILL`),500);try{by.close()}catch(e){N(`warn`,`gitService close failed: ${e.message}`)}try{xy.close()}catch(e){N(`warn`,`usageStore close failed: ${e.message}`)}try{yy.closeAll()}catch(e){N(`warn`,`watcherRegistry close failed: ${e.message}`)}try{Sy.flush()}catch(e){N(`warn`,`sessionState flush failed: ${e.message}`)}Ly(),Rt(),e.exit(t)}}function Vy(e){Ry++,vy.inFlight=Ry;let t=!1,n=(n,r)=>{if(t){r!==null&&N(`warn`,`exit-after-flush dropped: an earlier responder settled this socket`);return}t=!0;let i=r===null?void 0:()=>By(r);try{e.end(Ne(n),i)}catch(e){N(`warn`,`response write failed: ${e.message}`),i?.()}},r=setTimeout(()=>{vy.requestsTimedOut++,n({ok:!1,error:`request exceeded 200ms`,code:`TIMEOUT`,daemonV:3},null)},200),i=Pe(e=>{Uy(e).then(e=>n(e.resp,e.exitAfterFlush)).catch(e=>{N(`error`,`handler threw: ${e?.stack||e}`),n({ok:!1,error:String(e?.message||e),code:`RENDER_FAILED`,daemonV:3},null)})},e=>{N(`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=>{N(`warn`,`socket error: ${e.message}`)}),e.on(`close`,()=>{clearTimeout(r),Ry=Math.max(0,Ry-1),vy.inFlight=Ry})}const Hy=e=>({resp:e,exitAfterFlush:null});async function Uy(e){if(!e||typeof e!=`object`||typeof e.v!=`number`)return Hy({ok:!1,error:`malformed request`,code:`BAD_REQUEST`,daemonV:3});if(e.v!==3)return e.v>3?N(`info`,`version mismatch: client=${e.v} > daemon=3; binary likely upgraded — exiting after the response flushes`):N(`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 Hy({ok:!0,stats:vy.snapshot({gitCache:by.getStats(),usageCache:xy.getStats(),renderCacheSize:Ey.size,watchersActive:yy.size(),nextRestartReason:Py?.describeNextRestart()??null})});if(e.kind===`render`){vy.requestsTotal++;let t=Date.now();try{let{report:n}=qv(e.hookData);for(let e of n.unknownTopLevelFields)N(`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 vy.requestsErrored++,N(`warn`,`BAD_REQUEST: ${r.join(`; `)}`),Hy({ok:!1,error:`malformed hookData: ${r.join(`; `)}`,code:`BAD_REQUEST`,daemonV:3});let i=e.hookData.workspace.project_dir,{configFile:a,unknownFlagsError:o}=Ky(e.args),s=e.hookData.session_id,c=Sy.get(s,`config-override`)??a,l=Ey.getOrCreate(i,e.cwd,c),u=je(e.termCols),d=oy(u??120),f={...Xy,width:d},p=``;if(l.state!==null){let t=await Xh(e.hookData,eb,e.cwd,l.state.neededInputPaths),n=Vg(ts(Sy.get(e.hookData.session_id,`theme`),l.state.config.globals.palette));f.style=os(Sy.get(e.hookData.session_id,`style`),l.state.config.globals.style),p=j_(l.state.config,l.state.compiled,l.state.store,l.state.registry,t,n,f,l.state.lastRenderCellsBySegment)}let m=Sy.get(e.hookData.session_id,`click.error`);m&&Sy.clear(e.hookData.session_id,`click.error`);let h=[o,l.lastError,m].filter(Boolean).join(`
|
|
109
|
-
`)||null,g=
|
|
110
|
-
`})}catch(e){throw
|
|
111
|
-
`)}function
|
|
112
|
-
`);return e?`${i}\n${e}`:i}const
|
|
113
|
-
`);return}e.stdout.write(
|
|
107
|
+
`+t:t}this.refreshWatcher(e,t)}buildState(e,t){let{config:n,source:r}=kh(t),i=Ah(n,t??`<default>`,r),a=new lv,o=new Ig(a,i.globals.default_empty_value??``,this.deps.gitService,this.deps.sessionState),s,c=[];try{s=A_(i,o,{cwd:e.cwd});for(let{key:e,spec:t}of rv(i))c.push(U_(e,t))}catch(e){for(let e of c)e();throw o.dispose(),e}return{config:i,store:a,registry:o,compiled:s,neededInputPaths:Kh(i),lastRenderCellsBySegment:new Map,validatorDisposers:c}}refreshWatcher(e,t){(t!==e.configFilePath||e.watcher===null)&&(e.configFilePath=t,this.rebindWatcher(e,t))}rebindWatcher(e,t){e.watcher&&=(e.watcher.release(),null);let r=Eh(e.projectDir,e.cwd,e.configFile),i=new Map;for(let e of r){let t=o.dirname(e);if(!n.existsSync(t))continue;let r=o.basename(e);i.has(t)||i.set(t,new Set),i.get(t).add(r)}let a=[...i.entries()].map(([e,t])=>({path:e,filenames:[...t]})),s=`config:${e.projectDir}:${e.cwd}:${e.configFile??``}:${t??`<none>`}`;e.watcher=this.deps.watchers.acquire(s,{files:t===null?[]:[t],dirs:a},()=>this.onConfigChanged(e))}onConfigChanged(e){N(`info`,`config change detected for entry projectDir=${e.projectDir} cwd=${e.cwd}`),this.reloadInto(e)}get size(){return this.entries.size}firstPopulatedState(){for(let e of this.entries.values())if(e.state!==null)return e.state;return null}};const fv=16384;var pv=class{startedAt=new Date;requestsTotal=0;requestsErrored=0;requestsTimedOut=0;inFlight=0;watchersOpened=0;watchersClosed=0;watchersEvicted=0;subprocessTotal=0;subprocessInFlight=0;subprocessCount=new Map;subprocessHistogram=new Map;subprocessHistogramRotator=new Map;rollingTimestamps=[];rollingHead=0;launchStats={onStart:e=>{this.subprocessTotal++,this.subprocessInFlight++,this.subprocessCount.set(e,(this.subprocessCount.get(e)??0)+1),this.recordRollingNow()},onEnd:(e,t)=>{this.subprocessInFlight=Math.max(0,this.subprocessInFlight-1),this.recordDuration(e,t)}};recordRollingNow(){let e=Date.now();if(this.rollingTimestamps.length<fv){this.rollingTimestamps.push(e);return}this.rollingTimestamps[this.rollingHead]=e,this.rollingHead=(this.rollingHead+1)%fv}recordDuration(e,t){let n=this.subprocessHistogram.get(e);if(n||(n=[],this.subprocessHistogram.set(e,n)),n.length<16){n.push(t);return}let r=(this.subprocessHistogramRotator.get(e)??0)%16;n[r]=t,this.subprocessHistogramRotator.set(e,r+1)}snapshotSubprocesses(){let e=Date.now()-6e4,t=0;for(let n of this.rollingTimestamps)n>=e&&t++;let n={};for(let[e,t]of this.subprocessCount)t>0&&(n[e]=t);let r={},i={};for(let[e,t]of this.subprocessHistogram){if(t.length===0)continue;let n=[...t].sort((e,t)=>e-t),a=Math.floor(n.length*.5),o=Math.min(n.length-1,Math.floor(n.length*.99)),s=n[a],c=n[o];s!==void 0&&(r[e]=s),c!==void 0&&(i[e]=c)}return{total:this.subprocessTotal,inFlight:this.subprocessInFlight,lastMinute:t,byCategory:n,p50DurationMs:r,p99DurationMs:i}}snapshot(e){let t=process.memoryUsage();return{pid:process.pid,version:3,startedAt:this.startedAt.toISOString(),uptimeSec:Math.floor((Date.now()-this.startedAt.getTime())/1e3),rssBytes:t.rss,heapUsedBytes:t.heapUsed,heapTotalBytes:t.heapTotal,externalBytes:t.external,arrayBuffersBytes:t.arrayBuffers,requests:{total:this.requestsTotal,errored:this.requestsErrored,timedOut:this.requestsTimedOut,inFlight:this.inFlight},gitCache:e.gitCache,usageCache:e.usageCache,renderCache:{size:e.renderCacheSize},watchers:{active:e.watchersActive,opened:this.watchersOpened,closed:this.watchersClosed,evicted:this.watchersEvicted},subprocesses:this.snapshotSubprocesses(),nextRestartReason:e.nextRestartReason??null}}};const mv=(parseInt(process.env.CC_CANDYBAR_RSS_LIMIT_MB??``,10)||512)*1024*1024;function hv(e){let t=e.rssLimitBytes??mv,n=e.snapshotsKeep??3,r=!1;function i(){if(r)return!0;let i=e.rssBytes();if(i<=t)return!1;r=!0,e.log(`warn`,`RSS ${i} > limit ${t}; writing heap snapshot then shutting down`);try{let t=new Date(e.now()).toISOString().replace(/[:.]/g,`-`),r=o.join(e.snapshotDir,`heap-${t}-${e.pid}.heapsnapshot`),i=e.writeHeapSnapshot(r);e.log(`info`,`heap snapshot written: ${i}`),gv(e.listSnapshots(),n,e.removeFile)}catch(t){e.log(`warn`,`heap snapshot failed: ${t.message}`)}return e.shutdown(0),!0}function a(){let n=e.rssBytes();return n>t*.75?`rss ${n} approaching limit ${t}`:null}function s(e=6e4){let t=setInterval(()=>{i()},e);return t.unref(),{disarm:()=>clearInterval(t)}}return{checkRss:i,describeNextRestart:a,arm:s}}function gv(e,t,n){let r=[...e].sort((e,t)=>{let n=e.slice(e.lastIndexOf(`/`)+1);return t.slice(t.lastIndexOf(`/`)+1).localeCompare(n)});for(let e of r.slice(t))try{n(e)}catch{}}function _v(e,t,r={}){let i=we();return{now:()=>Date.now(),pid:process.pid,snapshotDir:i,log:N,rssBytes:()=>process.memoryUsage().rss,writeHeapSnapshot:e=>ie.writeHeapSnapshot(e),listSnapshots:()=>{try{return n.readdirSync(i).filter(e=>e.startsWith(`heap-`)&&e.endsWith(`.heapsnapshot`)).map(e=>o.join(i,e))}catch{return[]}},removeFile:e=>n.unlinkSync(e),shutdown:t,startedAtMs:e,...r}}const vv=`CC_CANDYBAR_PARENT_PID`;function yv(e){let t=e[vv];if(t===void 0)return{kind:`outlives-nobody`};let n=Number.parseInt(t,10);if(!Number.isInteger(n)||n<=0)throw Error(`${vv} must be a positive integer pid, got ${JSON.stringify(t)}`);return{kind:`anchored`,pid:n}}function bv(e){if(e.anchor.kind===`outlives-nobody`)return{disarm:()=>{}};let{pid:t}=e.anchor,n=setInterval(()=>{e.isAlive(t)||e.onOrphaned(`spawner pid ${t} gone`)},e.intervalMs??1e3);return n.unref(),{disarm:()=>clearInterval(n)}}function xv(t){try{return e.kill(t,0),!0}catch(e){return e.code===`EPERM`}}const Sv={load:()=>({}),save:()=>{},flush:()=>{}};function Cv(e){let t=new Map;for(let[n,r]of Object.entries(e))t.set(n,new Map(Object.entries(r)));return t}var wv=class{sessions;storage;atom=(0,X.createAtom)(`SessionState`);constructor(e=Sv,t=256){this.maxSessions=t,this.storage=e,this.sessions=new Map,this.hydrateFromStorage()}useStorage(e){this.storage=e,this.hydrateFromStorage()}hydrateFromStorage(){this.sessions=Cv(this.storage.load()),this.evictOldest(),this.persist()}get(e,t){this.atom.reportObserved();let n=this.sessions.get(e);return n?(this.touch(e,n),n.get(t)??null):null}set(e,t,n){this.setBatch(e,[{key:t,value:n}])}setBatch(e,t){t.length!==0&&(0,X.runInAction)(()=>{let n=this.sessions.get(e)??new Map;for(let{key:e,value:r}of t)n.set(e,r);this.touch(e,n),this.evictOldest(),this.persist(),this.atom.reportChanged()})}clear(e,t){(0,X.runInAction)(()=>{let n=this.sessions.get(e);n&&(n.delete(t),n.size===0?this.sessions.delete(e):this.touch(e,n)),this.persist(),this.atom.reportChanged()})}prune(e){(0,X.runInAction)(()=>{for(let t of this.sessions.keys())e.has(t)||this.sessions.delete(t);this.persist(),this.atom.reportChanged()})}touch(e,t){this.sessions.delete(e),this.sessions.set(e,t)}evictOldest(){let e=this.sessions.size-this.maxSessions;if(!(e<=0)){for(let t of this.sessions.keys())if(this.sessions.delete(t),--e===0)break}}flush(){this.storage.flush()}persist(){this.storage.save(this.serialize())}serialize(){let e=Object.create(null);for(let[t,n]of this.sessions)e[t]=Object.fromEntries(n);return e}};const Tv=(e,t)=>O(t);function Ev(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;for(let t of Object.values(e)){if(typeof t!=`object`||!t||Array.isArray(t))return!1;for(let e of Object.values(t))if(typeof e!=`string`)return!1}return!0}var Dv=class{timer=null;pending=null;constructor(e,t=500,n=Tv){this.filePath=e,this.debounceMs=t,this.logger=n}load(){let e;try{e=n.readFileSync(this.filePath,`utf8`)}catch(e){let t=e.code;return t!==`ENOENT`&&this.logger(`warn`,`session-state read failed (${t}); starting empty`),{}}try{let t=JSON.parse(e);return Ev(t)?t:(this.logger(`warn`,`session-state load: unexpected shape, starting empty`),{})}catch{return this.logger(`warn`,`session-state load: corrupt JSON, starting empty`),{}}}save(e){this.pending=e,!this.timer&&(this.timer=setTimeout(()=>this.flush(),this.debounceMs),this.timer.unref())}flush(){if(this.timer&&=(clearTimeout(this.timer),null),this.pending===null)return;let e=this.pending;try{n.mkdirSync(o.dirname(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp`;n.writeFileSync(t,JSON.stringify(e),{mode:384}),n.chmodSync(t,384),n.renameSync(t,this.filePath),this.pending=null}catch(e){this.logger(`warn`,`session-state save failed: ${e.message}`)}}},Ov=class extends Error{constructor(e){super(e),this.name=`BadVerbArgs`}};function kv(e){if(!e)throw new Ov(`session id is required`);if(e.includes(`/`)||e.includes(`..`))throw new Ov(`invalid session id "${e}"`);return e}function Av(e){return jv(()=>decodeURIComponent(e))}function jv(e){try{return e()}catch(e){throw e instanceof URIError?new Ov(`malformed wire encoding: ${e.message}`):e}}function Mv(e,t){let n=ve({bin:`/usr/bin/pbcopy`,stdinInput:e,category:`click.pbcopy`});if(!n.ok){if(n.reason===`rate-limited`){t.dlog(`warn`,`click.pbcopy rate-limited: ${n.error??``}`);return}throw Error(`pbcopy failed (${n.reason}, exit ${n.exitCode??`null`})`)}}const Nv=(e,t)=>Mv(Av(e),t),Pv=(e,t)=>{let n=ve({bin:`/usr/bin/open`,args:[`-a`,`Visual Studio Code`,Av(e)],category:`click.open`});if(!n.ok){if(n.reason===`rate-limited`){t.dlog(`warn`,`click.open rate-limited: ${n.error??``}`);return}throw Error(`open -a "Visual Studio Code" failed (${n.reason}, exit ${n.exitCode??`null`})`)}},Fv=(e,t)=>Mv(Av(e),t),Iv=(e,t)=>Mv(Av(e),t),Lv=(e,t)=>{let n=kv(Av(e));t.sessionState.get(n,`toolbar-expanded`)?t.sessionState.clear(n,`toolbar-expanded`):t.sessionState.set(n,`toolbar-expanded`,`1`)},Rv=(e,t)=>{let[n=``,...r]=jv(()=>ft(e)),i=kv(n);if(r.length===0)throw new Ov(`set-state: <key>/<value> is required (have keys: ${V_().join(`, `)})`);if(r.length%2!=0)throw new Ov(`set-state: expected even-count <key>/<value> pairs, got ${r.length} segment(s) after session id (have keys: ${V_().join(`, `)})`);let a=[];for(let e=0;e<r.length;e+=2){let t=r[e],n=r[e+1];if(!t)throw new Ov(`set-state: empty key at pair ${e/2+1} (expected <sessionId>/<key>/<value>[/<key>/<value>...] segments)`);let i=iv(t,n);if(!i.ok)throw new Ov(`set-state: pair ${e/2+1}: ${i.reason}`);a.push({key:t,value:i.value})}t.sessionState.setBatch(i,a);let o=a.map(e=>`${e.key}=${e.value}`).join(` `);t.dlog(`info`,`set-state: ${o} (session=${i})`)},zv=/^-?\d+$/;function Bv(e,t,n){return e>n?t:e<t?n:e}const Vv=(e,t)=>{let[n=``,r=``,i=``]=jv(()=>ft(e)),a=kv(n);if(!r)throw new Ov(`step-state: <key> is required (shape: <sessionId>/<key>/<by>)`);if(!zv.test(i))throw new Ov(`step-state: delta must be an integer, got "${i}"`);let o=parseInt(i,10),s=av(r);if(!s)throw new Ov(`step-state: key "${r}" is not a bounded (range) state key (have keys: ${V_().join(`, `)})`);let c=t.sessionState.get(a,r),l=c&&zv.test(c)?Math.max(s.min,Math.min(s.max,parseInt(c,10))):s.seed,u=Bv(l+o,s.min,s.max),d=iv(r,String(u));if(!d.ok)throw new Ov(`step-state: ${d.reason}`);t.sessionState.set(a,r,d.value),t.dlog(`info`,`step-state: ${r} ${l}→${d.value} (by ${o}, session=${a})`)},Hv=`config-override`,Uv=new Map([[st,Nv],[`load-config`,(e,t)=>{let n=e.indexOf(`/`);if(n===-1)throw new Ov(`load-config: expected <sessionId>/<path> (missing separator)`);let r=kv(jv(()=>decodeURIComponent(e.slice(0,n)))),i=jv(()=>decodeURIComponent(e.slice(n+1))).trim();if(i!==``){if(!i.startsWith(`/`))throw new Ov(`load-config: path must be absolute, got "${i}"`);if(!/\.(json5?|json)$/.test(i))throw new Ov(`load-config: path must end with .json5 or .json, got "${i}"`)}i===``?(t.sessionState.clear(r,Hv),t.dlog(`info`,`load-config: override cleared (session=${r})`)):(t.sessionState.set(r,Hv,i),t.dlog(`info`,`load-config: ${i} (session=${r})`))}],[ct,Pv],[at,Rv],[ot,Vv],[lt,Fv],[ut,Iv],[`toolbar-toggle`,Lv]]),Wv=(e,t)=>{let n=[],r=!1,i=null;for(let{verb:a,value:o}of mt(e)){if(!i&&(a===`set-state`||a===`step-state`||a===`toolbar-toggle`)){let e=ft(o);e.length>0&&e[0]&&(i=e[0])}let e=Uv.get(a);if(!e){n.push(`unknown effect verb "${a}"`);continue}try{e(o,t)}catch(e){e instanceof Ov||(r=!0),n.push(`${a}: ${e instanceof Error?e.message:String(e)}`)}}if(n.length>0){i&&t.sessionState.set(i,`click.error`,n.join(`
|
|
108
|
+
`));let e=`dispatch: ${n.join(`; `)}`;throw r?Error(e):new Ov(e)}},Gv=new Map([...Uv,[it,Wv]]);Object.freeze([...Gv.keys()]);const Kv=new Set([`hook_event_name`,`session_id`,`session_name`,`transcript_path`,`cwd`,`model`,`workspace`,`version`,`output_style`,`cost`,`context_window`,`exceeds_200k_tokens`,`effort`,`thinking`,`rate_limits`,`vim`,`agent`,`worktree`]),qv=[[`session_id`,`string`],[`transcript_path`,`string`],[`cwd`,`string`],[`model`,`object`],[`model.id`,`string`],[`model.display_name`,`string`],[`workspace`,`object`],[`workspace.current_dir`,`string`],[`workspace.project_dir`,`string`]];function Jv(e){let t={missingRequired:[],typeMismatches:[],unknownTopLevelFields:[]},n=typeof e==`object`&&e&&!Array.isArray(e)?e:{};for(let[e,r]of qv){let i=Yv(n,e);if(i==null)t.missingRequired.push(e);else{let n=Array.isArray(i)?`array`:typeof i;(r===`object`?n!==`object`:n!==r)&&t.typeMismatches.push({path:e,expected:r,got:n})}}for(let e of Object.keys(n))Kv.has(e)||t.unknownTopLevelFields.push(e);return{data:e,report:t}}function Yv(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n||Array.isArray(n))return;n=n[e]}return n}function Xv(e,t){switch(e){case`vars`:return{what:e,vars:Zv(t)};case`segments`:return{what:e,segments:ty(t)};case`config`:return{what:e,config:iy(t)}}}function Zv(e){if(e===null)return[];let{store:t,registry:n,config:r}=e,i=$v(r),a=t.names().sort(),o=[];for(let e of a){let r=t.getNode(e),a=n.getLastError(e);o.push({name:e,source:i.get(e)??null,type:r.type,value:r.read(),lastError:a===void 0?null:{timestampMs:a.timestamp,message:a.message},ageMs:Qv(r.lastUpdatedMs())})}return o}function Qv(e){return e===null?null:Math.max(0,Date.now()-e)}function $v(e){let t=new Map;for(let[n,r]of Object.entries(e.variables))t.set(n,ey(r));for(let[n,r]of Object.entries(e.segments))if(r.vars)for(let[e,i]of Object.entries(r.vars))t.set(`${n}.${e}`,ey(i));return t}function ey(e){return e.kind}function ty(e){if(e===null)return[];let{store:t,config:n,lastRenderBySegment:r}=e,i=new Set(t.names()),a=ny(n),o=[];for(let e of a){let t=n.segments[e];t&&o.push({name:e,template:t.template,referencedVars:ry(t.template,i),lastRender:r.get(e)??null})}return o}function ny(e){let t=[],n=new Set;for(let r of Nn(e.root))r.kind===`segment`&&e.segments[r.name]&&!n.has(r.name)&&(t.push(r.name),n.add(r.name));for(let r of Object.keys(e.segments))n.has(r)||(t.push(r),n.add(r));return t}function ry(e,t){let n=new Set;for(let r of ch(e)){if(t.has(r)){n.add(r);continue}let e=r.split(`.`);for(;e.length>1;){e.pop();let r=e.join(`.`);if(t.has(r)){n.add(r);break}}}return Array.from(n).sort()}function iy(e){return e===null?null:e.config}const ay=[`vars`,`segments`,`config`];function oy(e){return typeof e==`string`&&ay.includes(e)}function sy(e){return Math.max(1,e-2)}var cy=class{thresholds={LOW:50,MEDIUM:80};getContextUsageThresholds(){return this.thresholds}ratioPercentages(e,t){let n=Math.min(100,Math.max(0,Math.round(e/t*100)));return{percentage:n,contextLeftPercentage:Math.max(0,100-n)}}calculateContextFromHookData(e){let t=e.context_window;if(!t?.current_usage)return O(`No current_usage in hook data, falling back to transcript parsing`),null;let n=t.current_usage,r=t.context_window_size,i=(n.input_tokens||0)+(n.cache_creation_input_tokens||0)+(n.cache_read_input_tokens||0);O(`Native current_usage: input=${n.input_tokens}, cache_create=${n.cache_creation_input_tokens}, cache_read=${n.cache_read_input_tokens}, total=${i} (limit: ${r})`);let a=this.ratioPercentages(i,r);return{totalTokens:i,maxTokens:r,percentage:t.used_percentage==null?a.percentage:Math.round(t.used_percentage),contextLeftPercentage:t.remaining_percentage==null?a.contextLeftPercentage:Math.round(t.remaining_percentage)}}async calculateContextTokensFromTranscript(e,t){try{O(`Calculating context tokens from transcript: ${e}`);let n=await _n(e);if(n.length===0)return O(`No entries in transcript`),F;let r=null;for(let e=n.length-1;e>=0;e--){let t=n[e];if(t&&t.message?.usage?.input_tokens&&t.isSidechain!==!0){r=t,O(`Context segment: Found most recent entry at ${t.timestamp.toISOString()}, stopping search`);break}}if(r?.message?.usage){let e=r.message.usage,n=(e.input_tokens||0)+(e.cache_read_input_tokens||0)+(e.cache_creation_input_tokens||0);return O(`Most recent main chain context: ${n} tokens (limit: ${t})`),P({totalTokens:n,maxTokens:t,...this.ratioPercentages(n,t)})}return O(`No main chain entries with usage data found`),F}catch(e){return I(`context transcript: ${e instanceof Error?e.message:String(e)}`)}}async getContextInfo(e){let t=this.calculateContextFromHookData(e);if(t)return P(t);let n=e.context_window?.context_window_size??2e5;return this.calculateContextTokensFromTranscript(e.transcript_path,n)}};function ly(e){let t=e.type||e.message?.role||e.message?.type,n=e.type===`user`&&e.message?.firstContentType===`tool_result`;return t===`user`&&!n}var uy=class{calculateMessageCount(e){return e.filter(ly).length}calculateLastResponseTime(e){if(e.length===0)return null;let t=e.slice(-20),n=null,r=null;for(let e of t){let t=e.type||e.message?.role||e.message?.type;if(ly(e))n=e.timestamp;else if(t===`assistant`&&n){let t=(e.timestamp.getTime()-n.getTime())/1e3;t>.1&&t<300&&(r=t)}}return r}async getMetricsInfo(e,t){try{if(O(`Getting metrics from hook data for session: ${e}`),!t.cost)return F;let n=(await _n(t.transcript_path)).filter(e=>!e.isSidechain),r=this.calculateMessageCount(n),i=this.calculateLastResponseTime(n);return P({responseTime:t.cost.total_api_duration_ms/1e3,lastResponseTime:i,sessionDuration:t.cost.total_duration_ms/1e3,messageCount:r,linesAdded:t.cost.total_lines_added,linesRemoved:t.cost.total_lines_removed})}catch(t){return I(`metrics (${e}): ${t instanceof Error?t.message:String(t)}`)}}};const dy=new Map;function fy(e){if(!e)return``;let t=e.indexOf(`,`);return t<0?e:e.slice(0,t)}var py=class{async getSessionId(){if(!process.env.TMUX_PANE)return F;let e=fy(process.env.TMUX),t=dy.get(e);if(t!==void 0)return t;O(`Getting tmux session ID, TMUX_PANE: ${process.env.TMUX_PANE}`);let n=await _e({bin:`tmux`,args:[`display-message`,`-p`,`#S`],timeoutMs:1e3,category:`tmux`}),r=n.ok?n.stdout.trim()?P(n.stdout.trim()):F:I(`tmux display-message: ${n.reason}`);return dy.set(e,r),r}isInTmux(){return!!process.env.TMUX_PANE}};function my(e){return e<32||e===127||e>=128&&e<=159}function hy(e,t){let n=``;for(let t of e)n+=my(t.codePointAt(0)??0)?` `:t;n=n.replace(/\s+/g,` `).trim();let r=``,i=0;for(let e of n){if(i===t)return r.replace(/.$/u,`…`);r+=e,i++}return r}const gy=`\x1B[38;2;255;255;255m`,_y=`\x1B[48;2;200;40;40m`,vy=`\x1B[0m`,yy=new pv;k(yy.launchStats);const by=new Zt({counters:yy,logger:N}),xy=new rn({watchers:by,logger:N}),Sy=new jn,Cy=new wv,wy=new cy,Ty=new uy,Ey=new py,Dy=new dv({gitService:xy,sessionState:Cy,watchers:by});function Oy(){n.mkdirSync(we(),{recursive:!0}),Ee(Te()),Cy.useStorage(new Dv(Oe(),500,N)),e.on(`uncaughtException`,e=>{N(`error`,`uncaughtException: ${e.stack||e.message}`),Vy(1)}),e.on(`unhandledRejection`,e=>{N(`error`,`unhandledRejection: ${String(e)}`),Vy(1)});for(let t of[`SIGINT`,`SIGTERM`,`SIGHUP`])e.on(t,()=>{N(`info`,`received ${t}, shutting down`),Vy(0)});bv({anchor:yv(e.env),isAlive:xv,onOrphaned:e=>{N(`info`,`parent watchdog: ${e}; shutting down`),Vy(0)}}),ky(m.createServer({allowHalfOpen:!1},e=>{Hy(e)}),Te(),!1)}function ky(t,n,r){t.removeAllListeners(`error`),t.once(`error`,i=>{if(i.code!==`EADDRINUSE`){N(`error`,`server error: ${i.message}`),Vy(1);return}if(r){N(`info`,`lost rebind race; another daemon is alive — exiting`),e.exit(0);return}Ay(t,n)}),t.listen(n,()=>Ny(n))}async function Ay(t,r){await My(r)&&(N(`info`,`another daemon is listening on socket — exiting`),e.exit(0)),await My(r)&&(N(`info`,`race: another daemon claimed the socket during recovery — exiting`),e.exit(0)),N(`warn`,`stale socket from crashed daemon — unlinking and rebinding`);try{n.unlinkSync(r)}catch(e){if(e.code!==`ENOENT`){N(`error`,`cannot unlink stale socket ${r}: ${e.message}`),Vy(1);return}}ky(t,r,!0)}function jy(e){return new Promise(t=>{let n=m.connect(e),r=!1,i=null,a=e=>{r||(r=!0,i&&clearTimeout(i),n.removeAllListeners(),n.destroy(),t(e))};n.once(`connect`,()=>a(`alive`)),n.once(`error`,e=>{let t=e.code;a(t===`ECONNREFUSED`||t===`ENOENT`||t===`ENOTSOCK`?`dead`:`unknown`)}),i=setTimeout(()=>a(`unknown`),50),i.unref()})}async function My(e){return await jy(e)!==`dead`}function Ny(t){try{n.chmodSync(t,384)}catch(e){N(`warn`,`chmod socket failed: ${e.message}`)}Ly(),N(`info`,`daemon up: pid=${e.pid} v=3 sock=${t}`),Py(),Iy()}function Py(){let t=import.meta.url,r=[];t.startsWith(`file://`)&&r.push(_(t)),e.argv[1]&&r.push(e.argv[1]);let i=new Map;for(let e of r)try{i.set(e,n.statSync(e).mtimeMs)}catch{}if(i.size===0)return;let a=setInterval(()=>{for(let[e,t]of i)try{if(n.statSync(e).mtimeMs!==t){N(`info`,`binary mtime changed (${e}); shutting down`),clearInterval(a),Vy(0);return}}catch(e){N(`warn`,`bin stat failed: ${e.message}`)}},6e4);a.unref()}let Fy=null;function Iy(){Fy=hv(_v(yy.startedAt.getTime(),e=>Vy(e))),Fy.arm()}function Ly(){let t=JSON.stringify({pid:e.pid,version:3,binPath:e.argv[1],startedAt:new Date().toISOString()});try{n.writeFileSync(De(),t,{mode:384}),n.chmodSync(De(),384)}catch(e){N(`warn`,`pidfile write failed: ${e.message}`)}}function Ry(){try{n.unlinkSync(De())}catch{}}let zy=0,By=!1;function Vy(t){if(!By){By=!0,setTimeout(()=>e.kill(e.pid,`SIGKILL`),500);try{xy.close()}catch(e){N(`warn`,`gitService close failed: ${e.message}`)}try{Sy.close()}catch(e){N(`warn`,`usageStore close failed: ${e.message}`)}try{by.closeAll()}catch(e){N(`warn`,`watcherRegistry close failed: ${e.message}`)}try{Cy.flush()}catch(e){N(`warn`,`sessionState flush failed: ${e.message}`)}Ry(),Rt(),e.exit(t)}}function Hy(e){zy++,yy.inFlight=zy;let t=!1,n=(n,r)=>{if(t){r!==null&&N(`warn`,`exit-after-flush dropped: an earlier responder settled this socket`);return}t=!0;let i=r===null?void 0:()=>Vy(r);try{e.end(Ne(n),i)}catch(e){N(`warn`,`response write failed: ${e.message}`),i?.()}},r=setTimeout(()=>{yy.requestsTimedOut++,n({ok:!1,error:`request exceeded 200ms`,code:`TIMEOUT`,daemonV:3},null)},200),i=Pe(e=>{Wy(e).then(e=>n(e.resp,e.exitAfterFlush)).catch(e=>{N(`error`,`handler threw: ${e?.stack||e}`),n({ok:!1,error:String(e?.message||e),code:`RENDER_FAILED`,daemonV:3},null)})},e=>{N(`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=>{N(`warn`,`socket error: ${e.message}`)}),e.on(`close`,()=>{clearTimeout(r),zy=Math.max(0,zy-1),yy.inFlight=zy})}const Uy=e=>({resp:e,exitAfterFlush:null});async function Wy(e){if(!e||typeof e!=`object`||typeof e.v!=`number`)return Uy({ok:!1,error:`malformed request`,code:`BAD_REQUEST`,daemonV:3});if(e.v!==3)return e.v>3?N(`info`,`version mismatch: client=${e.v} > daemon=3; binary likely upgraded — exiting after the response flushes`):N(`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 Uy({ok:!0,stats:yy.snapshot({gitCache:xy.getStats(),usageCache:Sy.getStats(),renderCacheSize:Dy.size,watchersActive:by.size(),nextRestartReason:Fy?.describeNextRestart()??null})});if(e.kind===`render`){yy.requestsTotal++;let t=Date.now();try{let{report:n}=Jv(e.hookData);for(let e of n.unknownTopLevelFields)N(`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 yy.requestsErrored++,N(`warn`,`BAD_REQUEST: ${r.join(`; `)}`),Uy({ok:!1,error:`malformed hookData: ${r.join(`; `)}`,code:`BAD_REQUEST`,daemonV:3});let i=e.hookData.workspace.project_dir,{configFile:a,unknownFlagsError:o}=qy(e.args),s=e.hookData.session_id,c=Cy.get(s,`config-override`)??a,l=Dy.getOrCreate(i,e.cwd,c),u=je(e.termCols),d=sy(u??120),f={...Zy,width:d},p=``;if(l.state!==null){let t=await Xh(e.hookData,tb,e.cwd,l.state.neededInputPaths),n=Hg(ts(Cy.get(e.hookData.session_id,`theme`),l.state.config.globals.palette));f.style=os(Cy.get(e.hookData.session_id,`style`),l.state.config.globals.style),p=M_(l.state.config,l.state.compiled,l.state.store,l.state.registry,t,n,f,l.state.lastRenderCellsBySegment)}let m=Cy.get(e.hookData.session_id,`click.error`);m&&Cy.clear(e.hookData.session_id,`click.error`);let h=[o,l.lastError,m].filter(Boolean).join(`
|
|
109
|
+
`)||null,g=Yy(p,h,l.lastWarning),_=Date.now()-t,v=xy.getStats(),y=Sy.getStats();return N(`info`,`render sid=${e.hookData.session_id??`?`} took=${_}ms termCols=${u??`?`} width=${d} git=${v.size}/${v.hits}h/${v.misses}m usage=${y.size}/${y.hits}h/${y.misses}m err=${l.lastError?`Y`:`N`} warn=${l.lastWarning?`Y`:`N`}`),Uy({ok:!0,output:g+`
|
|
110
|
+
`})}catch(e){throw yy.requestsErrored++,e}}if(e.kind===`click`)return Uy(await nb(e.verb,e.value));if(e.kind===`debug`){if(!oy(e.what))return Uy({ok:!1,error:`unknown debug 'what': ${String(e.what)} (have: ${ay.join(`, `)})`,code:`BAD_REQUEST`,daemonV:3});let t=Dy.firstPopulatedState(),n=t===null?null:{store:t.store,registry:t.registry,config:t.config,compiled:t.compiled,lastRenderBySegment:e.what===`segments`?eb(t.lastRenderCellsBySegment):$y};return Uy({ok:!0,debug:Xv(e.what,n)})}return Uy({ok:!1,error:`unknown kind`,code:`BAD_REQUEST`,daemonV:3})}const Gy=`\x1B]8;;`,Ky=`\x1B]8;;\x1B\\`;function qy(e){let{values:t,tokens:n}=v({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}`))],i=t.config;return{configFile:i===void 0?void 0:Th(i),unknownFlagsError:r.length>0?`Unknown flags: ${r.join(`, `)}`:null}}function Jy(e,t,n,r){let i=pt([{verb:e,args:[t]}]),a=t.split(/\r\n|\r|\n/).map(e=>hy(e,120)).filter(Boolean).slice(0,8);return a.length===0?``:[`${Gy}${i}\\${n}${r} ⚠ ${a[0]} ${vy}${Ky}`,...a.slice(1).map(e=>`${Gy}${i}\\${n}${r} ${e} ${vy}${Ky}`)].join(`
|
|
111
|
+
`)}function Yy(e,t,n){let r=[];if(t&&r.push(Jy(lt,t,_y,gy)),n&&r.push(Jy(ut,n,`\x1B[48;2;220;160;40m`,`\x1B[38;2;0;0;0m`)),r.length===0)return e;let i=r.join(`
|
|
112
|
+
`);return e?`${i}\n${e}`:i}const Xy={sessionState:Cy,dlog:N},Zy={style:`powerline`,colorCompatibility:`truecolor`},Qy={...Zy,width:1/0},$y=new Map;function eb(e){let t=new Map;for(let[n,r]of e)t.set(n,zg(r,Qy));return t}const tb={gitProvider:xy,usageStore:Sy,contextProvider:wy,metricsProvider:Ty,tmuxService:Ey,sessionState:Cy,log:N,clock:()=>new Date};function nb(e,t){let n=Gv.get(e);if(!n)return{ok:!1,error:`unknown click verb: ${e}`,code:`BAD_REQUEST`,daemonV:3};try{return n(t,Xy),{ok:!0,output:``}}catch(e){let t=e instanceof Ov?`BAD_REQUEST`:`RENDER_FAILED`;return{ok:!1,error:String(e instanceof Error?e.message:e),code:t,daemonV:3}}}const rb={connectMs:200,budgetMs:500};async function ib(t){let n=t.includes(`--json`),r=await ab();if(r.kind!==`ok`&&(e.stderr.write(`daemon-stats: ${He(r)}\n`),e.exit(1)),n){e.stdout.write(JSON.stringify(r.value,null,2)+`
|
|
113
|
+
`);return}e.stdout.write(lb(r.value))}function ab(){return Ie({kind:`stats`},rb,e=>`stats`in e?e.stats:void 0)}function ob(e){return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function sb(e,t){let n=e+t;return n===0?`n/a`:`${(e/n*100).toFixed(1)}%`}function cb(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 lb(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(` startedAt ${e.startedAt}`),t.push(` uptime ${cb(e.uptimeSec)}`),t.push(` rss ${ob(e.rssBytes)}`),t.push(` heapUsed ${ob(e.heapUsedBytes)}`),t.push(` heapTotal ${ob(e.heapTotalBytes)}`),t.push(` external ${ob(e.externalBytes)}`),t.push(` arrayBuffers ${ob(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 ${sb(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 ${sb(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(`
|
|
114
114
|
`)+`
|
|
115
|
-
`}const
|
|
116
|
-
`);return}e.stdout.write(
|
|
117
|
-
`;let t=[`variables (${e.length})`,``],n=e.reduce((e,t)=>Math.max(e,t.name.length),4),r=e.reduce((e,t)=>Math.max(e,(t.source??`—`).length),6);for(let i of e){let e=i.ageMs===null?``:` ${
|
|
115
|
+
`}const ub={connectMs:200,budgetMs:500};async function db(t,n){let r=n.includes(`--json`),i=await fb(t);if(i.kind!==`ok`&&(e.stderr.write(`${t}: ${He(i)}\n`),e.exit(1)),r){e.stdout.write(JSON.stringify(i.value,null,2)+`
|
|
116
|
+
`);return}e.stdout.write(pb(i.value))}function fb(e){return Ie({kind:`debug`,what:e},ub,e=>`debug`in e?e.debug:void 0)}function pb(e){switch(e.what){case`vars`:return mb(e.vars);case`segments`:return hb(e.segments);case`config`:return gb(e.config);default:return e}}function mb(e){if(e.length===0)return`no variables (DSL not active)
|
|
117
|
+
`;let t=[`variables (${e.length})`,``],n=e.reduce((e,t)=>Math.max(e,t.name.length),4),r=e.reduce((e,t)=>Math.max(e,(t.source??`—`).length),6);for(let i of e){let e=i.ageMs===null?``:` ${vb(i.ageMs)}`,a=i.lastError?` ✗ ${i.lastError.message}`:``;t.push(` ${i.name.padEnd(n)} ${(i.source??`—`).padEnd(r)} ${i.type.padEnd(7)} ${_b(i.value)}${e}${a}`)}return t.join(`
|
|
118
118
|
`)+`
|
|
119
|
-
`}function
|
|
119
|
+
`}function hb(e){if(e.length===0)return`no segments (DSL not active)
|
|
120
120
|
`;let t=[`segments (${e.length})`,``];for(let n of e)t.push(` ${n.name}`),t.push(` template ${n.template}`),n.referencedVars.length>0&&t.push(` vars ${n.referencedVars.join(`, `)}`),n.lastRender!==null&&t.push(` last ${n.lastRender}`);return t.join(`
|
|
121
121
|
`)+`
|
|
122
|
-
`}function
|
|
122
|
+
`}function gb(e){return e===null?`config: DSL not active
|
|
123
123
|
`:JSON.stringify(e,null,2)+`
|
|
124
|
-
`}function
|
|
124
|
+
`}function _b(e){let t=typeof e==`string`?e:JSON.stringify(e);return t.length>60?t.slice(0,57)+`…`:t}function vb(e){return e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m`}function yb(e){let t=o.resolve(e),r;try{r=n.readFileSync(t,`utf-8`)}catch(t){return{kind:`unreadable`,path:e,message:t instanceof Error?t.message:String(t)}}try{let{config:e}=kh(t);Ah(e,t,r)}catch(e){if(e instanceof ss)return{kind:`invalid`,message:e.message};throw e}return{kind:`valid`,path:e}}function bb(t){let n=t[0];(n===void 0||n===``)&&(e.stderr.write(`lint: missing <path>
|
|
125
125
|
Usage: cc-candybar lint <config-file>
|
|
126
|
-
`),e.exit(2)),
|
|
127
|
-
`,code:1};case`unreadable`:return{stream:e.stderr,text:`lint: cannot read ${t.path}: ${t.message}\n`,code:2}}}function
|
|
128
|
-
`,kick:!0,debug:`daemon unavailable (transient: ${e.cause}: ${e.message}) — kicking daemon`};case`permanent`:return{output:
|
|
126
|
+
`),e.exit(2)),Sb(yb(n))}function xb(t){switch(t.kind){case`valid`:return{stream:e.stdout,text:`✓ ${t.path}: config valid\n`,code:0};case`invalid`:return{stream:e.stderr,text:t.message+`
|
|
127
|
+
`,code:1};case`unreadable`:return{stream:e.stderr,text:`lint: cannot read ${t.path}: ${t.message}\n`,code:2}}}function Sb(t){let n=xb(t);n.stream.write(n.text),e.exit(n.code)}function Cb(){let e=Tb();return e===null?null:n.readFileSync(e,`utf-8`)}function wb(){let t=Cb();t===null&&(e.stderr.write("schema: bundled schema not found (expected schema/cc-candybar.schema.json). Run `pnpm gen:schema` from a source checkout.\n"),e.exit(2)),e.stdout.write(t),e.exit(0)}function Tb(){let t=o.join(`schema`,`cc-candybar.schema.json`),r=e.argv[1];if(r===void 0)return null;let i=o.dirname(o.resolve(r));for(;;){let e=o.join(i,t);if(n.existsSync(e))return e;let r=o.dirname(i);if(r===i)return null;i=r}}const Eb=`${_y}${gy}`;function Db(e){return`${Eb}⚠ cc-candybar: ${Ob(e)}${vy}\n`}function Ob(e){switch(e.cause){case`version_mismatch`:{let t=e.daemonV===0?`unknown`:`v${e.daemonV}`;return`protocol mismatch (client v${e.clientV} ≠ daemon ${t})`}case`bad_request`:return`daemon rejected request: ${hy(e.message,60)}`;case`render_failed`:return`render failed: ${hy(e.message,60)}`;case`malformed_response`:return`malformed daemon response: ${hy(e.message,60)}`}}function kb(e){switch(e.kind){case`ok`:return{output:e.value,kick:!1,debug:null};case`transient`:return{output:`
|
|
128
|
+
`,kick:!0,debug:`daemon unavailable (transient: ${e.cause}: ${e.message}) — kicking daemon`};case`permanent`:return{output:Db(e),kick:!1,debug:`daemon refused request (permanent: ${e.cause}) — not kicking`}}}function Ab(){let t=e.env.COLUMNS;if(t){let e=parseInt(t,10);if(!isNaN(e)&&e>0)return e}let n=e.stderr.columns;if(n&&n>0)return n}function jb(){console.log(`
|
|
129
129
|
cc-candybar - Beautiful powerline statusline for Claude Code
|
|
130
130
|
|
|
131
131
|
Usage: cc-candybar [options]
|
|
@@ -166,7 +166,7 @@ Config tooling:
|
|
|
166
166
|
config [--json] The effective merged config. (All three query the
|
|
167
167
|
running daemon; none spawn one.)
|
|
168
168
|
|
|
169
|
-
`)}async function
|
|
169
|
+
`)}async function Mb(){try{(e.argv.includes(`--help`)||e.argv.includes(`-h`))&&(jb(),e.exit(0));let n=e.argv[2];if(n===`install`&&(Pt(e.argv.slice(3)),e.exit(0)),n===`install-url-handler`&&(At(),e.exit(0)),n===`url-handle`){await Mt(e.argv[3]);return}if(n===`daemon`){Oy();return}if(n===`daemon-stats`&&(await ib(e.argv.slice(3)),e.exit(0)),n===`lint`){bb(e.argv.slice(3));return}if(n===`schema`){wb();return}oy(n)&&(await db(n,e.argv.slice(3)),e.exit(0)),e.stdin.isTTY===!0&&(console.error(`Error: This tool requires input from Claude Code
|
|
170
170
|
|
|
171
171
|
cc-candybar is designed to be used as a Claude Code statusLine command.
|
|
172
172
|
It reads hook data from stdin and outputs formatted statusline.
|
|
@@ -182,4 +182,4 @@ Add to ~/.claude/settings.json:
|
|
|
182
182
|
Run with --help for more options.
|
|
183
183
|
|
|
184
184
|
To test output manually:
|
|
185
|
-
echo '{"session_id":"test-session","workspace":{"project_dir":"/path/to/project"},"model":{"id":"claude-sonnet-4-5","display_name":"Claude"}}' | cc-candybar --style=powerline`),e.exit(1)),O(`Working directory: ${e.cwd()}`),O(`Process args:`,e.argv);let r=await t(e.stdin);O(`Received hook data:`,JSON.stringify(r,null,2)),r||(console.error(`Error: No input data received from stdin`),
|
|
185
|
+
echo '{"session_id":"test-session","workspace":{"project_dir":"/path/to/project"},"model":{"id":"claude-sonnet-4-5","display_name":"Claude"}}' | cc-candybar --style=powerline`),e.exit(1)),O(`Working directory: ${e.cwd()}`),O(`Process args:`,e.argv);let r=await t(e.stdin);O(`Received hook data:`,JSON.stringify(r,null,2)),r||(console.error(`Error: No input data received from stdin`),jb(),e.exit(1));let i=kb(await Ke(r,e.argv,e.cwd(),Ab()));i.debug!==null&&O(i.debug),i.kick&&Je(),e.stdout.write(i.output),e.exit(0)}catch(t){let n=t instanceof Error?t.message:String(t);console.error(`Error generating statusline:`,n),e.exit(1)}}Mb();export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptctl/cc-candybar",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
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",
|
|
@@ -91,10 +91,10 @@
|
|
|
91
91
|
"mobx": "^6.15.0"
|
|
92
92
|
},
|
|
93
93
|
"optionalDependencies": {
|
|
94
|
-
"@promptctl/cc-candybar-darwin-arm64": "1.8.
|
|
95
|
-
"@promptctl/cc-candybar-darwin-x64": "1.8.
|
|
96
|
-
"@promptctl/cc-candybar-linux-x64": "1.8.
|
|
97
|
-
"@promptctl/cc-candybar-linux-arm64": "1.8.
|
|
94
|
+
"@promptctl/cc-candybar-darwin-arm64": "1.8.4",
|
|
95
|
+
"@promptctl/cc-candybar-darwin-x64": "1.8.4",
|
|
96
|
+
"@promptctl/cc-candybar-linux-x64": "1.8.4",
|
|
97
|
+
"@promptctl/cc-candybar-linux-arm64": "1.8.4"
|
|
98
98
|
},
|
|
99
99
|
"pnpm": {
|
|
100
100
|
"supportedArchitectures": {
|
package/src/dsl/render.ts
CHANGED
|
@@ -282,6 +282,10 @@ export function registerDslConfig(
|
|
|
282
282
|
const actionRuntime: ActionRuntime = {
|
|
283
283
|
store: registry.variableStore,
|
|
284
284
|
compiled: new Map(),
|
|
285
|
+
// [LAW:types-are-the-program] Always present — renderDsl republishes the live
|
|
286
|
+
// style each render; "powerline" is the registration-time default so a
|
|
287
|
+
// compile-only path (no render) still has a valid value.
|
|
288
|
+
stripStyle: "powerline",
|
|
285
289
|
};
|
|
286
290
|
// [LAW:one-way-deps] Inject action + picker feature funcs as data — the engine
|
|
287
291
|
// stays generic. The picker shares the ACTION runtime (it resolves its
|
|
@@ -517,11 +521,22 @@ export function renderDsl(
|
|
|
517
521
|
perSegmentSink?: Map<string, readonly RichText[]>,
|
|
518
522
|
): string {
|
|
519
523
|
// [LAW:one-source-of-truth] Inject the usable width as `term.cols` from the
|
|
520
|
-
// SAME opts.width the strip wraps to (below), so a width-paginated widget
|
|
521
|
-
//
|
|
524
|
+
// SAME opts.width the strip wraps to (below), so a width-paginated widget reads
|
|
525
|
+
// the exact wrap width — never a cached or independently-measured copy. This is
|
|
526
|
+
// the RAW usable width (terminal cols minus the Claude-Code reserve), the honest
|
|
527
|
+
// meaning every template — incl. user configs reading `.term.cols` — expects.
|
|
528
|
+
// The picker's strip-chrome reservation is NOT folded in here: that is a
|
|
529
|
+
// picker-local concern (the strip's end-caps wrap the picker's row, not every
|
|
530
|
+
// segment), applied at the pagination seam in renderPicker. [LAW:locality-or-seam]
|
|
522
531
|
// Spreading a non-object payload yields no keys (compile-only callers), so the
|
|
523
532
|
// width is set regardless without a trust-boundary guard.
|
|
524
533
|
registry.applyInput({ ...(payload as object), term: { cols: opts.width } });
|
|
534
|
+
// [LAW:single-enforcer] Publish the render's strip style onto the shared action
|
|
535
|
+
// runtime so the picker can reserve the joiner's end-cap chrome at its
|
|
536
|
+
// pagination seam (the menu body renders through the same renderPicker). Set
|
|
537
|
+
// once per render here — the same one-owner, per-render-mutation idiom as the
|
|
538
|
+
// menu placement cursor below. [LAW:no-ambient-temporal-coupling]
|
|
539
|
+
compiled.menuRuntime.action.stripStyle = opts.style;
|
|
525
540
|
|
|
526
541
|
const scope = buildScope(store);
|
|
527
542
|
// [LAW:one-source-of-truth] hueStep is a value in the store like every other
|
package/src/render/action.ts
CHANGED
|
@@ -26,7 +26,11 @@ import type { VariableStore } from "../var-system/store.js";
|
|
|
26
26
|
import { toString as varToString } from "../var-system/types.js";
|
|
27
27
|
import { buildScope } from "../template-engine/scope.js";
|
|
28
28
|
import type { ActionDecl, OptionSource } from "../config/action.js";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
listResolvablePaletteNames,
|
|
31
|
+
STRIP_STYLES,
|
|
32
|
+
type StripStyle,
|
|
33
|
+
} from "../themes/policy.js";
|
|
30
34
|
import {
|
|
31
35
|
effectsUrl,
|
|
32
36
|
VERB_COPY,
|
|
@@ -123,6 +127,13 @@ export interface ActionRuntime {
|
|
|
123
127
|
// values from the same store the renderer reads.
|
|
124
128
|
store: VariableStore;
|
|
125
129
|
compiled: CompiledActions;
|
|
130
|
+
// [LAW:locality-or-seam] The current render's strip style, published per render
|
|
131
|
+
// by renderDsl. The picker reads it to reserve the joiner's end-cap chrome at
|
|
132
|
+
// its pagination seam — the one place that needs strip geometry, kept off the
|
|
133
|
+
// shared `term.cols` budget. Defaulted at registration; renders are sequential
|
|
134
|
+
// and synchronous, so the per-render write never leaks across renders.
|
|
135
|
+
// [LAW:no-ambient-temporal-coupling]
|
|
136
|
+
stripStyle: StripStyle;
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
// ─── Compilation ───────────────────────────────────────────────────────────────
|
package/src/render/picker.ts
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
import { RichText } from "@promptctl/rich-js";
|
|
27
27
|
import type { FuncMap } from "@promptctl/go-template-js";
|
|
28
28
|
import { toNumber } from "../var-system/types.js";
|
|
29
|
+
import { stripChromeCols } from "./strip.js";
|
|
29
30
|
import { TERM_COLS_VAR } from "../config/dsl-types.js";
|
|
30
31
|
import { effectsUrl, VERB_SET_STATE } from "../click/wire.js";
|
|
31
32
|
import {
|
|
@@ -157,7 +158,23 @@ export function renderPicker(
|
|
|
157
158
|
// unconditionally is self-fulfilling (a run that fits with just ✕ could be
|
|
158
159
|
// forced to split, making arrows appear unnecessarily). In wrap mode
|
|
159
160
|
// (available = Infinity) paginate yields one page, so neither pass splits.
|
|
160
|
-
|
|
161
|
+
//
|
|
162
|
+
// [LAW:locality-or-seam] term.cols is the raw usable width the strip wraps to;
|
|
163
|
+
// the picker's row is itself a styled strip segment, so the joiner brackets it
|
|
164
|
+
// with end-caps (powerline's trailing separator, capsule's two caps) painted
|
|
165
|
+
// OUTSIDE that width. A page packed to the full term.cols is pushed past it by
|
|
166
|
+
// the caps — the maximally-packed middle pages overflowed and the terminal ate
|
|
167
|
+
// the trailing → (page 0 fit, page N did not). Reserve the chrome HERE, at the
|
|
168
|
+
// pagination seam, rather than shrinking the shared term.cols every template
|
|
169
|
+
// reads. stripChromeCols owns the per-style geometry; Infinity − chrome stays
|
|
170
|
+
// Infinity, so wrap mode is unaffected.
|
|
171
|
+
const available = paged
|
|
172
|
+
? Math.max(
|
|
173
|
+
1,
|
|
174
|
+
toNumber(store.read(TERM_COLS_VAR)) -
|
|
175
|
+
stripChromeCols(runtime.stripStyle),
|
|
176
|
+
)
|
|
177
|
+
: Infinity;
|
|
161
178
|
const closeReserve = cellWidth(PICKER_CLOSE) + 1;
|
|
162
179
|
const arrowReserve = cellWidth(PICKER_PREV) + 1 + cellWidth(PICKER_NEXT) + 1;
|
|
163
180
|
const firstPass = paginate(widths, available, closeReserve);
|
package/src/render/strip.ts
CHANGED
|
@@ -61,6 +61,35 @@ function pickJoiner(style: StripStyle, separator?: string): Joiner {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// [LAW:single-enforcer] Strip geometry has one owner — this module builds every
|
|
65
|
+
// joiner (pickJoiner) and so alone knows the structural chrome a styled row costs
|
|
66
|
+
// beyond its content: the joiner's end-caps, which FlexStrip paints OUTSIDE the
|
|
67
|
+
// width budget. A single full-width row's content can occupy only `width - chrome`
|
|
68
|
+
// before the caps push the line past `width`. Returned per style so a width-fit
|
|
69
|
+
// widget (the picker) can reserve it and never overflow the wrapped line.
|
|
70
|
+
//
|
|
71
|
+
// [LAW:dataflow-not-control-flow] / [LAW:types-are-the-program] Total over
|
|
72
|
+
// StripStyle — the `never` default makes adding a STRIP_STYLES member a compile
|
|
73
|
+
// error here until its chrome is declared, the same guard pickJoiner carries. The
|
|
74
|
+
// numbers are the default cap glyphs pickJoiner constructs: powerline appends ONE
|
|
75
|
+
// trailing separator (U+E0B0, 1 col); capsule brackets BOTH edges (U+E0B6 +
|
|
76
|
+
// U+E0B4, 2 cols); plain has no caps. test/picker-pagination.test.ts measures the
|
|
77
|
+
// real rendered chrome against these so the declaration cannot drift from rich-js.
|
|
78
|
+
export function stripChromeCols(style: StripStyle): number {
|
|
79
|
+
switch (style) {
|
|
80
|
+
case "powerline":
|
|
81
|
+
return 1;
|
|
82
|
+
case "capsule":
|
|
83
|
+
return 2;
|
|
84
|
+
case "plain":
|
|
85
|
+
return 0;
|
|
86
|
+
default: {
|
|
87
|
+
const _exhaustive: never = style;
|
|
88
|
+
return _exhaustive;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
64
93
|
function toCell(seg: RenderedSegmentLike): RichText {
|
|
65
94
|
// Padding mirrors the legacy buildLineFromSegments: one space on each side
|
|
66
95
|
// of the segment text. The joiners sit between cells; padding sits inside.
|