@promptctl/cc-candybar 1.8.4 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +5 -5
- package/package.json +5 -5
- package/schema/cc-candybar.schema.json +3 -0
- package/src/config/dsl-types.ts +7 -0
- package/src/config/loader/globals.ts +2 -0
- package/src/daemon/server.ts +7 -0
- package/src/daemon/verbs/state-validators.ts +4 -4
- package/src/demo/dsl.ts +4 -1
- package/src/render/strip.ts +23 -9
- package/src/themes/index.ts +0 -4
- package/src/themes/policy.ts +0 -33
- package/src/themes/session-random.ts +0 -88
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.
|
|
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.9.0`,...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)+`
|
|
@@ -79,7 +79,7 @@ Use 'override' annotation for methods overridden by subclass.`)}}var $i=aa(0),ea
|
|
|
79
79
|
`)),h.push(new Y(Rr(``,U(e.maxWidth)),s));return h}_emitRowContent(e,t,n,r,i,a,o){let s=t.content,c=n?this.cursorPosition-t.valueStart:-1;if(a===void 0){if(!n){s.length>0&&e.push(new Y(s,r));return}let t=s.slice(0,c),a=Vr(s,Lr(c)),o=s.slice(c,a)||` `,l=s.slice(a);t.length>0&&e.push(new Y(t,r)),e.push(new Y(o,i)),l.length>0&&e.push(new Y(l,r));return}let l=U(H(a.ch)),u=U(Math.max(0,o-l)),[d]=zr(s,u),f=Rr(d,u),p=n&&c>=0?H(s.slice(0,c)):-1;if(p>=0&&p<u){let[t,n]=zr(f,U(p)),a=``;for(let e of n){a=e;break}let o=a||` `,s=n.slice(a.length);t.length>0&&e.push(new Y(t,r)),e.push(new Y(o,i)),s.length>0&&e.push(new Y(s,r))}else f.length>0&&e.push(new Y(f,r));e.push(new Y(a.ch,a.style))}_computeVisualRows(e){let t=U(Math.max(1,e)),n=U(Math.max(1,t-this._markerWidth)),r=[],i=this.value.split(`
|
|
80
80
|
`),a=0;for(let e=0;e<i.length;e++){let o=i[e];if(this._wrap!==void 0){let e=this._wrap(o,{firstWidth:t,continuationWidth:n});if(e.length===0)r.push({content:``,valueStart:Lr(a),isContinuation:!1});else for(let t=0;t<e.length;t++){let n=e[t];r.push({content:n.content,valueStart:Lr(a+n.start),isContinuation:t>0})}}else r.push({content:o,valueStart:Lr(a),isContinuation:!1});a+=o.length+1}return r}measure(e){return{minimum:10,maximum:Math.max(10,Math.max(H(this.value),H(this.placeholder))+2)}}get scrollIndicatorText(){if(this._scrollIndicator!==`indices`||this._maxRows===void 0)return;let e=this._visualRows;if(!(e===null||e.length<=this._maxRows))return`[${this._cursorVisualRow()+1}/${e.length}]`}resolvePalette(e){let t=this._theme.palette.get(e);return K.fromRgba(t)}}})();var To=function(e,t,n){for(var r=arguments.length>2,i=0;i<t.length;i++)n=r?t[i].call(e,n):t[i].call(e);return r?n:void 0},Eo=function(e,t,n,r,i,a){function o(e){if(e!==void 0&&typeof e!=`function`)throw TypeError(`Function expected`);return e}for(var s=r.kind,c=s===`getter`?`get`:s===`setter`?`set`:`value`,l=!t&&e?r.static?e:e.prototype:null,u=t||(l?Object.getOwnPropertyDescriptor(l,r.name):{}),d,f=!1,p=n.length-1;p>=0;p--){var m={};for(var h in r)m[h]=h===`access`?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(f)throw TypeError(`Cannot add initializers after decoration has completed`);a.push(o(e||null))};var g=(0,n[p])(s===`accessor`?{get:u.get,set:u.set}:u[c],m);if(s===`accessor`){if(g===void 0)continue;if(typeof g!=`object`||!g)throw TypeError(`Object expected`);(d=o(g.get))&&(u.get=d),(d=o(g.set))&&(u.set=d),(d=o(g.init))&&i.unshift(d)}else (d=o(g))&&(s===`field`?i.unshift(d):u[c]=d)}l&&Object.defineProperty(l,r.name,u),f=!0};(()=>{var e,t;let n=$a,r=[],i,a=[],o=[],s,c=[],l=[],u,d=[],f=[],p,m=[],h=[],g,_=[],v=[],y,b=[],x=[],S,C,ee,te;return class extends n{static{let w=typeof Symbol==`function`&&Symbol.metadata?Object.create(n[Symbol.metadata]??null):void 0;i=[(e=X.observable).shallow.bind(e)],s=[X.observable],u=[X.observable],p=[X.observable],g=[X.observable],y=[(t=X.observable).ref.bind(t)],S=[X.action],C=[X.action],ee=[X.action],te=[X.action],Eo(this,null,i,{kind:`accessor`,name:`options`,static:!1,private:!1,access:{has:e=>`options`in e,get:e=>e.options,set:(e,t)=>{e.options=t}},metadata:w},a,o),Eo(this,null,s,{kind:`accessor`,name:`selectedIndex`,static:!1,private:!1,access:{has:e=>`selectedIndex`in e,get:e=>e.selectedIndex,set:(e,t)=>{e.selectedIndex=t}},metadata:w},c,l),Eo(this,null,u,{kind:`accessor`,name:`expanded`,static:!1,private:!1,access:{has:e=>`expanded`in e,get:e=>e.expanded,set:(e,t)=>{e.expanded=t}},metadata:w},d,f),Eo(this,null,p,{kind:`accessor`,name:`highlightedIndex`,static:!1,private:!1,access:{has:e=>`highlightedIndex`in e,get:e=>e.highlightedIndex,set:(e,t)=>{e.highlightedIndex=t}},metadata:w},m,h),Eo(this,null,g,{kind:`accessor`,name:`filter`,static:!1,private:!1,access:{has:e=>`filter`in e,get:e=>e.filter,set:(e,t)=>{e.filter=t}},metadata:w},_,v),Eo(this,null,y,{kind:`accessor`,name:`_theme`,static:!1,private:!1,access:{has:e=>`_theme`in e,get:e=>e._theme,set:(e,t)=>{e._theme=t}},metadata:w},b,x),Eo(this,null,S,{kind:`method`,name:`setTheme`,static:!1,private:!1,access:{has:e=>`setTheme`in e,get:e=>e.setTheme},metadata:w},null,r),Eo(this,null,C,{kind:`method`,name:`handleKey`,static:!1,private:!1,access:{has:e=>`handleKey`in e,get:e=>e.handleKey},metadata:w},null,r),Eo(this,null,ee,{kind:`method`,name:`handleMouse`,static:!1,private:!1,access:{has:e=>`handleMouse`in e,get:e=>e.handleMouse},metadata:w},null,r),Eo(this,null,te,{kind:`method`,name:`handleFocus`,static:!1,private:!1,access:{has:e=>`handleFocus`in e,get:e=>e.handleFocus},metadata:w},null,r),w&&Object.defineProperty(this,Symbol.metadata,{enumerable:!0,configurable:!0,writable:!0,value:w})}id=To(this,r);focusable=!0;#e=To(this,a,void 0);get options(){return this.#e}set options(e){this.#e=e}#t=(To(this,o),To(this,c,void 0));get selectedIndex(){return this.#t}set selectedIndex(e){this.#t=e}#n=(To(this,l),To(this,d,!1));get expanded(){return this.#n}set expanded(e){this.#n=e}#r=(To(this,f),To(this,m,void 0));get highlightedIndex(){return this.#r}set highlightedIndex(e){this.#r=e}#i=(To(this,h),To(this,_,``));get filter(){return this.#i}set filter(e){this.#i=e}get filteredOptions(){let e=this.filter.toLowerCase(),t=[];for(let n=0;n<this.options.length;n++){let r=this.options[n];r.toLowerCase().includes(e)&&t.push({label:r,idx:n})}return t}#a=(To(this,v),To(this,b,void 0));get _theme(){return this.#a}set _theme(e){this.#a=e}constructor(e){super(),To(this,x),this.id=e.id??`dropdown-${Math.random().toString(36).slice(2,8)}`,this.options=[...e.options],this.selectedIndex=this.clampIndex(e.selectedIndex??0),this.highlightedIndex=this.selectedIndex,this.disabled=e.disabled??!1,this._theme=e.theme??Yi}clampIndex(e){return this.options.length===0?0:Math.max(0,Math.min(e,this.options.length-1))}setTheme(e){this._theme=e}handleKey(e){if(this.disabled)return;let t=e.character.length===1&&!e.ctrl&&!e.meta&&e.character>=` `&&e.character!==``;if(!this.expanded){if(e.key===`enter`||e.key===`space`){this.expanded=!0,this.highlightedIndex=this.clampIndex(this.selectedIndex),e.stop();return}t&&(this.expanded=!0,this.filter+=e.character,this.highlightedIndex=0,e.stop());return}switch(e.key){case`up`:this.highlightedIndex=Math.max(0,this.highlightedIndex-1),e.stop();return;case`down`:{let t=Math.max(0,this.filteredOptions.length-1);this.highlightedIndex=Math.min(t,this.highlightedIndex+1),e.stop();return}case`enter`:{let t=this.filteredOptions[this.highlightedIndex];if(e.stop(),t===void 0)return;this.selectedIndex=t.idx,this.filter=``,this.expanded=!1,this.emitChange(),this.emitSubmit();return}case`escape`:this.filter=``,this.expanded=!1,e.stop();return;case`backspace`:this.filter=this.filter.slice(0,-1),this.highlightedIndex=0,e.stop();return;case`tab`:this.filter=``,this.expanded=!1,e.stop();return}t&&(this.filter+=e.character,this.highlightedIndex=0,e.stop())}handleMouse(e){if(this.disabled||e.type!==`mouse_up`)return;let t=this.bounds;if(!t)return;let n=e.x>=t.x&&e.x<t.x+t.width&&e.y>=t.y&&e.y<t.y+t.height;if(!this.expanded){n&&(this.expanded=!0,this.highlightedIndex=this.clampIndex(this.selectedIndex));return}if(!n){this.filter=``,this.expanded=!1;return}let r=e.y-t.y;if(r===0){this.filter=``,this.expanded=!1;return}let i=this.filteredOptions[r-1];i!==void 0&&(this.selectedIndex=i.idx,this.filter=``,this.expanded=!1,this.emitChange(),this.emitSubmit())}handleFocus(e){super.handleFocus(e),e.type===`blur`&&(this.filter=``,this.expanded=!1)}render(e){let t=e.asciiOnly?`v`:`▾`,n=this.focused?e.asciiOnly?`|`:`│`:``,r=this.maxLabelLen(),i=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0}):new J({color:this.resolvePalette(`foreground`),bgcolor:this.resolvePalette(`surface`),underline:this.focused}),a=this.headerText(r,n);return[new Y(`[`,i),new Y(`${a} ${t}`,i),new Y(`]`,i)]}headerText(e,t){if(this.filter===``){let t=this.options[this.selectedIndex]??``,n=H(t);if(n>=e)return Rr(t,U(e));let r=e-n,i=Math.floor(r/2),a=r-i;return` `.repeat(i)+t+` `.repeat(a)}let n=Math.max(0,e-H(t)-1),[r]=zr(this.filter,U(n));return Rr(` `+r+t,U(e))}renderOverlay(e){if(!this.expanded)return null;let t=this.maxLabelLen(),n=this.filteredOptions;if(n.length===0)return this.renderNoMatchRow(t);let r=[];for(let e=0;e<n.length;e++)e>0&&r.push(new Y(`
|
|
81
81
|
`)),r.push(...this.renderOptionRow(n[e],e,t));return r}renderNoMatchRow(e){let t=` ${Rr(`(no matches)`,U(e))} `,n=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0}):new J({color:this.resolvePalette(`foreground`),bgcolor:this.resolvePalette(`surface`),dim:!0});return[new Y(` `,n),new Y(t,n),new Y(` `,n)]}renderOptionRow(e,t,n){let r=` ${Rr(e.label,U(n))} `,i=e.idx===this.selectedIndex,a=t===this.highlightedIndex,o=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0}):a?new J({color:this.resolvePalette(`text-primary`),bgcolor:this.resolvePalette(`primary-muted`)}):i?new J({color:this.resolvePalette(`on-primary`),bgcolor:this.resolvePalette(`primary`)}):new J({color:this.resolvePalette(`foreground`),bgcolor:this.resolvePalette(`surface`)});return[new Y(` `,o),new Y(r,o),new Y(` `,o)]}maxLabelLen(){let e=0;for(let t of this.options){let n=H(t);n>e&&(e=n)}return e}measure(e){let t=this.maxLabelLen()+4;return{minimum:t,maximum:t}}resolvePalette(e){let t=this._theme.palette.get(e);return K.fromRgba(t)}}})();var Do=function(e,t,n){for(var r=arguments.length>2,i=0;i<t.length;i++)n=r?t[i].call(e,n):t[i].call(e);return r?n:void 0},Oo=function(e,t,n,r,i,a){function o(e){if(e!==void 0&&typeof e!=`function`)throw TypeError(`Function expected`);return e}for(var s=r.kind,c=s===`getter`?`get`:s===`setter`?`set`:`value`,l=!t&&e?r.static?e:e.prototype:null,u=t||(l?Object.getOwnPropertyDescriptor(l,r.name):{}),d,f=!1,p=n.length-1;p>=0;p--){var m={};for(var h in r)m[h]=h===`access`?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(f)throw TypeError(`Cannot add initializers after decoration has completed`);a.push(o(e||null))};var g=(0,n[p])(s===`accessor`?{get:u.get,set:u.set}:u[c],m);if(s===`accessor`){if(g===void 0)continue;if(typeof g!=`object`||!g)throw TypeError(`Object expected`);(d=o(g.get))&&(u.get=d),(d=o(g.set))&&(u.set=d),(d=o(g.init))&&i.unshift(d)}else (d=o(g))&&(s===`field`?i.unshift(d):u[c]=d)}l&&Object.defineProperty(l,r.name,u),f=!0};(()=>{var e,t,n,r,i;let a=$a,o=[],s,c=[],l=[],u,d=[],f=[],p,m=[],h=[],g,_=[],v=[],y,b=[],x=[],S,C=[],ee=[],te,w,ne,re;return class extends a{static{let ie=typeof Symbol==`function`&&Symbol.metadata?Object.create(a[Symbol.metadata]??null):void 0;s=[X.observable],u=[(e=X.observable).ref.bind(e)],p=[(t=X.observable).ref.bind(t)],g=[(n=X.observable).ref.bind(n)],y=[(r=X.observable).ref.bind(r)],S=[(i=X.observable).ref.bind(i)],te=[X.action],w=[X.action],ne=[X.action],re=[X.action],Oo(this,null,s,{kind:`accessor`,name:`value`,static:!1,private:!1,access:{has:e=>`value`in e,get:e=>e.value,set:(e,t)=>{e.value=t}},metadata:ie},c,l),Oo(this,null,u,{kind:`accessor`,name:`min`,static:!1,private:!1,access:{has:e=>`min`in e,get:e=>e.min,set:(e,t)=>{e.min=t}},metadata:ie},d,f),Oo(this,null,p,{kind:`accessor`,name:`max`,static:!1,private:!1,access:{has:e=>`max`in e,get:e=>e.max,set:(e,t)=>{e.max=t}},metadata:ie},m,h),Oo(this,null,g,{kind:`accessor`,name:`step`,static:!1,private:!1,access:{has:e=>`step`in e,get:e=>e.step,set:(e,t)=>{e.step=t}},metadata:ie},_,v),Oo(this,null,y,{kind:`accessor`,name:`width`,static:!1,private:!1,access:{has:e=>`width`in e,get:e=>e.width,set:(e,t)=>{e.width=t}},metadata:ie},b,x),Oo(this,null,S,{kind:`accessor`,name:`_theme`,static:!1,private:!1,access:{has:e=>`_theme`in e,get:e=>e._theme,set:(e,t)=>{e._theme=t}},metadata:ie},C,ee),Oo(this,null,te,{kind:`method`,name:`setTheme`,static:!1,private:!1,access:{has:e=>`setTheme`in e,get:e=>e.setTheme},metadata:ie},null,o),Oo(this,null,w,{kind:`method`,name:`handleKey`,static:!1,private:!1,access:{has:e=>`handleKey`in e,get:e=>e.handleKey},metadata:ie},null,o),Oo(this,null,ne,{kind:`method`,name:`handleMouse`,static:!1,private:!1,access:{has:e=>`handleMouse`in e,get:e=>e.handleMouse},metadata:ie},null,o),Oo(this,null,re,{kind:`method`,name:`setValue`,static:!1,private:!1,access:{has:e=>`setValue`in e,get:e=>e.setValue},metadata:ie},null,o),ie&&Object.defineProperty(this,Symbol.metadata,{enumerable:!0,configurable:!0,writable:!0,value:ie})}id=Do(this,o);focusable=!0;#e=Do(this,c,void 0);get value(){return this.#e}set value(e){this.#e=e}#t=(Do(this,l),Do(this,d,void 0));get min(){return this.#t}set min(e){this.#t=e}#n=(Do(this,f),Do(this,m,void 0));get max(){return this.#n}set max(e){this.#n=e}#r=(Do(this,h),Do(this,_,void 0));get step(){return this.#r}set step(e){this.#r=e}#i=(Do(this,v),Do(this,b,void 0));get width(){return this.#i}set width(e){this.#i=e}#a=(Do(this,x),Do(this,C,void 0));get _theme(){return this.#a}set _theme(e){this.#a=e}_dragging=(Do(this,ee),!1);constructor(e={}){super(),this.id=e.id??`slider-${Math.random().toString(36).slice(2,8)}`,this.min=e.min??0,this.max=e.max??100,this.step=e.step??1;let t=e.width??20;if(!Number.isInteger(t)||t<1)throw RangeError(`Slider width must be a positive integer; got ${t}`);this.width=t,this.value=ko(e.value??this.min,this.min,this.max,this.step),this.disabled=e.disabled??!1,this._theme=e.theme??Yi}setTheme(e){this._theme=e}handleKey(e){if(!this.disabled)switch(e.key){case`left`:this.setValue(this.value-this.step),e.stop();return;case`right`:this.setValue(this.value+this.step),e.stop();return;case`home`:this.setValue(this.min),e.stop();return;case`end`:this.setValue(this.max),e.stop();return}}handleMouse(e){if(!this.disabled){if(e.type===`mouse_down`){this._dragging=!0,this.setValueFromMouseX(e.x);return}if(e.type===`mouse_move`){this._dragging&&this.setValueFromMouseX(e.x);return}if(e.type===`mouse_up`){let t=this._dragging;this._dragging=!1,t&&(this.setValueFromMouseX(e.x),this.emitSubmit());return}}}setValue(e){let t=ko(e,this.min,this.max,this.step);t!==this.value&&(this.value=t,this.emitChange())}setValueFromMouseX(e){let t=this.bounds;if(!t)return;let n=Math.max(1,this.width-1),r=Math.max(0,Math.min(this.width-1,e-t.x))/n,i=this.min+r*(this.max-this.min);this.setValue(i)}render(e){let t=e.asciiOnly?`-`:`─`,n=e.asciiOnly?`*`:`●`,r=this.max-this.min,i=r===0?0:(this.value-this.min)/r,a=Math.round(i*(this.width-1)),o={underline:this.focused},s=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0,...o}):new J({color:this.resolvePalette(`primary`),...o}),c=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0,...o}):new J({color:this.resolvePalette(`surface`),...o}),l=this.disabled?new J({color:`#666666`,bgcolor:`#333333`,dim:!0,bold:!0,...o}):new J({color:this.resolvePalette(`primary`),bold:!0,...o}),u=[];a>0&&u.push(new Y(t.repeat(a),s)),u.push(new Y(n,l));let d=this.width-a-1;return d>0&&u.push(new Y(t.repeat(d),c)),u}measure(e){return{minimum:this.width,maximum:this.width}}resolvePalette(e){let t=this._theme.palette.get(e);return K.fromRgba(t)}}})();function ko(e,t,n,r){let i=Math.max(t,Math.min(n,e));if(r<=0)return i;let a=t+Math.round((i-t)/r)*r;return Math.max(t,Math.min(n,a))}new TextEncoder,new TextDecoder(`utf-8`),new TextDecoder(`ascii`);function Ao(e,t){if(!(e instanceof Ca))throw TypeError(`template function expected a RichText fragment, got ${typeof e==`object`?Object.prototype.toString.call(e):typeof e}`);let n=e.copy();return n.style=e.style.add(t),n}function jo(e){return{fn:(t=>Ao(t,e)),argTypes:[`liftable`],returnType:`T`}}function Mo(){let e={};for(let t of Object.keys(mi))e[t]=jo(new J({color:K.parse(t)}));return e}const No={fn:((e,t)=>{if(!Number.isInteger(e)||e<0||e>255)throw RangeError(`color index ${e} is out of range (0-255)`);return Ao(t,new J({color:K.fromAnsi(e)}))}),argTypes:[`int`,`liftable`],returnType:`T`},Po=/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/,Fo={fn:((e,t)=>{if(!Po.test(e))throw RangeError(`hex expected #RRGGBB or #RRGGBBAA, got ${JSON.stringify(e)}`);return Ao(t,new J({color:K.parse(e)}))}),argTypes:[`string`,`liftable`],returnType:`T`},Io={fn:((e,t,n,r)=>Ao(r,new J({color:K.fromRgb(e,t,n)}))),argTypes:[`int`,`int`,`int`,`liftable`],returnType:`T`},Lo={fn:((e,t)=>Ao(t,new J({bgcolor:K.parse(e)}))),argTypes:[`string`,`liftable`],returnType:`T`};function Ro(e,t){return new J({[e]:t})}function zo(){let e={};for(let t of ra)e[t]=jo(Ro(t,!0)),e[`not_${t}`]=jo(Ro(t,!1));for(let[t,n]of Object.entries(aa))e[t]=jo(Ro(n,!0));return e}const Bo={fn:((e,t)=>Ao(t,J.parse(e))),argTypes:[`string`,`liftable`],returnType:`T`},Vo={fn:((e,t)=>Ao(t,new J({link:e}))),argTypes:[`string`,`liftable`],returnType:`T`};function Ho(){return{...Mo(),color:No,hex:Fo,rgb:Io,on:Lo,...zo(),link:Vo,style:Bo}}const Uo=/^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/;function Wo(e){if(!Uo.test(e))throw RangeError(`palette background expected #RRGGBB or #RRGGBBAA, got ${JSON.stringify(e)}`);return K.parse(e).getTruecolor()}function Go(e,t,n,r){let i=e.resolve(t,n===void 0?void 0:{against:n});if(i===null){let e=n===void 0?`; for specs with alpha or auto-contrast, use paletteOver`:``;throw Error(`palette spec ${JSON.stringify(t)} did not resolve — check the spec string is valid and the variable exists${e}`)}return Ao(r,new J({color:K.fromRgba(i)}))}const Ko=/^[A-Za-z_][A-Za-z0-9_]*$/;function qo(e){let t={};for(let n of e.palette.vars.keys()){if(!Ko.test(n))continue;let r=n;t[r]={fn:(t=>Go(e,r,void 0,t)),argTypes:[`liftable`],returnType:`T`}}return t}function Jo(e){return{fn:((t,n)=>Go(e,t,void 0,n)),argTypes:[`string`,`liftable`],returnType:`T`}}function Yo(e){return{fn:((t,n,r)=>Go(e,t,Wo(n),r)),argTypes:[`string`,`string`,`liftable`],returnType:`T`}}function Xo(e){return{fn:((t,n)=>Go(e,`auto`,Wo(t),n)),argTypes:[`string`,`liftable`],returnType:`T`}}function Zo(e){return{...qo(e),palette:Jo(e),paletteOver:Yo(e),auto:Xo(e)}}function Qo(){return Ho()}new J({color:`red`,dim:!0});const $o={dark:`textual-dark`,light:`textual-light`};function es(e){return $o[e]??e}function ts(e,t){return e??t??`textual-dark`}function ns(){return Object.keys($o)}function rs(){return[...Bi(),...ns()]}const is=[`powerline`,`capsule`,`plain`];function as(e){return is.includes(e)}function os(e,t){let n=e??t??`powerline`;return as(n)?n:`powerline`}var ss=class extends Error{file;issues;constructor(e,t){super(us(e,t)),this.name=`ConfigError`,this.file=e,this.issues=t}};function Q(e,t){let n=0,r;for(let i of t){if(i===``||/^\d+$/.test(i))continue;let t=cs(e,n,i);if(t===-1)return r===void 0?void 0:ls(e,r);n=t,r=t}return r===void 0?void 0:ls(e,r)}function cs(e,t,n){let r=n.replace(/[\\^$.*+?()[\]{}|]/g,`\\$&`),i=RegExp(`(?:["']${r}["']|\\b${r}\\b)\\s*:`,`g`);i.lastIndex=t;let a=i.exec(e);return a?a.index:-1}function ls(e,t){let n=1;for(let r=0;r<t&&r<e.length;r++)e.charCodeAt(r)===10&&n++;return n}function us(e,t){if(t.length===0)return`${e}: invalid config (no details)`;let n=[`Invalid config in ${e} (${t.length} issue${t.length===1?``:`s`}):`];for(let e of t){let t=[];e.line!==void 0&&t.push(`line ${e.line}${e.col===void 0?``:`:${e.col}`}`),e.path&&t.push(e.path);let r=t.length>0?`[${t.join(` • `)}] `:``;n.push(` ${r}${e.message}`)}return n.join(`
|
|
82
|
-
`)}function ds(e,t,n,r){let i=n[r];return typeof i==`string`?i:(e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be a string, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),r])}),null)}function fs(e,t,n,r){let i=n.default;if(i!==void 0){if(!(r===`string`&&typeof i==`string`||r===`number`&&typeof i==`number`||r===`boolean`&&typeof i==`boolean`)){e.issues.push({path:`${t}.default`,message:`default must be a ${r}, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),`default`])});return}return i}}function ps(e,t,n,r){let i=n[r];if(i!==void 0){if(typeof i!=`string`){e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be a string, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),r])});return}return i}}function ms(e,t,n){let r=ps(e,t,n,`palette`);if(r!==void 0){if(!e.allowedPalettes.has(r)){e.issues.push({path:`${t}.palette`,message:`Unknown palette "${r}". Expected one of: ${[...e.allowedPalettes].sort().join(`, `)}`,line:Q(e.source,[...t.split(`.`),`palette`])});return}return r}}function hs(e,t,n,r,i){let a=n[r];if(a!==void 0){if(typeof a!=`string`||!i.includes(a)){e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be one of: ${i.join(`, `)}; got ${vs(a)}`,line:Q(e.source,[...t.split(`.`),r])});return}return a}}function gs(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _s(e){return e===null?`null`:Array.isArray(e)?`array`:typeof e}function vs(e){return typeof e==`string`?JSON.stringify(e):e===void 0?`undefined`:String(e)}function ys(e,t,n,r){return gs(r)?(xs(e,n,r,t.noun,new Set(Object.keys(t.fields))),bs(e,t.fields,n,r)):(e.issues.push({path:n,message:`${n} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null)}function bs(e,t,n,r){let i=t,a={},o=!0;for(let[t,s]of Object.entries(i)){let i=s.parse(e,n,t,r);i===void 0?s.required&&(o=!1):a[t]=i}return o?a:null}function xs(e,t,n,r,i){for(let a of Object.keys(n))i.has(a)||e.issues.push({path:`${t}.${a}`,message:`Unknown ${r} "${a}". Expected one of: ${[...i].join(`, `)}`,line:Q(e.source,[...t.split(`.`),a])})}function Ss(e,t,n,r){if(!gs(r))return e.issues.push({path:n,message:`${t.noun} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null;let i=t.arms,a=Object.keys(i),o=Object.keys(r).filter(e=>e in i),s=Object.keys(r).filter(e=>!(e in i));for(let r of s)e.issues.push({path:`${n}.${r}`,message:`Unknown ${t.noun} key "${r}". Expected exactly one of: ${a.join(`, `)}`,line:Q(e.source,[...n.split(`.`),r])});if(o.length===0)return e.issues.push({path:n,message:`${t.noun} must declare exactly one of: ${a.join(`, `)}`,line:Q(e.source,n.split(`.`))}),null;if(o.length>1)return e.issues.push({path:n,message:`${t.noun} must declare exactly one of: ${a.join(`, `)} (found: ${o.join(`, `)})`,line:Q(e.source,n.split(`.`))}),null;let c=o[0];return i[c].parse(e,`${n}.${c}`,r[c])}function Cs(e,t,n,r){if(!gs(r))return e.issues.push({path:n,message:`${n} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null;let i=r[t.tag];if(typeof i!=`string`)return e.issues.push({path:`${n}.${t.tag}`,message:`${n}.${t.tag} must be a string, got ${_s(i)}`,line:Q(e.source,n.split(`.`))}),null;let a=t.arms;return i in a?a[i].parse(e,n,r):(e.issues.push({path:`${n}.${t.tag}`,message:`Unknown ${t.noun} "${i}". Expected one of: ${Object.keys(a).join(`, `)}`,line:Q(e.source,[...n.split(`.`),t.tag])}),null)}function ws(e){return(...t)=>e()(...t)}function Ts(e,...t){return(n,r,i)=>{let a=e(n,r,i);if(a===null)return null;for(let e of t){if(e.ok(a))continue;let{field:t,message:i}=e.issue(a),o=t===``?r:`${r}.${t}`;return n.issues.push({path:o,message:i,line:Q(n.source,o.split(`.`))}),null}return a}}function Es(){return{required:!1,json:{type:`string`},parse:(e,t,n,r)=>ps(e,t,r,n)}}function Ds(){return{required:!1,json:{type:`boolean`},parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0){if(typeof i!=`boolean`){e.issues.push({path:`${t}.${n}`,message:`${n} must be a boolean, got ${_s(i)}`,line:Q(e.source,[n])});return}return i}}}}function Os(){return{required:!1,json:{type:`string`},parse:(e,t,n,r)=>ms(e,t,r)}}function ks(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>ds(e,t,r,n)??void 0}}function As(e){return{required:!1,json:{enum:[...e]},parse:(t,n,r,i)=>hs(t,n,i,r,e)}}function js(e,t={closed:!0}){let n=e,r={},i=[];for(let[e,t]of Object.entries(n))r[e]=t.json,t.required&&i.push(e);return{type:`object`,properties:r,...i.length>0&&{required:i},...t.closed&&{additionalProperties:!1}}}function Ms(e,t,n){let r=e,i={[t]:{const:n},...r.properties},a=[t,...r.required??[]];return{...r,properties:i,required:a}}function Ns(e){let t=e.arms;return{anyOf:Object.values(t).map(e=>e.json)}}function Ps(e){let t=e.arms;return{anyOf:Object.entries(t).map(([e,t])=>({type:`object`,properties:{[e]:t.json},required:[e],additionalProperties:!1}))}}function Fs(e,t=Yn){return{globals:{...t.globals,...e.globals??{}},variables:{...t.variables,...e.variables??{}},segments:{...t.segments,...e.segments??{}},root:e.root===void 0?t.root:e.root,actions:{...t.actions,...e.actions??{}},helpers:{...t.helpers,...e.helpers??{}}}}const Is={noun:`globals key`,fields:{default_bg:Es(),default_fg:Es(),default_empty_value:Es(),default_separator:Es(),default_truncate_marker:Es(),palette:Os(),style:As(is)}};function Ls(e,t){return t===void 0?{}:ys(e,Is,`globals`,t)??{}}function Rs(e,t,n,r){return n.cache===void 0?(In.includes(r)&&e.issues.push({path:`${t}.cache`,message:`${r} variables must declare a cache policy (one of: ${B.join(`, `)})`,line:Q(e.source,t.split(`.`))}),null):Ws(e,`${t}.cache`,n.cache)}function zs(e,t,n){if(n.cache!==void 0)return Ws(e,`${t}.cache`,n.cache)??void 0}function Bs(e){return{required:!0,json:qs(),parse:(t,n,r,i)=>Rs(t,n,i,e)??void 0}}function Vs(){return{required:!1,json:qs(),parse:(e,t,n,r)=>zs(e,t,r)}}function Hs(e,t,n){return e.issues.push({path:t,message:n,line:Q(e.source,t.split(`.`))}),null}const Us={noun:`cache`,arms:{ttl:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&Ys(n)?{ttl:n}:Hs(e,t,`cache.ttl must be a duration string like "5s", "100ms", "2m", "1h"; got ${vs(n)}`)},watch_file:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&n!==``?{watch_file:n}:Hs(e,t,`cache.watch_file must be a non-empty path string, got ${vs(n)}`)},depends_on:{json:{type:`array`,items:{type:`string`}},parse:(e,t,n)=>Array.isArray(n)&&n.every(e=>typeof e==`string`)?{depends_on:n}:Hs(e,t,`cache.depends_on must be an array of variable-name strings, got ${vs(n)}`)},key:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&n!==``?{key:n}:Hs(e,t,`cache.key must be a non-empty template string, got ${vs(n)}`)},never:{json:{const:!0},parse:(e,t,n)=>n===!0?{never:!0}:Hs(e,t,`cache.never must be the literal boolean true, got ${vs(n)}`)}}};function Ws(e,t,n){return Ss(e,Us,t,n)}const Gs={noun:`time-variable cache`,arms:{ttl:Us.arms.ttl}};function Ks(){return{required:!1,json:Ps(Gs),parse:(e,t,n,r)=>r.cache===void 0?void 0:Ss(e,Gs,`${t}.cache`,r.cache)??void 0}}function qs(){return Ps(Us)}const Js=/^(\d+(?:\.\d+)?)(ms|s|m|h)$/;function Ys(e){return Js.test(e)}function Xs(e,t,n){if(n===void 0)return{};if(!gs(n))return e.issues.push({path:t,message:`${t} must be an object, got ${_s(n)}`,line:Q(e.source,t.split(`.`))}),{};let r={};for(let[i,a]of Object.entries(n)){let n=Cs(e,uc,`${t}.${i}`,a);n!==null&&(r[i]=n)}return r}function Zs(){return{required:!0,json:{type:[`string`,`number`,`boolean`]},parse:(e,t,n,r)=>{let i=r.value;if(typeof i!=`string`&&typeof i!=`number`&&typeof i!=`boolean`){e.issues.push({path:`${t}.value`,message:`literal value must be string|number|boolean, got ${_s(i)}`,line:Q(e.source,t.split(`.`))});return}return i}}}function Qs(){return{required:!0,json:{enum:[...Fn]},parse:(e,t,n,r)=>{let i=r.field;if(typeof i!=`string`||!Fn.includes(i)){e.issues.push({path:`${t}.field`,message:`git field must be one of: ${Fn.join(`, `)}, got ${JSON.stringify(i)}`,line:Q(e.source,[...t.split(`.`),`field`])});return}return i}}}function $s(){return{required:!1,json:{type:[`string`,`number`,`boolean`]},parse:(e,t,n,r)=>{let i=r.type;return fs(e,t,r,i===`number`||i===`boolean`||i===`string`?i:`string`)}}}const ec={value:Zs(),default:Es()},tc={path:ks(),type:As([`string`,`number`,`boolean`]),default:$s()},nc={name:ks(),default:Es()},rc={path:ks(),readMode:As([`whole`,`first-line`]),regex:Es(),cache:Bs(`file`),default:Es()},ic={command:ks(),regex:Es(),cache:Bs(`shell`),default:Es()},ac={template:ks(),cache:Vs(),default:Es()},oc={layout:ks(),cache:Ks(),default:Es()},sc={field:Qs(),cache:Bs(`git`),default:Es()},cc={key:ks(),default:Es()};function lc(e,t){return{json:Ms(js(t),`kind`,e),parse:(n,r,i)=>{let a=bs(n,t,r,i);return a===null?null:{kind:e,...a}}}}const uc={tag:`kind`,noun:`source kind`,arms:{literal:lc(`literal`,ec),input:lc(`input`,tc),env:lc(`env`,nc),file:lc(`file`,rc),shell:lc(`shell`,ic),template:lc(`template`,ac),time:lc(`time`,oc),git:lc(`git`,sc),state:lc(`state`,cc)}};function dc(){return Ns(uc)}function fc(){return{type:`object`,additionalProperties:dc()}}function pc(e,t){if(t===void 0)return{};if(!gs(t))return e.issues.push({path:`segments`,message:`segments must be an object, got ${_s(t)}`,line:Q(e.source,[`segments`])}),{};let n={};for(let[r,i]of Object.entries(t)){let t=ys(e,gc,`segments.${r}`,i);t!==null&&(n[r]=t)}return n}function mc(){return{required:!1,json:{anyOf:[{const:`auto`},{type:`integer`,minimum:1}]},parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0){if(i===`auto`)return`auto`;if(typeof i==`number`&&Number.isInteger(i)&&i>0)return i;e.issues.push({path:`${t}.${n}`,message:`width must be "auto" or a positive integer, got ${vs(i)}`,line:Q(e.source,[...t.split(`.`),n])})}}}}function hc(){return{required:!1,json:fc(),parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0)return Xs(e,`${t}.${n}`,i)}}}const gc={noun:`segment key`,fields:{template:ks(),width:mc(),justify:As(Ln),truncate:As(Rn),bg:Es(),fg:Es(),when:Es(),palette:Os(),vars:hc()}},_c={kind:`container`,direction:`vertical`,children:[]};function vc(e){return{required:!0,json:{const:e},parse:()=>e}}function yc(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&i.length>0?i:(e.issues.push({path:`${t}.${n}`,message:`a segment node must have a non-empty "name" (a segment name), got ${vs(i)}`,line:Q(e.source,[`root`])}),``)}}}function bc(){return{required:!0,json:{enum:[...Mn]},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&Mn.includes(i)?i:(e.issues.push({path:`${t}.${n}`,message:`a container "direction" must be one of: ${Mn.join(`, `)} (got ${JSON.stringify(i)})`,line:Q(e.source,[`root`])}),`vertical`)}}}function xc(e){return{required:!0,json:{type:`array`,items:{$ref:`#/definitions/LayoutNode`}},parse:(t,n,r,i)=>{let a=i[r];return Array.isArray(a)?a.map((i,a)=>e(t,`${n}.${r}[${a}]`,i)):(t.issues.push({path:`${n}.${r}`,message:`a container must have a "children" array of layout nodes, got ${_s(a)}`,line:Q(t.source,[`root`])}),[])}}}const Sc={noun:`layout-node key`,fields:{kind:vc(`segment`),name:yc(),when:Es()}},Cc={noun:`layout-node key`,fields:{kind:vc(`container`),direction:bc(),children:xc(ws(()=>Oc)),when:Es()}};function wc(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&i.length>0?i:(e.issues.push({path:`${t}.${n}`,message:`a "seg" node must have a non-empty segment name, got ${vs(i)}`,line:Q(e.source,[`root`])}),``)}}}const Tc={noun:`layout-node key`,fields:{seg:wc(),when:Es()}},Ec={noun:`layout-node key`,fields:{h:xc(ws(()=>Oc)),when:Es()}},Dc={noun:`layout-node key`,fields:{v:xc(ws(()=>Oc)),when:Es()}},Oc=(e,t,n)=>{if(typeof n==`string`)return n.length===0?(e.issues.push({path:t,message:`a bare-string layout node must be a non-empty segment name`,line:Q(e.source,[`root`])}),_c):{kind:`segment`,name:n};if(!gs(n))return e.issues.push({path:t,message:`a layout node must be a string (segment name) or an object with "kind" / "seg" / "h" / "v", got ${_s(n)}`,line:Q(e.source,[`root`])}),_c;if(n.kind===`container`)return ys(e,Cc,t,n)??_c;if(n.kind===`segment`)return ys(e,Sc,t,n)??_c;if(n.kind===`cells`)return e.issues.push({path:t,message:`kind: "cells" is no longer supported — use the h-arm spelling instead:
|
|
82
|
+
`)}function ds(e,t,n,r){let i=n[r];return typeof i==`string`?i:(e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be a string, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),r])}),null)}function fs(e,t,n,r){let i=n.default;if(i!==void 0){if(!(r===`string`&&typeof i==`string`||r===`number`&&typeof i==`number`||r===`boolean`&&typeof i==`boolean`)){e.issues.push({path:`${t}.default`,message:`default must be a ${r}, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),`default`])});return}return i}}function ps(e,t,n,r){let i=n[r];if(i!==void 0){if(typeof i!=`string`){e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be a string, got ${_s(i)}`,line:Q(e.source,[...t.split(`.`),r])});return}return i}}function ms(e,t,n){let r=ps(e,t,n,`palette`);if(r!==void 0){if(!e.allowedPalettes.has(r)){e.issues.push({path:`${t}.palette`,message:`Unknown palette "${r}". Expected one of: ${[...e.allowedPalettes].sort().join(`, `)}`,line:Q(e.source,[...t.split(`.`),`palette`])});return}return r}}function hs(e,t,n,r,i){let a=n[r];if(a!==void 0){if(typeof a!=`string`||!i.includes(a)){e.issues.push({path:`${t}.${r}`,message:`${t}.${r} must be one of: ${i.join(`, `)}; got ${vs(a)}`,line:Q(e.source,[...t.split(`.`),r])});return}return a}}function gs(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function _s(e){return e===null?`null`:Array.isArray(e)?`array`:typeof e}function vs(e){return typeof e==`string`?JSON.stringify(e):e===void 0?`undefined`:String(e)}function ys(e,t,n,r){return gs(r)?(xs(e,n,r,t.noun,new Set(Object.keys(t.fields))),bs(e,t.fields,n,r)):(e.issues.push({path:n,message:`${n} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null)}function bs(e,t,n,r){let i=t,a={},o=!0;for(let[t,s]of Object.entries(i)){let i=s.parse(e,n,t,r);i===void 0?s.required&&(o=!1):a[t]=i}return o?a:null}function xs(e,t,n,r,i){for(let a of Object.keys(n))i.has(a)||e.issues.push({path:`${t}.${a}`,message:`Unknown ${r} "${a}". Expected one of: ${[...i].join(`, `)}`,line:Q(e.source,[...t.split(`.`),a])})}function Ss(e,t,n,r){if(!gs(r))return e.issues.push({path:n,message:`${t.noun} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null;let i=t.arms,a=Object.keys(i),o=Object.keys(r).filter(e=>e in i),s=Object.keys(r).filter(e=>!(e in i));for(let r of s)e.issues.push({path:`${n}.${r}`,message:`Unknown ${t.noun} key "${r}". Expected exactly one of: ${a.join(`, `)}`,line:Q(e.source,[...n.split(`.`),r])});if(o.length===0)return e.issues.push({path:n,message:`${t.noun} must declare exactly one of: ${a.join(`, `)}`,line:Q(e.source,n.split(`.`))}),null;if(o.length>1)return e.issues.push({path:n,message:`${t.noun} must declare exactly one of: ${a.join(`, `)} (found: ${o.join(`, `)})`,line:Q(e.source,n.split(`.`))}),null;let c=o[0];return i[c].parse(e,`${n}.${c}`,r[c])}function Cs(e,t,n,r){if(!gs(r))return e.issues.push({path:n,message:`${n} must be an object, got ${_s(r)}`,line:Q(e.source,n.split(`.`))}),null;let i=r[t.tag];if(typeof i!=`string`)return e.issues.push({path:`${n}.${t.tag}`,message:`${n}.${t.tag} must be a string, got ${_s(i)}`,line:Q(e.source,n.split(`.`))}),null;let a=t.arms;return i in a?a[i].parse(e,n,r):(e.issues.push({path:`${n}.${t.tag}`,message:`Unknown ${t.noun} "${i}". Expected one of: ${Object.keys(a).join(`, `)}`,line:Q(e.source,[...n.split(`.`),t.tag])}),null)}function ws(e){return(...t)=>e()(...t)}function Ts(e,...t){return(n,r,i)=>{let a=e(n,r,i);if(a===null)return null;for(let e of t){if(e.ok(a))continue;let{field:t,message:i}=e.issue(a),o=t===``?r:`${r}.${t}`;return n.issues.push({path:o,message:i,line:Q(n.source,o.split(`.`))}),null}return a}}function Es(){return{required:!1,json:{type:`string`},parse:(e,t,n,r)=>ps(e,t,r,n)}}function Ds(){return{required:!1,json:{type:`boolean`},parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0){if(typeof i!=`boolean`){e.issues.push({path:`${t}.${n}`,message:`${n} must be a boolean, got ${_s(i)}`,line:Q(e.source,[n])});return}return i}}}}function Os(){return{required:!1,json:{type:`string`},parse:(e,t,n,r)=>ms(e,t,r)}}function ks(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>ds(e,t,r,n)??void 0}}function As(e){return{required:!1,json:{enum:[...e]},parse:(t,n,r,i)=>hs(t,n,i,r,e)}}function js(e,t={closed:!0}){let n=e,r={},i=[];for(let[e,t]of Object.entries(n))r[e]=t.json,t.required&&i.push(e);return{type:`object`,properties:r,...i.length>0&&{required:i},...t.closed&&{additionalProperties:!1}}}function Ms(e,t,n){let r=e,i={[t]:{const:n},...r.properties},a=[t,...r.required??[]];return{...r,properties:i,required:a}}function Ns(e){let t=e.arms;return{anyOf:Object.values(t).map(e=>e.json)}}function Ps(e){let t=e.arms;return{anyOf:Object.entries(t).map(([e,t])=>({type:`object`,properties:{[e]:t.json},required:[e],additionalProperties:!1}))}}function Fs(e,t=Yn){return{globals:{...t.globals,...e.globals??{}},variables:{...t.variables,...e.variables??{}},segments:{...t.segments,...e.segments??{}},root:e.root===void 0?t.root:e.root,actions:{...t.actions,...e.actions??{}},helpers:{...t.helpers,...e.helpers??{}}}}const Is={noun:`globals key`,fields:{default_bg:Es(),default_fg:Es(),default_empty_value:Es(),default_separator:Es(),default_truncate_marker:Es(),palette:Os(),style:As(is),autoWrap:Ds()}};function Ls(e,t){return t===void 0?{}:ys(e,Is,`globals`,t)??{}}function Rs(e,t,n,r){return n.cache===void 0?(In.includes(r)&&e.issues.push({path:`${t}.cache`,message:`${r} variables must declare a cache policy (one of: ${B.join(`, `)})`,line:Q(e.source,t.split(`.`))}),null):Ws(e,`${t}.cache`,n.cache)}function zs(e,t,n){if(n.cache!==void 0)return Ws(e,`${t}.cache`,n.cache)??void 0}function Bs(e){return{required:!0,json:qs(),parse:(t,n,r,i)=>Rs(t,n,i,e)??void 0}}function Vs(){return{required:!1,json:qs(),parse:(e,t,n,r)=>zs(e,t,r)}}function Hs(e,t,n){return e.issues.push({path:t,message:n,line:Q(e.source,t.split(`.`))}),null}const Us={noun:`cache`,arms:{ttl:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&Ys(n)?{ttl:n}:Hs(e,t,`cache.ttl must be a duration string like "5s", "100ms", "2m", "1h"; got ${vs(n)}`)},watch_file:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&n!==``?{watch_file:n}:Hs(e,t,`cache.watch_file must be a non-empty path string, got ${vs(n)}`)},depends_on:{json:{type:`array`,items:{type:`string`}},parse:(e,t,n)=>Array.isArray(n)&&n.every(e=>typeof e==`string`)?{depends_on:n}:Hs(e,t,`cache.depends_on must be an array of variable-name strings, got ${vs(n)}`)},key:{json:{type:`string`},parse:(e,t,n)=>typeof n==`string`&&n!==``?{key:n}:Hs(e,t,`cache.key must be a non-empty template string, got ${vs(n)}`)},never:{json:{const:!0},parse:(e,t,n)=>n===!0?{never:!0}:Hs(e,t,`cache.never must be the literal boolean true, got ${vs(n)}`)}}};function Ws(e,t,n){return Ss(e,Us,t,n)}const Gs={noun:`time-variable cache`,arms:{ttl:Us.arms.ttl}};function Ks(){return{required:!1,json:Ps(Gs),parse:(e,t,n,r)=>r.cache===void 0?void 0:Ss(e,Gs,`${t}.cache`,r.cache)??void 0}}function qs(){return Ps(Us)}const Js=/^(\d+(?:\.\d+)?)(ms|s|m|h)$/;function Ys(e){return Js.test(e)}function Xs(e,t,n){if(n===void 0)return{};if(!gs(n))return e.issues.push({path:t,message:`${t} must be an object, got ${_s(n)}`,line:Q(e.source,t.split(`.`))}),{};let r={};for(let[i,a]of Object.entries(n)){let n=Cs(e,uc,`${t}.${i}`,a);n!==null&&(r[i]=n)}return r}function Zs(){return{required:!0,json:{type:[`string`,`number`,`boolean`]},parse:(e,t,n,r)=>{let i=r.value;if(typeof i!=`string`&&typeof i!=`number`&&typeof i!=`boolean`){e.issues.push({path:`${t}.value`,message:`literal value must be string|number|boolean, got ${_s(i)}`,line:Q(e.source,t.split(`.`))});return}return i}}}function Qs(){return{required:!0,json:{enum:[...Fn]},parse:(e,t,n,r)=>{let i=r.field;if(typeof i!=`string`||!Fn.includes(i)){e.issues.push({path:`${t}.field`,message:`git field must be one of: ${Fn.join(`, `)}, got ${JSON.stringify(i)}`,line:Q(e.source,[...t.split(`.`),`field`])});return}return i}}}function $s(){return{required:!1,json:{type:[`string`,`number`,`boolean`]},parse:(e,t,n,r)=>{let i=r.type;return fs(e,t,r,i===`number`||i===`boolean`||i===`string`?i:`string`)}}}const ec={value:Zs(),default:Es()},tc={path:ks(),type:As([`string`,`number`,`boolean`]),default:$s()},nc={name:ks(),default:Es()},rc={path:ks(),readMode:As([`whole`,`first-line`]),regex:Es(),cache:Bs(`file`),default:Es()},ic={command:ks(),regex:Es(),cache:Bs(`shell`),default:Es()},ac={template:ks(),cache:Vs(),default:Es()},oc={layout:ks(),cache:Ks(),default:Es()},sc={field:Qs(),cache:Bs(`git`),default:Es()},cc={key:ks(),default:Es()};function lc(e,t){return{json:Ms(js(t),`kind`,e),parse:(n,r,i)=>{let a=bs(n,t,r,i);return a===null?null:{kind:e,...a}}}}const uc={tag:`kind`,noun:`source kind`,arms:{literal:lc(`literal`,ec),input:lc(`input`,tc),env:lc(`env`,nc),file:lc(`file`,rc),shell:lc(`shell`,ic),template:lc(`template`,ac),time:lc(`time`,oc),git:lc(`git`,sc),state:lc(`state`,cc)}};function dc(){return Ns(uc)}function fc(){return{type:`object`,additionalProperties:dc()}}function pc(e,t){if(t===void 0)return{};if(!gs(t))return e.issues.push({path:`segments`,message:`segments must be an object, got ${_s(t)}`,line:Q(e.source,[`segments`])}),{};let n={};for(let[r,i]of Object.entries(t)){let t=ys(e,gc,`segments.${r}`,i);t!==null&&(n[r]=t)}return n}function mc(){return{required:!1,json:{anyOf:[{const:`auto`},{type:`integer`,minimum:1}]},parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0){if(i===`auto`)return`auto`;if(typeof i==`number`&&Number.isInteger(i)&&i>0)return i;e.issues.push({path:`${t}.${n}`,message:`width must be "auto" or a positive integer, got ${vs(i)}`,line:Q(e.source,[...t.split(`.`),n])})}}}}function hc(){return{required:!1,json:fc(),parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0)return Xs(e,`${t}.${n}`,i)}}}const gc={noun:`segment key`,fields:{template:ks(),width:mc(),justify:As(Ln),truncate:As(Rn),bg:Es(),fg:Es(),when:Es(),palette:Os(),vars:hc()}},_c={kind:`container`,direction:`vertical`,children:[]};function vc(e){return{required:!0,json:{const:e},parse:()=>e}}function yc(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&i.length>0?i:(e.issues.push({path:`${t}.${n}`,message:`a segment node must have a non-empty "name" (a segment name), got ${vs(i)}`,line:Q(e.source,[`root`])}),``)}}}function bc(){return{required:!0,json:{enum:[...Mn]},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&Mn.includes(i)?i:(e.issues.push({path:`${t}.${n}`,message:`a container "direction" must be one of: ${Mn.join(`, `)} (got ${JSON.stringify(i)})`,line:Q(e.source,[`root`])}),`vertical`)}}}function xc(e){return{required:!0,json:{type:`array`,items:{$ref:`#/definitions/LayoutNode`}},parse:(t,n,r,i)=>{let a=i[r];return Array.isArray(a)?a.map((i,a)=>e(t,`${n}.${r}[${a}]`,i)):(t.issues.push({path:`${n}.${r}`,message:`a container must have a "children" array of layout nodes, got ${_s(a)}`,line:Q(t.source,[`root`])}),[])}}}const Sc={noun:`layout-node key`,fields:{kind:vc(`segment`),name:yc(),when:Es()}},Cc={noun:`layout-node key`,fields:{kind:vc(`container`),direction:bc(),children:xc(ws(()=>Oc)),when:Es()}};function wc(){return{required:!0,json:{type:`string`},parse:(e,t,n,r)=>{let i=r[n];return typeof i==`string`&&i.length>0?i:(e.issues.push({path:`${t}.${n}`,message:`a "seg" node must have a non-empty segment name, got ${vs(i)}`,line:Q(e.source,[`root`])}),``)}}}const Tc={noun:`layout-node key`,fields:{seg:wc(),when:Es()}},Ec={noun:`layout-node key`,fields:{h:xc(ws(()=>Oc)),when:Es()}},Dc={noun:`layout-node key`,fields:{v:xc(ws(()=>Oc)),when:Es()}},Oc=(e,t,n)=>{if(typeof n==`string`)return n.length===0?(e.issues.push({path:t,message:`a bare-string layout node must be a non-empty segment name`,line:Q(e.source,[`root`])}),_c):{kind:`segment`,name:n};if(!gs(n))return e.issues.push({path:t,message:`a layout node must be a string (segment name) or an object with "kind" / "seg" / "h" / "v", got ${_s(n)}`,line:Q(e.source,[`root`])}),_c;if(n.kind===`container`)return ys(e,Cc,t,n)??_c;if(n.kind===`segment`)return ys(e,Sc,t,n)??_c;if(n.kind===`cells`)return e.issues.push({path:t,message:`kind: "cells" is no longer supported — use the h-arm spelling instead:
|
|
83
83
|
Old: { kind: "cells", segments: ["seg1", "seg2"] }
|
|
84
84
|
New: { h: ["seg1", "seg2"] }`,line:Q(e.source,[`root`])}),_c;if(n.kind===`group`){let r=ys(e,Fc,t,n);return r===null?_c:(e.groups.push({name:r.name,label:r.label,...r.open!==void 0&&{open:r.open},...r.direction!==void 0&&{direction:r.direction},...r.key!==void 0&&{key:r.key},...r.bg!==void 0&&{bg:r.bg},...r.fg!==void 0&&{fg:r.fg},...r.when!==void 0&&{when:r.when},path:t}),Lc(r))}let r=`h`in n,i=`v`in n,a=`seg`in n;if(+!!r+ +!!i+ +!!a>1){let r=[`seg`,`h`,`v`].filter(e=>e in n);return e.issues.push({path:t,message:`a layout node may have exactly one of "seg", "h", or "v" — got ${r.map(e=>`"${e}"`).join(` and `)} together`,line:Q(e.source,[`root`])}),_c}if(a){let r=ys(e,Tc,t,n);return r===null?_c:{kind:`segment`,name:r.seg,...r.when!==void 0&&{when:r.when}}}if(r){let r=ys(e,Ec,t,n);return r===null?_c:{kind:`container`,direction:`horizontal`,children:r.h,...r.when!==void 0&&{when:r.when}}}if(i){let r=ys(e,Dc,t,n);return r===null?_c:{kind:`container`,direction:`vertical`,children:r.v,...r.when!==void 0&&{when:r.when}}}return e.issues.push({path:`${t}.kind`,message:`a layout node "kind" must be "container", "segment", or "group", or use the terse A-grammar: a bare string, or an object with "seg", "h", or "v" (got ${JSON.stringify(n.kind)})`,line:Q(e.source,[`root`])}),_c},kc=`groups.`,Ac=`closed`,jc=/^[A-Za-z_][A-Za-z0-9_]*$/;function Mc(){return{required:!0,json:{type:`string`,pattern:jc.source},parse:(e,t,n,r)=>{let i=r[n];if(typeof i!=`string`||!jc.test(i)||i===Ac){e.issues.push({path:`${t}.${n}`,message:`a group "name" must be an identifier (letters, digits, _; not starting with a digit) and not the reserved "${Ac}", got ${vs(i)}`,line:Q(e.source,[`root`])});return}return i}}}function Nc(){return{required:!1,json:{type:`string`,minLength:1},parse:(e,t,n,r)=>{let i=r[n];if(i!==void 0){if(typeof i!=`string`||i===``||i.includes(`/`)){e.issues.push({path:`${t}.${n}`,message:`a group "key" must be a non-empty, slash-free SessionState key, got ${vs(i)}`,line:Q(e.source,[`root`])});return}return i}}}}function Pc(){return{required:!0,json:{type:`string`,pattern:`^[^\\n\\r]*$`},parse:(e,t,n,r)=>{let i=ds(e,t,r,n);if(i!==null){if(/[\n\r]/.test(i)){e.issues.push({path:`${t}.${n}`,message:`${t}.${n}: group label must not contain newlines`,line:Q(e.source,[...t.split(`.`),n])});return}return i}}}}const Fc={noun:`layout-node key`,fields:{kind:vc(`group`),name:Mc(),label:Pc(),open:Ds(),direction:As(Mn),key:Nc(),bg:Es(),fg:Es(),when:Es(),children:xc(ws(()=>Oc))}};function Ic(e){return e.key??`groups.`+e.name}function Lc(e){let t=kc+e.name;return{kind:`container`,direction:`vertical`,children:[{kind:`segment`,name:t},{kind:`container`,direction:e.direction??`vertical`,children:e.children,when:`{{ eq .${t} "${e.name}" }}`}],...e.when!==void 0&&{when:e.when}}}function Rc(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}function zc(e,t,n){e.issues.push({path:t,message:n,line:Q(e.source,[`root`])})}function Bc(e,t){let n=e.groups;if(n.length===0)return;for(let n of[`variables`,`actions`,`segments`])for(let r of Object.keys(t[n]??{}))r.startsWith(`groups.`)&&zc(e,`${n}.${r}`,`"${r}" is in the reserved "${kc}" namespace (synthesized by group nodes) — rename it`);let r=new Set;for(let t of n)r.has(t.name)&&zc(e,t.path,`duplicate group name "${t.name}" — group names must be unique (they name the synthesized state var, action, and toggle segment)`),r.add(t.name);for(let t of n)for(let r of n)t!==r&&t.path.startsWith(`${r.path}.`)&&Ic(t)===Ic(r)&&zc(e,t.path,`group "${t.name}" shares key "${Ic(t)}" with its ancestor group "${r.name}" — a shared key holds ONE open group, so an ancestor and a descendant cannot share one. Sibling accordions share a key; nested groups use distinct keys.`);let i=new Map;for(let t of n){let n=Ic(t);if(i.has(n)||i.set(n,Ac),t.open===!0){let r=i.get(n);r!==Ac&&zc(e,t.path,`groups "${r}" and "${t.name}" share key "${n}" and both declare open: true — a shared key holds one open group; pick one`),i.set(n,t.name)}}let a={},o={},s={};for(let e of n){let t=kc+e.name,r=Ic(e),c=Rc(e.label),l=n.filter(t=>t!==e&&e.path.startsWith(t.path+`.`)).length,u=` `.repeat(l);a[t]={kind:`state`,key:r,default:i.get(r)},o[t]={set:r,cycle:[Ac,e.name]},s[t]={template:`{{ action "${t}" "${u}${c} ▸" "${u}${c} ▾" }}`,...e.bg!==void 0&&{bg:e.bg},...e.fg!==void 0&&{fg:e.fg}}}t.variables={...t.variables??{},...a},t.actions={...t.actions??{},...o},t.segments={...t.segments??{},...s}}var Vc=class extends Error{name=`TemplateError`;kind=`EvalError`;pos;source;constructor(e,t,n={}){super(e),this.pos=t,this.source=n.source}get sourceSnippet(){return this.source?Jc(this.source,this.pos):``}toString(){let e=`${this.name}: ${this.message}\n at line ${this.pos.line}, column ${this.pos.column}`,t=this.sourceSnippet;return t?`${e}\n\n${t}`:e}},Hc=class extends Vc{name=`ParseError`;kind=`ParseError`;expected;found;constructor(e,t,n={}){super(e,t,n),this.expected=n.expected,this.found=n.found}},Uc=class extends Vc{name=`EvalError`;kind=`EvalError`},Wc=class extends Uc{name=`FuncNotFoundError`;kind=`FuncNotFoundError`;funcName;suggestions;constructor(e,t,n={}){let r=Yc(e,n.available??[]),i=r.length===0?``:` (did you mean: ${r.join(`, `)}?)`;super(`function ${JSON.stringify(e)} is not registered${i}`,t,n),this.funcName=e,this.suggestions=r}},Gc=class extends Uc{name=`TypeMismatchError`;kind=`TypeMismatchError`;funcName;argIndex;expected;receivedSummary;constructor(e,t,n,r,i,a={}){super(`function ${JSON.stringify(e)} arg ${t}: expected ${n}, but a ${r} flowed in. Pass it through \`unstyled\` (or your engine's flatten function) to convert.`,i,a),this.funcName=e,this.argIndex=t,this.expected=n,this.receivedSummary=r}},Kc=class extends Uc{name=`MissingFieldError`;kind=`MissingFieldError`;path;constructor(e,t,n={}){super(`field "${e.join(`.`)}" not found on receiver`,t,n),this.path=e}},qc=class extends Uc{name=`FailError`;kind=`FailError`;constructor(e,t={line:0,column:0,offset:0},n={}){super(e,t,n)}};function Jc(e,t){let n=e.split(`
|
|
85
85
|
`),r=t.line-1,i=[];if(r-1>=0&&r-1<n.length&&i.push({num:r,text:n[r-1]??``}),r>=0&&r<n.length&&i.push({num:r+1,text:n[r]??``}),r+1<n.length&&i.push({num:r+2,text:n[r+1]??``}),i.length===0)return``;let a=String(i[i.length-1]?.num??1).length,o=[];for(let e of i)if(o.push(` ${String(e.num).padStart(a,` `)} | ${e.text}`),e.num===t.line){let e=` ${` `.repeat(a)} | `,n=` `.repeat(Math.max(0,t.column-1));o.push(`${e}${n}^`)}return o.join(`
|
|
@@ -98,18 +98,18 @@ 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){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(`
|
|
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(t.wrap&&Number.isFinite(t.width)){let r=Pa(new Ka([...e],{joiner:n}),{width:t.width,colorSystem:t.colorCompatibility});return r.endsWith(`
|
|
102
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
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
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
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(`
|
|
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),f.wrap=l.state.config.globals.autoWrap??!0,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
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
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
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
|
|
112
|
+
`);return e?`${i}\n${e}`:i}const Xy={sessionState:Cy,dlog:N},Zy={style:`powerline`,colorCompatibility:`truecolor`,wrap:!0},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
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
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)+`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptctl/cc-candybar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Statusline renderer for Claude Code — a JSON5-configurable DSL with daemon-cached data sources, byte-clean palette-aware composition, and OSC8 click verbs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -91,10 +91,10 @@
|
|
|
91
91
|
"mobx": "^6.15.0"
|
|
92
92
|
},
|
|
93
93
|
"optionalDependencies": {
|
|
94
|
-
"@promptctl/cc-candybar-darwin-arm64": "1.
|
|
95
|
-
"@promptctl/cc-candybar-darwin-x64": "1.
|
|
96
|
-
"@promptctl/cc-candybar-linux-x64": "1.
|
|
97
|
-
"@promptctl/cc-candybar-linux-arm64": "1.
|
|
94
|
+
"@promptctl/cc-candybar-darwin-arm64": "1.9.0",
|
|
95
|
+
"@promptctl/cc-candybar-darwin-x64": "1.9.0",
|
|
96
|
+
"@promptctl/cc-candybar-linux-x64": "1.9.0",
|
|
97
|
+
"@promptctl/cc-candybar-linux-arm64": "1.9.0"
|
|
98
98
|
},
|
|
99
99
|
"pnpm": {
|
|
100
100
|
"supportedArchitectures": {
|
package/src/config/dsl-types.ts
CHANGED
|
@@ -189,6 +189,13 @@ export interface Globals {
|
|
|
189
189
|
// so a style click reshapes the bar live and a config can set the default
|
|
190
190
|
// shape without an edit-per-session.
|
|
191
191
|
readonly style?: StripStyle;
|
|
192
|
+
|
|
193
|
+
// The legacy display.autoWrap knob: whether FlexStrip soft-wraps a root
|
|
194
|
+
// row that exceeds the usable width. Default true (current behavior);
|
|
195
|
+
// false renders each row as one unbounded line, overflow off-screen.
|
|
196
|
+
// [config-only] Unlike palette/style there is no SessionState/click half —
|
|
197
|
+
// the daemon resolves `globals.autoWrap ?? true` into renderOpts.wrap.
|
|
198
|
+
readonly autoWrap?: boolean;
|
|
192
199
|
}
|
|
193
200
|
|
|
194
201
|
// [LAW:one-type-per-behavior] One discriminated union covers every source
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { type Globals } from "../dsl-types.js";
|
|
7
7
|
import { STRIP_STYLES } from "../../themes/policy.js";
|
|
8
8
|
import {
|
|
9
|
+
optionalBooleanSpec,
|
|
9
10
|
optionalEnumSpec,
|
|
10
11
|
optionalStringSpec,
|
|
11
12
|
paletteSpec,
|
|
@@ -29,6 +30,7 @@ const GLOBALS_SCHEMA: RecordSchema<Globals> = {
|
|
|
29
30
|
// shapes the joiner can render), unlike the open-ended palette NAME — so it
|
|
30
31
|
// validates by membership and emits a JSON-Schema `enum`.
|
|
31
32
|
style: optionalEnumSpec(STRIP_STYLES),
|
|
33
|
+
autoWrap: optionalBooleanSpec(),
|
|
32
34
|
},
|
|
33
35
|
};
|
|
34
36
|
|
package/src/daemon/server.ts
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
import {
|
|
48
48
|
renderStripCells,
|
|
49
49
|
DEFAULT_TERMINAL_WIDTH,
|
|
50
|
+
DEFAULT_WRAP,
|
|
50
51
|
type BuildLineOptions,
|
|
51
52
|
} from "../render/strip.js";
|
|
52
53
|
import { applyClaudeCodeReserve } from "../utils/terminal-width.js";
|
|
@@ -767,6 +768,11 @@ async function handleRequest(req: Request): Promise<HandledRequest> {
|
|
|
767
768
|
sessionState.get(req.hookData.session_id, "style"),
|
|
768
769
|
entry.state.config.globals.style,
|
|
769
770
|
);
|
|
771
|
+
// [config-only] globals.autoWrap has no SessionState half (no click
|
|
772
|
+
// verb) — the config global over the base floor is the whole
|
|
773
|
+
// resolution. Width stays finite regardless: it also feeds the
|
|
774
|
+
// picker's pagination (term.cols), which no-wrap must not break.
|
|
775
|
+
renderOpts.wrap = entry.state.config.globals.autoWrap ?? DEFAULT_WRAP;
|
|
770
776
|
// [LAW:single-enforcer] renderDsl internally calls
|
|
771
777
|
// `registry.applyInput(payload)` as its first step (see step 1 in
|
|
772
778
|
// src/dsl/render.ts). The daemon must not pre-apply — doing so
|
|
@@ -1057,6 +1063,7 @@ const verbCtx = { sessionState, dlog };
|
|
|
1057
1063
|
const RENDER_OPTS_BASE = {
|
|
1058
1064
|
style: "powerline" as const,
|
|
1059
1065
|
colorCompatibility: "truecolor" as const,
|
|
1066
|
+
wrap: DEFAULT_WRAP,
|
|
1060
1067
|
};
|
|
1061
1068
|
const DEBUG_RENDER_OPTS: BuildLineOptions = {
|
|
1062
1069
|
...RENDER_OPTS_BASE,
|
|
@@ -81,10 +81,10 @@ export type DerivedValidatorSpec =
|
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
// [LAW:one-source-of-truth] listResolvablePaletteNames is THE set whose
|
|
84
|
-
// members resolve to a concrete Palette.
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
84
|
+
// members resolve to a concrete Palette. It deliberately excludes the "custom"
|
|
85
|
+
// sentinel (which needs inline colors and is not a renderable theme name):
|
|
86
|
+
// accepting "custom" here would persist an unrenderable value into SessionState
|
|
87
|
+
// and break the next render.
|
|
88
88
|
//
|
|
89
89
|
// [LAW:single-enforcer] Each validator's accepted-set is one constant
|
|
90
90
|
// lookup structure — a Set for O(1) `has` (matching the BOOLEAN_*
|
package/src/demo/dsl.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { SessionState } from "../daemon/session-state.js";
|
|
|
31
31
|
import { listResolvablePaletteNames } from "../themes/policy.js";
|
|
32
32
|
import { effectiveThemeName, resolverForThemeName } from "../themes/index.js";
|
|
33
33
|
import { registerDslConfig, renderDsl } from "../dsl/render.js";
|
|
34
|
-
import { DEFAULT_TERMINAL_WIDTH } from "../render/strip.js";
|
|
34
|
+
import { DEFAULT_TERMINAL_WIDTH, DEFAULT_WRAP } from "../render/strip.js";
|
|
35
35
|
import { applyClaudeCodeReserve } from "../utils/terminal-width.js";
|
|
36
36
|
|
|
37
37
|
const FRAMES = 4;
|
|
@@ -110,6 +110,9 @@ try {
|
|
|
110
110
|
width: applyClaudeCodeReserve(
|
|
111
111
|
process.stdout.columns ?? DEFAULT_TERMINAL_WIDTH,
|
|
112
112
|
),
|
|
113
|
+
// Same resolution the daemon applies: the config global over the
|
|
114
|
+
// default-on floor.
|
|
115
|
+
wrap: config.globals.autoWrap ?? DEFAULT_WRAP,
|
|
113
116
|
},
|
|
114
117
|
);
|
|
115
118
|
process.stdout.write(` ${line}\n`);
|
package/src/render/strip.ts
CHANGED
|
@@ -32,14 +32,27 @@ export type { StripStyle };
|
|
|
32
32
|
// applyClaudeCodeReserve from src/utils/terminal-width).
|
|
33
33
|
export const DEFAULT_TERMINAL_WIDTH = 120;
|
|
34
34
|
|
|
35
|
+
// [LAW:one-source-of-truth] The one statement of the globals.autoWrap
|
|
36
|
+
// default (on — current behavior). Every resolver of the config global
|
|
37
|
+
// (`globals.autoWrap ?? DEFAULT_WRAP`) derives from this constant.
|
|
38
|
+
export const DEFAULT_WRAP = true;
|
|
39
|
+
|
|
35
40
|
export interface BuildLineOptions {
|
|
36
41
|
style: StripStyle;
|
|
37
42
|
colorCompatibility: ColorSystemSpec;
|
|
38
43
|
separator?: string;
|
|
39
|
-
// [LAW:types-are-the-program] Every render carries a width.
|
|
40
|
-
//
|
|
41
|
-
//
|
|
44
|
+
// [LAW:types-are-the-program] Every render carries a width. Required (not
|
|
45
|
+
// optional) so callers cannot silently drop the wire's value.
|
|
46
|
+
// [LAW:one-source-of-truth] Width is a FACT (usable cells) feeding two
|
|
47
|
+
// consumers — FlexStrip's wrap limit AND the picker's pagination
|
|
48
|
+
// (`term.cols`). It stays finite even when wrapping is off; `wrap` below is
|
|
49
|
+
// the separate POLICY of whether rows may soft-break at that width.
|
|
42
50
|
width: number;
|
|
51
|
+
// [LAW:types-are-the-program] Required for the same reason as width: the
|
|
52
|
+
// wrap decision (globals.autoWrap, default on) must reach every render
|
|
53
|
+
// explicitly — encoding "no wrap" as width=Infinity would corrupt the
|
|
54
|
+
// picker's pagination, which reads the same width value.
|
|
55
|
+
wrap: boolean;
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
function pickJoiner(style: StripStyle, separator?: string): Joiner {
|
|
@@ -106,12 +119,13 @@ function toCell(seg: RenderedSegmentLike): RichText {
|
|
|
106
119
|
* string. Every render path (DSL RichText[] via the template-engine
|
|
107
120
|
* pipeline, buildLineStrip's input-shape adapter, debug per-segment
|
|
108
121
|
* serialization) flows through here. The wrap dispatch lives here too:
|
|
109
|
-
* finite width → FlexStrip (rich-js owns the wrap
|
|
110
|
-
*
|
|
122
|
+
* wrap enabled at a finite width → FlexStrip (rich-js owns the wrap
|
|
123
|
+
* algebra); otherwise → Strip, one unbounded line.
|
|
111
124
|
*
|
|
112
|
-
* [LAW:dataflow-not-control-flow] The dispatch is on
|
|
113
|
-
*
|
|
114
|
-
*
|
|
125
|
+
* [LAW:dataflow-not-control-flow] The dispatch is on values, not on caller
|
|
126
|
+
* branches: `wrap` (the globals.autoWrap policy) gates whether the finite
|
|
127
|
+
* width acts as a break limit. An infinite width has nothing to break at,
|
|
128
|
+
* so it renders unbounded regardless of `wrap`.
|
|
115
129
|
*/
|
|
116
130
|
export function renderStripCells(
|
|
117
131
|
cells: readonly RichText[],
|
|
@@ -119,7 +133,7 @@ export function renderStripCells(
|
|
|
119
133
|
): string {
|
|
120
134
|
if (cells.length === 0) return "";
|
|
121
135
|
const joiner = pickJoiner(options.style, options.separator);
|
|
122
|
-
if (Number.isFinite(options.width)) {
|
|
136
|
+
if (options.wrap && Number.isFinite(options.width)) {
|
|
123
137
|
const flex = new FlexStrip([...cells], { joiner });
|
|
124
138
|
const out = renderToString(flex, {
|
|
125
139
|
width: options.width,
|
package/src/themes/index.ts
CHANGED
package/src/themes/policy.ts
CHANGED
|
@@ -47,14 +47,6 @@ export function listResolvablePaletteNames(): readonly string[] {
|
|
|
47
47
|
return [...listThemePalettes(), ...listThemeAliases()];
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// Selectable theme names for the random pool + picker: registry names plus the
|
|
51
|
-
// "custom" sentinel. Aliases are excluded — they duplicate registry entries.
|
|
52
|
-
export function listAvailableThemes(): string[] {
|
|
53
|
-
const allNames = new Set<string>(listThemePalettes() as readonly string[]);
|
|
54
|
-
allNames.add("custom");
|
|
55
|
-
return [...allNames].sort();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
50
|
// --- Powerline strip-style identifiers ---
|
|
59
51
|
|
|
60
52
|
// [LAW:one-source-of-truth][LAW:types-are-the-program] The single canonical set
|
|
@@ -87,28 +79,3 @@ export function effectiveStripStyle(
|
|
|
87
79
|
const chosen = sessionStyle ?? globalsStyle ?? "powerline";
|
|
88
80
|
return isStripStyle(chosen) ? chosen : "powerline";
|
|
89
81
|
}
|
|
90
|
-
|
|
91
|
-
// --- Legacy palette-preset identifiers (per-session random feature only) ---
|
|
92
|
-
// [LAW:no-silent-failure] NOT the picker's style domain — these were the
|
|
93
|
-
// pre-DSL bg/fg derivation presets, surviving only as the random pool for
|
|
94
|
-
// session-random.ts. The interactive style picker resolves over STRIP_STYLES.
|
|
95
|
-
export const STYLE_ORDER: readonly string[] = [
|
|
96
|
-
"surface",
|
|
97
|
-
"muted",
|
|
98
|
-
"button",
|
|
99
|
-
"hue",
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
export const DISPLAY_STYLES: ReadonlyArray<
|
|
103
|
-
"minimal" | "powerline" | "capsule"
|
|
104
|
-
> = ["minimal", "powerline", "capsule"];
|
|
105
|
-
|
|
106
|
-
// --- Session-random pick ---
|
|
107
|
-
|
|
108
|
-
// [LAW:one-source-of-truth] The random pool derives from the same registry the
|
|
109
|
-
// rest of the system uses. "custom" is excluded because it requires inline
|
|
110
|
-
// colors.custom to be defined.
|
|
111
|
-
export function pickRandomTheme(): string {
|
|
112
|
-
const themes = listAvailableThemes().filter((t) => t !== "custom");
|
|
113
|
-
return themes[Math.floor(Math.random() * themes.length)]!;
|
|
114
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// [LAW:single-enforcer] One place resolves the "random" sentinel into a
|
|
2
|
-
// concrete value, keyed by sessionId so the random pick is *stable for the
|
|
3
|
-
// life of that session* (pick once; clicks like set-state overwrite it).
|
|
4
|
-
// Each setting (theme / style / endpoints) flows through the same pattern:
|
|
5
|
-
// read sessionState → if cached return it → if config says "random" pick
|
|
6
|
-
// + cache → otherwise return config value as-is.
|
|
7
|
-
//
|
|
8
|
-
// The cache is sessionState itself: that means a) the set-state click
|
|
9
|
-
// verb continues to work (it overwrites the same key), and b) the
|
|
10
|
-
// dataflow is uniform — no parallel "random cache" to keep in sync with
|
|
11
|
-
// sessionState.
|
|
12
|
-
|
|
13
|
-
import { pickRandomTheme, DISPLAY_STYLES, STYLE_ORDER } from "./policy.js";
|
|
14
|
-
|
|
15
|
-
interface SessionStateRW {
|
|
16
|
-
get(sessionId: string, key: string): string | null;
|
|
17
|
-
set(sessionId: string, key: string, value: string): void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const SENTINEL = "random";
|
|
21
|
-
|
|
22
|
-
// [LAW:dataflow-not-control-flow] Same shape every call — the only branch is
|
|
23
|
-
// "is this random?" and that's a value-driven question, not a control-flow
|
|
24
|
-
// special case. No early returns hide the cache write from later readers.
|
|
25
|
-
function resolve(
|
|
26
|
-
sessionId: string,
|
|
27
|
-
key: string,
|
|
28
|
-
configValue: string | undefined,
|
|
29
|
-
sessionState: SessionStateRW | undefined,
|
|
30
|
-
pick: () => string,
|
|
31
|
-
fallback: string,
|
|
32
|
-
): string {
|
|
33
|
-
if (!sessionState) {
|
|
34
|
-
return configValue === SENTINEL ? pick() : (configValue ?? fallback);
|
|
35
|
-
}
|
|
36
|
-
const cached = sessionState.get(sessionId, key);
|
|
37
|
-
if (cached) return cached;
|
|
38
|
-
if (configValue !== SENTINEL) return configValue ?? fallback;
|
|
39
|
-
const chosen = pick();
|
|
40
|
-
sessionState.set(sessionId, key, chosen);
|
|
41
|
-
return chosen;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function resolveSessionTheme(
|
|
45
|
-
sessionId: string,
|
|
46
|
-
configTheme: string | undefined,
|
|
47
|
-
sessionState: SessionStateRW | undefined,
|
|
48
|
-
): string {
|
|
49
|
-
return resolve(
|
|
50
|
-
sessionId,
|
|
51
|
-
"theme",
|
|
52
|
-
configTheme,
|
|
53
|
-
sessionState,
|
|
54
|
-
pickRandomTheme,
|
|
55
|
-
"dark",
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function resolveSessionStyle(
|
|
60
|
-
sessionId: string,
|
|
61
|
-
configStyle: string | undefined,
|
|
62
|
-
sessionState: SessionStateRW | undefined,
|
|
63
|
-
): string {
|
|
64
|
-
return resolve(
|
|
65
|
-
sessionId,
|
|
66
|
-
"style",
|
|
67
|
-
configStyle,
|
|
68
|
-
sessionState,
|
|
69
|
-
() => STYLE_ORDER[Math.floor(Math.random() * STYLE_ORDER.length)]!,
|
|
70
|
-
"surface",
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function resolveSessionDisplayStyle(
|
|
75
|
-
sessionId: string,
|
|
76
|
-
configDisplayStyle: string | undefined,
|
|
77
|
-
sessionState: SessionStateRW | undefined,
|
|
78
|
-
): "minimal" | "powerline" | "capsule" {
|
|
79
|
-
const value = resolve(
|
|
80
|
-
sessionId,
|
|
81
|
-
"displayStyle",
|
|
82
|
-
configDisplayStyle,
|
|
83
|
-
sessionState,
|
|
84
|
-
() => DISPLAY_STYLES[Math.floor(Math.random() * DISPLAY_STYLES.length)]!,
|
|
85
|
-
"minimal",
|
|
86
|
-
);
|
|
87
|
-
return value === "powerline" || value === "capsule" ? value : "minimal";
|
|
88
|
-
}
|