@promptctl/cc-candybar 1.34.0 → 1.34.1
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 +1 -1
- package/package.json +5 -5
- package/src/demo/statusline.json5 +8 -6
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import{createRequire as e}from"node:module";import t from"node:process";import{json as n}from"node:stream/consumers";import r,{createReadStream as i,existsSync as a,statSync as o,watch as s}from"node:fs";import c,{basename as l,dirname as u,join as d}from"node:path";import f,{homedir as p}from"node:os";import{spawn as m,spawnSync as h}from"node:child_process";import g from"node:net";import{URL as _,URLSearchParams as v,fileURLToPath as y}from"node:url";import{parseArgs as b}from"node:util";import{get as x}from"node:https";import{createHash as S}from"node:crypto";import{setTimeout as C}from"node:timers/promises";import{open as ee,readFile as te,readdir as w,stat as ne}from"node:fs/promises";import{createInterface as re}from"node:readline";import{clearInterval as ie,setInterval as T}from"node:timers";import E from"node:v8";var ae=Object.create,oe=Object.defineProperty,se=Object.getOwnPropertyDescriptor,ce=Object.getOwnPropertyNames,le=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty,de=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),fe=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=ce(t),a=0,o=i.length,s;a<o;a++)s=i[a],!ue.call(e,s)&&s!==n&&oe(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=se(t,s))||r.enumerable});return e},pe=(e,t,n)=>(n=e==null?{}:ae(le(e)),fe(t||!e||!e.__esModule?oe(n,`default`,{value:e,enumerable:!0}):n,e));function D(e,...t){process.env.CC_CANDYBAR_DEBUG&&console.error(`[DEBUG] ${e}`,...t)}const me={"click.pbcopy":1e3,"click.open":1e3},he=new Map;function ge(e){let t=me[e];if(t===void 0)return{allowed:!0};let n=he.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 _e(e){he.set(e,Date.now())}function O(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 ve=null;function ye(e){ve=e}async function be(e){let t=ge(e.category);if(!t.allowed)return O(e.category,t.minIntervalMs,t.sinceLastMs);_e(e.category);let n=Date.now();return ve?.onStart(e.category),new Promise(t=>{let r;try{r=m(e.bin,e.args??[],{cwd:e.cwd,env:e.env,stdio:[`pipe`,`pipe`,`pipe`]})}catch(r){ve?.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),ve?.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 xe(e){let t=ge(e.category);if(!t.allowed)return O(e.category,t.minIntervalMs,t.sinceLastMs);_e(e.category);let n=Date.now();ve?.onStart(e.category);let r=[`pipe`,`pipe`,`pipe`];try{let t=h(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`});ve?.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 ve?.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 Se(e){let t=ge(e.category);if(!t.allowed)return O(e.category,t.minIntervalMs,t.sinceLastMs);_e(e.category);let n=Date.now();ve?.onStart(e.category);let r=Ce(e);return ve?.onEnd(e.category,Date.now()-n),r}function Ce(e){let t;try{t=m(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 we(e){let t=process.env[e];return t&&t.length>0?t:void 0}function Te(){let e=we(`XDG_STATE_HOME`)??c.join(f.homedir(),`.local`,`state`);return c.join(e,`cc-candybar`)}function Ee(){let e=we(`XDG_CACHE_HOME`)??c.join(f.homedir(),`.cache`);return c.join(e,`cc-candybar`)}function De(){return Te()}function Oe(){let e=process.env.CC_CANDYBAR_SOCKET;if(e)return e;let t=f.userInfo().uid;return c.join(`/tmp`,`cc-candybar-${t}`,`socket`)}function ke(e){r.mkdirSync(e,{recursive:!0,mode:448});let t=r.lstatSync(e);if(t.isSymbolicLink())throw Error(`directory is a symlink: ${e}`);if(!t.isDirectory())throw Error(`not a directory: ${e}`);let n=f.userInfo().uid;if(typeof n==`number`&&t.uid!==n)throw Error(`directory is not owned by uid ${n}: ${e} (owner uid=${t.uid})`);if(t.mode&63)throw Error(`directory has unsafe permissions: ${e} (mode=${(t.mode&511).toString(8)}, expected 0700)`)}function Ae(e){ke(c.dirname(e));for(let t of[e,k(e)])try{if(r.lstatSync(t).isSymbolicLink())throw Error(`path is a symlink: ${t}`)}catch(e){if(e.code!==`ENOENT`)throw e}}function k(e){return`${e}.lease`}function je(){return k(Oe())}function Me(){return c.join(Te(),`session-state.json`)}function Ne(){return c.join(Te(),`config-overrides.json`)}function Pe(){let e=process.env.CC_CANDYBAR_DAEMON_REGISTRY_DIR;if(e)return e;let t=f.userInfo().uid;return c.join(`/tmp`,`cc-candybar-${t}`,`daemons`)}function Fe(){return c.join(Te(),`spawn.lock`)}function Ie(){return c.join(Te(),`spawn.cooldown`)}function Le(){return c.join(Te(),`spawn.backoff`)}function Re(){return c.join(Te(),`daemon.log`)}const ze=1e4;function Be(e){if(typeof e!=`number`||!Number.isFinite(e))return;let t=Math.floor(e);if(!(t<=0))return t>ze?ze:t}var Ve=class extends Error{constructor(e){super(e),this.name=`ProtocolError`}};function He(e){let t=Buffer.from(JSON.stringify(e),`utf8`),n=Buffer.alloc(4);return n.writeUInt32BE(t.length,0),Buffer.concat([n,t])}function Ue(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 Ve(`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 Ve(e instanceof Error?e.message:String(e));e instanceof Error&&(n.cause=e),t(n);return}}}}function We(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=Ue(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(He(t))})}async function Ge(e,t,n){let r=null;try{r=await Xe(Oe(),t.connectMs);let i=await We(r,{v:3,...e},t.budgetMs);return Je(e.kind,i,n)}catch(e){return Ye(e)}finally{r&&r.destroy()}}function Ke(e,t){return typeof e==`string`?e:t}function qe(e){return typeof e==`number`&&Number.isInteger(e)&&e>=0?e:0}function Je(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=Ke(r.error,`(no error message)`);switch(r.code){case`VERSION_MISMATCH`:return{kind:`permanent`,cause:`version_mismatch`,clientV:3,daemonV:qe(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 Ye(e){if(e instanceof Ve||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 Xe(e,t){return new Promise((n,r)=>{let i=g.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 Ze(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 Qe={connectMs:50,budgetMs:150},$e={connectMs:50,budgetMs:200};function et(e){let t=e.output;return typeof t==`string`?t:void 0}function tt(e,t,n,r){return Ge({kind:`render`,hookData:e,args:t,cwd:n,termCols:r},Qe,et)}function nt(e,t){return Ge({kind:`click`,verb:e,value:t},$e,et)}function rt(e={}){if(yt()!==null)return;let n=e.spawn??bt,r=gt();if(r.kind===`contended`){let e=at();e!==null&&e>2e3&&(t.stderr.write(`cc-candybar: spawn-lock held ${e}ms (likely crashed holder) — spawning unlocked\n`),it(n));return}if(r.kind===`error`){t.stderr.write(`cc-candybar: spawn-lock unavailable (${r.reason}) — spawning unlocked\n`),it(n);return}try{it(n)}finally{vt()}}function it(e){ft()&&ot(e)}function at(){try{let e=r.statSync(Fe());return Date.now()-e.mtimeMs}catch{return null}}function ot(e){try{e()||t.stderr.write(`cc-candybar: daemon spawn returned false (unable to resolve script path?)
|
|
3
3
|
`)}catch(e){t.stderr.write(`cc-candybar: daemon spawn failed: ${e.message}\n`)}}function st(e,t){return e===null?{kind:`allow`}:e<-1e4?{kind:`allow-future-garbage`,futureMs:-e}:e<t?{kind:`deny`}:{kind:`allow`}}function ct(e){return Math.min(3e3*2**Math.min(Math.max(e,0),5),6e4)}function lt(e){try{let t=r.readFileSync(e,`utf8`).trim(),n=Number(t);return!Number.isInteger(n)||n<0?0:Math.min(n,5)}catch{return 0}}function ut(e,n){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,String(n),{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.backoff: ${e.message}\n`)}}function dt(){try{r.unlinkSync(Le())}catch(e){e.code!==`ENOENT`&&t.stderr.write(`cc-candybar: could not reset spawn.backoff: ${e.message}\n`)}}function ft(){let e=Ie(),n=Le(),r=lt(n),i=st(pt(e),ct(r));return i.kind===`deny`?!1:(i.kind===`allow-future-garbage`&&t.stderr.write(`cc-candybar: spawn.cooldown mtime is ${i.futureMs}ms in the future — ignoring and spawning\n`),mt(e),ut(n,Math.min(r+1,5)),!0)}function pt(e){try{return Date.now()-r.statSync(e).mtimeMs}catch{return null}}function mt(e){try{r.mkdirSync(c.dirname(e),{recursive:!0}),r.writeFileSync(e,`${t.pid} ${Date.now()}\n`,{mode:384})}catch(e){t.stderr.write(`cc-candybar: could not record spawn.cooldown: ${e.message}\n`)}}let ht=null;function gt(){let e=Fe();for(let n=0;n<2;n++){try{let n=r.openSync(e,`wx`,384);try{r.writeSync(n,JSON.stringify({pid:t.pid,ts:Date.now()}))}catch{}return ht={fd:n,path:e},{kind:`held`}}catch(t){let n=t.code;if(n!==`EEXIST`)return{kind:`error`,reason:`openSync(${e}): ${n??t.message}`}}if(!_t(e))return{kind:`contended`};try{r.unlinkSync(e)}catch(e){if(e.code!==`ENOENT`)return{kind:`error`,reason:`unlink stale spawn.lock: ${e.message}`}}}return{kind:`contended`}}function _t(e){try{let t=r.statSync(e);return Date.now()-t.mtimeMs>1e4}catch{return!0}}function vt(){if(!ht)return;let{fd:e,path:t}=ht;ht=null;try{r.closeSync(e)}catch{}try{r.unlinkSync(t)}catch{}}function yt(){try{return r.mkdirSync(De(),{recursive:!0}),null}catch(e){return`mkdir ${De()}: ${e.message}`}}function bt(){let e=t.execPath,n=t.argv[1];return n?Se({bin:e,args:[`--max-old-space-size=400`,n,`daemon`],category:`daemon-spawn`}).ok:!1}const xt=`cc-candybar`,St=`dispatch`,Ct=`set-state`,wt=`step-state`,Tt=`copy`,Et=`open-vscode`,Dt=`show-config-error`,Ot=`show-config-warning`,kt=`set-config`,At=`step-config`,jt=`reset-config`,Mt=`apply-layout-op`,Nt=`undo`,Pt=`redo`;function Ft(e){return e.map(encodeURIComponent).join(`/`)}function A(e){return e.length===0?[]:e.split(`/`).map(decodeURIComponent)}function It(e){return`${xt}://${St}/${e.map(e=>`e=${encodeURIComponent(`${e.verb}/${Ft(e.args)}`)}`).join(`&`)}`}function j(e){return new v(e).getAll(`e`).map(Lt)}function Lt(e){let t=e.indexOf(`/`);return t===-1?{verb:e,value:``}:{verb:e.slice(0,t),value:e.slice(t+1)}}const Rt=`closed`;function zt(e,t){return{kind:`state`,key:e,default:t}}function Bt(e,t){return{set:e,cycle:[Rt,t]}}const Vt=`@promptctl/cc-candybar`,Ht=`CCCandybarURLHandler`,Ut=[],Wt={"darwin-arm64":`@promptctl/cc-candybar-darwin-arm64`,"darwin-x64":`@promptctl/cc-candybar-darwin-x64`,"linux-x64":`@promptctl/cc-candybar-linux-x64`,"linux-arm64":`@promptctl/cc-candybar-linux-arm64`};function Gt(e){return/^[A-Za-z0-9_./=,:-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function Kt(e,t){return[e,...t].map(Gt).join(` `)}function qt(){return c.join(f.homedir(),`Applications`,`${Ht}.app`)}function Jt(){return c.join(f.homedir(),`.claude`,`settings.json`)}function Yt(){if(process.platform!==`darwin`)throw Error(`URL handler installation requires macOS (found platform: ${process.platform}).`)}function Xt(){if(process.platform===`darwin`)return c.join(f.homedir(),`Library`,`Application Support`,`CCCandybar`);let e=process.env.XDG_DATA_HOME??c.join(f.homedir(),`.local`,`share`);return c.join(e,`cc-candybar`)}function Zt(){return c.join(Xt(),`bin`,`cc-candybar`)}function Qt(){return c.join(Xt(),`dist`,`index.mjs`)}function $t(e,t){return[`on open location L`,`\tdo shell script "'${e.replace(/"/g,`\\"`)}' '${t.replace(/"/g,`\\"`)}' url-handle " & quoted form of L`,`end open location`].join(`
|
|
4
|
-
`)}function en(e){if(!e)throw Error(`install: process.argv[1] not set`);return e.endsWith(`.mjs`)||e.endsWith(`.js`)?e:c.resolve(c.dirname(e),`..`,`dist`,`index.mjs`)}function tn(t){let n=Wt[`${process.platform}-${process.arch}`];if(n){let r=e(t);try{return{kind:`native`,sourcePath:r.resolve(`${n}/bin/cc-candybar`)}}catch{}}return{kind:`node-shim`,sourcePath:c.resolve(c.dirname(t),`..`,`bin`,`cc-candybar`)}}function nn(e,t){c.resolve(e)!==c.resolve(t)&&r.copyFileSync(e,t)}function rn(e){let t=r.openSync(e,`r`);try{let n=Buffer.alloc(2),i=r.readSync(t,n,0,2,0);if(i<2)throw Error(`install: staged render entry at ${e} is truncated (${i} byte(s)). Re-run: pnpm dlx ${Vt}@latest install`);return n.toString(`latin1`)===`#!`?`node-shim`:`native`}finally{r.closeSync(t)}}function M(){let e=en(process.argv[1]);if(!r.existsSync(e))throw Error(`install: bundled dist not found at ${e}. Reinstall the package.`);let t=tn(e);if(!r.existsSync(t.sourcePath))throw Error(`install: render entry not found at ${t.sourcePath}. Reinstall the package.`);r.mkdirSync(c.dirname(Qt()),{recursive:!0}),r.mkdirSync(c.dirname(Zt()),{recursive:!0}),nn(e,Qt()),nn(t.sourcePath,Zt()),r.chmodSync(Zt(),493),r.rmSync(c.join(Xt(),`url-handler.mjs`),{force:!0});let n=rn(Zt());return process.stdout.write(`Staged cc-candybar v1.34.
|
|
4
|
+
`)}function en(e){if(!e)throw Error(`install: process.argv[1] not set`);return e.endsWith(`.mjs`)||e.endsWith(`.js`)?e:c.resolve(c.dirname(e),`..`,`dist`,`index.mjs`)}function tn(t){let n=Wt[`${process.platform}-${process.arch}`];if(n){let r=e(t);try{return{kind:`native`,sourcePath:r.resolve(`${n}/bin/cc-candybar`)}}catch{}}return{kind:`node-shim`,sourcePath:c.resolve(c.dirname(t),`..`,`bin`,`cc-candybar`)}}function nn(e,t){c.resolve(e)!==c.resolve(t)&&r.copyFileSync(e,t)}function rn(e){let t=r.openSync(e,`r`);try{let n=Buffer.alloc(2),i=r.readSync(t,n,0,2,0);if(i<2)throw Error(`install: staged render entry at ${e} is truncated (${i} byte(s)). Re-run: pnpm dlx ${Vt}@latest install`);return n.toString(`latin1`)===`#!`?`node-shim`:`native`}finally{r.closeSync(t)}}function M(){let e=en(process.argv[1]);if(!r.existsSync(e))throw Error(`install: bundled dist not found at ${e}. Reinstall the package.`);let t=tn(e);if(!r.existsSync(t.sourcePath))throw Error(`install: render entry not found at ${t.sourcePath}. Reinstall the package.`);r.mkdirSync(c.dirname(Qt()),{recursive:!0}),r.mkdirSync(c.dirname(Zt()),{recursive:!0}),nn(e,Qt()),nn(t.sourcePath,Zt()),r.chmodSync(Zt(),493),r.rmSync(c.join(Xt(),`url-handler.mjs`),{force:!0});let n=rn(Zt());return process.stdout.write(`Staged cc-candybar v1.34.1 runtime at ${Xt()}\n`+(n===`native`?` render entry: native binary (${process.platform}-${process.arch})\n`:` render entry: node shim (no native binary for ${process.platform}-${process.arch}; renders are correct but pay node startup)\n`)),{binPath:Zt(),distPath:Qt(),entryKind:n}}function an(){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>${xt}</string>`,` </array>`,` </dict>`,`</array>`].join(`
|
|
5
5
|
`)}]}function on(e){let t=qt();r.mkdirSync(c.dirname(t),{recursive:!0}),r.existsSync(t)&&r.rmSync(t,{recursive:!0,force:!0}),process.stdout.write(`Building ${t}\n`);let n=xe({bin:`/usr/bin/osacompile`,args:[`-o`,t,`-e`,$t(process.execPath,e)],category:`install.osacompile`});if(!n.ok)throw process.stderr.write(n.stderr),Error(`osacompile failed (${n.reason})`);let i=c.join(t,`Contents`,`Info.plist`);for(let{key:e}of an())xe({bin:`/usr/bin/plutil`,args:[`-remove`,e,i],category:`install.plutil`});for(let{key:e,xml:t}of an()){let n=xe({bin:`/usr/bin/plutil`,args:[`-insert`,e,`-xml`,t,i],category:`install.plutil`});if(!n.ok)throw process.stderr.write(n.stderr),Error(`plutil -insert ${e} failed (${n.reason})`)}process.stdout.write(`Registering ${xt}:// with Launch Services\n`);let a=xe({bin:`/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister`,args:[`-f`,t],category:`install.lsregister`});if(!a.ok)throw process.stderr.write(a.stderr),Error(`lsregister failed (${a.reason})`);process.stdout.write(`✓ ${Ht}.app installed and registered.\n`),process.stdout.write(` Test: open '${xt}://hello-world' && pbpaste\n`)}function sn(){Yt(),on(M().distPath)}function cn(e,t=xt){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:Tt,value:r}:{verb:decodeURIComponent(r.slice(0,i)),value:r.slice(i+1)}}async function ln(e){e||(process.stderr.write(`url-handle: missing URL argument.
|
|
6
6
|
`),process.exit(1));let t;try{t=cn(e)}catch(e){process.stderr.write(`url-handle: ${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let n=await nt(t.verb,t.value);n.kind===`ok`&&process.exit(0),n.kind===`transient`&&(rt(),process.stderr.write(`url-handle: daemon unavailable (${n.cause}: ${n.message})\n`),process.exit(1)),process.stderr.write(un(n)+`
|
|
7
7
|
`),process.exit(1)}function un(e){switch(e.cause){case`version_mismatch`:return`url-handle: daemon rejected click (version mismatch: client v${e.clientV} ≠ daemon v${e.daemonV})`;case`bad_request`:return`url-handle: daemon rejected click (bad request: ${e.message})`;case`render_failed`:return`url-handle: daemon rejected click (handler failed: ${e.message})`;case`malformed_response`:return`url-handle: daemon rejected click (malformed response: ${e.message})`}}function dn(){return`✓ install complete.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptctl/cc-candybar",
|
|
3
|
-
"version": "1.34.
|
|
3
|
+
"version": "1.34.1",
|
|
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,9 +91,9 @@
|
|
|
91
91
|
"mobx": "^6.15.0"
|
|
92
92
|
},
|
|
93
93
|
"optionalDependencies": {
|
|
94
|
-
"@promptctl/cc-candybar-darwin-arm64": "1.34.
|
|
95
|
-
"@promptctl/cc-candybar-darwin-x64": "1.34.
|
|
96
|
-
"@promptctl/cc-candybar-linux-x64": "1.34.
|
|
97
|
-
"@promptctl/cc-candybar-linux-arm64": "1.34.
|
|
94
|
+
"@promptctl/cc-candybar-darwin-arm64": "1.34.1",
|
|
95
|
+
"@promptctl/cc-candybar-darwin-x64": "1.34.1",
|
|
96
|
+
"@promptctl/cc-candybar-linux-x64": "1.34.1",
|
|
97
|
+
"@promptctl/cc-candybar-linux-arm64": "1.34.1"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -47,13 +47,15 @@
|
|
|
47
47
|
},
|
|
48
48
|
|
|
49
49
|
// ── Segments: how each piece of data is drawn ────────────────────────────
|
|
50
|
-
// `bg`/`fg` are palette spec strings
|
|
51
|
-
//
|
|
50
|
+
// `bg`/`fg` are palette spec strings, and either may also be a template
|
|
51
|
+
// that computes a color — `fg: '{{ contrastOn (bgOf) }}'` below picks
|
|
52
|
+
// black or white, whichever is readable against this segment's own
|
|
53
|
+
// background. `when` hides a segment when it evaluates false.
|
|
52
54
|
segments: {
|
|
53
55
|
user: {
|
|
54
56
|
template: ' {{ .user }} ',
|
|
55
57
|
bg: 'primary',
|
|
56
|
-
fg: '
|
|
58
|
+
fg: '{{ contrastOn (bgOf) }}',
|
|
57
59
|
},
|
|
58
60
|
directory: {
|
|
59
61
|
template: ' {{ .here }} ',
|
|
@@ -63,14 +65,14 @@
|
|
|
63
65
|
branch: {
|
|
64
66
|
template: ' {{ .branch }} ',
|
|
65
67
|
bg: 'accent',
|
|
66
|
-
fg: '
|
|
68
|
+
fg: '{{ contrastOn (bgOf) }}',
|
|
67
69
|
when: '{{ ne .branch "" }}', // hidden entirely outside a git repo
|
|
68
70
|
palette: 'gruvbox', // this segment pulls its OWN palette (per-segment switch)
|
|
69
71
|
},
|
|
70
72
|
model: {
|
|
71
73
|
template: ' {{ .model }} ',
|
|
72
74
|
bg: 'secondary',
|
|
73
|
-
fg: '
|
|
75
|
+
fg: '{{ contrastOn (bgOf) }}',
|
|
74
76
|
when: '{{ ne .model "" }}',
|
|
75
77
|
},
|
|
76
78
|
session: {
|
|
@@ -81,7 +83,7 @@
|
|
|
81
83
|
clock: {
|
|
82
84
|
template: ' {{ .clock }} ',
|
|
83
85
|
bg: 'primary',
|
|
84
|
-
fg: '
|
|
86
|
+
fg: '{{ contrastOn (bgOf) }}',
|
|
85
87
|
},
|
|
86
88
|
},
|
|
87
89
|
|