@promptctl/cc-candybar 1.154.0 → 1.154.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.
@@ -1,2 +1,2 @@
1
- cc-extra ec94ee89583246d1b7ef577c71500a2151980ad5
1
+ cc-extra b6134fb6e35aae96fe984b37f63d9c25f67912f8
2
2
  Copied by scripts/vendor-cc-extra.mjs; do not edit these files here.
@@ -19,7 +19,8 @@
19
19
  // one as its chunk parses (MEASURED: `breakpointResolved` at the predicted line and column).
20
20
  // [LAW:no-ambient-temporal-coupling] the order is this sequence's, and two waits in it are on a clock,
21
21
  // each with one owner: the socket's appearance, which has a deadline, and the question asked of the
22
- // released process (WHY IT STAYS CONNECTED), which is asked once, at ASK_AFTER_MS.
22
+ // released process (WHY IT STAYS CONNECTED), which is asked again and again until it is a TUI or
23
+ // ASK_WITHIN_MS has passed.
23
24
  //
24
25
  // WHY A UNIX SOCKET. The inspector runs arbitrary code in the session. On TCP it is reachable by every
25
26
  // process on the machine; a socket in a directory only this user can enter is reachable by this user.
@@ -33,7 +34,8 @@
33
34
  // (MEASURED: `/exit` ended it, exit 0). The run it lets go is a one-shot: the inspector holds a process
34
35
  // that ends by draining its loop (`--version`) for as long as it is connected, and that process gives
35
36
  // no sign it is done (MEASURED: `beforeExit` never fires while it is held). Which of the two a run is,
36
- // the process is ASKED, ASK_AFTER_MS after release: a TUI has stdin in raw mode by then.
37
+ // the process is ASKED, every ASK_EVERY_MS after release: a TUI puts stdin in raw mode as it mounts,
38
+ // and the first answer that it has is the verdict.
37
39
  //
38
40
  // FAILURE. Every step before release happens while the binary is held at entry, where nothing the user
39
41
  // asked for has run, so a failure there is answered by killing the held process and exiting non-zero,
@@ -66,10 +68,15 @@ const SOCKET_DEADLINE_MS = 5000;
66
68
  // `--version` not raw, exiting as soon as it was let go — the asking does not hold it).
67
69
  const TUI_IS_UP = 'process.stdin.isTTY === true && process.stdin.isRaw === true';
68
70
 
69
- // When after release the process is asked TUI_IS_UP: about fifteen times the measured time to raw
70
- // mode, and the wait an interactive one-shot like `--version` pays before it is let go. A TUI that
71
- // mounts slower than this is taken for a one-shot and runs without the push; the log says which.
72
- const ASK_AFTER_MS = 2000;
71
+ // How often after release the process is asked TUI_IS_UP, and for how long. A TUI is attached the
72
+ // moment it answers raw, so the deadline is paid only by a run that never does — an interactive
73
+ // one-shot like `--version`, held that long before it is let go. Asking once, at 2s, took a TUI that
74
+ // mounted later for a one-shot: `--resume` restarts on 2.1.289 reached raw mode 2.0-3.3s after release,
75
+ // and 2 of 11 ran without the push. A real session (more plugins, a longer transcript) mounts slower
76
+ // still, so the deadline is three times the slowest measured mount. A TUI slower than that is taken for
77
+ // a one-shot and runs without the push; the log says which, and when the answer came.
78
+ const ASK_EVERY_MS = 100;
79
+ const ASK_WITHIN_MS = 10000;
73
80
  const SOCKET_NAME = 'inspector.sock';
74
81
 
75
82
  // Per user, never the shared temp dir: on Linux that is /tmp, where another user could plant the log
@@ -132,20 +139,45 @@ function socketAppears(dir, name, deadlineMs, exited) {
132
139
 
133
140
  const describeEnding = ({ code, signal, error }) => (error ? `could not start: ${error}` : `exited ${signal || code}`);
134
141
 
135
- // What the released run is, asked of it `askAfterMs` after release: `{ runs: 'tui' }`, `{ runs:
136
- // 'one-shot' }`, `{ runs: 'closed' }` when the inspector went away first (the run ended, or the
137
- // connection did), or `{ runs: 'unanswered', why }` when the question itself failed. A close resolves
142
+ // What the released run is, asked of it every `everyMs` after release, one question in flight at a
143
+ // time: `{ runs: 'tui' }` at the first answer that stdin is raw, `{ runs: 'one-shot' }` at the first
144
+ // answer that it is not once `withinMs` has passed, `{ runs: 'closed' }` when the inspector went away
145
+ // first (the run ended, or the connection did), or `{ runs: 'unanswered', why }` when the first answer
146
+ // after the deadline is a question that failed. A failure before then is asked again: one of a hundred
147
+ // questions failing while the run mounts says nothing about whether it will mount. A close resolves
138
148
  // before the rejection it causes reaches here, so a rejection that does is the question failing.
149
+ // [LAW:no-ambient-temporal-coupling] the verdict waits on the fact it is about: the deadline ends the
150
+ // ASKING, and the question in flight is always waited for, never decided over while it could still say
151
+ // otherwise — so a run that never answers at all is waited on for as long as it is connected.
139
152
  // `session` is anything with the session's `send` and `on`; `delay(ms, fn)` is a cancellable timer. A
140
153
  // pure seam, so the suite drives it with neither an inspector nor a clock. [LAW:effects-at-boundaries]
141
- function askWhatRuns(session, askAfterMs, delay) {
154
+ function askWhatRuns(session, { everyMs, withinMs }, delay) {
142
155
  return new Promise((resolve) => {
143
- const answered = (r) => (r.wasThrown
144
- ? { runs: 'unanswered', why: r.result.description ?? JSON.stringify(r.result.value) }
145
- : { runs: r.result.value === true ? 'tui' : 'one-shot' });
146
- const cancel = delay(askAfterMs, () => session.send('Runtime.evaluate', { expression: TUI_IS_UP, returnByValue: true })
147
- .then((r) => resolve(answered(r)), (e) => resolve({ runs: 'unanswered', why: e.message })));
148
- session.on('close', () => { cancel(); resolve({ runs: 'closed' }); });
156
+ let settled = false;
157
+ let expired = false;
158
+ let cancelNext = () => {};
159
+ const cancelDeadline = delay(withinMs, () => { expired = true; });
160
+ const settle = (verdict) => {
161
+ if (settled) return;
162
+ settled = true;
163
+ cancelNext();
164
+ cancelDeadline();
165
+ resolve(verdict);
166
+ };
167
+ // `why` is the failure of the question just answered, null when it answered not raw.
168
+ const notYet = (why) => {
169
+ if (expired) return settle(why === null ? { runs: 'one-shot' } : { runs: 'unanswered', why });
170
+ if (!settled) cancelNext = delay(everyMs, ask);
171
+ };
172
+ const answered = (r) => {
173
+ if (r.wasThrown) return notYet(r.result.description ?? JSON.stringify(r.result.value));
174
+ if (r.result.value === true) return settle({ runs: 'tui' });
175
+ return notYet(null);
176
+ };
177
+ const ask = () => session.send('Runtime.evaluate', { expression: TUI_IS_UP, returnByValue: true })
178
+ .then(answered, (e) => notYet(e.message));
179
+ cancelNext = delay(everyMs, ask);
180
+ session.on('close', () => settle({ runs: 'closed' }));
149
181
  });
150
182
  }
151
183
 
@@ -197,7 +229,7 @@ async function attachAndRun(binary, args, io = {}) {
197
229
  // Only a TUI has a status line to drive. A headless, piped or print-mode run (`-p`, at a terminal or
198
230
  // not) is a one-shot that would pay the wait below for nothing and wants to stay exactly as fast as
199
231
  // it shipped. [LAW:one-source-of-truth] whether a run renders a TUI is launch.js's one parse of it; an
200
- // interactive `--version` still reads as a TUI there, and is let go at ASK_AFTER_MS.
232
+ // interactive `--version` still reads as a TUI there, and is let go at ASK_WITHIN_MS.
201
233
  if (!rendersTui(args, io.terminal ?? attachedToTerminal())) return runStock(binary, args, 'not a TUI: no status line to drive', { stderr });
202
234
 
203
235
  const graph = readGraphFromFile(binary);
@@ -261,8 +293,9 @@ async function attachAndRun(binary, args, io = {}) {
261
293
  // Only a run that answered 'tui' keeps the launcher connected for the session (see WHY IT STAYS
262
294
  // CONNECTED). Anything else is let go, because staying is what holds a one-shot, and a question that
263
295
  // could not be answered is said why.
264
- const { runs, why } = await askWhatRuns(session, ASK_AFTER_MS, (ms, fn) => { const t = setTimeout(fn, ms); return () => clearTimeout(t); });
265
- log(`after release: ${runs}${why ? ` (${why})` : ''}`);
296
+ const releasedAt = Date.now();
297
+ const { runs, why } = await askWhatRuns(session, { everyMs: ASK_EVERY_MS, withinMs: ASK_WITHIN_MS }, (ms, fn) => { const t = setTimeout(fn, ms); return () => clearTimeout(t); });
298
+ log(`after release: ${runs} at ${Date.now() - releasedAt}ms${why ? ` (${why})` : ''}`);
266
299
  if (runs !== 'tui') session.close();
267
300
  if (runs === 'unanswered') troubles.add(`could not ask the session whether it is a TUI, so it ran without the push: ${why}`);
268
301
 
@@ -278,7 +311,7 @@ async function attachAndRun(binary, args, io = {}) {
278
311
  return exitStatus(code, signal);
279
312
  }
280
313
 
281
- module.exports = { SOCKET_DEADLINE_MS, ASK_AFTER_MS, TUI_IS_UP, LOG_PATH, inspectedEnv, attachCalls, readSample, socketAppears, askWhatRuns, attachAndRun };
314
+ module.exports = { SOCKET_DEADLINE_MS, ASK_EVERY_MS, ASK_WITHIN_MS, TUI_IS_UP, LOG_PATH, inspectedEnv, attachCalls, readSample, socketAppears, askWhatRuns, attachAndRun };
282
315
 
283
316
  if (require.main === module) (async function main() {
284
317
  const [binary, ...args] = process.argv.slice(2);
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as e}from"node:module";import t from"node:process";import{URL as n,URLSearchParams as r,fileURLToPath as i,pathToFileURL as a}from"node:url";import{json as o}from"node:stream/consumers";import s,{basename as c,dirname as l,isAbsolute as u,join as d,sep as f}from"node:path";import p,{closeSync as m,constants as h,existsSync as g,fstatSync as _,openSync as v,readSync as y,realpathSync as b,statSync as ee,watch as x}from"node:fs";import S,{createHash as te,randomUUID as ne}from"node:crypto";import C,{homedir as re}from"node:os";import{spawn as ie,spawnSync as ae}from"node:child_process";import{inspect as w,parseArgs as T,types as oe}from"node:util";import E from"node:net";import se from"node:v8";import{open as ce,readFile as le,readdir as ue,stat as de}from"node:fs/promises";import{clearInterval as fe,setImmediate as pe,setInterval as me}from"node:timers";import{get as he}from"node:https";import{setTimeout as ge}from"node:timers/promises";import{WriteStream as _e}from"node:tty";import{createInterface as ve}from"node:readline";var ye=Object.create,be=Object.defineProperty,xe=Object.getOwnPropertyDescriptor,Se=Object.getOwnPropertyNames,Ce=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty,Te=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),Ee=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=Se(t),a=0,o=i.length,s;a<o;a++)s=i[a],!we.call(e,s)&&s!==n&&be(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=xe(t,s))||r.enumerable});return e},De=(e,t,n)=>(n=e==null?{}:ye(Ce(e)),Ee(t||!e||!e.__esModule?be(n,`default`,{value:e,enumerable:!0}):n,e));function D(e,...t){process.env.CC_CANDYBAR_DEBUG&&console.error(`[DEBUG] ${e}`,...t)}const Oe=(e,t)=>D(t),ke=/^[A-Za-z0-9_./,:@%+-][A-Za-z0-9_./,:@%+=-]*$/;function Ae(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function je(e){return ke.test(e)?e:Ae(e)}function Me(e){return`${e.dir===void 0?``:`cd ${je(e.dir)} && `}${e.env.map(([e,t])=>`${e}=${je(t)} `).join(``)}${[e.program,...e.args].map(je).join(` `)}`}const Ne=`cc-extra`;function Pe(e){return s.join(s.dirname(e),Ne,`src`,`bun-attach.js`)}function Fe(e){return s.join(s.dirname(e),`bun-graph.js`)}const Ie=`attach-preload.cjs`;function Le(e){return s.join(s.dirname(e),Ie)}function Re(e,t){return Me({...t,env:[...t.env,[`BUN_OPTIONS`,`--preload ${e.replace(/[\\\s]/g,`\\$&`)}`]]})}const ze=e=>!e.startsWith(`.`)&&!e.endsWith(`~`);function Be(e,t){return t.isSymbolicLink()?Buffer.from(p.readlinkSync(e)):p.readFileSync(e)}function Ve(e,t,n=ze){return p.readdirSync(t).filter(n).sort().flatMap(n=>{let r=s.join(t,n),i=p.lstatSync(r,{throwIfNoEntry:!1});return i===void 0?[]:i.isDirectory()?Ve(e,r):[[s.relative(e,r).split(s.sep).join(`/`),Be(r,i)]]})}function He(e){let t=S.createHash(`sha256`);for(let[n,r]of e)t.update(n).update(`\0`).update(r).update(`\0`);return t.digest(`hex`)}function Ue(e){return He(Ve(e,e))}const We=[`Cargo.toml`,`Cargo.lock`,`src`];function Ge(e){return He(Ve(e,e,e=>We.includes(e)))}const Ke=e=>e.slice(0,7),qe=`1.154.0`;function Je(e){let t=s.dirname(s.dirname(e));return p.existsSync(s.join(t,`src`))?t:null}function Ye(){let e=Xe();if(e===null)throw Error("this bundle carries no source digest (build via `pnpm build`, which stamps it)");return{version:qe,digest:e}}function Xe(){return`e63da1c35e83321daee55bd8bb54bce75ae8d765951697f418135777ddd84924`}function Ze(e){let t=JSON.parse(p.readFileSync(s.join(e,`package.json`),`utf8`)),n=typeof t==`object`&&t?t.version:void 0;if(typeof n!=`string`)throw Error(`${s.join(e,`package.json`)} has no version string`);return n}function Qe(e,t){try{let n=Je(i(e));if(n===null)return{kind:`not-source-checkout`};let r=t(),a=Ue(s.join(n,`src`));return a===r.digest?{kind:`current`,root:n,stamp:r}:{kind:`stale`,root:n,source:{version:Ze(n),digest:a},running:r}}catch(e){return{kind:`unchecked`,reason:e.message}}}function $e(e,t){return oe.isNativeError(e)?e.code===`ENOENT`&&t!==void 0&&!g(t)?`working directory does not exist: ${t}`:e.message:String(e)}const et={"click.pbcopy":1e3,"click.open":1e3,"doctor.tmux":1e3,"doctor.font":1e3,"doctor.process":1e3,"claude-input.type":1e3},tt=new Map;function nt(e){let t=et[e];if(t===void 0)return{allowed:!0};let n=tt.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 rt(e){tt.set(e,Date.now())}function it(e){return e.env??process.env}function at(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 ot=null;function st(e){ot=e}function ct(e,t){try{process.kill(-e,t)}catch(e){if(e.code!==`ESRCH`)throw e}}async function lt(e){if(e.signal?.aborted)return{ok:!1,reason:`aborted`,stdout:``,stderr:``,exitCode:null,signal:null};let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();return ot?.onStart(e.category),new Promise(t=>{let r;try{r=ie(e.bin,e.args??[],{cwd:e.cwd,env:it(e),stdio:[`pipe`,`pipe`,`pipe`],detached:!0})}catch(r){ot?.onEnd(e.category,Date.now()-n),t({ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(r,e.cwd)});return}let i=``,a=``,o=!1,s=null,c=null,l=null,u=()=>m(`aborted`),d=t=>{o||(o=!0,s&&clearTimeout(s),c&&clearTimeout(c),e.signal?.removeEventListener(`abort`,u),ot?.onEnd(e.category,Date.now()-n),t())},f=e=>d(()=>t(e)),p=(e,t)=>{try{ct(e,t)}catch(e){f({ok:!1,reason:`signal-refused`,stdout:i,stderr:a,exitCode:null,signal:null,error:e instanceof Error?e.message:String(e)})}},m=t=>{l=t,s&&clearTimeout(s),e.signal?.removeEventListener(`abort`,u);let n=r.pid;n!==void 0&&(c=setTimeout(()=>p(n,`SIGKILL`),250),p(n,`SIGTERM`))};r.stdout?.on(`data`,e=>{i+=e.toString(`utf8`)}),r.stderr?.on(`data`,e=>{a+=e.toString(`utf8`)}),r.on(`error`,t=>{f({ok:!1,reason:`spawn-error`,stdout:i,stderr:a,exitCode:null,signal:null,error:$e(t,e.cwd)})}),r.on(`close`,(e,t)=>{if(l!==null){f({ok:!1,reason:l,stdout:i,stderr:a,exitCode:e,signal:t});return}if(e===0){f({ok:!0,stdout:i,stderr:a,exitCode:e});return}f({ok:!1,reason:t?`signal`:`non-zero`,stdout:i,stderr:a,exitCode:e,signal:t})}),e.timeoutMs&&e.timeoutMs>0&&(s=setTimeout(()=>m(`timeout`),e.timeoutMs)),e.signal?.addEventListener(`abort`,u,{once:!0}),e.stdinInput!==void 0&&r.stdin?r.stdin.end(e.stdinInput):r.stdin&&r.stdin.end()})}function ut(e){let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();ot?.onStart(e.category);let r=[`pipe`,`pipe`,`pipe`];try{let t=ae(e.bin,e.args??[],{cwd:e.cwd,env:it(e),input:e.stdinInput,timeout:e.timeoutMs&&e.timeoutMs>0?e.timeoutMs:void 0,stdio:r,encoding:`utf8`});ot?.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:$e(t.error,e.cwd)};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 ot?.onEnd(e.category,Date.now()-n),{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(t,e.cwd)}}}function dt(e){let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();ot?.onStart(e.category);let r=ft(e);return ot?.onEnd(e.category,Date.now()-n),r}function ft(e){let t;try{t=ie(e.bin,e.args??[],{cwd:e.cwd,env:it(e),detached:!0,stdio:`ignore`})}catch(t){return{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(t,e.cwd)}}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 O(e,t,n){let r=pt(e);p.mkdirSync(s.dirname(r),{recursive:!0});let i=`${r}.tmp`,a=n??p.statSync(r,{throwIfNoEntry:!1})?.mode;try{p.writeFileSync(i,t,a===void 0?{}:{mode:a}),p.renameSync(i,r)}catch(e){throw p.rmSync(i,{force:!0}),e}}function pt(e){let t=e;for(let e=0;e<mt;e++){let e;try{e=p.lstatSync(t)}catch(e){if(e.code===`ENOENT`)return t;throw e}if(!e.isSymbolicLink())return t;t=s.resolve(p.realpathSync(s.dirname(t)),p.readlinkSync(t))}throw Error(`${e}: more than ${mt} symbolic links`)}const mt=40;function ht(e,t){let n=e[t];return n&&n.length>0?n:void 0}function gt(e=process.env){let t=ht(e,`XDG_STATE_HOME`)??s.join(C.homedir(),`.local`,`state`);return s.join(t,`cc-candybar`)}function k(){let e=ht(process.env,`XDG_CACHE_HOME`)??s.join(C.homedir(),`.cache`);return s.join(e,`cc-candybar`)}function _t(){return gt()}function vt(){return process.env.CC_CANDYBAR_SOCKET||yt()}function yt(){let e=C.userInfo().uid;return s.join(`/tmp`,`cc-candybar-${e}`,`socket`)}function bt(e){p.mkdirSync(e,{recursive:!0,mode:448});let t=p.lstatSync(e);if(t.isSymbolicLink())throw Error(`directory is a symlink: ${e}`);if(!t.isDirectory())throw Error(`not a directory: ${e}`);let n=C.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 xt(e){bt(s.dirname(e));for(let t of[e,St(e)])try{if(p.lstatSync(t).isSymbolicLink())throw Error(`path is a symlink: ${t}`)}catch(e){if(e.code!==`ENOENT`)throw e}}function St(e){return`${e}.lease`}function Ct(){return St(vt())}function wt(){return s.join(gt(),`session-state.json`)}function Tt(){return s.join(gt(),`settings-history.json`)}function Et(){let e=process.env.CC_CANDYBAR_DAEMON_REGISTRY_DIR;if(e)return e;let t=C.userInfo().uid;return s.join(`/tmp`,`cc-candybar-${t}`,`daemons`)}function Dt(){return s.join(gt(),`spawn.lock`)}function Ot(){return s.join(gt(),`spawn.cooldown`)}function kt(){return s.join(gt(),`spawn.backoff`)}function At(){return s.join(gt(),`diagnostics`)}function jt(e=process.env){return s.join(gt(e),`daemon.log`)}const Mt=[`MEMENTO_CONFIG_HOME`,`XDG_CONFIG_HOME`];function Nt(e,t){return Object.fromEntries(Mt.flatMap(n=>{let r=e[n]??``;return r===``?[]:[[n,s.resolve(t,r)]]}))}const Pt=[`TERM_PROGRAM`,`TERM_PROGRAM_VERSION`,`TERM`,`ITERM_PROFILE`,`XDG_CONFIG_HOME`];function Ft(e){return Object.fromEntries(Pt.flatMap(t=>{let n=e[t]??``;return n===``?[]:[[t,n]]}))}const It=[`native`,`node`,`frames`];function Lt(e,t){return{kind:e,bundle:t,source:null}}const Rt=Object.keys({termCols:!0,termRows:!0,ssh:!0,tmux:!0,configEnv:!0,claudeConfigDir:!0,mementoEnv:!0,terminalEnv:!0,client:!0});function zt(e){let t=Jt(e.termCols),n=Jt(e.termRows),r=Yt(e.ssh),i=Kt(e.tmux),a=Gt(e.configEnv),o=Gt(e.claudeConfigDir),s=Wt(e.mementoEnv),c=A(e.terminalEnv),l=tn(e.client);return{...t!==void 0&&{termCols:t},...n!==void 0&&{termRows:n},...r!==void 0&&{ssh:r},...i!==void 0&&{tmux:i},...a!==void 0&&{configEnv:a},...o!==void 0&&{claudeConfigDir:o},...s!==void 0&&{mementoEnv:s},...c!==void 0&&{terminalEnv:c},...l!==void 0&&{client:l}}}function Bt(e,t){return Rt.filter(n=>e[n]!==void 0&&t[n]===void 0).map(t=>({hint:t,sent:e[t]}))}function Vt(e){return e.length===0?null:`Client hints refused: ${e.map(({hint:e,sent:t})=>`${e}=${JSON.stringify(t)}`).join(`, `)} — is the statusline client older than the daemon? Reinstall it (\`cc-candybar install\`, or \`just install-rust\` in a checkout).`}const Ht={unknown:e=>`Unknown flags: ${e}`,"no-value":e=>`${e} names no file — the bar renders with no ${e}`,positional:e=>`Unexpected arguments: ${e}`};function Ut(e){let t=Object.keys(Ht).flatMap(t=>{let n=e.filter(e=>e.why===t).map(e=>e.arg);return n.length===0?[]:[Ht[t](n.join(`, `))]});return t.length===0?null:t.join(`
2
+ import{createRequire as e}from"node:module";import t from"node:process";import{URL as n,URLSearchParams as r,fileURLToPath as i,pathToFileURL as a}from"node:url";import{json as o}from"node:stream/consumers";import s,{basename as c,dirname as l,isAbsolute as u,join as d,sep as f}from"node:path";import p,{closeSync as m,constants as h,existsSync as g,fstatSync as _,openSync as v,readSync as y,realpathSync as b,statSync as ee,watch as x}from"node:fs";import S,{createHash as te,randomUUID as ne}from"node:crypto";import C,{homedir as re}from"node:os";import{spawn as ie,spawnSync as ae}from"node:child_process";import{inspect as w,parseArgs as T,types as oe}from"node:util";import E from"node:net";import se from"node:v8";import{open as ce,readFile as le,readdir as ue,stat as de}from"node:fs/promises";import{clearInterval as fe,setImmediate as pe,setInterval as me}from"node:timers";import{get as he}from"node:https";import{setTimeout as ge}from"node:timers/promises";import{WriteStream as _e}from"node:tty";import{createInterface as ve}from"node:readline";var ye=Object.create,be=Object.defineProperty,xe=Object.getOwnPropertyDescriptor,Se=Object.getOwnPropertyNames,Ce=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty,Te=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),Ee=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=Se(t),a=0,o=i.length,s;a<o;a++)s=i[a],!we.call(e,s)&&s!==n&&be(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=xe(t,s))||r.enumerable});return e},De=(e,t,n)=>(n=e==null?{}:ye(Ce(e)),Ee(t||!e||!e.__esModule?be(n,`default`,{value:e,enumerable:!0}):n,e));function D(e,...t){process.env.CC_CANDYBAR_DEBUG&&console.error(`[DEBUG] ${e}`,...t)}const Oe=(e,t)=>D(t),ke=/^[A-Za-z0-9_./,:@%+-][A-Za-z0-9_./,:@%+=-]*$/;function Ae(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function je(e){return ke.test(e)?e:Ae(e)}function Me(e){return`${e.dir===void 0?``:`cd ${je(e.dir)} && `}${e.env.map(([e,t])=>`${e}=${je(t)} `).join(``)}${[e.program,...e.args].map(je).join(` `)}`}const Ne=`cc-extra`;function Pe(e){return s.join(s.dirname(e),Ne,`src`,`bun-attach.js`)}function Fe(e){return s.join(s.dirname(e),`bun-graph.js`)}const Ie=`attach-preload.cjs`;function Le(e){return s.join(s.dirname(e),Ie)}function Re(e,t){return Me({...t,env:[...t.env,[`BUN_OPTIONS`,`--preload ${e.replace(/[\\\s]/g,`\\$&`)}`]]})}const ze=e=>!e.startsWith(`.`)&&!e.endsWith(`~`);function Be(e,t){return t.isSymbolicLink()?Buffer.from(p.readlinkSync(e)):p.readFileSync(e)}function Ve(e,t,n=ze){return p.readdirSync(t).filter(n).sort().flatMap(n=>{let r=s.join(t,n),i=p.lstatSync(r,{throwIfNoEntry:!1});return i===void 0?[]:i.isDirectory()?Ve(e,r):[[s.relative(e,r).split(s.sep).join(`/`),Be(r,i)]]})}function He(e){let t=S.createHash(`sha256`);for(let[n,r]of e)t.update(n).update(`\0`).update(r).update(`\0`);return t.digest(`hex`)}function Ue(e){return He(Ve(e,e))}const We=[`Cargo.toml`,`Cargo.lock`,`src`];function Ge(e){return He(Ve(e,e,e=>We.includes(e)))}const Ke=e=>e.slice(0,7),qe=`1.154.1`;function Je(e){let t=s.dirname(s.dirname(e));return p.existsSync(s.join(t,`src`))?t:null}function Ye(){let e=Xe();if(e===null)throw Error("this bundle carries no source digest (build via `pnpm build`, which stamps it)");return{version:qe,digest:e}}function Xe(){return`e63da1c35e83321daee55bd8bb54bce75ae8d765951697f418135777ddd84924`}function Ze(e){let t=JSON.parse(p.readFileSync(s.join(e,`package.json`),`utf8`)),n=typeof t==`object`&&t?t.version:void 0;if(typeof n!=`string`)throw Error(`${s.join(e,`package.json`)} has no version string`);return n}function Qe(e,t){try{let n=Je(i(e));if(n===null)return{kind:`not-source-checkout`};let r=t(),a=Ue(s.join(n,`src`));return a===r.digest?{kind:`current`,root:n,stamp:r}:{kind:`stale`,root:n,source:{version:Ze(n),digest:a},running:r}}catch(e){return{kind:`unchecked`,reason:e.message}}}function $e(e,t){return oe.isNativeError(e)?e.code===`ENOENT`&&t!==void 0&&!g(t)?`working directory does not exist: ${t}`:e.message:String(e)}const et={"click.pbcopy":1e3,"click.open":1e3,"doctor.tmux":1e3,"doctor.font":1e3,"doctor.process":1e3,"claude-input.type":1e3},tt=new Map;function nt(e){let t=et[e];if(t===void 0)return{allowed:!0};let n=tt.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 rt(e){tt.set(e,Date.now())}function it(e){return e.env??process.env}function at(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 ot=null;function st(e){ot=e}function ct(e,t){try{process.kill(-e,t)}catch(e){if(e.code!==`ESRCH`)throw e}}async function lt(e){if(e.signal?.aborted)return{ok:!1,reason:`aborted`,stdout:``,stderr:``,exitCode:null,signal:null};let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();return ot?.onStart(e.category),new Promise(t=>{let r;try{r=ie(e.bin,e.args??[],{cwd:e.cwd,env:it(e),stdio:[`pipe`,`pipe`,`pipe`],detached:!0})}catch(r){ot?.onEnd(e.category,Date.now()-n),t({ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(r,e.cwd)});return}let i=``,a=``,o=!1,s=null,c=null,l=null,u=()=>m(`aborted`),d=t=>{o||(o=!0,s&&clearTimeout(s),c&&clearTimeout(c),e.signal?.removeEventListener(`abort`,u),ot?.onEnd(e.category,Date.now()-n),t())},f=e=>d(()=>t(e)),p=(e,t)=>{try{ct(e,t)}catch(e){f({ok:!1,reason:`signal-refused`,stdout:i,stderr:a,exitCode:null,signal:null,error:e instanceof Error?e.message:String(e)})}},m=t=>{l=t,s&&clearTimeout(s),e.signal?.removeEventListener(`abort`,u);let n=r.pid;n!==void 0&&(c=setTimeout(()=>p(n,`SIGKILL`),250),p(n,`SIGTERM`))};r.stdout?.on(`data`,e=>{i+=e.toString(`utf8`)}),r.stderr?.on(`data`,e=>{a+=e.toString(`utf8`)}),r.on(`error`,t=>{f({ok:!1,reason:`spawn-error`,stdout:i,stderr:a,exitCode:null,signal:null,error:$e(t,e.cwd)})}),r.on(`close`,(e,t)=>{if(l!==null){f({ok:!1,reason:l,stdout:i,stderr:a,exitCode:e,signal:t});return}if(e===0){f({ok:!0,stdout:i,stderr:a,exitCode:e});return}f({ok:!1,reason:t?`signal`:`non-zero`,stdout:i,stderr:a,exitCode:e,signal:t})}),e.timeoutMs&&e.timeoutMs>0&&(s=setTimeout(()=>m(`timeout`),e.timeoutMs)),e.signal?.addEventListener(`abort`,u,{once:!0}),e.stdinInput!==void 0&&r.stdin?r.stdin.end(e.stdinInput):r.stdin&&r.stdin.end()})}function ut(e){let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();ot?.onStart(e.category);let r=[`pipe`,`pipe`,`pipe`];try{let t=ae(e.bin,e.args??[],{cwd:e.cwd,env:it(e),input:e.stdinInput,timeout:e.timeoutMs&&e.timeoutMs>0?e.timeoutMs:void 0,stdio:r,encoding:`utf8`});ot?.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:$e(t.error,e.cwd)};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 ot?.onEnd(e.category,Date.now()-n),{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(t,e.cwd)}}}function dt(e){let t=nt(e.category);if(!t.allowed)return at(e.category,t.minIntervalMs,t.sinceLastMs);rt(e.category);let n=Date.now();ot?.onStart(e.category);let r=ft(e);return ot?.onEnd(e.category,Date.now()-n),r}function ft(e){let t;try{t=ie(e.bin,e.args??[],{cwd:e.cwd,env:it(e),detached:!0,stdio:`ignore`})}catch(t){return{ok:!1,reason:`spawn-error`,stdout:``,stderr:``,exitCode:null,signal:null,error:$e(t,e.cwd)}}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 O(e,t,n){let r=pt(e);p.mkdirSync(s.dirname(r),{recursive:!0});let i=`${r}.tmp`,a=n??p.statSync(r,{throwIfNoEntry:!1})?.mode;try{p.writeFileSync(i,t,a===void 0?{}:{mode:a}),p.renameSync(i,r)}catch(e){throw p.rmSync(i,{force:!0}),e}}function pt(e){let t=e;for(let e=0;e<mt;e++){let e;try{e=p.lstatSync(t)}catch(e){if(e.code===`ENOENT`)return t;throw e}if(!e.isSymbolicLink())return t;t=s.resolve(p.realpathSync(s.dirname(t)),p.readlinkSync(t))}throw Error(`${e}: more than ${mt} symbolic links`)}const mt=40;function ht(e,t){let n=e[t];return n&&n.length>0?n:void 0}function gt(e=process.env){let t=ht(e,`XDG_STATE_HOME`)??s.join(C.homedir(),`.local`,`state`);return s.join(t,`cc-candybar`)}function k(){let e=ht(process.env,`XDG_CACHE_HOME`)??s.join(C.homedir(),`.cache`);return s.join(e,`cc-candybar`)}function _t(){return gt()}function vt(){return process.env.CC_CANDYBAR_SOCKET||yt()}function yt(){let e=C.userInfo().uid;return s.join(`/tmp`,`cc-candybar-${e}`,`socket`)}function bt(e){p.mkdirSync(e,{recursive:!0,mode:448});let t=p.lstatSync(e);if(t.isSymbolicLink())throw Error(`directory is a symlink: ${e}`);if(!t.isDirectory())throw Error(`not a directory: ${e}`);let n=C.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 xt(e){bt(s.dirname(e));for(let t of[e,St(e)])try{if(p.lstatSync(t).isSymbolicLink())throw Error(`path is a symlink: ${t}`)}catch(e){if(e.code!==`ENOENT`)throw e}}function St(e){return`${e}.lease`}function Ct(){return St(vt())}function wt(){return s.join(gt(),`session-state.json`)}function Tt(){return s.join(gt(),`settings-history.json`)}function Et(){let e=process.env.CC_CANDYBAR_DAEMON_REGISTRY_DIR;if(e)return e;let t=C.userInfo().uid;return s.join(`/tmp`,`cc-candybar-${t}`,`daemons`)}function Dt(){return s.join(gt(),`spawn.lock`)}function Ot(){return s.join(gt(),`spawn.cooldown`)}function kt(){return s.join(gt(),`spawn.backoff`)}function At(){return s.join(gt(),`diagnostics`)}function jt(e=process.env){return s.join(gt(e),`daemon.log`)}const Mt=[`MEMENTO_CONFIG_HOME`,`XDG_CONFIG_HOME`];function Nt(e,t){return Object.fromEntries(Mt.flatMap(n=>{let r=e[n]??``;return r===``?[]:[[n,s.resolve(t,r)]]}))}const Pt=[`TERM_PROGRAM`,`TERM_PROGRAM_VERSION`,`TERM`,`ITERM_PROFILE`,`XDG_CONFIG_HOME`];function Ft(e){return Object.fromEntries(Pt.flatMap(t=>{let n=e[t]??``;return n===``?[]:[[t,n]]}))}const It=[`native`,`node`,`frames`];function Lt(e,t){return{kind:e,bundle:t,source:null}}const Rt=Object.keys({termCols:!0,termRows:!0,ssh:!0,tmux:!0,configEnv:!0,claudeConfigDir:!0,mementoEnv:!0,terminalEnv:!0,client:!0});function zt(e){let t=Jt(e.termCols),n=Jt(e.termRows),r=Yt(e.ssh),i=Kt(e.tmux),a=Gt(e.configEnv),o=Gt(e.claudeConfigDir),s=Wt(e.mementoEnv),c=A(e.terminalEnv),l=tn(e.client);return{...t!==void 0&&{termCols:t},...n!==void 0&&{termRows:n},...r!==void 0&&{ssh:r},...i!==void 0&&{tmux:i},...a!==void 0&&{configEnv:a},...o!==void 0&&{claudeConfigDir:o},...s!==void 0&&{mementoEnv:s},...c!==void 0&&{terminalEnv:c},...l!==void 0&&{client:l}}}function Bt(e,t){return Rt.filter(n=>e[n]!==void 0&&t[n]===void 0).map(t=>({hint:t,sent:e[t]}))}function Vt(e){return e.length===0?null:`Client hints refused: ${e.map(({hint:e,sent:t})=>`${e}=${JSON.stringify(t)}`).join(`, `)} — is the statusline client older than the daemon? Reinstall it (\`cc-candybar install\`, or \`just install-rust\` in a checkout).`}const Ht={unknown:e=>`Unknown flags: ${e}`,"no-value":e=>`${e} names no file — the bar renders with no ${e}`,positional:e=>`Unexpected arguments: ${e}`};function Ut(e){let t=Object.keys(Ht).flatMap(t=>{let n=e.filter(e=>e.why===t).map(e=>e.arg);return n.length===0?[]:[Ht[t](n.join(`, `))]});return t.length===0?null:t.join(`
3
3
  `)}function Wt(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e,n=Mt.filter(e=>t[e]!==void 0);return n.every(e=>Gt(t[e])!==void 0)?Object.fromEntries(n.map(e=>[e,t[e]])):void 0}function A(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=e,n=Pt.filter(e=>t[e]!==void 0);return n.every(e=>typeof t[e]==`string`&&t[e]!==``)?Object.fromEntries(n.map(e=>[e,t[e]])):void 0}function Gt(e){return typeof e==`string`&&s.isAbsolute(e)?e:void 0}function Kt(e){if(e===null)return null;if(typeof e!=`object`)return;let{socket:t,pane:n,truecolor:r}=e;if(!(typeof t!=`string`||t===``)&&!(typeof n!=`string`||n===``)&&!(r!==null&&(typeof r!=`string`||r===``)))return{socket:t,pane:n,truecolor:r}}const qt=1e4;function Jt(e){if(typeof e!=`number`||!Number.isFinite(e))return;let t=Math.floor(e);if(!(t<=0))return t>qt?qt:t}function Yt(e){return typeof e==`boolean`?e:void 0}function Xt(e){return typeof e==`string`&&e!==``&&e.length<=64?e:null}var j=class extends Error{constructor(e){super(e),this.name=`ProtocolError`}};function Zt(e){return Qt(JSON.stringify(e))}function Qt(e){let t=Buffer.from(e,`utf8`),n=Buffer.alloc(4);return n.writeUInt32BE(t.length,0),Buffer.concat([n,t])}function $t(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 j(`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 j(e instanceof Error?e.message:String(e));e instanceof Error&&(n.cause=e),t(n);return}}}}function en(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=$t(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(Zt(t))})}function tn(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let{kind:t,bundle:n,source:r}=e,i=Gt(n);return It.includes(t)&&i!==void 0&&(r===null||typeof r==`string`&&r!==``)?{kind:t,bundle:i,source:r}:void 0}async function nn(e,t,n){let r=null;try{r=await cn(vt(),t.connectMs);let i=await en(r,{v:3,...e},t.budgetMs);return on(e.kind,i,n)}catch(e){return sn(e)}finally{r&&r.destroy()}}function rn(e,t){return typeof e==`string`?e:t}function an(e){return typeof e==`number`&&Number.isInteger(e)&&e>=0?e:0}function on(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=rn(r.error,`(no error message)`);switch(r.code){case`VERSION_MISMATCH`:return{kind:`permanent`,cause:`version_mismatch`,clientV:3,daemonV:an(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};case`SWITCHED_OFF`:return{kind:`permanent`,cause:`switched_off`,message:i};default:return{kind:`permanent`,cause:`malformed_response`,message:`unknown error code: ${String(r.code)}`}}}function sn(e){if(e instanceof j||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 cn(e,t){return new Promise((n,r)=>{let i=E.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 ln(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`switched_off`:case`malformed_response`:return`daemon error (${e.cause}): ${e.message}`}}const un={connectMs:50,budgetMs:150},dn={connectMs:50,budgetMs:200};function fn(e){let t=e.output;return typeof t==`string`?t:void 0}function pn(e){return on(`render`,e,fn)}function mn(e,t,n,r){return nn({kind:`render`,hookData:e,args:t,cwd:n,...r},un,fn)}function hn(e,t){return nn({kind:`pane-session`,socket:e,pane:t},dn,e=>`paneSession`in e?e.paneSession:void 0)}function gn(e,t){return nn({kind:`click`,verb:e,value:t,clientVersion:qe},dn,fn)}let _n=null;function vn(e){if(_n!==null)return _n;p.mkdirSync(s.dirname(e),{recursive:!0});try{_n=p.statSync(e).size}catch{_n=0}return _n}function yn(e){for(let t=2;t>=1;t--){let n=`${e}.${t}`,r=`${e}.${t+1}`;try{p.renameSync(n,r)}catch{}}try{p.renameSync(e,`${e}.1`)}catch{}_n=0}function M(e,t){let n=`${new Date().toISOString()} [${e}] ${t}\n`;try{let e=jt(),t=vn(e);p.appendFileSync(e,n),_n=t+Buffer.byteLength(n,`utf8`),_n>=5242880&&yn(e)}catch(e){_n=null;try{process.stderr.write(`${n}cc-candybar: daemon.log unwritable: ${e.message}\n`)}catch{}}}const bn=5e3;function xn(e){let t=[];for(let n of e){let e=n.read();if(e.kind===`text`)return`# memory report from: ${n.name}\n${e.text}`;t.push(`# ${n.name}: unavailable — ${e.reason}`)}return[`# memory report: no probe answered`,...t.length>0?t:[`# no probe is known for this platform`]].join(`
4
4
  `)}const Sn=`/usr/bin/footprint`;function Cn(e,t){return e===`darwin`?[En(Sn,[`-p`,String(t)]),En(`/usr/bin/vmmap`,[`--summary`,String(t)])]:e===`linux`?[Dn(`/proc/self/smaps_rollup`),Dn(`/proc/self/status`)]:[]}function wn(e,t){return e===`darwin`?Tn(t,e=>lt({bin:Sn,args:e,timeoutMs:bn,category:`limits.charge`})):async e=>({kind:`charged`,measure:`rss`,bytes:e})}function Tn(e,t){return async n=>{let r=await t([`-p`,String(e),`--noCategories`,`-f`,`bytes`]);if(!r.ok)return{kind:`stand-in`,bytes:n,unread:`footprint ${r.reason}${r.error===void 0?``:`: ${r.error}`}${On(r.stderr)}`};let i=N(r.stdout);return i===null?{kind:`stand-in`,bytes:n,unread:`footprint printed no phys_footprint line`}:{kind:`charged`,measure:`phys_footprint`,bytes:i}}}function N(e){let t=/^\s*phys_footprint:\s+(\d+) B\s*$/m.exec(e);return t===null?null:Number(t[1])}function En(e,t){return{name:`${e} ${t.join(` `)}`,read:()=>{let n=ut({bin:e,args:[...t],timeoutMs:bn,category:`limits.memory-report`});return n.ok?n.stdout.trim().length>0?{kind:`text`,text:n.stdout}:{kind:`unavailable`,reason:`exited 0 but printed nothing`}:{kind:`unavailable`,reason:`${n.reason}${n.error===void 0?``:`: ${n.error}`}${On(n.stderr)}`}}}}function Dn(e){return{name:e,read:()=>{try{let t=p.readFileSync(e,`utf8`);return t.trim().length>0?{kind:`text`,text:t}:{kind:`unavailable`,reason:`empty file`}}catch(e){return{kind:`unavailable`,reason:e.message}}}}}function On(e){let t=e.split(`
5
5
  `).map(e=>e.trim()).find(e=>e.length>0);return t===void 0?``:` (${t})`}const kn=`CC_CANDYBAR_RSS_LIMIT_MB`;function An(e){let t=e[kn];if(t===void 0)return 512;let n=/^\d+$/.test(t)?Number(t):NaN;if(!Number.isSafeInteger(n)||n<=0)throw Error(`${kn} must be a positive integer (MB), got ${JSON.stringify(t)}`);return n}function jn(e){return An(e)*2}const Mn=1024*1024,Nn=e=>Math.round(e/Mn);function Pn(e){return An(e)*Mn}const Fn={memoryReport:{prefix:`memory-`,suffix:`.txt`},heapSnapshot:{prefix:`heap-`,suffix:`.heapsnapshot`}};function In(e,t){return e>t}function Ln(e,t){return e>t*.75}function Rn(e,t,n){let{prefix:r,suffix:i}=Fn[t];return s.join(e,`${r}${n}${i}`)}function zn(e){for(let t of Object.keys(Fn)){let{prefix:n,suffix:r}=Fn[t];if(e.startsWith(n)&&e.endsWith(r))return t}return null}function Bn(e){let t=e.limitBytes??512*Mn,n=e.snapshotsKeep??3,r=!1,i={kind:`unmeasured`},a=null;function o(){return a??=s().finally(()=>{a=null}),a}async function s(){if(r)return!0;let{rss:a,heapTotal:o}=e.memoryBytes(),s=await e.memoryCharge(a),c={kind:`measured`,charge:s,rss:a,heapTotal:o};if(i=c,e.log(`info`,`memory ${Un(c,t)}`),s.bytes<=t)return!1;r=!0,e.log(`warn`,`${Vn(s)} > limit ${Nn(t)} MB (rss ${Nn(a)} MB, v8 heap ${Nn(o)} MB); recording memory then shutting down`);let l=`${new Date(e.now()).toISOString().replace(/[:.]/g,`-`)}-${e.pid}`;return Wn(e.log,`memory report`,()=>{let t=Rn(e.snapshotDir,`memoryReport`,l);e.writeMemoryReport(t,e.captureMemoryReport()),e.log(`info`,`memory report written: ${t}`)}),Wn(e.log,`heap snapshot`,()=>{let t=Rn(e.snapshotDir,`heapSnapshot`,l);e.log(`info`,`heap snapshot written: ${e.writeHeapSnapshot(t)}`)}),Wn(e.log,`artifact rotation`,()=>{for(let{artifacts:t}of Gn(e.listArtifacts()).slice(n))for(let n of Object.values(t))Wn(e.log,`evicting ${n}`,()=>e.removeFile(n))}),e.shutdown(0),!0}function c(){return i.kind===`measured`&&Ln(i.charge.bytes,t)?`${Vn(i.charge)} approaching limit ${Nn(t)} MB (v8 heap ${Nn(i.heapTotal)} MB)`:null}function l(){let n;try{n={kind:`ok`,value:Gn(e.listArtifacts())}}catch(e){n={kind:`failed`,reason:e.message}}return{pid:e.pid,memory:i,limit:t,postMortems:n}}function u(t=6e4){let n,r=!0,i=async()=>{try{if(await o())return}catch(t){e.log(`warn`,`memory check failed: ${t.message}`)}r&&(n=setTimeout(()=>void i(),t),n.unref())};return i(),{disarm:()=>{r=!1,clearTimeout(n)}}}return{check:o,describeNextRestart:c,serving:l,arm:u}}function Vn(e){return e.kind===`charged`?`${e.measure} ${Nn(e.bytes)} MB`:`rss ${Nn(e.bytes)} MB (standing in: ${e.unread})`}function Hn(e){return e.kind===`charged`?e.measure:`rss-stand-in`}function Un({charge:e,rss:t,heapTotal:n},r){let i=e.kind===`stand-in`?` unread=${JSON.stringify(e.unread)}`:``;return`measure=${Hn(e)} charge=${Nn(e.bytes)}MB rss=${Nn(t)}MB heap=${Nn(n)}MB limit=${Nn(r)}MB${i}`}function Wn(e,t,n){try{n()}catch(n){e(`warn`,`${t} failed: ${n.message}`)}}function Gn(e){let t=new Map;for(let n of e){let e=s.basename(n),r=zn(e);if(r===null)continue;let{prefix:i,suffix:a}=Fn[r],o=e.slice(i.length,e.length-a.length);t.set(o,{...t.get(o),[r]:n})}let n=Object.keys(Fn);return[...t].sort(([e],[t])=>In(e,t)?-1:1).map(([e,t])=>({identity:e,artifacts:Object.fromEntries(n.flatMap(e=>t[e]===void 0?[]:[[e,t[e]]]))}))}function Kn(e,t,n={}){let r=_t();return{now:()=>Date.now(),pid:process.pid,snapshotDir:r,log:M,memoryBytes:()=>{let e=process.memoryUsage();return{rss:e.rss,heapTotal:e.heapTotal}},memoryCharge:wn(process.platform,process.pid),captureMemoryReport:()=>xn(Cn(process.platform,process.pid)),writeMemoryReport:(e,t)=>p.writeFileSync(e,t,{mode:384}),writeHeapSnapshot:e=>se.writeHeapSnapshot(e),listArtifacts:()=>{let e;try{e=p.readdirSync(r)}catch(e){if(e.code===`ENOENT`)return[];throw e}return e.filter(e=>zn(e)!==null).map(e=>s.join(r,e))},removeFile:e=>p.unlinkSync(e),shutdown:t,startedAtMs:e,...n}}function qn(e={}){if(lr()!==null)return;let n=e.spawn??ur,r=or();if(r.kind===`contended`){let e=Yn();e!==null&&e>2e3&&(t.stderr.write(`cc-candybar: spawn-lock held ${e}ms (likely crashed holder) — spawning unlocked\n`),Jn(n));return}if(r.kind===`error`){t.stderr.write(`cc-candybar: spawn-lock unavailable (${r.reason}) — spawning unlocked\n`),Jn(n);return}try{Jn(n)}finally{cr()}}function Jn(e){nr()&&Xn(e)}function Yn(){try{let e=p.statSync(Dt());return Date.now()-e.mtimeMs}catch{return null}}function Xn(e){try{e()||t.stderr.write(`cc-candybar: daemon spawn returned false (unable to resolve script path?)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptctl/cc-candybar",
3
- "version": "1.154.0",
3
+ "version": "1.154.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",
@@ -104,9 +104,9 @@
104
104
  "typescript": "^5.0.0"
105
105
  },
106
106
  "optionalDependencies": {
107
- "@promptctl/cc-candybar-darwin-arm64": "1.154.0",
108
- "@promptctl/cc-candybar-darwin-x64": "1.154.0",
109
- "@promptctl/cc-candybar-linux-arm64": "1.154.0",
110
- "@promptctl/cc-candybar-linux-x64": "1.154.0"
107
+ "@promptctl/cc-candybar-darwin-arm64": "1.154.1",
108
+ "@promptctl/cc-candybar-darwin-x64": "1.154.1",
109
+ "@promptctl/cc-candybar-linux-arm64": "1.154.1",
110
+ "@promptctl/cc-candybar-linux-x64": "1.154.1"
111
111
  }
112
112
  }