@leftoff/cli 0.9.17-beta.4 → 0.9.17-beta.6

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/bin/leftoff.js CHANGED
@@ -182,59 +182,59 @@ Turn it off first: tailscale funnel --https=`+y+" off"),1;if((S.proxy||S.other)&
182
182
  `),t=[],s=!1;for(let i of e.split(`
183
183
  `)){let r=i.trim();if(/^(```|~~~)/.test(r)){s=!s;continue}if(r){if(!s){if(/^([-*_])(\s*\1){2,}$/.test(r))continue;let o;if(o=r.match(/^#{1,6}\s+(.*?)\s*#*$/)){r=tE(o[1]),r&&!/[.:!?…]$/.test(r)&&(r+=":"),t.push(r);continue}r=r.replace(/^>\s?/,""),(o=r.match(/^[-*+]\s+(.*)$/))&&(r="• "+o[1])}t.push(s?r:tE(r))}}return t.join(" ").replace(/\s+/g," ").trim()}function tE(n){return n.replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/\*\*([^*]+)\*\*/g,"$1").replace(/__([^_]+)__/g,"$1").replace(/(^|[^\w*])\*([^*\s][^*]*?)\*(?![\w*])/g,"$1$2").replace(/(^|[^\w])_([^_\s][^_]*?)_(?!\w)/g,"$1$2").replace(/~~([^~]+)~~/g,"$1").trim()}function _n(n){let e=String(n??"");if(!/<\/?channel\b/i.test(e))return e.trim();for(let t=0;t<8&&_p.test(e);t++)_p.lastIndex=0,e=e.replace(_p,"$1");return _p.lastIndex=0,e=e.replace(/<channel\b[^>]*>/g,"").replace(/<\/channel\s*>/g,"").replace(/<\/?channel\b[^>]*$/,""),e.trim()}function Ep(n){let e=String(n||"").trim(),t=[[/^I(?:'|’)ve\s+/,"Claude has "],[/^I(?:'|’)m\s+/,"Claude is "],[/^I(?:'|’)ll\s+/,"Claude will "],[/^I(?:'|’)d\s+/,"Claude would "],[/^I am\s+/,"Claude is "],[/^I have\s+/,"Claude has "],[/^I was\s+/,"Claude was "],[/^I\s+(?=[a-z])/,"Claude "]],s=!1;for(let[i,r]of t)if(i.test(e)){e=e.replace(i,r),s=!0;break}return s&&(e=e.replace(/\b(and|then|so|but|,)\s+I(?:'|’)ve\b/g,"$1 it has").replace(/\b(and|then|so|but|,)\s+I\b(?!['’])/g,"$1 it"),e=e.replace(/\b(the \w+|that|which) I (added|made|wrote|changed|removed|created|put)\b/g,"$1 it $2"),e=e.replace(/\bmyself\b/g,"itself")),Tp.test(e)?null:e}function K6(n){let e=String(n??"");if(!/(^|\n|:)\s*(?:[-*+•]|\d{1,3}[.)])\s+\S/.test(e))return e;let t="",s=!1;for(let i of e.replace(/\r\n?/g,`
184
184
  `).split(`
185
- `)){let r=i.trim();if(!r)continue;let o=r.split(/(?<=:)\s+(?=(?:[-*+•]|\d{1,3}[.)])\s+\S)/);for(let a of o){let l=a.match(/^(?:[-*+•]|\d{1,3}[.)])\s+(.*)$/);if(l){let c=$6(l[1].replace(/\s+(?:[-*+•])\s+(?=\S)/g,"; ").replace(/[\s.;,]+$/,""));t+=s?"; "+c:(/:$/.test(t)?" ":t?": ":"")+c,s=!0}else s&&(t+="."),t+=(t?" ":"")+a,s=!1}}return s&&(t+="."),t.replace(/\s+/g," ").replace(/\.\.$/,".").trim()}function vi(n){if(!n||typeof n!="object")return n;let e={...n},t=!1,s=(r,o)=>{o!==e[r]&&(e[r]=o,t=!0)};for(let r of["doing","stoppedAt","next","openQuestion","recap","userNote","sessionTitle"])typeof e[r]=="string"&&/<\/?channel\b/i.test(e[r])&&s(r,_n(e[r]));for(let r of["nextSteps","questions","decisions","didntWork"])Array.isArray(e[r])&&e[r].some(o=>typeof o=="string"&&/<\/?channel\b/i.test(o))&&s(r,e[r].map(o=>typeof o=="string"?_n(o):o));if((n.generator&&n.generator.by==="heuristic"||W6.test(String(e.doing||"")))&&e.format!=="markdown"){if(typeof e.doing=="string"&&s("doing",e.doing.replace(/^(Working on:\s*[“"])\s+/,"$1").replace(/\s+([”"])$/,"$1")),typeof e.stoppedAt=="string"&&e.stoppedAt&&!/^(?:Last error:|No reply captured|Claude’s last word:)/.test(e.stoppedAt)){let r=K6(e.stoppedAt),o=Ep(r);s("stoppedAt",o??"Claude’s last word: “"+r.replace(/^[“"]|[”"]$/g,"")+"”")}typeof e.next=="string"&&Yu.test(e.next.trim())&&s("next",""),Array.isArray(e.nextSteps)&&e.nextSteps.some(r=>Yu.test(String(r||"").trim()))&&s("nextSteps",e.nextSteps.filter(r=>!Yu.test(String(r||"").trim())))}return t?e:n}var Ee,_p,Tp,Yu,G6,$6,W6,Hn=K(()=>{Ee=n=>{let e=_n(n);return B6(e)?z6(e):e},_p=/<channel\b[^>]*>([\s\S]*?)<\/channel\s*>/g;Tp=/\b(?:I|I'(?:m|ve|ll|d)|I’(?:m|ve|ll|d)|me|my|mine|myself)\b/;Yu=/^(?:resume|reopen|open|continue|pick (?:it )?(?:back )?up)\b[^.]*\b(?:session|last reply|where (?:it|you|claude) left off)\b|^(?:continue|resume)\.?$/i,G6=/^(?:A|An|The|Added|Removed|Changed|Fixed|Updated|Moved|Renamed|Created|Deleted|Wrote|Made|Kept|Put|Ran|Used)\b/,$6=n=>G6.test(n)?n.charAt(0).toLowerCase()+n.slice(1):n;W6=/^(?:Working on:\s*[“"]|No prompt captured)/});import{spawn as Y6,execFileSync as q6}from"node:child_process";import J6 from"node:fs";import bk from"node:path";function Q6(){if(process.env.CHECKPOINTS_NO_CLAUDE)return!1;try{return q6(process.platform==="win32"?"where":"which",["claude"],{stdio:"ignore"}),!0}catch{return!1}}function iE(n){let e=String(n||"");return/previous checkpoint\s*:/i.test(e)||/files touched since then\s*:/i.test(e)||/^\s*repo\s*:.*·\s*cwd\b/im.test(e)||/title\s*:\s*\(none yet\)/i.test(e)||/transcript \(oldest→newest/i.test(e)||/what the developer asked for\s*:/i.test(e)||/before \/clear, this tab was working toward/i.test(e)||/uncommitted files now\s*:/i.test(e)}function eU(n){let e=n.summarizer||{},t=String(e.provider||e.mode||"auto").toLowerCase();return sE[t]?sE[t]:Q6()?"claude":process.env.ANTHROPIC_API_KEY?"anthropic":"heuristic"}function tU({system:n=null,model:e=null}={}){let t=["-p","--model",e||"haiku","--output-format","text","--permission-mode","default"];return n&&t.push("--append-system-prompt",n),t}function nU(n=process.env){return{...n,CHECKPOINTS_INTERNAL:"1",LEFTOFF_INTERNAL:"1",CLAUDE_CODE_FORK_SUBAGENT:"0"}}function sU({system:n,prompt:e,model:t,bin:s},i=6e4){return new Promise((r,o)=>{let a=Y6(s||"claude",tU({system:n,model:t}),{env:nU(),stdio:["pipe","pipe","pipe"]}),l="",c="",u=setTimeout(()=>{a.kill("SIGKILL"),o(new Error("claude -p timed out"))},i);a.stdout.on("data",d=>l+=d),a.stderr.on("data",d=>c+=d),a.on("error",d=>{clearTimeout(u),o(d)}),a.on("close",d=>{clearTimeout(u),d===0?r({text:l.trim(),usage:null}):o(new Error("claude -p exited "+d+": "+c.slice(0,300)))}),a.stdin.end(e)})}async function xk(n,e,t,s,i){let r=await n(e,{method:"POST",headers:{"content-type":"application/json",...t},body:JSON.stringify(s),signal:AbortSignal.timeout(i)}),o=await r.json().catch(()=>({}));if(!r.ok)throw new Error(e+" -> "+r.status+": "+(o.error&&(o.error.message||o.error)||"error"));return o}function iU(n={},e=process.env){return xi("anthropic",n,e)}function xi(n,{apiKeyEnv:e,apiKeyFile:t,root:s}={},i=process.env){let r=Op[n]||{},o=e||r.env;if(o&&i[o])return i[o];for(let a of[t,e==="__none__"?null:r.file]){if(!a)continue;let l=bk.isAbsolute(a)?null:b_(a,i.HOME||i.XDG_CONFIG_HOME?i:process.env);for(let c of[l,bk.isAbsolute(a)?a:bk.join(s||re(),a)])if(c)try{let u=J6.readFileSync(c,"utf8").trim();if(u)return u}catch{}}return null}async function rU(n,{system:e,prompt:t,model:s,maxTokens:i,apiKeyEnv:r,apiKeyFile:o,root:a,timeoutMs:l}){let c=iU({apiKeyEnv:r,apiKeyFile:o,root:a});if(!c)throw new Error((r||"ANTHROPIC_API_KEY")+" is not set");let u=(process.env.ANTHROPIC_BASE_URL||"https://api.anthropic.com").replace(/\/$/,""),d=await xk(n,u+"/v1/messages",{"x-api-key":c,"anthropic-version":"2023-06-01"},{model:nE[s]||s||nE.haiku,max_tokens:i||300,system:e,messages:[{role:"user",content:t}]},l||3e4);return{text:(d.content||[]).filter(h=>h.type==="text").map(h=>h.text).join(`
186
- `),usage:d.usage?{inputTokens:d.usage.input_tokens,outputTokens:d.usage.output_tokens}:null}}function oU(n,e,t){let s=Math.ceil(((n||"").length+(e||"").length)/3.2)+(t||300)+256;for(let i of vk)if(s<=i)return i;return vk[vk.length-1]}async function rE(n,{system:e,prompt:t,model:s,maxTokens:i,baseUrl:r,key:o,cloud:a,json:l,timeoutMs:c}){let u=a?Math.max(1024,(i||300)*4):i||300,d=await xk(n,r.replace(/\/$/,"")+"/api/chat",o?{authorization:"Bearer "+o}:{},{model:s,stream:!1,...l?{format:"json"}:{},messages:[...e?[{role:"system",content:e}]:[],{role:"user",content:t}],options:{num_predict:u,temperature:.2,...a?{}:{num_ctx:oU(e,t,u)}}},Math.max(c||0,a?6e4:12e4));return{text:d.message&&d.message.content||"",usage:{inputTokens:d.prompt_eval_count,outputTokens:d.eval_count}}}async function aU(n,{system:e,prompt:t,model:s,maxTokens:i,baseUrl:r,apiKeyEnv:o}){let a=o?process.env[o]:null,l=await xk(n,r.replace(/\/$/,"")+"/chat/completions",a?{authorization:"Bearer "+a}:{},{model:s,max_tokens:i||300,temperature:.2,messages:[...e?[{role:"system",content:e}]:[],{role:"user",content:t}]},12e4),c=l.choices&&l.choices[0];return{text:c&&c.message&&c.message.content||c&&c.text||"",usage:l.usage?{inputTokens:l.usage.prompt_tokens,outputTokens:l.usage.completion_tokens}:null}}function aE(n){let e=Ak(n,200).toLowerCase();return!e||cU.test(e)}function uU(n,{prompts:e=8,replies:t=1,max:s=300}={}){let i=(n||[]).filter(l=>!oE(l)),r=i.filter(l=>l.role==="user").slice(-e),o=new Set(i.filter(l=>l.role==="assistant").slice(-t)),a=new Set(r);return i.filter(l=>a.has(l)||o.has(l)).map(l=>({role:l.role,text:Ak(l.text,s)}))}function dU(n,{firstPrompt:e=""}={}){let t=n.filter(o=>o.role==="user").map(o=>o.text),s=n.filter(o=>o.role==="assistant").map(o=>o.text),i=Ak(e,200),r=[];return i&&!t.some(o=>o.startsWith(i.slice(0,80)))&&r.push("Session started with: "+i),t.length&&r.push(`Recent requests from the user, oldest first:
185
+ `)){let r=i.trim();if(!r)continue;let o=r.split(/(?<=:)\s+(?=(?:[-*+•]|\d{1,3}[.)])\s+\S)/);for(let a of o){let l=a.match(/^(?:[-*+•]|\d{1,3}[.)])\s+(.*)$/);if(l){let c=$6(l[1].replace(/\s+(?:[-*+•])\s+(?=\S)/g,"; ").replace(/[\s.;,]+$/,""));t+=s?"; "+c:(/:$/.test(t)?" ":t?": ":"")+c,s=!0}else s&&(t+="."),t+=(t?" ":"")+a,s=!1}}return s&&(t+="."),t.replace(/\s+/g," ").replace(/\.\.$/,".").trim()}function vi(n){if(!n||typeof n!="object")return n;let e={...n},t=!1,s=(r,o)=>{o!==e[r]&&(e[r]=o,t=!0)};for(let r of["doing","stoppedAt","next","openQuestion","recap","userNote","sessionTitle"])typeof e[r]=="string"&&/<\/?channel\b/i.test(e[r])&&s(r,_n(e[r]));for(let r of["nextSteps","questions","decisions","didntWork"])Array.isArray(e[r])&&e[r].some(o=>typeof o=="string"&&/<\/?channel\b/i.test(o))&&s(r,e[r].map(o=>typeof o=="string"?_n(o):o));if((n.generator&&n.generator.by==="heuristic"||W6.test(String(e.doing||"")))&&e.format!=="markdown"){if(typeof e.doing=="string"&&s("doing",e.doing.replace(/^(Working on:\s*[“"])\s+/,"$1").replace(/\s+([”"])$/,"$1")),typeof e.stoppedAt=="string"&&e.stoppedAt&&!/^(?:Last error:|No reply captured|Claude’s last word:)/.test(e.stoppedAt)){let r=K6(e.stoppedAt),o=Ep(r);s("stoppedAt",o??"Claude’s last word: “"+r.replace(/^[“"]|[”"]$/g,"")+"”")}typeof e.next=="string"&&Yu.test(e.next.trim())&&s("next",""),Array.isArray(e.nextSteps)&&e.nextSteps.some(r=>Yu.test(String(r||"").trim()))&&s("nextSteps",e.nextSteps.filter(r=>!Yu.test(String(r||"").trim())))}return t?e:n}var Ee,_p,Tp,Yu,G6,$6,W6,Hn=K(()=>{Ee=n=>{let e=_n(n);return B6(e)?z6(e):e},_p=/<channel\b[^>]*>([\s\S]*?)<\/channel\s*>/g;Tp=/\b(?:I|I'(?:m|ve|ll|d)|I’(?:m|ve|ll|d)|me|my|mine|myself)\b/;Yu=/^(?:resume|reopen|open|continue|pick (?:it )?(?:back )?up)\b[^.]*\b(?:session|last reply|where (?:it|you|claude) left off)\b|^(?:continue|resume)\.?$/i,G6=/^(?:A|An|The|Added|Removed|Changed|Fixed|Updated|Moved|Renamed|Created|Deleted|Wrote|Made|Kept|Put|Ran|Used)\b/,$6=n=>G6.test(n)?n.charAt(0).toLowerCase()+n.slice(1):n;W6=/^(?:Working on:\s*[“"]|No prompt captured)/});import{spawn as Y6,execFileSync as q6}from"node:child_process";import J6 from"node:fs";import bk from"node:path";function Q6(){if(process.env.CHECKPOINTS_NO_CLAUDE)return!1;try{return q6(process.platform==="win32"?"where":"which",["claude"],{stdio:"ignore"}),!0}catch{return!1}}function iE(n){let e=String(n||"");return/previous checkpoint\s*:/i.test(e)||/files touched since then\s*:/i.test(e)||/^\s*repo\s*:.*·\s*cwd\b/im.test(e)||/title\s*:\s*\(none yet\)/i.test(e)||/transcript \(oldest→newest/i.test(e)||/what the developer asked for\s*:/i.test(e)||/before \/clear, this tab was working toward/i.test(e)||/uncommitted files now\s*:/i.test(e)}function e3(n){let e=n.summarizer||{},t=String(e.provider||e.mode||"auto").toLowerCase();return sE[t]?sE[t]:Q6()?"claude":process.env.ANTHROPIC_API_KEY?"anthropic":"heuristic"}function t3({system:n=null,model:e=null}={}){let t=["-p","--model",e||"haiku","--output-format","text","--permission-mode","default"];return n&&t.push("--append-system-prompt",n),t}function n3(n=process.env){return{...n,CHECKPOINTS_INTERNAL:"1",LEFTOFF_INTERNAL:"1",CLAUDE_CODE_FORK_SUBAGENT:"0"}}function s3({system:n,prompt:e,model:t,bin:s},i=6e4){return new Promise((r,o)=>{let a=Y6(s||"claude",t3({system:n,model:t}),{env:n3(),stdio:["pipe","pipe","pipe"]}),l="",c="",u=setTimeout(()=>{a.kill("SIGKILL"),o(new Error("claude -p timed out"))},i);a.stdout.on("data",d=>l+=d),a.stderr.on("data",d=>c+=d),a.on("error",d=>{clearTimeout(u),o(d)}),a.on("close",d=>{clearTimeout(u),d===0?r({text:l.trim(),usage:null}):o(new Error("claude -p exited "+d+": "+c.slice(0,300)))}),a.stdin.end(e)})}async function xk(n,e,t,s,i){let r=await n(e,{method:"POST",headers:{"content-type":"application/json",...t},body:JSON.stringify(s),signal:AbortSignal.timeout(i)}),o=await r.json().catch(()=>({}));if(!r.ok)throw new Error(e+" -> "+r.status+": "+(o.error&&(o.error.message||o.error)||"error"));return o}function i3(n={},e=process.env){return xi("anthropic",n,e)}function xi(n,{apiKeyEnv:e,apiKeyFile:t,root:s}={},i=process.env){let r=Op[n]||{},o=e||r.env;if(o&&i[o])return i[o];for(let a of[t,e==="__none__"?null:r.file]){if(!a)continue;let l=bk.isAbsolute(a)?null:b_(a,i.HOME||i.XDG_CONFIG_HOME?i:process.env);for(let c of[l,bk.isAbsolute(a)?a:bk.join(s||re(),a)])if(c)try{let u=J6.readFileSync(c,"utf8").trim();if(u)return u}catch{}}return null}async function r3(n,{system:e,prompt:t,model:s,maxTokens:i,apiKeyEnv:r,apiKeyFile:o,root:a,timeoutMs:l}){let c=i3({apiKeyEnv:r,apiKeyFile:o,root:a});if(!c)throw new Error((r||"ANTHROPIC_API_KEY")+" is not set");let u=(process.env.ANTHROPIC_BASE_URL||"https://api.anthropic.com").replace(/\/$/,""),d=await xk(n,u+"/v1/messages",{"x-api-key":c,"anthropic-version":"2023-06-01"},{model:nE[s]||s||nE.haiku,max_tokens:i||300,system:e,messages:[{role:"user",content:t}]},l||3e4);return{text:(d.content||[]).filter(h=>h.type==="text").map(h=>h.text).join(`
186
+ `),usage:d.usage?{inputTokens:d.usage.input_tokens,outputTokens:d.usage.output_tokens}:null}}function o3(n,e,t){let s=Math.ceil(((n||"").length+(e||"").length)/3.2)+(t||300)+256;for(let i of vk)if(s<=i)return i;return vk[vk.length-1]}async function rE(n,{system:e,prompt:t,model:s,maxTokens:i,baseUrl:r,key:o,cloud:a,json:l,timeoutMs:c}){let u=a?Math.max(1024,(i||300)*4):i||300,d=await xk(n,r.replace(/\/$/,"")+"/api/chat",o?{authorization:"Bearer "+o}:{},{model:s,stream:!1,...l?{format:"json"}:{},messages:[...e?[{role:"system",content:e}]:[],{role:"user",content:t}],options:{num_predict:u,temperature:.2,...a?{}:{num_ctx:o3(e,t,u)}}},Math.max(c||0,a?6e4:12e4));return{text:d.message&&d.message.content||"",usage:{inputTokens:d.prompt_eval_count,outputTokens:d.eval_count}}}async function a3(n,{system:e,prompt:t,model:s,maxTokens:i,baseUrl:r,apiKeyEnv:o}){let a=o?process.env[o]:null,l=await xk(n,r.replace(/\/$/,"")+"/chat/completions",a?{authorization:"Bearer "+a}:{},{model:s,max_tokens:i||300,temperature:.2,messages:[...e?[{role:"system",content:e}]:[],{role:"user",content:t}]},12e4),c=l.choices&&l.choices[0];return{text:c&&c.message&&c.message.content||c&&c.text||"",usage:l.usage?{inputTokens:l.usage.prompt_tokens,outputTokens:l.usage.completion_tokens}:null}}function aE(n){let e=Ak(n,200).toLowerCase();return!e||c3.test(e)}function u3(n,{prompts:e=8,replies:t=1,max:s=300}={}){let i=(n||[]).filter(l=>!oE(l)),r=i.filter(l=>l.role==="user").slice(-e),o=new Set(i.filter(l=>l.role==="assistant").slice(-t)),a=new Set(r);return i.filter(l=>a.has(l)||o.has(l)).map(l=>({role:l.role,text:Ak(l.text,s)}))}function d3(n,{firstPrompt:e=""}={}){let t=n.filter(o=>o.role==="user").map(o=>o.text),s=n.filter(o=>o.role==="assistant").map(o=>o.text),i=Ak(e,200),r=[];return i&&!t.some(o=>o.startsWith(i.slice(0,80)))&&r.push("Session started with: "+i),t.length&&r.push(`Recent requests from the user, oldest first:
187
187
  `+t.map(o=>"- "+o).join(`
188
188
  `)),s.length&&r.push("Latest reply: "+s.join(" … ")),r.join(`
189
189
 
190
- `)}function hU(n){let e=n.filter(s=>s.role==="user").map(s=>s.text).filter(s=>!aE(s)),t=s=>s.split(" ").filter(Boolean).length;return[...e].reverse().find(s=>t(s)>=4)||e.at(-1)||""}var nE,V6,X6,Z6,Cp,Op,sE,vk,lU,oE,Ak,cU,Lt,Ho=K(()=>{Fe();Hn();Te();nE={haiku:"claude-haiku-5-5",sonnet:"claude-sonnet-5-5",opus:"claude-opus-5-5"},V6=["haiku","sonnet","opus",""],X6="https://ollama.com",Z6="gpt-oss:20b",Cp={ollama:{baseUrl:"http://localhost:11434",model:"llama3.2"},"ollama-cloud":{baseUrl:X6,model:Z6},"openai-compatible":{baseUrl:"http://localhost:1234/v1",model:"local-model"}},Op={anthropic:{env:"ANTHROPIC_API_KEY",file:".secret/anthropic-api-key"},"ollama-cloud":{env:"OLLAMA_API_KEY",file:".secret/ollama-api-key"}},sE={stub:"heuristic",none:"heuristic",heuristic:"heuristic",api:"anthropic",anthropic:"anthropic",claude:"claude",ollama:"ollama","ollama-cloud":"ollama-cloud","ollama.com":"ollama-cloud",cloud:"ollama-cloud","openai-compatible":"openai-compatible",openai:"openai-compatible",lmstudio:"openai-compatible",llamacpp:"openai-compatible",vllm:"openai-compatible"};vk=[8192,16384,32768];lU=`Write a title of at most 6 words naming the main thing this coding session is building or fixing, judging by all of the user's recent requests together. Ignore routine follow-ups like "check PR comments", "run tests", "commit", "continue" or "fix that": they are not the topic. `+w0+" Reply with the title only, no quotes, no punctuation at the end.",oE=n=>!n||!(n.role==="user"||n.role==="assistant")||!String(n.text||"").trim()||/^\s*<(command-|local-command|system-reminder)/.test(n.text)||/^\s*\//.test(n.text),Ak=(n,e)=>String(n||"").replace(/\s+/g," ").trim().slice(0,e),cU=/^(please |pls |ok(ay)?,? |now |and |then |can you |could you |go ahead and )*(check( for)?( the)?( new)?( pr| github)?( review)? comments|address( the)?( pr)?( review)? comments|(re)?run( the)?( unit| all)?( tests?| checks?| ci)|tests?|commit( it| this| that| and push)?|push( it)?|merge( it)?|ship( it)?|continue|keep going|go on|go ahead|do it|yes|yep|yeah|no|ok(ay)?|sure|thanks|thank you|lgtm|looks good|great|nice|fix (it|that|this|those|them)|try again|again|retry|what('| i)?s next|next|status|done\??)( please| pls)?[\s.!?]*$/i;Lt=class{constructor(e,{fetchImpl:t,root:s,claudeBin:i}={}){this.cfg=e,this.root=s||null,this.claudeBin=i||null,this.fetchImpl=t||((...r)=>fetch(...r)),this.mode=eU(e)}get model(){let e=String(this.cfg.summarizer&&this.cfg.summarizer.model||"");return Cp[this.mode]&&V6.includes(e)?Cp[this.mode].model:e||"haiku"}get baseUrl(){return this.cfg.summarizer&&this.cfg.summarizer.baseUrl||Cp[this.mode]&&Cp[this.mode].baseUrl||null}describe(){return{provider:this.mode,model:this.mode==="heuristic"?null:this.model,baseUrl:this.baseUrl}}async complete({system:e,prompt:t,maxTokens:s,json:i=!1,timeoutMs:r=null}){let o=this.cfg.summarizer||{},a={system:e,prompt:t,maxTokens:s,json:i,timeoutMs:r,model:this.model,baseUrl:this.baseUrl,apiKeyEnv:o.apiKeyEnv,apiKeyFile:o.apiKeyFile,root:this.root,bin:this.claudeBin};if(this.mode==="claude")return sU(a,r||void 0);if(this.mode==="anthropic")return rU(this.fetchImpl,a);if(this.mode==="ollama")return rE(this.fetchImpl,a);if(this.mode==="ollama-cloud"){let l=xi("ollama-cloud",{apiKeyEnv:o.apiKeyEnv,apiKeyFile:o.apiKeyFile,root:this.root});if(!l)throw new Error((o.apiKeyEnv||"OLLAMA_API_KEY")+" is not set (create a key at https://ollama.com/settings/keys)");return rE(this.fetchImpl,{...a,key:l,cloud:!0})}if(this.mode==="openai-compatible")return aU(this.fetchImpl,a);throw new Error("no model in heuristic mode")}async checkpoint({system:e,prompt:t,messages:s,session:i,maxTokens:r=300,length:o="short"}){if(this.mode!=="heuristic")try{let a=f=>String(f.text||"").replace(/<think>[\s\S]*?<\/think>/gi,"").trim(),l=await this.complete({system:e,prompt:t,maxTokens:r}),c=a(l);if(iE(c))throw new Error("the model repeated its instructions instead of summarizing");let u=p0(c),d=!1;if(u.parseOk===!1){d=!0;try{let f=await this.complete({system:e,prompt:QA(t),maxTokens:r}),p=a(f),m=iE(p)?null:p0(p);m&&m.parseOk!==!1?(u=m,l=f):m&&(u=ZA(u,m))}catch{}}let h={by:"daemon",provider:this.mode,model:this.model,...d?{retried:!0}:{}};return l.usage&&l.usage.inputTokens!=null&&(h.inputTokens=l.usage.inputTokens),l.usage&&l.usage.outputTokens!=null&&(h.outputTokens=l.usage.outputTokens),{...u,generator:h}}catch(a){let l=g0(s,i,{length:o});return vi({...l,generator:{by:"heuristic",fallbackFrom:this.mode,error:String(a.message||a).slice(0,160)}})}return vi({...g0(s,i,{length:o}),generator:{by:"heuristic"}})}async title(e){if(this.mode!=="heuristic"&&e.firstPrompt)try{let t=await this.titleInUserLanguage(e_,s=>`First prompt:
190
+ `)}function h3(n){let e=n.filter(s=>s.role==="user").map(s=>s.text).filter(s=>!aE(s)),t=s=>s.split(" ").filter(Boolean).length;return[...e].reverse().find(s=>t(s)>=4)||e.at(-1)||""}var nE,V6,X6,Z6,Cp,Op,sE,vk,l3,oE,Ak,c3,Lt,Ho=K(()=>{Fe();Hn();Te();nE={haiku:"claude-haiku-5-5",sonnet:"claude-sonnet-5-5",opus:"claude-opus-5-5"},V6=["haiku","sonnet","opus",""],X6="https://ollama.com",Z6="gpt-oss:20b",Cp={ollama:{baseUrl:"http://localhost:11434",model:"llama3.2"},"ollama-cloud":{baseUrl:X6,model:Z6},"openai-compatible":{baseUrl:"http://localhost:1234/v1",model:"local-model"}},Op={anthropic:{env:"ANTHROPIC_API_KEY",file:".secret/anthropic-api-key"},"ollama-cloud":{env:"OLLAMA_API_KEY",file:".secret/ollama-api-key"}},sE={stub:"heuristic",none:"heuristic",heuristic:"heuristic",api:"anthropic",anthropic:"anthropic",claude:"claude",ollama:"ollama","ollama-cloud":"ollama-cloud","ollama.com":"ollama-cloud",cloud:"ollama-cloud","openai-compatible":"openai-compatible",openai:"openai-compatible",lmstudio:"openai-compatible",llamacpp:"openai-compatible",vllm:"openai-compatible"};vk=[8192,16384,32768];l3=`Write a title of at most 6 words naming the main thing this coding session is building or fixing, judging by all of the user's recent requests together. Ignore routine follow-ups like "check PR comments", "run tests", "commit", "continue" or "fix that": they are not the topic. `+w0+" Reply with the title only, no quotes, no punctuation at the end.",oE=n=>!n||!(n.role==="user"||n.role==="assistant")||!String(n.text||"").trim()||/^\s*<(command-|local-command|system-reminder)/.test(n.text)||/^\s*\//.test(n.text),Ak=(n,e)=>String(n||"").replace(/\s+/g," ").trim().slice(0,e),c3=/^(please |pls |ok(ay)?,? |now |and |then |can you |could you |go ahead and )*(check( for)?( the)?( new)?( pr| github)?( review)? comments|address( the)?( pr)?( review)? comments|(re)?run( the)?( unit| all)?( tests?| checks?| ci)|tests?|commit( it| this| that| and push)?|push( it)?|merge( it)?|ship( it)?|continue|keep going|go on|go ahead|do it|yes|yep|yeah|no|ok(ay)?|sure|thanks|thank you|lgtm|looks good|great|nice|fix (it|that|this|those|them)|try again|again|retry|what('| i)?s next|next|status|done\??)( please| pls)?[\s.!?]*$/i;Lt=class{constructor(e,{fetchImpl:t,root:s,claudeBin:i}={}){this.cfg=e,this.root=s||null,this.claudeBin=i||null,this.fetchImpl=t||((...r)=>fetch(...r)),this.mode=e3(e)}get model(){let e=String(this.cfg.summarizer&&this.cfg.summarizer.model||"");return Cp[this.mode]&&V6.includes(e)?Cp[this.mode].model:e||"haiku"}get baseUrl(){return this.cfg.summarizer&&this.cfg.summarizer.baseUrl||Cp[this.mode]&&Cp[this.mode].baseUrl||null}describe(){return{provider:this.mode,model:this.mode==="heuristic"?null:this.model,baseUrl:this.baseUrl}}async complete({system:e,prompt:t,maxTokens:s,json:i=!1,timeoutMs:r=null}){let o=this.cfg.summarizer||{},a={system:e,prompt:t,maxTokens:s,json:i,timeoutMs:r,model:this.model,baseUrl:this.baseUrl,apiKeyEnv:o.apiKeyEnv,apiKeyFile:o.apiKeyFile,root:this.root,bin:this.claudeBin};if(this.mode==="claude")return s3(a,r||void 0);if(this.mode==="anthropic")return r3(this.fetchImpl,a);if(this.mode==="ollama")return rE(this.fetchImpl,a);if(this.mode==="ollama-cloud"){let l=xi("ollama-cloud",{apiKeyEnv:o.apiKeyEnv,apiKeyFile:o.apiKeyFile,root:this.root});if(!l)throw new Error((o.apiKeyEnv||"OLLAMA_API_KEY")+" is not set (create a key at https://ollama.com/settings/keys)");return rE(this.fetchImpl,{...a,key:l,cloud:!0})}if(this.mode==="openai-compatible")return a3(this.fetchImpl,a);throw new Error("no model in heuristic mode")}async checkpoint({system:e,prompt:t,messages:s,session:i,maxTokens:r=300,length:o="short"}){if(this.mode!=="heuristic")try{let a=f=>String(f.text||"").replace(/<think>[\s\S]*?<\/think>/gi,"").trim(),l=await this.complete({system:e,prompt:t,maxTokens:r}),c=a(l);if(iE(c))throw new Error("the model repeated its instructions instead of summarizing");let u=p0(c),d=!1;if(u.parseOk===!1){d=!0;try{let f=await this.complete({system:e,prompt:QA(t),maxTokens:r}),p=a(f),m=iE(p)?null:p0(p);m&&m.parseOk!==!1?(u=m,l=f):m&&(u=ZA(u,m))}catch{}}let h={by:"daemon",provider:this.mode,model:this.model,...d?{retried:!0}:{}};return l.usage&&l.usage.inputTokens!=null&&(h.inputTokens=l.usage.inputTokens),l.usage&&l.usage.outputTokens!=null&&(h.outputTokens=l.usage.outputTokens),{...u,generator:h}}catch(a){let l=g0(s,i,{length:o});return vi({...l,generator:{by:"heuristic",fallbackFrom:this.mode,error:String(a.message||a).slice(0,160)}})}return vi({...g0(s,i,{length:o}),generator:{by:"heuristic"}})}async title(e){if(this.mode!=="heuristic"&&e.firstPrompt)try{let t=await this.titleInUserLanguage(e_,s=>`First prompt:
191
191
  `+e.firstPrompt+`
192
192
 
193
- `+s,e.firstPrompt);if(t)return{title:t,titleSource:"generated"}}catch{}return{title:y0(e),titleSource:"fallback"}}async titleInUserLanguage(e,t,s){for(let i of[!1,!0]){let r=await this.complete({system:e,prompt:t(a_(s,{firm:i})),maxTokens:30}),o=t_(r.text);if(!o)return null;if(n_(o,s))return o}return null}async recentTitle(e,t={}){let s=uU(e),i=(e||[]).find(a=>!oE(a)&&a.role==="user"),r=t.firstPrompt||i&&i.text||"";if(this.mode!=="heuristic"&&s.length)try{let a=s.filter(u=>u.role==="user").map(u=>u.text).join(`
194
- `),l=dU(s,{firstPrompt:r}),c=await this.titleInUserLanguage(lU,u=>l+`
195
-
196
- `+u,a||r);if(c)return{title:c,titleSource:"generated",by:this.mode}}catch{}let o=hU(s);return{title:y0({...t,firstPrompt:o||!aE(t.lastPrompt)&&t.lastPrompt||t.firstPrompt||t.lastPrompt||""}),titleSource:"fallback",by:"heuristic"}}async paragraph(e,t){if(this.mode==="heuristic")return null;try{return(await this.complete({system:e,prompt:t,maxTokens:200})).text.trim()}catch{return null}}}});import pl from"node:fs";import fU from"node:os";import Mp from"node:path";import{execFileSync as VJ,spawn as pU,spawnSync as mU}from"node:child_process";import{fileURLToPath as gU}from"node:url";async function Vu({baseUrl:n=process.env.CHECKPOINTS_CLOUD_URL||Bo,fetchImpl:e=fetch,timeoutMs:t=5e3}={}){let s=n.replace(/\/$/,"");try{let i=await Ip(e,s+"/api/tags",t);return{ok:!0,baseUrl:s,models:(i.models||[]).map(r=>r.name||r.model).filter(Boolean),error:null}}catch(i){return{ok:!1,baseUrl:s,models:[],error:i.cause&&i.cause.code||i.message}}}function Lp(n=[],{curated:e=Ju,current:t=null}={}){let s=r=>n.some(o=>Ct(o,r)),i=e.map(r=>({...r,curated:!0,available:n.length?s(r.tag):null,current:!!t&&Ct(t,r.tag)}));for(let r of n)i.some(o=>Ct(o.tag,r))||i.push({tag:r,name:r,curated:!1,available:!0,recommended:!1,current:!!t&&Ct(t,r)});return i}function Np(n){let e=String(n||"").trim().toLowerCase();return e?e.includes(":")?e:e+":latest":""}function Ct(n,e){return Np(n)===Np(e)}function gl(n=[],{curated:e=qu,current:t=null}={}){let s=n.map(o=>typeof o=="string"?{name:o}:o),i=o=>s.some(a=>Ct(a.name||a.model,o)),r=e.map(o=>({...o,curated:!0,installed:i(o.tag),current:!!t&&Ct(t,o.tag)}));for(let o of s){let a=o.name||o.model;!a||r.some(l=>Ct(l.tag,a))||/embed/i.test(a)||r.push({tag:a,name:a,sizeBytes:o.size||null,curated:!1,installed:!0,recommended:!1,current:!!t&&Ct(t,a)})}return r}function cE(n,{totalMemBytes:e=fU.totalmem()}={}){let t=n.find(r=>r.current&&r.installed);if(t)return t.tag;let s=n.find(r=>r.recommended);if(s&&s.installed)return s.tag;let i=n.find(r=>r.curated&&r.installed);if(i)return i.tag;if(e&&e<85e8){let r=n.filter(o=>o.curated).sort((o,a)=>o.ramGB-a.ramGB)[0];if(r)return r.tag}return s?s.tag:n[0]&&n[0].tag}function jp(n,e){let t=[];return n.sizeBytes&&t.push(e(n.sizeBytes)),n.ramGB&&t.push("~"+n.ramGB+" GB RAM"),n.speed&&t.push(n.speed),t.join(" · ")}function vr(n,e=process.env){let t=String(e.PATH||"").split(Mp.delimiter).filter(Boolean),s=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let i of t)for(let r of s){let o=Mp.join(i,n+r);try{if(pl.statSync(o).isFile())return pl.accessSync(o,pl.constants.X_OK),o}catch{}}return null}function Ai(n=process.env){let e=vr("ollama",n);if(e)return e;if(n.CHECKPOINTS_TEST_NO_SYSTEM_BINS)return null;for(let t of["/opt/homebrew/bin/ollama","/usr/local/bin/ollama","/Applications/Ollama.app/Contents/Resources/ollama"])if(pl.existsSync(t))return t;return null}async function Ip(n,e,t=1500){let s=await n(e,{signal:AbortSignal.timeout(t)});if(!s.ok)throw new Error(e+" -> HTTP "+s.status);return s.json()}async function jt({baseUrl:n=Pt,fetchImpl:e=fetch,env:t=process.env}={}){let s=n.replace(/\/$/,""),i={kind:"ollama",running:!1,baseUrl:s,version:null,models:[],binary:Ai(t),error:null};try{let r=await Ip(e,s+"/api/tags");i.running=!0,i.models=(r.models||[]).map(o=>({name:o.name||o.model,size:o.size,modifiedAt:o.modified_at,parameterSize:o.details&&o.details.parameter_size,quantization:o.details&&o.details.quantization_level}));try{i.version=(await Ip(e,s+"/api/version")).version||null}catch{}}catch(r){i.error=r.cause&&r.cause.code||r.name||r.message}return i}async function _i({baseUrl:n=zs,fetchImpl:e=fetch}={}){let t=n.replace(/\/$/,""),s={kind:"openai-compatible",running:!1,baseUrl:t,models:[],error:null};try{let i=await Ip(e,t+"/models");s.running=!0,s.models=(i.data||[]).map(r=>r.id).filter(r=>r&&!/embed/i.test(r))}catch(i){s.error=i.cause&&i.cause.code||i.name||i.message}return s}async function yl({baseUrl:n=Pt,fetchImpl:e=fetch,timeoutMs:t=2e4}={}){let s=Date.now()+t;for(;Date.now()<s;){let i=await jt({baseUrl:n,fetchImpl:e});if(i.running)return i;await wU(500)}return jt({baseUrl:n,fetchImpl:e})}function kU(n,e){let t=n||{layers:{},status:"",total:0,completed:0,fraction:0,done:!1,error:null};if(e.error)return{...t,error:String(e.error)};let s={...t.layers};e.digest&&e.total&&(s[e.digest]={total:e.total,completed:Math.min(e.completed||0,e.total)});let i=Object.values(s),r=i.reduce((c,u)=>c+u.total,0),o=i.reduce((c,u)=>c+u.completed,0),a=e.status==="success",l=a?1:r?Math.min(.999,o/r):t.fraction;return{layers:s,status:e.status||t.status,total:r,completed:o,fraction:Math.max(t.fraction,l),done:a,error:null}}async function wl({tag:n,baseUrl:e=Pt,fetchImpl:t=fetch,onProgress:s=()=>{},signal:i}={}){let r=await t(e.replace(/\/$/,"")+"/api/pull",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:n,stream:!0}),signal:i});if(!r.ok||!r.body){let u="HTTP "+r.status;try{let d=await r.json();d.error&&(u=d.error)}catch{}throw new Error("pull "+n+" failed: "+u)}let o=null,a="",l=new TextDecoder,c=u=>{if(!u.trim())return;let d;try{d=JSON.parse(u)}catch{return}if(o=kU(o,d),o.error)throw new Error("pull "+n+" failed: "+o.error);s(o)};for await(let u of r.body){a+=l.decode(u,{stream:!0});let d;for(;(d=a.indexOf(`
197
- `))>=0;)c(a.slice(0,d)),a=a.slice(d+1)}if(c(a),!o||!o.done)throw new Error("pull "+n+" ended early (last status: "+(o&&o.status||"none")+")");return o}async function Ti(n,{fetchImpl:e,transcriptFile:t=yU,root:s}={}){let i=eu(Be,{summarizer:n}),{messages:r,meta:o}=fl(pl.readFileSync(t,"utf8")),a={id:o.sessionId||"sample",cwd:o.cwd||"/work/acme",title:o.summary||"Sample session",repo:{root:o.cwd,branch:o.gitBranch}},l=Cf({session:a,messages:r,cfg:i}),c=new Lt(i,{...e?{fetchImpl:e}:{},...s?{root:s}:{}}),u=Date.now(),d=await c.checkpoint({...l,messages:r,session:a}),h=Date.now()-u,f=d.generator&&d.generator.by==="heuristic"&&d.generator.fallbackFrom;return{ok:!f,doing:d.doing,stoppedAt:d.stoppedAt,next:d.next,parseOk:d.parseOk!==!1,ms:h,generator:d.generator,error:f?d.generator.error:null}}function uE(n=process.platform,e=process.env){let t={id:"script",label:"Official install script",shell:"curl -fsSL https://ollama.com/install.sh | sh",cmd:["sh","-c","curl -fsSL https://ollama.com/install.sh | sh"]};if(n==="darwin"){let s=[];return vr("brew",e)&&s.push({id:"brew",label:"Homebrew",shell:"brew install ollama",cmd:["brew","install","ollama"]}),s.push({...t,note:"installs the Ollama app"}),s.push({id:"manual",label:"Download the app myself",shell:"open https://ollama.com/download",cmd:null,url:"https://ollama.com/download"}),s}return n==="linux"?[{...t,note:"asks for sudo; sets up a systemd service"},{id:"manual",label:"Install it myself",shell:"see https://ollama.com/download/linux",cmd:null,url:"https://ollama.com/download/linux"}]:n==="win32"?[{id:"manual",label:"PowerShell installer",shell:"irm https://ollama.com/install.ps1 | iex",cmd:null,url:"https://ollama.com/download/windows"}]:[{id:"manual",label:"Install it myself",shell:"see https://ollama.com/download",cmd:null,url:"https://ollama.com/download"}]}function zo(n=process.platform,e=Ai()){return n==="darwin"&&pl.existsSync("/Applications/Ollama.app")?{shell:"open -a Ollama",cmd:["open","-a","Ollama"],detached:!1}:e?{shell:e+" serve",cmd:[e,"serve"],detached:!0}:null}function Pp({platform:n=process.platform,binary:e,env:t=process.env}={}){if(t.CHECKPOINTS_OLLAMA_START_CMD)try{let s=JSON.parse(t.CHECKPOINTS_OLLAMA_START_CMD);if(Array.isArray(s)&&s.length)return{shell:s.join(" "),cmd:s,detached:!0}}catch{}return e?zo(n,e):null}function dE(n,{spawnImpl:e=pU,spawnSyncImpl:t=mU}={}){if(!n||!Array.isArray(n.cmd))return{started:!1,shell:null,error:"no start command"};try{if(n.detached){let s=e(n.cmd[0],n.cmd.slice(1),{detached:!0,stdio:"ignore"});s.on("error",()=>{}),s.unref()}else{let s=t(n.cmd[0],n.cmd.slice(1),{stdio:"ignore",timeout:15e3});if(s&&s.status)return{started:!1,shell:n.shell,error:n.shell+" exited "+s.status}}return{started:!0,shell:n.shell}}catch(s){return{started:!1,shell:n.shell,error:String(s.message||s)}}}var Pt,zs,yU,ml,qu,Bo,lE,Ju,wU,Bs=K(()=>{Uo();Te();Ho();Pt="http://localhost:11434",zs="http://localhost:1234/v1",yU=Mp.resolve(Mp.dirname(gU(import.meta.url)),"..","assets","sample-transcript.jsonl"),ml="2026-10-09",qu=[{tag:"qwen2.5:3b",name:"Qwen 2.5 · 3B",sizeBytes:19e8,ramGB:4,speed:"fast",note:"Sticks to the 3-line format, good with code and file names",recommended:!0},{tag:"llama3.2:3b",name:"Llama 3.2 · 3B",sizeBytes:2e9,ramGB:4,speed:"fast",note:"Solid all-rounder from Meta"},{tag:"gemma3:4b",name:"Gemma 3 · 4B",sizeBytes:34e8,ramGB:6,speed:"medium",note:"Best-written summaries of the four, slower without a GPU"},{tag:"llama3.2:1b",name:"Llama 3.2 · 1B",sizeBytes:13e8,ramGB:2.5,speed:"fastest",note:'For 8 GB machines; terser, sometimes vague on "Next"'}],Bo="https://ollama.com",lE="2026-10-09",Ju=[{tag:"gpt-oss:20b",name:"gpt-oss · 20B",note:"OpenAI's open-weight model; quick, plenty for 3 lines",recommended:!0},{tag:"gemma4:31b",name:"Gemma 4 · 31B",note:"Google; the model Ollama's own cloud docs use"},{tag:"nemotron-3-nano:30b",name:"Nemotron 3 Nano · 30B",note:"NVIDIA; small and fast"},{tag:"gpt-oss:120b",name:"gpt-oss · 120B",note:"Bigger and slower; more than a checkpoint needs"}];wU=n=>new Promise(e=>setTimeout(e,n))});import Rt from"node:fs";import _k from"node:os";import ze from"node:path";import{spawnSync as SU}from"node:child_process";import{fileURLToPath as bU}from"node:url";function xU(n=process.env,e=_k.homedir(),t=process.execPath){let s=[ze.join(e,".local","bin","claude"),ze.join(e,".claude","local","claude"),"/opt/homebrew/bin/claude","/usr/local/bin/claude",ze.join(e,".npm-global","bin","claude"),ze.join(e,".bun","bin","claude"),ze.join(e,".volta","bin","claude"),ze.join(ze.dirname(t),"claude")];if(n.NVM_DIR||e){let i=ze.join(n.NVM_DIR||ze.join(e,".nvm"),"versions","node");try{let r=Rt.readdirSync(i).filter(o=>/^v\d/.test(o)).sort((o,a)=>fE(a.slice(1),o.slice(1)));for(let o of r)s.push(ze.join(i,o,"bin","claude"))}catch{}}return s}function Tn(n=process.env,{home:e=_k.homedir(),execPath:t=process.execPath}={}){if(n.CHECKPOINTS_CLAUDE_BIN)return n.CHECKPOINTS_CLAUDE_BIN;let s=vr("claude",n);if(s)return s;if(n.CHECKPOINTS_TEST_NO_SYSTEM_BINS&&!n.LEFTOFF_TEST_CLAUDE_HOME)return null;for(let i of xU(n,n.LEFTOFF_TEST_CLAUDE_HOME||e,t))try{if(Rt.statSync(i).isFile())return Rt.accessSync(i,Rt.constants.X_OK),i}catch{}return null}function Ei(n,e,{env:t=process.env,timeoutMs:s=12e4}={}){let i=SU(n,e,{env:{...t,CHECKPOINTS_INTERNAL:"1",LEFTOFF_INTERNAL:"1"},encoding:"utf8",timeout:s});return{code:i.status==null?-1:i.status,stdout:i.stdout||"",stderr:i.stderr||(i.error?String(i.error.message):""),args:e}}function AU(n){let e=String(n||"").match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}function fE(n,e){let t=String(n).split(".").map(Number),s=String(e).split(".").map(Number);for(let i=0;i<3;i++){let r=(t[i]||0)-(s[i]||0);if(r)return r>0?1:-1}return 0}function pE(n=process.env){let e=Tn(n);if(!e)return{found:!1,bin:null,version:null,modsSupported:!1};let t=Ei(e,["--version"],{env:n,timeoutMs:15e3}),s=AU(t.stdout+" "+t.stderr);return{found:!0,bin:e,version:s,modsSupported:!!s&&fE(s,Xu)>=0}}function Tk(n){return/[\\/]_npx[\\/]/.test(n)||/[\\/]\.npm[\\/]/.test(n)}function Ek(n=kl){try{return JSON.parse(Rt.readFileSync(ze.join(n,"package.json"),"utf8")).leftoffBuild==="npm"}catch{return!1}}function _U(n=process.env){return n.LEFTOFF_PLUGIN_DIR?n.LEFTOFF_PLUGIN_DIR:ze.join(n.XDG_CONFIG_HOME||ze.join(n.HOME||_k.homedir(),".config"),"checkpoints","plugin")}function Ck({from:n=kl,env:e=process.env}={}){let t=_U(e);if(!Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json")))throw new Error("no .claude-plugin/marketplace.json in "+n);let s=t+"."+process.pid+".tmp";Rt.rmSync(s,{recursive:!0,force:!0}),Rt.mkdirSync(ze.join(s,".claude-plugin"),{recursive:!0}),Rt.copyFileSync(ze.join(n,".claude-plugin","marketplace.json"),ze.join(s,".claude-plugin","marketplace.json"));let i=r=>/^(tests|tsconfig\.json)$/.test(r)||/(^|[\\/])types([\\/]|$)/.test(r);return Rt.cpSync(ze.join(n,"mod"),ze.join(s,"mod"),{recursive:!0,filter:r=>!i(ze.relative(ze.join(n,"mod"),r))}),Rt.writeFileSync(ze.join(s,"README.md"),"Leftoff's Claude Code plugin (the mod), copied here by `leftoff setup` / `leftoff upgrade` from the installed package.\nClaude Code reads it as a local marketplace. Safe to delete: `leftoff setup` puts it back.\n"),Rt.rmSync(t,{recursive:!0,force:!0}),Rt.mkdirSync(ze.dirname(t),{recursive:!0}),Rt.renameSync(s,t),t}function mE({repoDir:n=kl,override:e,env:t=process.env,copy:s=Ck}={}){if(e)return e;if(!Tk(n)&&Rt.existsSync(ze.join(n,".git"))&&Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json")))return n;if(Ek(n)&&Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json"))){try{return s({from:n,env:t})}catch{}return n}return Rp}function hE(n,e=lt){let t=String(n||""),s=t.search(new RegExp("(^|[^\\w-])"+e.replace(/[.@]/g,"\\$&")+"(?![\\w-])","m"));if(s<0)return{installed:!1,enabled:!1};let i=t.slice(s,s+400).split(/\n\s*\n/)[0];return{installed:!0,enabled:!(/disabled/i.test(i)&&!/✔\s*enabled|status:\s*enabled/i.test(i))}}function TU(n){return new RegExp("(^|[^\\w-])"+Gs+"([^\\w-]|$)","m").test(String(n||""))}function Dp(n,e){let t=Ei(n,["plugin","list"],{env:e,timeoutMs:3e4}),s=Ei(n,["plugin","marketplace","list"],{env:e,timeoutMs:3e4}),i=hE(t.stdout,Tr);return{...hE(t.stdout),legacyInstalled:i.installed,legacyEnabled:i.enabled,marketplaceAdded:s.code===0&&TU(s.stdout),listOk:t.code===0}}function Ok({bin:n,env:e=process.env,state:t=null,onStep:s=()=>{}}){let i=t||Dp(n,e);if(!i.legacyInstalled)return{ok:!0,migrated:!1,steps:[]};let r=[],o=c=>{s("claude "+c.join(" "));let u=Ei(n,c,{env:e});return r.push(u),u},a=c=>(c.stderr||c.stdout).trim().split(`
198
- `).pop()||"exit "+c.code;if(!i.installed){o(["plugin","marketplace","update",Gs]);let c=o(["plugin","install",lt]);if(c.code!==0&&!/already installed/i.test(c.stdout+c.stderr))return{ok:!1,migrated:!1,steps:r,error:a(c)};i.legacyEnabled===!1&&o(["plugin","disable",lt])}let l=o(["plugin","uninstall",Tr]);return l.code!==0?{ok:!1,migrated:!0,steps:r,error:"installed "+lt+" but couldn't uninstall "+Tr+": "+a(l)}:{ok:!0,migrated:!0,enabled:i.legacyEnabled!==!1,steps:r}}function Mk({bin:n,source:e,env:t=process.env,onStep:s=()=>{}}){let i=[],r=Dp(n,t);if(r.legacyInstalled){let l=Ok({bin:n,env:t,state:r,onStep:s});if(!l.ok)return{ok:!1,steps:l.steps,state:r,error:l.error};let c=Mk({bin:n,source:e,env:t,onStep:s});return{...c,migrated:l.migrated,steps:[...l.steps,...c.steps]}}if(r.installed&&r.enabled)return{ok:!0,already:!0,steps:i,state:r};if(r.installed&&!r.enabled){s("claude plugin enable "+lt);let l=Ei(n,["plugin","enable",lt],{env:t});return i.push(l),{ok:l.code===0,already:!0,enabled:l.code===0,steps:i,state:r,error:l.code?(l.stderr||l.stdout).trim():null}}if(!r.marketplaceAdded){s("claude plugin marketplace add "+e);let l=Ei(n,["plugin","marketplace","add",e],{env:t});if(i.push(l),l.code!==0&&!/already/i.test(l.stdout+l.stderr))return{ok:!1,steps:i,state:r,error:(l.stderr||l.stdout).trim()||"exit "+l.code}}s("claude plugin install "+lt);let o=Ei(n,["plugin","install",lt],{env:t});i.push(o);let a=o.code===0||/already installed/i.test(o.stdout+o.stderr);return{ok:a,steps:i,state:r,error:a?null:(o.stderr||o.stdout).trim()||"exit "+o.code}}function gE(n){return!!(n&&n.disableAllHooks===!0)}var kl,Rp,Gs,vU,lt,Tr,Xu,Ci=K(()=>{Bs();Wt();kl=ze.resolve(ze.dirname(bU(import.meta.url)),".."),Rp=gi,Gs=T_,vU=E_,lt=vU+"@"+Gs,Tr=C_+"@"+Gs,Xu="2.1.287"});import wE from"node:fs";import Fp from"node:path";function Er(n,{statfs:e=wE.statfsSync}={}){if(!n||typeof e!="function")return null;let t=Fp.resolve(String(n));for(let s=0;s<64;s++){try{let r=e(t),o=Number(r.bsize||r.frsize||0),a=Number(r.blocks)*o,l=Number(r.bavail!=null?r.bavail:r.bfree)*o;return a?{path:t,freeBytes:l,totalBytes:a,pct:Math.round(l/a*1e4)/100}:null}catch{}let i=Fp.dirname(t);if(i===t)return null;t=i}return null}function IU(n){return!n||!n.totalBytes?"ok":n.pct<EU?"red":n.freeBytes<Math.max(n.totalBytes*CU/100,OU)?"warn":"ok"}function $o(n){return n=Number(n)||0,n>=100*Zu?Math.round(n/Zu)+" GB":n>=Zu?Math.round(n/Zu*10)/10+" GB":Math.round(n/1024**2)+" MB"}function Hp(n){let e={ok:0,warn:1,red:2},t=null;for(let s of n||[]){if(!s)continue;let i=IU(s);(!t||e[i]>e[t.level]||e[i]===e[t.level]&&s.freeBytes<t.freeBytes)&&(t={...s,level:i})}return t}function Up(n,{machine:e="this Mac"}={}){if(!n||n.level==="ok")return null;let t=$o(n.freeBytes)+" free";return n.level==="red"?"Disk full on "+e+": "+t+" ("+kE(n.pct)+"). Syncing has stopped.":"Low disk on "+e+": "+t+". Syncing stops below 1%."}function Go(n,{platform:e="darwin"}={}){let t=n?$o(n.freeBytes)+" free":null;return{text:"free up disk space"+(t?" (you have "+t+(n.pct!=null?", "+kE(n.pct):"")+")":"")+"; Syncthing resumes on its own",more:[...e==="darwin"?["storage settings: "+yE]:["see what's big: du -sh ~/* | sort -h | tail"],"last resort: lower Syncthing's minHomeDiskFree ("+NU+")"],cmd:e==="darwin"?yE:null}}function SE(n,e={}){let t=e.localErrors||[];if(t.some(i=>/insufficient space/i.test(i.error||"")))return{text:"this Mac's disk is full (see the folder error below); "+n+" reconnects once you free space here"};if(t.length)return{text:"fix the folder error below first; "+n+" reconnects on its own"};let s=e.peerHealth;return s&&s.disk&&s.disk.level&&s.disk.level!=="ok"?{text:n+" is low on disk ("+$o(s.disk.freeBytes)+" free when last heard); free up space there"}:{text:"wake "+n+" (open it, or check it's on and online); if it is, run there: leftoff doctor",more:["if Syncthing isn't running on "+n+": leftoff sync start (on "+n+")"]}}function LU(n){if(/^[\w@%+=:,./~-]+$/.test(n))return n;let e=n.startsWith("~/")?"~/":"";return e+"'"+n.slice(e.length).replace(/'/g,"'\\''")+"'"}function Qu(n,e={}){let t=String(n||"");if(!/^(!|✗)\s/.test(t))return null;let s=t.replace(/^(!|✗)\s+/,""),i=e.platform||"darwin",r=e.syncthing||{},o=r.folder&&r.folder.errors||[],a=i==="darwin"&&(e.syncthingVia==="brew"||r.via==="brew"),l=i==="linux"&&!a&&!!(e.syncthingSystemd||r.service&&r.service.systemd&&r.service.unit),c=a?{text:"brew services restart syncthing",auto:{id:"syncthing-restart",label:"restart Syncthing (brew services restart syncthing)"}}:l?{text:"systemctl --user restart syncthing",auto:{id:"syncthing-restart",label:"restart Syncthing (systemctl --user restart syncthing)"}}:null,u;if(u=s.match(/insufficient space on disk(?: for (?:the )?database)?\s*\(([^)]+)\)/i)){let d=typeof e.disk=="function"?e.disk(u[1]):null;return Go(d,{platform:i})}if(/insufficient space/i.test(s))return Go(null,{platform:i});if(/^(low disk|disk full)\b/i.test(s)){let d=e.lowDisk&&e.lowDisk.freeBytes!=null?e.lowDisk:null;return Go(d,{platform:i})}if(u=s.match(/null\/ folder is committed in (.+): git rm -r null\/$/))return{text:"cd "+LU(u[1])+' && git rm -r null/ && git commit -m "Remove stray null/ folder"'};if(u=s.match(/^worktree (.+?) is still locked by Leftoff/)){let d=(e.parkLocks||[]).find(f=>f.path===u[1]),h=f=>/^[A-Za-z0-9_./~@%+=:,-]+$/.test(f)?f:"'"+String(f).replace(/'/g,"'\\''")+"'";return{text:"git -C "+h(d&&d.root||u[1])+" worktree unlock "+h(u[1])+" (unlocks it; nothing is removed)"}}if(/^daemon on /.test(s))return{text:"leftoff start",more:["or run it in this terminal to see why it stops: leftoff serve"],auto:e.serviceInstalled?{id:"daemon-restart",label:"restart the Leftoff daemon"}:null};if(/^folder /.test(s))return{text:"leftoff setup (it makes the folder and picks up where it left off)"};if(/^token /.test(s))return{text:"leftoff setup (writes a new board token)"};if(u=s.match(/^mod command \/(\S+) failed to register/))return{text:"start a new Claude Code session (commands register at start); if /"+u[1]+" fails again: leftoff upgrade --force"};if(/^mod commands failed to register/.test(s))return{text:"start a new Claude Code session; if it fails again: leftoff upgrade --force"};if(/^update available/.test(s))return{text:"leftoff upgrade"};if(/^settings hooks are from before/.test(s)||/^the login service still has its old name/.test(s)||/^login service is from before/.test(s))return{text:"leftoff upgrade --force"};if(/^digest:/.test(s))return{text:"leftoff digest",auto:{id:"digest",label:"make today's digest now"}};if(/known only by id/.test(s))return{text:"nothing to run: it shows as itself after that session's next prompt, or closes with it"};if(/^API key files inside the folder/.test(s))return{text:"leftoff start (the daemon moves them when it starts)",auto:e.serviceInstalled?{id:"daemon-restart",label:"restart the Leftoff daemon"}:null};if(/^remote access: remoteHosts is set but no tailscale/.test(s))return{text:"install Tailscale from https://tailscale.com/download, or turn remote access off: leftoff tailscale off"};if(/^remote access: /.test(s))return{text:"leftoff tailscale on",auto:{id:"tailscale-on",label:"point tailscale serve at the board again (tailnet only)"}};if(/^Syncthing: installed, not running/.test(s))return{text:a?"leftoff sync start (runs: brew services start syncthing)":l?"systemctl --user enable --now syncthing (or: leftoff sync start)":"leftoff sync start",auto:{id:"syncthing-start",label:l?"start Syncthing (systemctl --user enable --now syncthing)":"start Syncthing"}};if(/^Leftoff folder: .*Leftoff uses another folder/.test(s))return{text:"leftoff sync setup"};if(/^Leftoff folder: /.test(s))return o.some(d=>/insufficient space/i.test(d.error||""))?{text:"Syncthing stopped because the disk is full; see the folder error below"}:o.length?{text:"see the folder error below"}:c||{text:i==="darwin"?"quit and reopen Syncthing":"restart Syncthing (stop it, then: leftoff sync start)",auto:null};if(u=s.match(/^Peer (.+?)(?: \(Leftoff\))?: not connected/)){let d=u[1];return SE(d,{localErrors:o,peerHealth:(e.peers||{})[d]||null})}return(u=s.match(/^Peer (.+?)(?: \(Leftoff\))?: /))&&/not sharing|hasn.t accepted/.test(s)?{text:"on "+u[1]+": Settings → Sync, accept this Mac (or: leftoff sync accept)"}:/^Folder error: /.test(s)?/folder marker missing|\.stfolder/i.test(s)?{text:`the folder's .stfolder marker is gone; if the folder is really there: mkdir "`+(r.folder&&r.folder.path||"<folder>")+'/.stfolder"'}:/folder path missing|no such file/i.test(s)?{text:"the folder moved or was deleted; point Syncthing at it again: leftoff sync setup"}:/permission denied/i.test(s)?{text:i==="darwin"?"give your user access to the folder again (Finder → Get Info → Sharing & Permissions), then restart Syncthing":"give your user access to the folder again (chown/chmod), then restart Syncthing"}:{text:(c?c.text:"restart Syncthing")+"; if the error comes back, open Syncthing's web page for details",auto:c?c.auto:null}:(u=s.match(/^A (?:Mac|machine) named “(.+?)” asked to connect/))?{text:`only if it's your machine: leftoff sync accept "`+u[1]+'"'}:/^Syncthing/.test(s)?c||{text:"leftoff sync start",auto:{id:"syncthing-start",label:"start Syncthing"}}:(u=s.match(/^(.+?) stopped syncing/))?{text:"free up disk space on "+u[1]+"; it catches up on its own"}:(u=s.match(/^(.+?): data as of /))?{text:"wake "+u[1]+" (open it, or check it's online); its sessions update once it syncs"}:/^summarizer: the shared setting is Ollama/.test(s)?{text:"give this machine its own summarizer: Settings → Summarizer → Just this machine, or leftoff models set claude --this-machine"+(/isn.t answering/.test(s)?" (or start Ollama here: ollama serve)":"")}:/^summarizer: this machine.s own setting is Ollama/.test(s)?{text:"install Ollama from https://ollama.com/download, or use the shared setting here again: leftoff models shared"}:/^summarizer: Ollama isn.t answering/.test(s)?{text:i==="darwin"?"ollama serve (or open the Ollama app)":"ollama serve",auto:e.ollamaBinary?{id:"ollama-start",label:"start Ollama"}:null}:/^summarizer: .*Ollama isn.t installed/.test(s)?{text:"install Ollama from https://ollama.com/download, or pick another summarizer: leftoff models"}:/^summarizer: /.test(s)?{text:"leftoff models (pick or test the summarizer)"}:/^PR cards: gh is signed out/.test(s)?{text:"gh auth login"}:/^PR cards: gh /.test(s)?{text:e.brew?"brew install gh && gh auth login (Leftoff won't install it for you)":"install gh from https://cli.github.com, then: gh auth login"}:(u=s.match(/^agent .*?\(([^)]+)\):|^agent (\S+)/))?{text:"check its feed and key: leftoff agents refresh "+(u[1]||u[2]).replace(/:$/,"")+"; to drop it: leftoff agents remove "+(u[1]||u[2]).replace(/:$/,"")}:/^notifications: .*another version/.test(s)?{text:"leftoff notifier rebuild (or restart the daemon: leftoff start)",auto:{id:"notifier-rebuild",label:"rebuild Leftoff.app, what notifications come from"}}:/^notifications: /.test(s)?{text:"leftoff notifier rebuild",auto:{id:"notifier-rebuild",label:"rebuild Leftoff.app, what notifications come from"}}:/^automation from /.test(s)?{text:i==="darwin"?"allow it in System Settings → Privacy & Security → Automation: "+MU:"allow the terminal to be scripted, then run leftoff doctor again"}:/^Go speed from the daemon/.test(s)?{text:"leftoff upgrade --force (refreshes the login service so macOS doesn't throttle it)"}:/^Go speed from this terminal/.test(s)?{text:"make sure Ghostty is running, then run leftoff doctor again"}:{text:"run leftoff doctor again after a minute; if it stays, send this line along with leftoff --version"}}function $s(n){let e=String(n&&n.provider||"auto").toLowerCase();return(jU[e]||e)+(n&&n.model&&e!=="heuristic"?" · "+n.model:"")}function bE({info:n,ollama:e=null}={}){if(!n)return[];let t=n.summarizer||{},s=[];if(n.source==="env"?s.push("· summarizer on this machine: "+$s(t)+" (from CHECKPOINTS_SUMMARIZER, which beats the settings)"):n.source==="machine"?s.push("· summarizer on this machine: "+$s(t)+", this machine's own setting (the shared one is "+$s(n.shared)+")"):s.push("· summarizer on this machine: "+$s(t)+" (the shared setting, used by every machine without its own)"),String(t.provider||"").toLowerCase()!=="ollama"||!e)return s;let i=e.baseUrl||t.baseUrl||"http://localhost:11434";if(e.running)return s.push("✓ summarizer: Ollama answering"+(e.version?" (v"+e.version+")":"")),s;if(n.source==="shared"||n.source==="default")return s.push(e.binary?"! summarizer: the shared setting is Ollama, and it isn't answering at "+i+" on this machine (checkpoints fall back to short summaries)":"! summarizer: the shared setting is Ollama, but Ollama isn't installed on this machine (checkpoints fall back to short summaries)"),s;let r=n.source==="machine"?" (this machine's own setting)":"";return s.push(e.binary?"! summarizer: Ollama isn't answering at "+i+r+" (checkpoints fall back to short summaries)":n.source==="machine"?"! summarizer: this machine's own setting is Ollama, but Ollama isn't installed here":"! summarizer: set to Ollama, but Ollama isn't installed"),s}function vE(n,e,{dim:t=i=>i,seen:s=null}={}){let i=Qu(n,e);return i?s&&s.has(i.text)?{lines:[n,t(" fix: same as above")],fix:i}:(s&&s.add(i.text),{lines:[n,t(" fix: "+i.text),...(i.more||[]).map(r=>t(" "+r))],fix:i}):{lines:[n],fix:null}}function PU(n,e={}){let t=e.leftoff||["leftoff"];if(n==="daemon-restart")return e.serviceCommands||null;let s=(e.platform||"darwin")==="darwin";return n==="syncthing-start"?s&&e.syncthingVia==="brew"&&e.brew?[[e.brew,"services","start","syncthing"]]:s&&e.syncthingVia==="app"&&e.syncthingPath?[["open","-a",e.syncthingPath]]:e.syncthingSystemd?[["systemctl","--user","enable","--now","syncthing"]]:null:n==="syncthing-restart"?s&&e.syncthingVia==="brew"&&e.brew?[[e.brew,"services","restart","syncthing"]]:e.syncthingSystemd?[["systemctl","--user","restart","syncthing"]]:null:n==="digest"?[[...t,"digest"]]:n==="notifier-rebuild"?[[...t,"notifier","rebuild"]]:n==="tailscale-on"?[[...t,"tailscale","on"]]:n==="ollama-start"&&e.ollamaStart?[e.ollamaStart]:null}async function xE(n,{confirm:e,run:t,say:s=()=>{},ctx:i={}}={}){let r=new Set,o=[];for(let a of n||[]){let l=a&&a.auto;if(!l||r.has(l.id))continue;r.add(l.id);let c=PU(l.id,i);if(!c||!c.length)continue;let u=c.map(f=>f.map(p=>/\s/.test(p)?'"'+p+'"':p).join(" ")).join(" && ");if(!await e(l.label.charAt(0).toUpperCase()+l.label.slice(1)+"? ("+u+")")){s("· skipped: "+l.label),o.push({id:l.id,ran:!1});continue}let d=!0,h="";for(let f of c){let p=await t(f);if(!p||p.status!==0){d=!1,h=(p&&(p.stderr||p.stdout)||"").toString().trim().split(`
199
- `).pop()||"exit "+(p&&p.status);break}}s(d?"✓ did: "+l.label:"✗ "+l.label+" failed: "+h),o.push({id:l.id,ran:!0,ok:d,error:d?null:h})}return r.size||s("· nothing doctor can fix by itself here; the fix: lines above say what to do"),o}function AE({me:n,disk:e=null,st:t=null,healths:s=[],now:i=Date.now(),platform:r="darwin"}={}){let o=[],a=(y,w,S,k,v=null)=>o.push({machine:y,level:w,text:S,fix:k||null,...v?{cmd:v}:{}});if(e&&e.level&&e.level!=="ok"){let y=Go(e,{platform:r});a(n,e.level,Up(e,{machine:n}),y.text,y.cmd)}let l=t&&t.folder&&t.folder.errors||[],c=l.find(y=>/insufficient space/i.test(y.error||""));c&&!(e&&e.level==="red")&&a(n,"red","Syncing stopped on "+n+": disk full.",Go(e,{platform:r}).text);for(let y of l)y!==c&&a(n,"red","Sync error on "+n+": "+(y.error||"unknown"),Qu("! Folder error: "+y.error,{syncthing:t}).text);t&&t.installed&&!t.running&&a(n,"warn","Syncthing isn't running on "+n+".","leftoff sync start");let u={},d=t&&t.peers||[],h=new Set;for(let y of s){if(!y||!y.machine||y.machine===n)continue;h.add(y.machine);let w=i-Date.parse(y.at||0),S=d.find(v=>v.name===y.machine),k=y.disk&&y.disk.level;k==="red"||y.syncError&&/insufficient space/i.test(y.syncError)?a(y.machine,"red",y.machine+" stopped syncing: disk full.","free up disk space on "+y.machine+"; it catches up on its own"):k==="warn"&&w>Nk?a(y.machine,"red",y.machine+" stopped syncing: disk probably full ("+$o(y.disk.freeBytes)+" free when last heard).","free up disk space on "+y.machine):k==="warn"?a(y.machine,"warn",Up(y.disk,{machine:y.machine}),"free up disk space on "+y.machine):y.syncError&&a(y.machine,"red","Sync error on "+y.machine+": "+y.syncError,"run leftoff doctor on "+y.machine),w>Nk&&!(S&&S.connected)&&(u[y.machine]=y.at)}for(let y of d)y.connected||y.notSharing||(y.lastSeen?i-Date.parse(y.lastSeen):1/0)<=Nk||(u[y.name]||(u[y.name]=y.lastSeen||null),o.some(S=>S.machine===y.name)||a(y.name,"warn",y.name+" hasn't synced "+(y.lastSeen?"for "+RU(i-Date.parse(y.lastSeen)):"yet")+".",SE(y.name,{localErrors:l,peerHealth:s.find(S=>S&&S.machine===y.name)||null}).text));o.sort((y,w)=>(y.level==="red"?0:1)-(w.level==="red"?0:1));let f=o.some(y=>y.level==="red")?"red":o.length?"warn":"ok",p=o.find(y=>y.level==="red")||o[0],m=f==="ok"?"In sync":p.level==="red"&&/stopped|full/.test(p.text)?p.machine===n?"Sync stopped":p.machine+": sync stopped":p.level==="red"?"Sync error":p.machine===n&&/disk/i.test(p.text)?"Low disk":p.machine!==n?p.machine+" not syncing":"Sync: check";return{level:f,label:m,items:o,stale:u}}function RU(n){let e=Math.max(0,Math.round(n/6e4));if(e<60)return e+" min";let t=Math.round(e/60);return t<48?t+" h":Math.round(t/24)+" days"}function _E({remote:n=!1,machine:e=null,folder:t=null,home:s=null}={}){if(!n)return null;let i=t||null;i&&s&&(i===s||i.startsWith(s+"/"))&&(i="~"+i.slice(s.length));let r="npx -y -p @leftoff/cli leftoff setup"+(i?" --dir "+(/\s/.test(i)?'"'+i+'"':i):"");return{machine:e,dir:i,command:r}}function Oi(n,{fsImpl:e=wE}={}){let t=[],s=[];try{s=e.readdirSync(n)}catch{return t}for(let i of s)if(/^\.health\..+\.json$/.test(i))try{let r=JSON.parse(e.readFileSync(Fp.join(n,i),"utf8"));r&&r.machine&&t.push(r)}catch{}return t}function EE({machine:n,disk:e=null,st:t=null,now:s=Date.now()}={}){let i=t&&t.folder&&t.folder.errors||[];return{machine:n,at:new Date(s).toISOString(),disk:e?{level:e.level,freeBytes:e.freeBytes,totalBytes:e.totalBytes,pct:e.pct,what:e.what||null}:null,syncError:i.length?String(i[0].error||"").replace(/\([^)]*\/[^)]*\)/g,"").replace(/\s+/g," ").trim().slice(0,200):null}}function CE(n,e={}){let t={...e,syncthing:n},s=(n&&n.folder&&n.folder.errors||[]).map(r=>{let o=Qu("! Folder error: "+r.error,t);return o?[o.text,...o.more||[]].join(" · "):null}),i={};for(let r of n&&n.peers||[])if(!r.connected&&!r.notSharing){let o=Qu("! Peer "+r.name+": not connected",t);o&&(i[r.name]=o.text)}return{errors:s,peers:i,notRunning:n&&n.installed&&!n.running?Qu("! Syncthing: installed, not running",t).text:null}}var Zu,EU,CU,OU,yE,MU,NU,Nk,kE,jU,TE,ed=K(()=>{Zu=1024**3,EU=1,CU=5,OU=5*Zu,yE='open "x-apple.systempreferences:com.apple.settings.Storage"',MU='open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"',NU="https://docs.syncthing.net/users/config.html#config-option-options.minhomediskfree",Nk=900*1e3;kE=n=>(n<10?Math.round(n*100)/100:Math.round(n))+"%";jU={auto:"auto",claude:"Claude Code",anthropic:"Anthropic API",ollama:"Ollama","ollama-cloud":"Ollama cloud","openai-compatible":"OpenAI-compatible server",heuristic:"no model (heuristic)"};TE=(n,e)=>Fp.join(n,".health."+String(e).replace(/[^\w.-]/g,"_")+".json")});import{execFile as DU}from"node:child_process";import FU from"node:fs";import td from"node:path";function OE(n,{timeoutMs:e=5e3}={}){return new Promise(t=>{let[s,...i]=n;try{DU(s,i,{timeout:e},(r,o,a)=>t({code:r?typeof r.code=="number"?r.code:1:0,stdout:String(o||""),stderr:String(a||"")||(r?String(r.message||r):"")}))}catch(r){t({code:1,stdout:"",stderr:String(r&&r.message||r)})}})}function ME(n,{machine:e=null,fsImpl:t=FU}={}){let s=new Set;for(let o of n||[]){if(!o||e&&o.machine&&o.machine!==e)continue;o.repo&&typeof o.repo.root=="string"&&o.repo.root&&s.add(o.repo.root);let a=o.parked&&o.parked.worktreeLock;a&&typeof a.root=="string"&&a.root&&s.add(a.root)}let i=[],r=new Set;for(let o of s){let a=td.join(o,".git","worktrees"),l=[];try{l=t.readdirSync(a)}catch{continue}for(let c of l){let u;try{u=String(t.readFileSync(td.join(a,c,"locked"),"utf8")).replace(/\n$/,"")}catch{continue}let d=c0(u);if(!d)continue;let h=null;try{h=td.dirname(String(t.readFileSync(td.join(a,c,"gitdir"),"utf8")).trim())}catch{}let f=h||td.join(a,c);if(r.has(f))continue;r.add(f);let p=(n||[]).find(m=>m&&m.id===d)||null;i.push({path:f,root:o,sessionId:d,title:p&&p.title||null,parked:!!(p&&p.parked)})}}return i}function NE(n){return(n||[]).filter(e=>!e.parked).map(e=>"! worktree "+e.path+" is still locked by Leftoff, but "+(e.title?"“"+e.title+"”":"its session")+" isn’t parked any more")}var Ik=K(()=>{Te()});import Cr from"node:fs";import UU from"node:os";import Lk from"node:path";import{execFile as HU}from"node:child_process";function GU(n=process.env){return n.CLAUDE_CONFIG_DIR||Lk.join(n.HOME||UU.homedir(),".claude")}function Or(n,{env:e=process.env,dirs:t}={}){if(!n||!zU.test(n))return null;let s=t||[Lk.join(GU(e),"projects")],i=null;for(let r of s){let o=[];try{o=Cr.readdirSync(r,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name)}catch{continue}for(let a of o){let l=Lk.join(r,a,n+".jsonl");try{let c=Cr.statSync(l);(!i||c.mtimeMs>i.mtimeMs)&&(i={file:l,mtimeMs:c.mtimeMs,size:c.size})}catch{}}}return i?i.file:null}function zp(n,{maxBytes:e=BU}={}){try{let t=Cr.statSync(n).size,s;if(t>e){let a=Cr.openSync(n,"r"),l=Buffer.alloc(256*1024),c=Cr.readSync(a,l,0,l.length,0);Cr.closeSync(a),s=l.subarray(0,c).toString("utf8");let{meta:u}=fl(s);return{cwd:u.cwd||null,prompts:1,customTitle:u.customTitle||null,gitBranch:u.gitBranch||null,truncated:!0}}s=Cr.readFileSync(n,"utf8");let{messages:i,meta:r}=fl(s),o=i.filter(a=>a.role==="user"&&a.text&&a.text.trim()).length;return{cwd:r.cwd||null,prompts:o,customTitle:r.customTitle||null,gitBranch:r.gitBranch||null,...r.model?{model:r.model}:{}}}catch{return null}}function LE(n,e,t=5e3){return new Promise(s=>{HU(n,e,{env:{...process.env,LC_ALL:"C"},timeout:t,maxBuffer:8*1024*1024},(i,r)=>s(i&&!r?"":String(r||"")))})}function $U(n){let e=[];for(let t of String(n||"").split(`
200
- `)){let s=t.match(/^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)$/);s&&e.push({pid:Number(s[1]),ppid:Number(s[2]),tty:s[3],etime:s[4],args:s[5].trim()})}return e}function KU(n){let e=new Map;for(let t of String(n||"").split(`
201
- `)){let s=t.match(/^\s*(\d+)\s+(.*)$/);s&&e.set(Number(s[1]),s[2].trim())}return e}function jE(n,e){let t=Bp(e||"").toLowerCase(),s=Bp(String(n.args||"").split(/\s+/)[0]).toLowerCase();if(/^claude(\s|$)/.test(t)||s==="claude")return!0;let i=String(n.args||"").split(/\s+/);return/^(node|bun)$/.test(s)&&(Bp(i[1])==="claude"||/@anthropic-ai\/claude-code\/cli\.m?js$/.test(i[1]||""))}function WU(n,e,t=new Map){let s=String(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp("(?:^|\\s)(?:--resume|-r|--session-id)(?:=|\\s+)"+s+"(?=\\s|$)"),r=e.filter(l=>i.test(l.args)&&jE(l,t.get(l.pid))),o=new Set(r.map(l=>l.pid)),a=r.filter(l=>!r.some(c=>c.ppid===l.pid&&o.has(c.pid)));return a.length===1?a[0]:null}async function IE(n,{platform:e=process.platform,runner:t=LE}={}){let s=new Map,i=n.filter(a=>Number.isInteger(a)&&a>1);if(!i.length)return s;if(e==="linux"){for(let a of i)try{s.set(a,Cr.readlinkSync("/proc/"+a+"/cwd"))}catch{}return s}let r=await t("lsof",["-a","-d","cwd","-p",i.join(","),"-Fpn"]),o=null;for(let a of r.split(`
202
- `))a.startsWith("p")?o=Number(a.slice(1)):a.startsWith("n")&&o&&s.set(o,a.slice(1));return s}function qU(n,e,t=new Map){let s=new Map(e.map(r=>[r.pid,r])),i=s.get(n);for(let r=0;i&&r<12;r++){let o=Bp(t.get(i.pid)||String(i.args).split(/\s+/)[0]);for(let[a,l]of YU)if(a.test(o))return{...hr(l==="kitty"?{TERM:"xterm-kitty"}:{TERM_PROGRAM:l}),source:"ps"};if(/^tmux/i.test(o))return null;i=s.get(i.ppid)}return null}async function PE(n,{cwd:e=null,claimedPids:t=new Set,env:s=process.env,platform:i=process.platform,runner:r=LE,now:o=Date.now(),transcriptDirs:a}={}){let l={via:[]},c=Or(n,{env:s,dirs:a});if(c){l.transcriptPath=c;let p=zp(c);p&&(p.cwd&&(l.cwd=p.cwd),l.prompts=p.prompts,p.customTitle&&(l.customTitle=p.customTitle),l.via.push("transcript"))}let u=e||l.cwd||null,d=$U(await r("ps",["-axo","pid=,ppid=,tty=,etime=,command="]));if(!d.length)return l;let h=KU(await r("ps",["-axo","pid=,comm="])),f=WU(n,d,h);if(f)l.via.push("ps-args");else if(u){let p=d.filter(S=>jE(S,h.get(S.pid))&&!t.has(S.pid)),m=p.filter(S=>!p.some(k=>k.ppid===S.pid)),y=await IE(m.map(S=>S.pid),{platform:i,runner:r}),w=m.filter(S=>y.get(S.pid)===u);w.length===1&&(f=w[0],l.via.push("ps-cwd"))}if(f){let p=Eo(f.etime);l.proc={pid:f.pid,tty:o0(f.tty),pidStartedAt:p==null?null:Z(o-p*1e3),source:"daemon"};let m=qU(f.pid,d,h);if(m&&(l.term=m,l.via.push("ps-term")),!l.cwd&&!e){let y=(await IE([f.pid],{platform:i,runner:r})).get(f.pid);y&&(l.cwd=y)}}return l}var BU,zU,Bp,YU,Gp=K(()=>{Uo();Te();BU=32*1024*1024,zU=/^[0-9A-Za-z][0-9A-Za-z_-]{6,80}$/;Bp=n=>String(n||"").split("/").pop();YU=[[/^ghostty$/i,"ghostty"],[/^iterm2?$/i,"iTerm.app"],[/^terminal$/i,"Apple_Terminal"],[/^wezterm(-gui)?$/i,"WezTerm"],[/^kitty$/i,"kitty"]]});import Nr from"node:fs";import Mr from"node:path";import JU from"node:crypto";function id(n){let e=VU[n]||n;if(!sd.includes(e))throw Object.assign(new Error("kind is machine, repo, session or agent"),{code:"bad_kind"});return e}function Ko(n){return DE.test(String(n))}function bl(n){return String(n).replace(DE,"")}function rd(n){let e=String(n??"").normalize("NFC").replace(/\s+/g," ").trim();if(!e)throw Object.assign(new Error("a space needs a name"),{code:"bad_space"});if(e.length>32)throw Object.assign(new Error("a space name is at most 32 characters"),{code:"bad_space"});if(!/^[\p{L}\p{N}][\p{L}\p{N} ._&'-]*$/u.test(e))throw Object.assign(new Error("a space name is letters, numbers, spaces and . _ & ' -"),{code:"bad_space"});return e}function FE(n,e){let t=String(e??"").trim();if(!t||t.length>400||/[\u0000-\u001F]/.test(t))throw Object.assign(new Error("bad "+n.replace(/s$/,"")+" key"),{code:"bad_key"});return t}function Wo(){return{schema:1,machines:{},repos:{},sessions:{},agents:{}}}function XU(n){if(n==null)return null;if(typeof n=="string")return{space:n,at:"1970-01-01T00:00:00.000Z",by:""};if(typeof n!="object")return null;let e=n.space==null?null:String(n.space),t=typeof n.at=="string"&&!Number.isNaN(Date.parse(n.at))?n.at:"1970-01-01T00:00:00.000Z";return{space:e,at:t,by:typeof n.by=="string"?n.by:""}}function UE(n){let e=Wo();if(!n||typeof n!="object")return e;for(let t of sd){let s=n[t];if(!(!s||typeof s!="object"))for(let[i,r]of Object.entries(s)){let o=XU(r);o&&(e[t][i]=o)}}return e}function ZU(n,e){if(!n)return e;if(!e)return n;let t=Date.parse(n.at),s=Date.parse(e.at);return t!==s?t>s?n:e:n.by!==e.by?n.by>e.by?n:e:n.space==null!=(e.space==null)?n.space==null?e:n:String(n.space)>=String(e.space)?n:e}function QU(...n){let e=Wo();for(let t of n){let s=UE(t);for(let i of sd)for(let[r,o]of Object.entries(s[i]))e[i][r]=ZU(e[i][r],o)}return e}function Yo(n){let e=[],t=[];try{t=Nr.readdirSync(n)}catch{}for(let r of t)(r===nd||r.startsWith("spaces.")&&r.endsWith(".json")&&Ko(r)&&bl(r)===nd)&&e.push(r);let s=[],i=[];for(let r of e.sort())try{s.push(JSON.parse(Nr.readFileSync(Mr.join(n,r),"utf8"))),r!==nd&&i.push(r)}catch{}return{map:QU(...s),conflicts:i}}function vl(n,e){Nr.mkdirSync(Mr.dirname(n),{recursive:!0});let t=Mr.join(Mr.dirname(n),".syncthing."+Mr.basename(n)+"."+process.pid+"."+JU.randomBytes(4).toString("hex")+".tmp");Nr.writeFileSync(t,e),Nr.renameSync(t,n)}function e3(n,e,{removeConflicts:t=[]}={}){let s=UE(e),i={schema:1};for(let r of sd)i[r]=Object.fromEntries(Object.entries(s[r]).sort(([o],[a])=>o.localeCompare(a)));vl(Mr.join(n,nd),JSON.stringify(i,null,2)+`
203
- `);for(let r of t)try{Nr.unlinkSync(Mr.join(n,r))}catch{}}function jk(n,e,{machine:t="",now:s=Date.now()}={}){let{map:i,conflicts:r}=Yo(n),o={at:new Date(s).toISOString(),by:t},a=e(i,o);return e3(n,i,{removeConflicts:r}),a===void 0?i:a}function ds(n,e){let t={};for(let[s,i]of Object.entries(n&&n[e]||{}))i&&i.space!=null&&(t[s]=i.space);return t}function Ks(n,e=[]){let t=new Set;for(let s of sd)for(let i of Object.values(ds(n,s)))t.add(i);for(let s of e)t.add(Ir(n,s));return xl([...t])}function xl(n){return[...new Set(n.filter(Boolean))].sort((e,t)=>e==="Work"?-1:t==="Work"?1:e.localeCompare(t,"en",{sensitivity:"base"})||e.localeCompare(t))}function Ir(n,e){let t=n&&n.machines&&n.machines[e];return t&&t.space!=null?t.space:e||"Unsorted"}function n3(n,{repoKey:e,repoName:t,repoLabel:s}={}){let i=ds(n,"repos");if(e&&i[e]!=null)return{key:e,space:i[e]};let r=[s,t,t3(e)].filter(Boolean).map(RE);for(let o of r)for(let[a,l]of Object.entries(i))if(RE(a)===o)return{key:a,space:l};return null}function Lr(n,e,{repoKey:t,repoName:s,repoLabel:i,machine:r}={}){let o=ds(n,"sessions");if(e&&e.id&&o[e.id]!=null)return{space:o[e.id],source:"session",key:e.id};let a=e&&(e.agent&&e.agent.name||(typeof e.id=="string"&&e.id.startsWith("agent:")?e.id.split(":")[1]:null));if(a){let d=ds(n,"agents");if(d[a]!=null)return{space:d[a],source:"agent",key:a}}let l=!a&&n3(n,{repoKey:t||e&&(e.repoKey||e.repo&&e.repo.root||e.cwd),repoName:s||e&&(e.repoName||e.repo&&e.repo.name),repoLabel:i||e&&e.repoLabel});if(l)return{space:l.space,source:"repo",key:l.key};let c=r||(e&&a?e.agent&&e.agent.puller:e&&e.machine)||"",u=n&&n.machines&&n.machines[c];return u&&u.space!=null?{space:u.space,source:"machine",key:c}:{space:c||"Unsorted",source:"default",key:c}}function HE(n,{home:e=""}={}){let t=[e,"/root"].filter(Boolean).map(o=>o.replace(/\/+$/,"")),s=o=>t.includes(o)||/^\/(Users|home)\/[^/]+$/.test(o)||/^[A-Za-z]:\\Users\\[^\\]+$/.test(o),i=o=>{for(let l of t)if(l&&(o===l||o.startsWith(l+"/")))return"~"+o.slice(l.length);let a=/^\/(Users|home)\/[^/]+(?=\/|$)/.exec(o);return a?"~"+o.slice(a[0].length):o},r=new Map;for(let o of n||[]){let a=String(o&&o.key||"").trim().replace(/\/+$/,"")||(o&&o.key?"/":""),l=String(o&&o.name||"").trim();if(!l||["/",".","..","~","no-repo"].includes(l)||/^[\\/]+$/.test(l)||!a||a==="/"||a==="~"||s(a))continue;let c=Date.parse(o&&o.at||"")||0,u=l.toLowerCase(),d=r.get(u);if(d&&d.t>=c)continue;let h=a.includes("/")?i(a.slice(0,a.lastIndexOf("/"))||"/"):"";r.set(u,{name:l,parent:h,lastAt:c?new Date(c).toISOString():null,t:c})}return[...r.values()].sort((o,a)=>a.t-o.t||o.name.localeCompare(a.name)).map(({t:o,...a})=>a)}var nd,Sl,sd,VU,DE,RE,t3,$p,jr=K(()=>{nd="spaces.json",Sl=["Work","Personal"],sd=["machines","repos","sessions","agents"],VU={machine:"machines",repo:"repos",session:"sessions",agent:"agents"};DE=/\.sync-conflict-(\d{8})-(\d{6})-([A-Za-z0-9]{1,16})(?=\.[^.]+$|$)/;RE=n=>String(n||"").toLowerCase(),t3=n=>{let e=String(n||"").split(/[\\/]+/).filter(Boolean);return e.length?e[e.length-1]:""};$p=class{constructor(e,t,{now:s=()=>Date.now()}={}){this.root=e,this.machine=t,this.now=s,this.cache=null,this.checkedAt=0}sig(){let e=[];try{e=Nr.readdirSync(this.root).filter(t=>t===nd||t.startsWith("spaces.")&&Ko(t))}catch{}return e.sort().map(t=>{try{let s=Nr.statSync(Mr.join(this.root,t));return t+":"+s.mtimeMs+":"+s.size}catch{return t}}).join("|")}map({fresh:e=!1}={}){let t=Date.now();if(!e&&this.cache&&t-this.checkedAt<2e3)return this.cache.map;let s=this.sig();if(this.checkedAt=t,!e&&this.cache&&this.cache.sig===s)return this.cache.map;let{map:i,conflicts:r}=Yo(this.root);return this.cache={sig:s,map:i,conflicts:r},i}update(e){let t=jk(this.root,e,{machine:this.machine,now:this.now()});return this.cache=null,t}resolve(e,t){return Lr(this.map(),e,t)}machineSpace(e=this.machine){return Ir(this.map(),e)}}});import Se from"node:fs";import ge from"node:path";import Pk from"node:crypto";function Jt(n,e){Se.mkdirSync(ge.dirname(n),{recursive:!0});let t=ge.join(ge.dirname(n),"."+ge.basename(n)+"."+process.pid+"."+Pk.randomBytes(4).toString("hex")+".tmp");Se.writeFileSync(t,e),Se.renameSync(t,n)}function Mi(n){try{return Se.readdirSync(n,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name)}catch{return[]}}function BE(n){return Se.existsSync(ge.join(n,"session.md"))||Se.existsSync(ge.join(n,"checkpoints"))}function zE(n,e,t,s){let i=ge.join(qe(n).spool,e,String(t||"unknown").replace(/[^A-Za-z0-9_-]/g,"_"));Se.mkdirSync(i,{recursive:!0});let r=ge.join(i,Date.now()+"-"+Pk.randomBytes(4).toString("hex")+".json");return Se.writeFileSync(r,JSON.stringify(s)+`
193
+ `+s,e.firstPrompt);if(t)return{title:t,titleSource:"generated"}}catch{}return{title:y0(e),titleSource:"fallback"}}async titleInUserLanguage(e,t,s){for(let i of[!1,!0]){let r=await this.complete({system:e,prompt:t(a_(s,{firm:i})),maxTokens:30}),o=t_(r.text);if(!o)return null;if(n_(o,s))return o}return null}async recentTitle(e,t={}){let s=u3(e),i=(e||[]).find(a=>!oE(a)&&a.role==="user"),r=t.firstPrompt||i&&i.text||"";if(this.mode!=="heuristic"&&s.length)try{let a=s.filter(u=>u.role==="user").map(u=>u.text).join(`
194
+ `),l=d3(s,{firstPrompt:r}),c=await this.titleInUserLanguage(l3,u=>l+`
195
+
196
+ `+u,a||r);if(c)return{title:c,titleSource:"generated",by:this.mode}}catch{}let o=h3(s);return{title:y0({...t,firstPrompt:o||!aE(t.lastPrompt)&&t.lastPrompt||t.firstPrompt||t.lastPrompt||""}),titleSource:"fallback",by:"heuristic"}}async paragraph(e,t){if(this.mode==="heuristic")return null;try{return(await this.complete({system:e,prompt:t,maxTokens:200})).text.trim()}catch{return null}}}});import pl from"node:fs";import f3 from"node:os";import Mp from"node:path";import{execFileSync as VJ,spawn as p3,spawnSync as m3}from"node:child_process";import{fileURLToPath as g3}from"node:url";async function Vu({baseUrl:n=process.env.CHECKPOINTS_CLOUD_URL||Bo,fetchImpl:e=fetch,timeoutMs:t=5e3}={}){let s=n.replace(/\/$/,"");try{let i=await Ip(e,s+"/api/tags",t);return{ok:!0,baseUrl:s,models:(i.models||[]).map(r=>r.name||r.model).filter(Boolean),error:null}}catch(i){return{ok:!1,baseUrl:s,models:[],error:i.cause&&i.cause.code||i.message}}}function Lp(n=[],{curated:e=Ju,current:t=null}={}){let s=r=>n.some(o=>Ct(o,r)),i=e.map(r=>({...r,curated:!0,available:n.length?s(r.tag):null,current:!!t&&Ct(t,r.tag)}));for(let r of n)i.some(o=>Ct(o.tag,r))||i.push({tag:r,name:r,curated:!1,available:!0,recommended:!1,current:!!t&&Ct(t,r)});return i}function Np(n){let e=String(n||"").trim().toLowerCase();return e?e.includes(":")?e:e+":latest":""}function Ct(n,e){return Np(n)===Np(e)}function gl(n=[],{curated:e=qu,current:t=null}={}){let s=n.map(o=>typeof o=="string"?{name:o}:o),i=o=>s.some(a=>Ct(a.name||a.model,o)),r=e.map(o=>({...o,curated:!0,installed:i(o.tag),current:!!t&&Ct(t,o.tag)}));for(let o of s){let a=o.name||o.model;!a||r.some(l=>Ct(l.tag,a))||/embed/i.test(a)||r.push({tag:a,name:a,sizeBytes:o.size||null,curated:!1,installed:!0,recommended:!1,current:!!t&&Ct(t,a)})}return r}function cE(n,{totalMemBytes:e=f3.totalmem()}={}){let t=n.find(r=>r.current&&r.installed);if(t)return t.tag;let s=n.find(r=>r.recommended);if(s&&s.installed)return s.tag;let i=n.find(r=>r.curated&&r.installed);if(i)return i.tag;if(e&&e<85e8){let r=n.filter(o=>o.curated).sort((o,a)=>o.ramGB-a.ramGB)[0];if(r)return r.tag}return s?s.tag:n[0]&&n[0].tag}function jp(n,e){let t=[];return n.sizeBytes&&t.push(e(n.sizeBytes)),n.ramGB&&t.push("~"+n.ramGB+" GB RAM"),n.speed&&t.push(n.speed),t.join(" · ")}function vr(n,e=process.env){let t=String(e.PATH||"").split(Mp.delimiter).filter(Boolean),s=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let i of t)for(let r of s){let o=Mp.join(i,n+r);try{if(pl.statSync(o).isFile())return pl.accessSync(o,pl.constants.X_OK),o}catch{}}return null}function Ai(n=process.env){let e=vr("ollama",n);if(e)return e;if(n.CHECKPOINTS_TEST_NO_SYSTEM_BINS)return null;for(let t of["/opt/homebrew/bin/ollama","/usr/local/bin/ollama","/Applications/Ollama.app/Contents/Resources/ollama"])if(pl.existsSync(t))return t;return null}async function Ip(n,e,t=1500){let s=await n(e,{signal:AbortSignal.timeout(t)});if(!s.ok)throw new Error(e+" -> HTTP "+s.status);return s.json()}async function jt({baseUrl:n=Pt,fetchImpl:e=fetch,env:t=process.env}={}){let s=n.replace(/\/$/,""),i={kind:"ollama",running:!1,baseUrl:s,version:null,models:[],binary:Ai(t),error:null};try{let r=await Ip(e,s+"/api/tags");i.running=!0,i.models=(r.models||[]).map(o=>({name:o.name||o.model,size:o.size,modifiedAt:o.modified_at,parameterSize:o.details&&o.details.parameter_size,quantization:o.details&&o.details.quantization_level}));try{i.version=(await Ip(e,s+"/api/version")).version||null}catch{}}catch(r){i.error=r.cause&&r.cause.code||r.name||r.message}return i}async function _i({baseUrl:n=zs,fetchImpl:e=fetch}={}){let t=n.replace(/\/$/,""),s={kind:"openai-compatible",running:!1,baseUrl:t,models:[],error:null};try{let i=await Ip(e,t+"/models");s.running=!0,s.models=(i.data||[]).map(r=>r.id).filter(r=>r&&!/embed/i.test(r))}catch(i){s.error=i.cause&&i.cause.code||i.name||i.message}return s}async function yl({baseUrl:n=Pt,fetchImpl:e=fetch,timeoutMs:t=2e4}={}){let s=Date.now()+t;for(;Date.now()<s;){let i=await jt({baseUrl:n,fetchImpl:e});if(i.running)return i;await w3(500)}return jt({baseUrl:n,fetchImpl:e})}function k3(n,e){let t=n||{layers:{},status:"",total:0,completed:0,fraction:0,done:!1,error:null};if(e.error)return{...t,error:String(e.error)};let s={...t.layers};e.digest&&e.total&&(s[e.digest]={total:e.total,completed:Math.min(e.completed||0,e.total)});let i=Object.values(s),r=i.reduce((c,u)=>c+u.total,0),o=i.reduce((c,u)=>c+u.completed,0),a=e.status==="success",l=a?1:r?Math.min(.999,o/r):t.fraction;return{layers:s,status:e.status||t.status,total:r,completed:o,fraction:Math.max(t.fraction,l),done:a,error:null}}async function wl({tag:n,baseUrl:e=Pt,fetchImpl:t=fetch,onProgress:s=()=>{},signal:i}={}){let r=await t(e.replace(/\/$/,"")+"/api/pull",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({model:n,stream:!0}),signal:i});if(!r.ok||!r.body){let u="HTTP "+r.status;try{let d=await r.json();d.error&&(u=d.error)}catch{}throw new Error("pull "+n+" failed: "+u)}let o=null,a="",l=new TextDecoder,c=u=>{if(!u.trim())return;let d;try{d=JSON.parse(u)}catch{return}if(o=k3(o,d),o.error)throw new Error("pull "+n+" failed: "+o.error);s(o)};for await(let u of r.body){a+=l.decode(u,{stream:!0});let d;for(;(d=a.indexOf(`
197
+ `))>=0;)c(a.slice(0,d)),a=a.slice(d+1)}if(c(a),!o||!o.done)throw new Error("pull "+n+" ended early (last status: "+(o&&o.status||"none")+")");return o}async function Ti(n,{fetchImpl:e,transcriptFile:t=y3,root:s}={}){let i=eu(Be,{summarizer:n}),{messages:r,meta:o}=fl(pl.readFileSync(t,"utf8")),a={id:o.sessionId||"sample",cwd:o.cwd||"/work/acme",title:o.summary||"Sample session",repo:{root:o.cwd,branch:o.gitBranch}},l=Cf({session:a,messages:r,cfg:i}),c=new Lt(i,{...e?{fetchImpl:e}:{},...s?{root:s}:{}}),u=Date.now(),d=await c.checkpoint({...l,messages:r,session:a}),h=Date.now()-u,f=d.generator&&d.generator.by==="heuristic"&&d.generator.fallbackFrom;return{ok:!f,doing:d.doing,stoppedAt:d.stoppedAt,next:d.next,parseOk:d.parseOk!==!1,ms:h,generator:d.generator,error:f?d.generator.error:null}}function uE(n=process.platform,e=process.env){let t={id:"script",label:"Official install script",shell:"curl -fsSL https://ollama.com/install.sh | sh",cmd:["sh","-c","curl -fsSL https://ollama.com/install.sh | sh"]};if(n==="darwin"){let s=[];return vr("brew",e)&&s.push({id:"brew",label:"Homebrew",shell:"brew install ollama",cmd:["brew","install","ollama"]}),s.push({...t,note:"installs the Ollama app"}),s.push({id:"manual",label:"Download the app myself",shell:"open https://ollama.com/download",cmd:null,url:"https://ollama.com/download"}),s}return n==="linux"?[{...t,note:"asks for sudo; sets up a systemd service"},{id:"manual",label:"Install it myself",shell:"see https://ollama.com/download/linux",cmd:null,url:"https://ollama.com/download/linux"}]:n==="win32"?[{id:"manual",label:"PowerShell installer",shell:"irm https://ollama.com/install.ps1 | iex",cmd:null,url:"https://ollama.com/download/windows"}]:[{id:"manual",label:"Install it myself",shell:"see https://ollama.com/download",cmd:null,url:"https://ollama.com/download"}]}function zo(n=process.platform,e=Ai()){return n==="darwin"&&pl.existsSync("/Applications/Ollama.app")?{shell:"open -a Ollama",cmd:["open","-a","Ollama"],detached:!1}:e?{shell:e+" serve",cmd:[e,"serve"],detached:!0}:null}function Pp({platform:n=process.platform,binary:e,env:t=process.env}={}){if(t.CHECKPOINTS_OLLAMA_START_CMD)try{let s=JSON.parse(t.CHECKPOINTS_OLLAMA_START_CMD);if(Array.isArray(s)&&s.length)return{shell:s.join(" "),cmd:s,detached:!0}}catch{}return e?zo(n,e):null}function dE(n,{spawnImpl:e=p3,spawnSyncImpl:t=m3}={}){if(!n||!Array.isArray(n.cmd))return{started:!1,shell:null,error:"no start command"};try{if(n.detached){let s=e(n.cmd[0],n.cmd.slice(1),{detached:!0,stdio:"ignore"});s.on("error",()=>{}),s.unref()}else{let s=t(n.cmd[0],n.cmd.slice(1),{stdio:"ignore",timeout:15e3});if(s&&s.status)return{started:!1,shell:n.shell,error:n.shell+" exited "+s.status}}return{started:!0,shell:n.shell}}catch(s){return{started:!1,shell:n.shell,error:String(s.message||s)}}}var Pt,zs,y3,ml,qu,Bo,lE,Ju,w3,Bs=K(()=>{Uo();Te();Ho();Pt="http://localhost:11434",zs="http://localhost:1234/v1",y3=Mp.resolve(Mp.dirname(g3(import.meta.url)),"..","assets","sample-transcript.jsonl"),ml="2026-10-09",qu=[{tag:"qwen2.5:3b",name:"Qwen 2.5 · 3B",sizeBytes:19e8,ramGB:4,speed:"fast",note:"Sticks to the 3-line format, good with code and file names",recommended:!0},{tag:"llama3.2:3b",name:"Llama 3.2 · 3B",sizeBytes:2e9,ramGB:4,speed:"fast",note:"Solid all-rounder from Meta"},{tag:"gemma3:4b",name:"Gemma 3 · 4B",sizeBytes:34e8,ramGB:6,speed:"medium",note:"Best-written summaries of the four, slower without a GPU"},{tag:"llama3.2:1b",name:"Llama 3.2 · 1B",sizeBytes:13e8,ramGB:2.5,speed:"fastest",note:'For 8 GB machines; terser, sometimes vague on "Next"'}],Bo="https://ollama.com",lE="2026-10-09",Ju=[{tag:"gpt-oss:20b",name:"gpt-oss · 20B",note:"OpenAI's open-weight model; quick, plenty for 3 lines",recommended:!0},{tag:"gemma4:31b",name:"Gemma 4 · 31B",note:"Google; the model Ollama's own cloud docs use"},{tag:"nemotron-3-nano:30b",name:"Nemotron 3 Nano · 30B",note:"NVIDIA; small and fast"},{tag:"gpt-oss:120b",name:"gpt-oss · 120B",note:"Bigger and slower; more than a checkpoint needs"}];w3=n=>new Promise(e=>setTimeout(e,n))});import Rt from"node:fs";import _k from"node:os";import ze from"node:path";import{spawnSync as S3}from"node:child_process";import{fileURLToPath as b3}from"node:url";function x3(n=process.env,e=_k.homedir(),t=process.execPath){let s=[ze.join(e,".local","bin","claude"),ze.join(e,".claude","local","claude"),"/opt/homebrew/bin/claude","/usr/local/bin/claude",ze.join(e,".npm-global","bin","claude"),ze.join(e,".bun","bin","claude"),ze.join(e,".volta","bin","claude"),ze.join(ze.dirname(t),"claude")];if(n.NVM_DIR||e){let i=ze.join(n.NVM_DIR||ze.join(e,".nvm"),"versions","node");try{let r=Rt.readdirSync(i).filter(o=>/^v\d/.test(o)).sort((o,a)=>fE(a.slice(1),o.slice(1)));for(let o of r)s.push(ze.join(i,o,"bin","claude"))}catch{}}return s}function Tn(n=process.env,{home:e=_k.homedir(),execPath:t=process.execPath}={}){if(n.CHECKPOINTS_CLAUDE_BIN)return n.CHECKPOINTS_CLAUDE_BIN;let s=vr("claude",n);if(s)return s;if(n.CHECKPOINTS_TEST_NO_SYSTEM_BINS&&!n.LEFTOFF_TEST_CLAUDE_HOME)return null;for(let i of x3(n,n.LEFTOFF_TEST_CLAUDE_HOME||e,t))try{if(Rt.statSync(i).isFile())return Rt.accessSync(i,Rt.constants.X_OK),i}catch{}return null}function Ei(n,e,{env:t=process.env,timeoutMs:s=12e4}={}){let i=S3(n,e,{env:{...t,CHECKPOINTS_INTERNAL:"1",LEFTOFF_INTERNAL:"1"},encoding:"utf8",timeout:s});return{code:i.status==null?-1:i.status,stdout:i.stdout||"",stderr:i.stderr||(i.error?String(i.error.message):""),args:e}}function A3(n){let e=String(n||"").match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}function fE(n,e){let t=String(n).split(".").map(Number),s=String(e).split(".").map(Number);for(let i=0;i<3;i++){let r=(t[i]||0)-(s[i]||0);if(r)return r>0?1:-1}return 0}function pE(n=process.env){let e=Tn(n);if(!e)return{found:!1,bin:null,version:null,modsSupported:!1};let t=Ei(e,["--version"],{env:n,timeoutMs:15e3}),s=A3(t.stdout+" "+t.stderr);return{found:!0,bin:e,version:s,modsSupported:!!s&&fE(s,Xu)>=0}}function Tk(n){return/[\\/]_npx[\\/]/.test(n)||/[\\/]\.npm[\\/]/.test(n)}function Ek(n=kl){try{return JSON.parse(Rt.readFileSync(ze.join(n,"package.json"),"utf8")).leftoffBuild==="npm"}catch{return!1}}function _3(n=process.env){return n.LEFTOFF_PLUGIN_DIR?n.LEFTOFF_PLUGIN_DIR:ze.join(n.XDG_CONFIG_HOME||ze.join(n.HOME||_k.homedir(),".config"),"checkpoints","plugin")}function Ck({from:n=kl,env:e=process.env}={}){let t=_3(e);if(!Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json")))throw new Error("no .claude-plugin/marketplace.json in "+n);let s=t+"."+process.pid+".tmp";Rt.rmSync(s,{recursive:!0,force:!0}),Rt.mkdirSync(ze.join(s,".claude-plugin"),{recursive:!0}),Rt.copyFileSync(ze.join(n,".claude-plugin","marketplace.json"),ze.join(s,".claude-plugin","marketplace.json"));let i=r=>/^(tests|tsconfig\.json)$/.test(r)||/(^|[\\/])types([\\/]|$)/.test(r);return Rt.cpSync(ze.join(n,"mod"),ze.join(s,"mod"),{recursive:!0,filter:r=>!i(ze.relative(ze.join(n,"mod"),r))}),Rt.writeFileSync(ze.join(s,"README.md"),"Leftoff's Claude Code plugin (the mod), copied here by `leftoff setup` / `leftoff upgrade` from the installed package.\nClaude Code reads it as a local marketplace. Safe to delete: `leftoff setup` puts it back.\n"),Rt.rmSync(t,{recursive:!0,force:!0}),Rt.mkdirSync(ze.dirname(t),{recursive:!0}),Rt.renameSync(s,t),t}function mE({repoDir:n=kl,override:e,env:t=process.env,copy:s=Ck}={}){if(e)return e;if(!Tk(n)&&Rt.existsSync(ze.join(n,".git"))&&Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json")))return n;if(Ek(n)&&Rt.existsSync(ze.join(n,".claude-plugin","marketplace.json"))){try{return s({from:n,env:t})}catch{}return n}return Rp}function hE(n,e=lt){let t=String(n||""),s=t.search(new RegExp("(^|[^\\w-])"+e.replace(/[.@]/g,"\\$&")+"(?![\\w-])","m"));if(s<0)return{installed:!1,enabled:!1};let i=t.slice(s,s+400).split(/\n\s*\n/)[0];return{installed:!0,enabled:!(/disabled/i.test(i)&&!/✔\s*enabled|status:\s*enabled/i.test(i))}}function T3(n){return new RegExp("(^|[^\\w-])"+Gs+"([^\\w-]|$)","m").test(String(n||""))}function Dp(n,e){let t=Ei(n,["plugin","list"],{env:e,timeoutMs:3e4}),s=Ei(n,["plugin","marketplace","list"],{env:e,timeoutMs:3e4}),i=hE(t.stdout,Tr);return{...hE(t.stdout),legacyInstalled:i.installed,legacyEnabled:i.enabled,marketplaceAdded:s.code===0&&T3(s.stdout),listOk:t.code===0}}function Ok({bin:n,env:e=process.env,state:t=null,onStep:s=()=>{}}){let i=t||Dp(n,e);if(!i.legacyInstalled)return{ok:!0,migrated:!1,steps:[]};let r=[],o=c=>{s("claude "+c.join(" "));let u=Ei(n,c,{env:e});return r.push(u),u},a=c=>(c.stderr||c.stdout).trim().split(`
198
+ `).pop()||"exit "+c.code;if(!i.installed){o(["plugin","marketplace","update",Gs]);let c=o(["plugin","install",lt]);if(c.code!==0&&!/already installed/i.test(c.stdout+c.stderr))return{ok:!1,migrated:!1,steps:r,error:a(c)};i.legacyEnabled===!1&&o(["plugin","disable",lt])}let l=o(["plugin","uninstall",Tr]);return l.code!==0?{ok:!1,migrated:!0,steps:r,error:"installed "+lt+" but couldn't uninstall "+Tr+": "+a(l)}:{ok:!0,migrated:!0,enabled:i.legacyEnabled!==!1,steps:r}}function Mk({bin:n,source:e,env:t=process.env,onStep:s=()=>{}}){let i=[],r=Dp(n,t);if(r.legacyInstalled){let l=Ok({bin:n,env:t,state:r,onStep:s});if(!l.ok)return{ok:!1,steps:l.steps,state:r,error:l.error};let c=Mk({bin:n,source:e,env:t,onStep:s});return{...c,migrated:l.migrated,steps:[...l.steps,...c.steps]}}if(r.installed&&r.enabled)return{ok:!0,already:!0,steps:i,state:r};if(r.installed&&!r.enabled){s("claude plugin enable "+lt);let l=Ei(n,["plugin","enable",lt],{env:t});return i.push(l),{ok:l.code===0,already:!0,enabled:l.code===0,steps:i,state:r,error:l.code?(l.stderr||l.stdout).trim():null}}if(!r.marketplaceAdded){s("claude plugin marketplace add "+e);let l=Ei(n,["plugin","marketplace","add",e],{env:t});if(i.push(l),l.code!==0&&!/already/i.test(l.stdout+l.stderr))return{ok:!1,steps:i,state:r,error:(l.stderr||l.stdout).trim()||"exit "+l.code}}s("claude plugin install "+lt);let o=Ei(n,["plugin","install",lt],{env:t});i.push(o);let a=o.code===0||/already installed/i.test(o.stdout+o.stderr);return{ok:a,steps:i,state:r,error:a?null:(o.stderr||o.stdout).trim()||"exit "+o.code}}function gE(n){return!!(n&&n.disableAllHooks===!0)}var kl,Rp,Gs,v3,lt,Tr,Xu,Ci=K(()=>{Bs();Wt();kl=ze.resolve(ze.dirname(b3(import.meta.url)),".."),Rp=gi,Gs=T_,v3=E_,lt=v3+"@"+Gs,Tr=C_+"@"+Gs,Xu="2.1.287"});import wE from"node:fs";import Fp from"node:path";function Er(n,{statfs:e=wE.statfsSync}={}){if(!n||typeof e!="function")return null;let t=Fp.resolve(String(n));for(let s=0;s<64;s++){try{let r=e(t),o=Number(r.bsize||r.frsize||0),a=Number(r.blocks)*o,l=Number(r.bavail!=null?r.bavail:r.bfree)*o;return a?{path:t,freeBytes:l,totalBytes:a,pct:Math.round(l/a*1e4)/100}:null}catch{}let i=Fp.dirname(t);if(i===t)return null;t=i}return null}function I3(n){return!n||!n.totalBytes?"ok":n.pct<E3?"red":n.freeBytes<Math.max(n.totalBytes*C3/100,O3)?"warn":"ok"}function $o(n){return n=Number(n)||0,n>=100*Zu?Math.round(n/Zu)+" GB":n>=Zu?Math.round(n/Zu*10)/10+" GB":Math.round(n/1024**2)+" MB"}function Hp(n){let e={ok:0,warn:1,red:2},t=null;for(let s of n||[]){if(!s)continue;let i=I3(s);(!t||e[i]>e[t.level]||e[i]===e[t.level]&&s.freeBytes<t.freeBytes)&&(t={...s,level:i})}return t}function Up(n,{machine:e="this Mac"}={}){if(!n||n.level==="ok")return null;let t=$o(n.freeBytes)+" free";return n.level==="red"?"Disk full on "+e+": "+t+" ("+kE(n.pct)+"). Syncing has stopped.":"Low disk on "+e+": "+t+". Syncing stops below 1%."}function Go(n,{platform:e="darwin"}={}){let t=n?$o(n.freeBytes)+" free":null;return{text:"free up disk space"+(t?" (you have "+t+(n.pct!=null?", "+kE(n.pct):"")+")":"")+"; Syncthing resumes on its own",more:[...e==="darwin"?["storage settings: "+yE]:["see what's big: du -sh ~/* | sort -h | tail"],"last resort: lower Syncthing's minHomeDiskFree ("+N3+")"],cmd:e==="darwin"?yE:null}}function SE(n,e={}){let t=e.localErrors||[];if(t.some(i=>/insufficient space/i.test(i.error||"")))return{text:"this Mac's disk is full (see the folder error below); "+n+" reconnects once you free space here"};if(t.length)return{text:"fix the folder error below first; "+n+" reconnects on its own"};let s=e.peerHealth;return s&&s.disk&&s.disk.level&&s.disk.level!=="ok"?{text:n+" is low on disk ("+$o(s.disk.freeBytes)+" free when last heard); free up space there"}:{text:"wake "+n+" (open it, or check it's on and online); if it is, run there: leftoff doctor",more:["if Syncthing isn't running on "+n+": leftoff sync start (on "+n+")"]}}function L3(n){if(/^[\w@%+=:,./~-]+$/.test(n))return n;let e=n.startsWith("~/")?"~/":"";return e+"'"+n.slice(e.length).replace(/'/g,"'\\''")+"'"}function Qu(n,e={}){let t=String(n||"");if(!/^(!|✗)\s/.test(t))return null;let s=t.replace(/^(!|✗)\s+/,""),i=e.platform||"darwin",r=e.syncthing||{},o=r.folder&&r.folder.errors||[],a=i==="darwin"&&(e.syncthingVia==="brew"||r.via==="brew"),l=i==="linux"&&!a&&!!(e.syncthingSystemd||r.service&&r.service.systemd&&r.service.unit),c=a?{text:"brew services restart syncthing",auto:{id:"syncthing-restart",label:"restart Syncthing (brew services restart syncthing)"}}:l?{text:"systemctl --user restart syncthing",auto:{id:"syncthing-restart",label:"restart Syncthing (systemctl --user restart syncthing)"}}:null,u;if(u=s.match(/insufficient space on disk(?: for (?:the )?database)?\s*\(([^)]+)\)/i)){let d=typeof e.disk=="function"?e.disk(u[1]):null;return Go(d,{platform:i})}if(/insufficient space/i.test(s))return Go(null,{platform:i});if(/^(low disk|disk full)\b/i.test(s)){let d=e.lowDisk&&e.lowDisk.freeBytes!=null?e.lowDisk:null;return Go(d,{platform:i})}if(u=s.match(/null\/ folder is committed in (.+): git rm -r null\/$/))return{text:"cd "+L3(u[1])+' && git rm -r null/ && git commit -m "Remove stray null/ folder"'};if(u=s.match(/^worktree (.+?) is still locked by Leftoff/)){let d=(e.parkLocks||[]).find(f=>f.path===u[1]),h=f=>/^[A-Za-z0-9_./~@%+=:,-]+$/.test(f)?f:"'"+String(f).replace(/'/g,"'\\''")+"'";return{text:"git -C "+h(d&&d.root||u[1])+" worktree unlock "+h(u[1])+" (unlocks it; nothing is removed)"}}if(/^daemon on /.test(s))return{text:"leftoff start",more:["or run it in this terminal to see why it stops: leftoff serve"],auto:e.serviceInstalled?{id:"daemon-restart",label:"restart the Leftoff daemon"}:null};if(/^folder /.test(s))return{text:"leftoff setup (it makes the folder and picks up where it left off)"};if(/^token /.test(s))return{text:"leftoff setup (writes a new board token)"};if(u=s.match(/^mod command \/(\S+) failed to register/))return{text:"start a new Claude Code session (commands register at start); if /"+u[1]+" fails again: leftoff upgrade --force"};if(/^mod commands failed to register/.test(s))return{text:"start a new Claude Code session; if it fails again: leftoff upgrade --force"};if(/^update available/.test(s))return{text:"leftoff upgrade"};if(/^settings hooks are from before/.test(s)||/^the login service still has its old name/.test(s)||/^login service is from before/.test(s))return{text:"leftoff upgrade --force"};if(/^digest:/.test(s))return{text:"leftoff digest",auto:{id:"digest",label:"make today's digest now"}};if(/known only by id/.test(s))return{text:"nothing to run: it shows as itself after that session's next prompt, or closes with it"};if(/^API key files inside the folder/.test(s))return{text:"leftoff start (the daemon moves them when it starts)",auto:e.serviceInstalled?{id:"daemon-restart",label:"restart the Leftoff daemon"}:null};if(/^remote access: remoteHosts is set but no tailscale/.test(s))return{text:"install Tailscale from https://tailscale.com/download, or turn remote access off: leftoff tailscale off"};if(/^remote access: /.test(s))return{text:"leftoff tailscale on",auto:{id:"tailscale-on",label:"point tailscale serve at the board again (tailnet only)"}};if(/^Syncthing: installed, not running/.test(s))return{text:a?"leftoff sync start (runs: brew services start syncthing)":l?"systemctl --user enable --now syncthing (or: leftoff sync start)":"leftoff sync start",auto:{id:"syncthing-start",label:l?"start Syncthing (systemctl --user enable --now syncthing)":"start Syncthing"}};if(/^Leftoff folder: .*Leftoff uses another folder/.test(s))return{text:"leftoff sync setup"};if(/^Leftoff folder: /.test(s))return o.some(d=>/insufficient space/i.test(d.error||""))?{text:"Syncthing stopped because the disk is full; see the folder error below"}:o.length?{text:"see the folder error below"}:c||{text:i==="darwin"?"quit and reopen Syncthing":"restart Syncthing (stop it, then: leftoff sync start)",auto:null};if(u=s.match(/^Peer (.+?)(?: \(Leftoff\))?: not connected/)){let d=u[1];return SE(d,{localErrors:o,peerHealth:(e.peers||{})[d]||null})}return(u=s.match(/^Peer (.+?)(?: \(Leftoff\))?: /))&&/not sharing|hasn.t accepted/.test(s)?{text:"on "+u[1]+": Settings → Sync, accept this Mac (or: leftoff sync accept)"}:/^Folder error: /.test(s)?/folder marker missing|\.stfolder/i.test(s)?{text:`the folder's .stfolder marker is gone; if the folder is really there: mkdir "`+(r.folder&&r.folder.path||"<folder>")+'/.stfolder"'}:/folder path missing|no such file/i.test(s)?{text:"the folder moved or was deleted; point Syncthing at it again: leftoff sync setup"}:/permission denied/i.test(s)?{text:i==="darwin"?"give your user access to the folder again (Finder → Get Info → Sharing & Permissions), then restart Syncthing":"give your user access to the folder again (chown/chmod), then restart Syncthing"}:{text:(c?c.text:"restart Syncthing")+"; if the error comes back, open Syncthing's web page for details",auto:c?c.auto:null}:(u=s.match(/^A (?:Mac|machine) named “(.+?)” asked to connect/))?{text:`only if it's your machine: leftoff sync accept "`+u[1]+'"'}:/^Syncthing/.test(s)?c||{text:"leftoff sync start",auto:{id:"syncthing-start",label:"start Syncthing"}}:(u=s.match(/^(.+?) stopped syncing/))?{text:"free up disk space on "+u[1]+"; it catches up on its own"}:(u=s.match(/^(.+?): data as of /))?{text:"wake "+u[1]+" (open it, or check it's online); its sessions update once it syncs"}:/^summarizer: the shared setting is Ollama/.test(s)?{text:"give this machine its own summarizer: Settings → Summarizer → Just this machine, or leftoff models set claude --this-machine"+(/isn.t answering/.test(s)?" (or start Ollama here: ollama serve)":"")}:/^summarizer: this machine.s own setting is Ollama/.test(s)?{text:"install Ollama from https://ollama.com/download, or use the shared setting here again: leftoff models shared"}:/^summarizer: Ollama isn.t answering/.test(s)?{text:i==="darwin"?"ollama serve (or open the Ollama app)":"ollama serve",auto:e.ollamaBinary?{id:"ollama-start",label:"start Ollama"}:null}:/^summarizer: .*Ollama isn.t installed/.test(s)?{text:"install Ollama from https://ollama.com/download, or pick another summarizer: leftoff models"}:/^summarizer: /.test(s)?{text:"leftoff models (pick or test the summarizer)"}:/^PR cards: gh is signed out/.test(s)?{text:"gh auth login"}:/^PR cards: gh /.test(s)?{text:e.brew?"brew install gh && gh auth login (Leftoff won't install it for you)":"install gh from https://cli.github.com, then: gh auth login"}:(u=s.match(/^agent .*?\(([^)]+)\):|^agent (\S+)/))?{text:"check its feed and key: leftoff agents refresh "+(u[1]||u[2]).replace(/:$/,"")+"; to drop it: leftoff agents remove "+(u[1]||u[2]).replace(/:$/,"")}:/^notifications: .*another version/.test(s)?{text:"leftoff notifier rebuild (or restart the daemon: leftoff start)",auto:{id:"notifier-rebuild",label:"rebuild Leftoff.app, what notifications come from"}}:/^notifications: /.test(s)?{text:"leftoff notifier rebuild",auto:{id:"notifier-rebuild",label:"rebuild Leftoff.app, what notifications come from"}}:/^automation from /.test(s)?{text:i==="darwin"?"allow it in System Settings → Privacy & Security → Automation: "+M3:"allow the terminal to be scripted, then run leftoff doctor again"}:/^Go speed from the daemon/.test(s)?{text:"leftoff upgrade --force (refreshes the login service so macOS doesn't throttle it)"}:/^Go speed from this terminal/.test(s)?{text:"make sure Ghostty is running, then run leftoff doctor again"}:{text:"run leftoff doctor again after a minute; if it stays, send this line along with leftoff --version"}}function $s(n){let e=String(n&&n.provider||"auto").toLowerCase();return(j3[e]||e)+(n&&n.model&&e!=="heuristic"?" · "+n.model:"")}function bE({info:n,ollama:e=null}={}){if(!n)return[];let t=n.summarizer||{},s=[];if(n.source==="env"?s.push("· summarizer on this machine: "+$s(t)+" (from CHECKPOINTS_SUMMARIZER, which beats the settings)"):n.source==="machine"?s.push("· summarizer on this machine: "+$s(t)+", this machine's own setting (the shared one is "+$s(n.shared)+")"):s.push("· summarizer on this machine: "+$s(t)+" (the shared setting, used by every machine without its own)"),String(t.provider||"").toLowerCase()!=="ollama"||!e)return s;let i=e.baseUrl||t.baseUrl||"http://localhost:11434";if(e.running)return s.push("✓ summarizer: Ollama answering"+(e.version?" (v"+e.version+")":"")),s;if(n.source==="shared"||n.source==="default")return s.push(e.binary?"! summarizer: the shared setting is Ollama, and it isn't answering at "+i+" on this machine (checkpoints fall back to short summaries)":"! summarizer: the shared setting is Ollama, but Ollama isn't installed on this machine (checkpoints fall back to short summaries)"),s;let r=n.source==="machine"?" (this machine's own setting)":"";return s.push(e.binary?"! summarizer: Ollama isn't answering at "+i+r+" (checkpoints fall back to short summaries)":n.source==="machine"?"! summarizer: this machine's own setting is Ollama, but Ollama isn't installed here":"! summarizer: set to Ollama, but Ollama isn't installed"),s}function vE(n,e,{dim:t=i=>i,seen:s=null}={}){let i=Qu(n,e);return i?s&&s.has(i.text)?{lines:[n,t(" fix: same as above")],fix:i}:(s&&s.add(i.text),{lines:[n,t(" fix: "+i.text),...(i.more||[]).map(r=>t(" "+r))],fix:i}):{lines:[n],fix:null}}function P3(n,e={}){let t=e.leftoff||["leftoff"];if(n==="daemon-restart")return e.serviceCommands||null;let s=(e.platform||"darwin")==="darwin";return n==="syncthing-start"?s&&e.syncthingVia==="brew"&&e.brew?[[e.brew,"services","start","syncthing"]]:s&&e.syncthingVia==="app"&&e.syncthingPath?[["open","-a",e.syncthingPath]]:e.syncthingSystemd?[["systemctl","--user","enable","--now","syncthing"]]:null:n==="syncthing-restart"?s&&e.syncthingVia==="brew"&&e.brew?[[e.brew,"services","restart","syncthing"]]:e.syncthingSystemd?[["systemctl","--user","restart","syncthing"]]:null:n==="digest"?[[...t,"digest"]]:n==="notifier-rebuild"?[[...t,"notifier","rebuild"]]:n==="tailscale-on"?[[...t,"tailscale","on"]]:n==="ollama-start"&&e.ollamaStart?[e.ollamaStart]:null}async function xE(n,{confirm:e,run:t,say:s=()=>{},ctx:i={}}={}){let r=new Set,o=[];for(let a of n||[]){let l=a&&a.auto;if(!l||r.has(l.id))continue;r.add(l.id);let c=P3(l.id,i);if(!c||!c.length)continue;let u=c.map(f=>f.map(p=>/\s/.test(p)?'"'+p+'"':p).join(" ")).join(" && ");if(!await e(l.label.charAt(0).toUpperCase()+l.label.slice(1)+"? ("+u+")")){s("· skipped: "+l.label),o.push({id:l.id,ran:!1});continue}let d=!0,h="";for(let f of c){let p=await t(f);if(!p||p.status!==0){d=!1,h=(p&&(p.stderr||p.stdout)||"").toString().trim().split(`
199
+ `).pop()||"exit "+(p&&p.status);break}}s(d?"✓ did: "+l.label:"✗ "+l.label+" failed: "+h),o.push({id:l.id,ran:!0,ok:d,error:d?null:h})}return r.size||s("· nothing doctor can fix by itself here; the fix: lines above say what to do"),o}function AE({me:n,disk:e=null,st:t=null,healths:s=[],now:i=Date.now(),platform:r="darwin"}={}){let o=[],a=(y,w,S,k,v=null)=>o.push({machine:y,level:w,text:S,fix:k||null,...v?{cmd:v}:{}});if(e&&e.level&&e.level!=="ok"){let y=Go(e,{platform:r});a(n,e.level,Up(e,{machine:n}),y.text,y.cmd)}let l=t&&t.folder&&t.folder.errors||[],c=l.find(y=>/insufficient space/i.test(y.error||""));c&&!(e&&e.level==="red")&&a(n,"red","Syncing stopped on "+n+": disk full.",Go(e,{platform:r}).text);for(let y of l)y!==c&&a(n,"red","Sync error on "+n+": "+(y.error||"unknown"),Qu("! Folder error: "+y.error,{syncthing:t}).text);t&&t.installed&&!t.running&&a(n,"warn","Syncthing isn't running on "+n+".","leftoff sync start");let u={},d=t&&t.peers||[],h=new Set;for(let y of s){if(!y||!y.machine||y.machine===n)continue;h.add(y.machine);let w=i-Date.parse(y.at||0),S=d.find(v=>v.name===y.machine),k=y.disk&&y.disk.level;k==="red"||y.syncError&&/insufficient space/i.test(y.syncError)?a(y.machine,"red",y.machine+" stopped syncing: disk full.","free up disk space on "+y.machine+"; it catches up on its own"):k==="warn"&&w>Nk?a(y.machine,"red",y.machine+" stopped syncing: disk probably full ("+$o(y.disk.freeBytes)+" free when last heard).","free up disk space on "+y.machine):k==="warn"?a(y.machine,"warn",Up(y.disk,{machine:y.machine}),"free up disk space on "+y.machine):y.syncError&&a(y.machine,"red","Sync error on "+y.machine+": "+y.syncError,"run leftoff doctor on "+y.machine),w>Nk&&!(S&&S.connected)&&(u[y.machine]=y.at)}for(let y of d)y.connected||y.notSharing||(y.lastSeen?i-Date.parse(y.lastSeen):1/0)<=Nk||(u[y.name]||(u[y.name]=y.lastSeen||null),o.some(S=>S.machine===y.name)||a(y.name,"warn",y.name+" hasn't synced "+(y.lastSeen?"for "+R3(i-Date.parse(y.lastSeen)):"yet")+".",SE(y.name,{localErrors:l,peerHealth:s.find(S=>S&&S.machine===y.name)||null}).text));o.sort((y,w)=>(y.level==="red"?0:1)-(w.level==="red"?0:1));let f=o.some(y=>y.level==="red")?"red":o.length?"warn":"ok",p=o.find(y=>y.level==="red")||o[0],m=f==="ok"?"In sync":p.level==="red"&&/stopped|full/.test(p.text)?p.machine===n?"Sync stopped":p.machine+": sync stopped":p.level==="red"?"Sync error":p.machine===n&&/disk/i.test(p.text)?"Low disk":p.machine!==n?p.machine+" not syncing":"Sync: check";return{level:f,label:m,items:o,stale:u}}function R3(n){let e=Math.max(0,Math.round(n/6e4));if(e<60)return e+" min";let t=Math.round(e/60);return t<48?t+" h":Math.round(t/24)+" days"}function _E({remote:n=!1,machine:e=null,folder:t=null,home:s=null}={}){if(!n)return null;let i=t||null;i&&s&&(i===s||i.startsWith(s+"/"))&&(i="~"+i.slice(s.length));let r="npx -y -p @leftoff/cli leftoff setup"+(i?" --dir "+(/\s/.test(i)?'"'+i+'"':i):"");return{machine:e,dir:i,command:r}}function Oi(n,{fsImpl:e=wE}={}){let t=[],s=[];try{s=e.readdirSync(n)}catch{return t}for(let i of s)if(/^\.health\..+\.json$/.test(i))try{let r=JSON.parse(e.readFileSync(Fp.join(n,i),"utf8"));r&&r.machine&&t.push(r)}catch{}return t}function EE({machine:n,disk:e=null,st:t=null,now:s=Date.now()}={}){let i=t&&t.folder&&t.folder.errors||[];return{machine:n,at:new Date(s).toISOString(),disk:e?{level:e.level,freeBytes:e.freeBytes,totalBytes:e.totalBytes,pct:e.pct,what:e.what||null}:null,syncError:i.length?String(i[0].error||"").replace(/\([^)]*\/[^)]*\)/g,"").replace(/\s+/g," ").trim().slice(0,200):null}}function CE(n,e={}){let t={...e,syncthing:n},s=(n&&n.folder&&n.folder.errors||[]).map(r=>{let o=Qu("! Folder error: "+r.error,t);return o?[o.text,...o.more||[]].join(" · "):null}),i={};for(let r of n&&n.peers||[])if(!r.connected&&!r.notSharing){let o=Qu("! Peer "+r.name+": not connected",t);o&&(i[r.name]=o.text)}return{errors:s,peers:i,notRunning:n&&n.installed&&!n.running?Qu("! Syncthing: installed, not running",t).text:null}}var Zu,E3,C3,O3,yE,M3,N3,Nk,kE,j3,TE,ed=K(()=>{Zu=1024**3,E3=1,C3=5,O3=5*Zu,yE='open "x-apple.systempreferences:com.apple.settings.Storage"',M3='open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"',N3="https://docs.syncthing.net/users/config.html#config-option-options.minhomediskfree",Nk=900*1e3;kE=n=>(n<10?Math.round(n*100)/100:Math.round(n))+"%";j3={auto:"auto",claude:"Claude Code",anthropic:"Anthropic API",ollama:"Ollama","ollama-cloud":"Ollama cloud","openai-compatible":"OpenAI-compatible server",heuristic:"no model (heuristic)"};TE=(n,e)=>Fp.join(n,".health."+String(e).replace(/[^\w.-]/g,"_")+".json")});import{execFile as D3}from"node:child_process";import F3 from"node:fs";import td from"node:path";function OE(n,{timeoutMs:e=5e3}={}){return new Promise(t=>{let[s,...i]=n;try{D3(s,i,{timeout:e},(r,o,a)=>t({code:r?typeof r.code=="number"?r.code:1:0,stdout:String(o||""),stderr:String(a||"")||(r?String(r.message||r):"")}))}catch(r){t({code:1,stdout:"",stderr:String(r&&r.message||r)})}})}function ME(n,{machine:e=null,fsImpl:t=F3}={}){let s=new Set;for(let o of n||[]){if(!o||e&&o.machine&&o.machine!==e)continue;o.repo&&typeof o.repo.root=="string"&&o.repo.root&&s.add(o.repo.root);let a=o.parked&&o.parked.worktreeLock;a&&typeof a.root=="string"&&a.root&&s.add(a.root)}let i=[],r=new Set;for(let o of s){let a=td.join(o,".git","worktrees"),l=[];try{l=t.readdirSync(a)}catch{continue}for(let c of l){let u;try{u=String(t.readFileSync(td.join(a,c,"locked"),"utf8")).replace(/\n$/,"")}catch{continue}let d=c0(u);if(!d)continue;let h=null;try{h=td.dirname(String(t.readFileSync(td.join(a,c,"gitdir"),"utf8")).trim())}catch{}let f=h||td.join(a,c);if(r.has(f))continue;r.add(f);let p=(n||[]).find(m=>m&&m.id===d)||null;i.push({path:f,root:o,sessionId:d,title:p&&p.title||null,parked:!!(p&&p.parked)})}}return i}function NE(n){return(n||[]).filter(e=>!e.parked).map(e=>"! worktree "+e.path+" is still locked by Leftoff, but "+(e.title?"“"+e.title+"”":"its session")+" isn’t parked any more")}var Ik=K(()=>{Te()});import Cr from"node:fs";import U3 from"node:os";import Lk from"node:path";import{execFile as H3}from"node:child_process";function G3(n=process.env){return n.CLAUDE_CONFIG_DIR||Lk.join(n.HOME||U3.homedir(),".claude")}function Or(n,{env:e=process.env,dirs:t}={}){if(!n||!z3.test(n))return null;let s=t||[Lk.join(G3(e),"projects")],i=null;for(let r of s){let o=[];try{o=Cr.readdirSync(r,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>a.name)}catch{continue}for(let a of o){let l=Lk.join(r,a,n+".jsonl");try{let c=Cr.statSync(l);(!i||c.mtimeMs>i.mtimeMs)&&(i={file:l,mtimeMs:c.mtimeMs,size:c.size})}catch{}}}return i?i.file:null}function zp(n,{maxBytes:e=B3}={}){try{let t=Cr.statSync(n).size,s;if(t>e){let a=Cr.openSync(n,"r"),l=Buffer.alloc(256*1024),c=Cr.readSync(a,l,0,l.length,0);Cr.closeSync(a),s=l.subarray(0,c).toString("utf8");let{meta:u}=fl(s);return{cwd:u.cwd||null,prompts:1,customTitle:u.customTitle||null,gitBranch:u.gitBranch||null,truncated:!0}}s=Cr.readFileSync(n,"utf8");let{messages:i,meta:r}=fl(s),o=i.filter(a=>a.role==="user"&&a.text&&a.text.trim()).length;return{cwd:r.cwd||null,prompts:o,customTitle:r.customTitle||null,gitBranch:r.gitBranch||null,...r.model?{model:r.model}:{}}}catch{return null}}function LE(n,e,t=5e3){return new Promise(s=>{H3(n,e,{env:{...process.env,LC_ALL:"C"},timeout:t,maxBuffer:8*1024*1024},(i,r)=>s(i&&!r?"":String(r||"")))})}function $3(n){let e=[];for(let t of String(n||"").split(`
200
+ `)){let s=t.match(/^\s*(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)$/);s&&e.push({pid:Number(s[1]),ppid:Number(s[2]),tty:s[3],etime:s[4],args:s[5].trim()})}return e}function K3(n){let e=new Map;for(let t of String(n||"").split(`
201
+ `)){let s=t.match(/^\s*(\d+)\s+(.*)$/);s&&e.set(Number(s[1]),s[2].trim())}return e}function jE(n,e){let t=Bp(e||"").toLowerCase(),s=Bp(String(n.args||"").split(/\s+/)[0]).toLowerCase();if(/^claude(\s|$)/.test(t)||s==="claude")return!0;let i=String(n.args||"").split(/\s+/);return/^(node|bun)$/.test(s)&&(Bp(i[1])==="claude"||/@anthropic-ai\/claude-code\/cli\.m?js$/.test(i[1]||""))}function W3(n,e,t=new Map){let s=String(n).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=new RegExp("(?:^|\\s)(?:--resume|-r|--session-id)(?:=|\\s+)"+s+"(?=\\s|$)"),r=e.filter(l=>i.test(l.args)&&jE(l,t.get(l.pid))),o=new Set(r.map(l=>l.pid)),a=r.filter(l=>!r.some(c=>c.ppid===l.pid&&o.has(c.pid)));return a.length===1?a[0]:null}async function IE(n,{platform:e=process.platform,runner:t=LE}={}){let s=new Map,i=n.filter(a=>Number.isInteger(a)&&a>1);if(!i.length)return s;if(e==="linux"){for(let a of i)try{s.set(a,Cr.readlinkSync("/proc/"+a+"/cwd"))}catch{}return s}let r=await t("lsof",["-a","-d","cwd","-p",i.join(","),"-Fpn"]),o=null;for(let a of r.split(`
202
+ `))a.startsWith("p")?o=Number(a.slice(1)):a.startsWith("n")&&o&&s.set(o,a.slice(1));return s}function q3(n,e,t=new Map){let s=new Map(e.map(r=>[r.pid,r])),i=s.get(n);for(let r=0;i&&r<12;r++){let o=Bp(t.get(i.pid)||String(i.args).split(/\s+/)[0]);for(let[a,l]of Y3)if(a.test(o))return{...hr(l==="kitty"?{TERM:"xterm-kitty"}:{TERM_PROGRAM:l}),source:"ps"};if(/^tmux/i.test(o))return null;i=s.get(i.ppid)}return null}async function PE(n,{cwd:e=null,claimedPids:t=new Set,env:s=process.env,platform:i=process.platform,runner:r=LE,now:o=Date.now(),transcriptDirs:a}={}){let l={via:[]},c=Or(n,{env:s,dirs:a});if(c){l.transcriptPath=c;let p=zp(c);p&&(p.cwd&&(l.cwd=p.cwd),l.prompts=p.prompts,p.customTitle&&(l.customTitle=p.customTitle),l.via.push("transcript"))}let u=e||l.cwd||null,d=$3(await r("ps",["-axo","pid=,ppid=,tty=,etime=,command="]));if(!d.length)return l;let h=K3(await r("ps",["-axo","pid=,comm="])),f=W3(n,d,h);if(f)l.via.push("ps-args");else if(u){let p=d.filter(S=>jE(S,h.get(S.pid))&&!t.has(S.pid)),m=p.filter(S=>!p.some(k=>k.ppid===S.pid)),y=await IE(m.map(S=>S.pid),{platform:i,runner:r}),w=m.filter(S=>y.get(S.pid)===u);w.length===1&&(f=w[0],l.via.push("ps-cwd"))}if(f){let p=Eo(f.etime);l.proc={pid:f.pid,tty:o0(f.tty),pidStartedAt:p==null?null:Z(o-p*1e3),source:"daemon"};let m=q3(f.pid,d,h);if(m&&(l.term=m,l.via.push("ps-term")),!l.cwd&&!e){let y=(await IE([f.pid],{platform:i,runner:r})).get(f.pid);y&&(l.cwd=y)}}return l}var B3,z3,Bp,Y3,Gp=K(()=>{Uo();Te();B3=32*1024*1024,z3=/^[0-9A-Za-z][0-9A-Za-z_-]{6,80}$/;Bp=n=>String(n||"").split("/").pop();Y3=[[/^ghostty$/i,"ghostty"],[/^iterm2?$/i,"iTerm.app"],[/^terminal$/i,"Apple_Terminal"],[/^wezterm(-gui)?$/i,"WezTerm"],[/^kitty$/i,"kitty"]]});import Nr from"node:fs";import Mr from"node:path";import J3 from"node:crypto";function id(n){let e=V3[n]||n;if(!sd.includes(e))throw Object.assign(new Error("kind is machine, repo, session or agent"),{code:"bad_kind"});return e}function Ko(n){return DE.test(String(n))}function bl(n){return String(n).replace(DE,"")}function rd(n){let e=String(n??"").normalize("NFC").replace(/\s+/g," ").trim();if(!e)throw Object.assign(new Error("a space needs a name"),{code:"bad_space"});if(e.length>32)throw Object.assign(new Error("a space name is at most 32 characters"),{code:"bad_space"});if(!/^[\p{L}\p{N}][\p{L}\p{N} ._&'-]*$/u.test(e))throw Object.assign(new Error("a space name is letters, numbers, spaces and . _ & ' -"),{code:"bad_space"});return e}function FE(n,e){let t=String(e??"").trim();if(!t||t.length>400||/[\u0000-\u001F]/.test(t))throw Object.assign(new Error("bad "+n.replace(/s$/,"")+" key"),{code:"bad_key"});return t}function Wo(){return{schema:1,machines:{},repos:{},sessions:{},agents:{}}}function X3(n){if(n==null)return null;if(typeof n=="string")return{space:n,at:"1970-01-01T00:00:00.000Z",by:""};if(typeof n!="object")return null;let e=n.space==null?null:String(n.space),t=typeof n.at=="string"&&!Number.isNaN(Date.parse(n.at))?n.at:"1970-01-01T00:00:00.000Z";return{space:e,at:t,by:typeof n.by=="string"?n.by:""}}function UE(n){let e=Wo();if(!n||typeof n!="object")return e;for(let t of sd){let s=n[t];if(!(!s||typeof s!="object"))for(let[i,r]of Object.entries(s)){let o=X3(r);o&&(e[t][i]=o)}}return e}function Z3(n,e){if(!n)return e;if(!e)return n;let t=Date.parse(n.at),s=Date.parse(e.at);return t!==s?t>s?n:e:n.by!==e.by?n.by>e.by?n:e:n.space==null!=(e.space==null)?n.space==null?e:n:String(n.space)>=String(e.space)?n:e}function Q3(...n){let e=Wo();for(let t of n){let s=UE(t);for(let i of sd)for(let[r,o]of Object.entries(s[i]))e[i][r]=Z3(e[i][r],o)}return e}function Yo(n){let e=[],t=[];try{t=Nr.readdirSync(n)}catch{}for(let r of t)(r===nd||r.startsWith("spaces.")&&r.endsWith(".json")&&Ko(r)&&bl(r)===nd)&&e.push(r);let s=[],i=[];for(let r of e.sort())try{s.push(JSON.parse(Nr.readFileSync(Mr.join(n,r),"utf8"))),r!==nd&&i.push(r)}catch{}return{map:Q3(...s),conflicts:i}}function vl(n,e){Nr.mkdirSync(Mr.dirname(n),{recursive:!0});let t=Mr.join(Mr.dirname(n),".syncthing."+Mr.basename(n)+"."+process.pid+"."+J3.randomBytes(4).toString("hex")+".tmp");Nr.writeFileSync(t,e),Nr.renameSync(t,n)}function eU(n,e,{removeConflicts:t=[]}={}){let s=UE(e),i={schema:1};for(let r of sd)i[r]=Object.fromEntries(Object.entries(s[r]).sort(([o],[a])=>o.localeCompare(a)));vl(Mr.join(n,nd),JSON.stringify(i,null,2)+`
203
+ `);for(let r of t)try{Nr.unlinkSync(Mr.join(n,r))}catch{}}function jk(n,e,{machine:t="",now:s=Date.now()}={}){let{map:i,conflicts:r}=Yo(n),o={at:new Date(s).toISOString(),by:t},a=e(i,o);return eU(n,i,{removeConflicts:r}),a===void 0?i:a}function ds(n,e){let t={};for(let[s,i]of Object.entries(n&&n[e]||{}))i&&i.space!=null&&(t[s]=i.space);return t}function Ks(n,e=[]){let t=new Set;for(let s of sd)for(let i of Object.values(ds(n,s)))t.add(i);for(let s of e)t.add(Ir(n,s));return xl([...t])}function xl(n){return[...new Set(n.filter(Boolean))].sort((e,t)=>e==="Work"?-1:t==="Work"?1:e.localeCompare(t,"en",{sensitivity:"base"})||e.localeCompare(t))}function Ir(n,e){let t=n&&n.machines&&n.machines[e];return t&&t.space!=null?t.space:e||"Unsorted"}function nU(n,{repoKey:e,repoName:t,repoLabel:s}={}){let i=ds(n,"repos");if(e&&i[e]!=null)return{key:e,space:i[e]};let r=[s,t,tU(e)].filter(Boolean).map(RE);for(let o of r)for(let[a,l]of Object.entries(i))if(RE(a)===o)return{key:a,space:l};return null}function Lr(n,e,{repoKey:t,repoName:s,repoLabel:i,machine:r}={}){let o=ds(n,"sessions");if(e&&e.id&&o[e.id]!=null)return{space:o[e.id],source:"session",key:e.id};let a=e&&(e.agent&&e.agent.name||(typeof e.id=="string"&&e.id.startsWith("agent:")?e.id.split(":")[1]:null));if(a){let d=ds(n,"agents");if(d[a]!=null)return{space:d[a],source:"agent",key:a}}let l=!a&&nU(n,{repoKey:t||e&&(e.repoKey||e.repo&&e.repo.root||e.cwd),repoName:s||e&&(e.repoName||e.repo&&e.repo.name),repoLabel:i||e&&e.repoLabel});if(l)return{space:l.space,source:"repo",key:l.key};let c=r||(e&&a?e.agent&&e.agent.puller:e&&e.machine)||"",u=n&&n.machines&&n.machines[c];return u&&u.space!=null?{space:u.space,source:"machine",key:c}:{space:c||"Unsorted",source:"default",key:c}}function HE(n,{home:e=""}={}){let t=[e,"/root"].filter(Boolean).map(o=>o.replace(/\/+$/,"")),s=o=>t.includes(o)||/^\/(Users|home)\/[^/]+$/.test(o)||/^[A-Za-z]:\\Users\\[^\\]+$/.test(o),i=o=>{for(let l of t)if(l&&(o===l||o.startsWith(l+"/")))return"~"+o.slice(l.length);let a=/^\/(Users|home)\/[^/]+(?=\/|$)/.exec(o);return a?"~"+o.slice(a[0].length):o},r=new Map;for(let o of n||[]){let a=String(o&&o.key||"").trim().replace(/\/+$/,"")||(o&&o.key?"/":""),l=String(o&&o.name||"").trim();if(!l||["/",".","..","~","no-repo"].includes(l)||/^[\\/]+$/.test(l)||!a||a==="/"||a==="~"||s(a))continue;let c=Date.parse(o&&o.at||"")||0,u=l.toLowerCase(),d=r.get(u);if(d&&d.t>=c)continue;let h=a.includes("/")?i(a.slice(0,a.lastIndexOf("/"))||"/"):"";r.set(u,{name:l,parent:h,lastAt:c?new Date(c).toISOString():null,t:c})}return[...r.values()].sort((o,a)=>a.t-o.t||o.name.localeCompare(a.name)).map(({t:o,...a})=>a)}var nd,Sl,sd,V3,DE,RE,tU,$p,jr=K(()=>{nd="spaces.json",Sl=["Work","Personal"],sd=["machines","repos","sessions","agents"],V3={machine:"machines",repo:"repos",session:"sessions",agent:"agents"};DE=/\.sync-conflict-(\d{8})-(\d{6})-([A-Za-z0-9]{1,16})(?=\.[^.]+$|$)/;RE=n=>String(n||"").toLowerCase(),tU=n=>{let e=String(n||"").split(/[\\/]+/).filter(Boolean);return e.length?e[e.length-1]:""};$p=class{constructor(e,t,{now:s=()=>Date.now()}={}){this.root=e,this.machine=t,this.now=s,this.cache=null,this.checkedAt=0}sig(){let e=[];try{e=Nr.readdirSync(this.root).filter(t=>t===nd||t.startsWith("spaces.")&&Ko(t))}catch{}return e.sort().map(t=>{try{let s=Nr.statSync(Mr.join(this.root,t));return t+":"+s.mtimeMs+":"+s.size}catch{return t}}).join("|")}map({fresh:e=!1}={}){let t=Date.now();if(!e&&this.cache&&t-this.checkedAt<2e3)return this.cache.map;let s=this.sig();if(this.checkedAt=t,!e&&this.cache&&this.cache.sig===s)return this.cache.map;let{map:i,conflicts:r}=Yo(this.root);return this.cache={sig:s,map:i,conflicts:r},i}update(e){let t=jk(this.root,e,{machine:this.machine,now:this.now()});return this.cache=null,t}resolve(e,t){return Lr(this.map(),e,t)}machineSpace(e=this.machine){return Ir(this.map(),e)}}});import Se from"node:fs";import ge from"node:path";import Pk from"node:crypto";function Jt(n,e){Se.mkdirSync(ge.dirname(n),{recursive:!0});let t=ge.join(ge.dirname(n),"."+ge.basename(n)+"."+process.pid+"."+Pk.randomBytes(4).toString("hex")+".tmp");Se.writeFileSync(t,e),Se.renameSync(t,n)}function Mi(n){try{return Se.readdirSync(n,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.name.startsWith(".")).map(e=>e.name)}catch{return[]}}function BE(n){return Se.existsSync(ge.join(n,"session.md"))||Se.existsSync(ge.join(n,"checkpoints"))}function zE(n,e,t,s){let i=ge.join(qe(n).spool,e,String(t||"unknown").replace(/[^A-Za-z0-9_-]/g,"_"));Se.mkdirSync(i,{recursive:!0});let r=ge.join(i,Date.now()+"-"+Pk.randomBytes(4).toString("hex")+".json");return Se.writeFileSync(r,JSON.stringify(s)+`
204
204
  `,{flag:"wx"}),r}var En,hs=K(()=>{Te();Fe();Hn();jr();En=class{constructor(e,t="unknown"){this.root=e,this.machine=t,this.p=qe(e)}get mySessions(){return ge.join(this.p.sessions,this.machine)}get mySpool(){return ge.join(this.p.spool,this.machine)}get myDigests(){return ge.join(this.p.digests,this.machine)}sessionDir(e){return e.folder||(e.folder=this.findFolderFor(e.id)||this.machine+"/"+AA(e)),ge.join(this.p.sessions,e.folder)}findFolderFor(e){let t="_"+tu(e),s="_"+xA(e);for(let i of Mi(this.mySessions)){if(s!==t&&i.endsWith(s)){try{if(Tt(Se.readFileSync(ge.join(this.mySessions,i,"session.md"),"utf8")).data.id===e)return this.machine+"/"+i}catch{}continue}if(!i.endsWith(t))continue;let r=ge.join(this.mySessions,i,"session.md");if(!Se.existsSync(r))return this.machine+"/"+i;try{if(Tt(Se.readFileSync(r,"utf8")).data.id===e)return this.machine+"/"+i}catch{}}return null}writeSession(e,t){let s=ge.join(this.sessionDir(e),"session.md");return Jt(s,Tf(e,t)),s}writeCheckpoint(e,t){let s=ge.join(this.sessionDir(e),"checkpoints");Se.mkdirSync(s,{recursive:!0});for(let i=0;i<50;i++){let r=ge.join(s,t0(t.createdAt,i)),o={...vi(t),machine:t.machine||e.machine||this.machine,id:t.id&&i===0?t.id:xf(t.sessionId,t.createdAt,i),file:ge.basename(r)};try{return Se.writeFileSync(r,FA({...o,backend:e.backend}),{flag:"wx"}),o}catch(a){if(a.code!=="EEXIST")throw a}}throw new Error("could not find a free checkpoint file name")}loadSessionDir(e,t,s){let i=[];try{for(let o of Se.readdirSync(ge.join(e,"checkpoints")).filter(a=>a.endsWith(".md")).sort())try{let a=vi(UA(Se.readFileSync(ge.join(e,"checkpoints",o),"utf8")));a.file=o,!a.machine&&s&&(a.machine=s),a.sessionId&&a.createdAt&&i.push(a)}catch{}}catch{}let r=null;try{r=Ef(Se.readFileSync(ge.join(e,"session.md"),"utf8"))}catch{}if(!r||!r.id){if(!i.length)return null;let o=i[i.length-1];r={id:o.sessionId,title:o.sessionTitle,titleSource:o.sessionTitle?"custom":null,cwd:o.cwd,machine:o.machine||s,repo:o.repo?{name:o.repo,branch:o.branch}:null,capture:"mod",status:"stale",startedAt:i[0].createdAt,lastActivityAt:o.createdAt,turns:0,turnsSinceCheckpoint:0,backgroundTasks:0,lastHeartbeatAt:o.createdAt,needsRewrite:!0}}return!r.machine&&s&&(r.machine=s),r.folder=t,{session:r,checkpoints:i}}loadAll({machine:e}={}){let t=[];for(let s of Mi(this.p.sessions)){let i=ge.join(this.p.sessions,s);if(BE(i)){let r=this.loadSessionDir(i,s,null);r&&(!e||r.session.machine===e)&&t.push(r);continue}if(!(e&&s!==e))for(let r of Mi(i)){let o=this.loadSessionDir(ge.join(i,r),s+"/"+r,s);o&&t.push(o)}}return t}machines(){let e=new Set([this.machine]);for(let t of Mi(this.p.sessions))BE(ge.join(this.p.sessions,t))||e.add(t);for(let t of Mi(this.p.digests))e.add(t);return[...e].sort()}writeDigest(e,t){let s=ge.join(this.p.digests,e+".md");vl(s,t);for(let i of this.digestCopies(e))if(i!==e+".md")try{Se.unlinkSync(ge.join(this.p.digests,i))}catch{}return s}writeMachineDigest(e,t){let s=ge.join(this.myDigests,e+".md");return Jt(s,t),s}digestCopies(e){let t=[];try{t=Se.readdirSync(this.p.digests)}catch{}return t.filter(s=>s===e+".md"||s.startsWith(e+".")&&s.endsWith(".md")&&Ko(s)&&bl(s)===e+".md")}readSharedDigest(e){let t=null,s=this.digestCopies(e);for(let i of s)try{let r=ge.join(this.p.digests,i),o=Se.readFileSync(r,"utf8"),a=Tt(o).data||{},l=Date.parse(a.generated_at)||Se.statSync(r).mtimeMs;(!t||l>t.t||l===t.t&&i===e+".md")&&(t={t:l,file:i,markdown:o,by:a.machine||null})}catch{}return t?{machine:null,shared:!0,by:t.by,file:t.file,duplicates:s.length-1,markdown:t.markdown}:null}readDigest(e,t){if(t&&t!=="all")try{return{machine:t,shared:!1,markdown:Se.readFileSync(ge.join(this.p.digests,t,e+".md"),"utf8")}}catch{return null}let s=this.readSharedDigest(e);if(s||t==="all")return s;for(let i of[this.machine,...Mi(this.p.digests).filter(r=>r!==this.machine)])try{return{machine:i,shared:!1,markdown:Se.readFileSync(ge.join(this.p.digests,i,e+".md"),"utf8")}}catch{}return null}listDigests(){let e=[],t=new Set;try{for(let i of Se.readdirSync(this.p.digests)){let r=/^(\d{4}-\d{2}-\d{2})\.(?:.*\.)?md$/.exec(i);r&&(i===r[1]+".md"||bl(i)===r[1]+".md")&&t.add(r[1])}}catch{}for(let i of t)e.push({date:i,machine:null,shared:!0});for(let i of Mi(this.p.digests))try{for(let r of Se.readdirSync(ge.join(this.p.digests,i)))/^\d{4}-\d{2}-\d{2}\.md$/.test(r)&&e.push({date:r.slice(0,10),machine:i})}catch{}let s=i=>i.shared?0:i.machine===this.machine?1:2;return e.sort((i,r)=>r.date.localeCompare(i.date)||s(i)-s(r)||String(i.machine).localeCompare(String(r.machine)))}stampAlive(e={},t=Date.now()){let s=ge.join(this.p.digests,".machines",this.machine.replace(/[^\w.-]/g,"_")+".json");vl(s,JSON.stringify({machine:this.machine,seenAt:new Date(t).toISOString(),...e},null,2)+`
205
- `)}aliveMachines(){let e=[],t=ge.join(this.p.digests,".machines"),s=[];try{s=Se.readdirSync(t).filter(i=>i.endsWith(".json")&&!i.startsWith(".")&&!Ko(i))}catch{}for(let i of s)try{let r=JSON.parse(Se.readFileSync(ge.join(t,i),"utf8"));r&&r.machine&&e.push(r)}catch{}return e}writeCatchup(e,t){Se.mkdirSync(this.p.catchups,{recursive:!0});let s=String(e).replace(/\.md$/,"");for(let i=0;i<50;i++){let r=i?s+"-"+(i+1):s,o=ge.join(this.p.catchups,r+".md");try{let a=ge.join(this.p.catchups,"."+r+"."+process.pid+"."+Pk.randomBytes(4).toString("hex")+".tmp");Se.writeFileSync(a,t);try{try{Se.linkSync(a,o)}catch(l){if(l.code==="EEXIST")throw l;Se.writeFileSync(o,t,{flag:"wx"})}}finally{try{Se.unlinkSync(a)}catch{}}return{name:r,file:o}}catch(a){if(a.code!=="EEXIST")throw a}}throw new Error("could not find a free catch-up file name")}readCatchup(e){if(!/^\d{4}-\d{2}-\d{2}T\d{4}(?:-\d+)?$/.test(String(e||"")))return null;try{return{name:e,markdown:Se.readFileSync(ge.join(this.p.catchups,e+".md"),"utf8")}}catch{return null}}listCatchups(){let e=[];try{e=Se.readdirSync(this.p.catchups).filter(i=>/^\d{4}-\d{2}-\d{2}T\d{4}(?:-\d+)?\.md$/.test(i))}catch{return[]}let t=[];for(let i of e){let r={};try{let o=Se.openSync(ge.join(this.p.catchups,i),"r");try{let a=Buffer.alloc(8192),l=Se.readSync(o,a,0,a.length,0);r=Tt(a.slice(0,l).toString("utf8")).data||{}}finally{Se.closeSync(o)}}catch{}t.push({name:i.slice(0,-3),generatedAt:r.generated_at?Z(r.generated_at):null,from:r.window_from?Z(r.window_from):null,to:r.window_to?Z(r.window_to):null,label:r.window_label||null,sessions:typeof r.sessions=="number"?r.sessions:null,needsYou:Array.isArray(r.needs_you)?r.needs_you.length:0,repos:r.repos==="all"||r.repos==null?"all":[].concat(r.repos).map(String),machine:r.made_on==null?null:String(r.made_on),model:r.model==null?null:String(r.model)})}let s=i=>Date.parse(i.generatedAt||"")||0;return t.sort((i,r)=>s(r)-s(i)||r.name.localeCompare(i.name))}lastCatchupAt(){let e=this.listCatchups()[0];if(!e)return null;let t=Date.parse(e.to||e.generatedAt||"");return isNaN(t)?null:t}readSpool(){let e=[];for(let t of Mi(this.mySpool)){let s=ge.join(this.mySpool,t),i=[];try{i=Se.readdirSync(s)}catch{}for(let r of i){if(!r.endsWith(".json"))continue;let o=ge.join(s,r),a=null;try{a=Se.readFileSync(o,"utf8")}catch{continue}e.push({file:o,t:Number(r.split("-")[0])||0,body:a})}}return e.sort((t,s)=>t.t-s.t||t.file.localeCompare(s.file))}spoolCount(){let e=0;for(let t of Mi(this.mySpool))try{e+=Se.readdirSync(ge.join(this.mySpool,t)).filter(s=>s.endsWith(".json")).length}catch{}return e}}});import _l from"node:fs";import s3 from"node:os";import Cn from"node:path";import{execFileSync as i3}from"node:child_process";function Wp(n){let e=new Set;for(let t of n||[])for(let s of[t&&t.cwd,t&&t.repo&&t.repo.root])typeof s=="string"&&Cn.isAbsolute(s)&&e.add(Cn.resolve(s));return[...e]}function l3(n){let e=Cn.join(n,"null"),t=Cn.join(e,".spool");if(!od(e)||!od(t))return null;let s={dir:n,nullDir:e,files:[],foreign:null},i=r=>(s.foreign=s.foreign||r,s);for(let r of Al(e)||[])if(r!==".spool")return i(Cn.join(e,r));for(let r of Al(t)||[]){let o=Cn.join(t,r);if(!od(o))return i(o);for(let a of Al(o)||[]){let l=Cn.join(o,a);if(!r3.test(a)||!od(l))return i(l);for(let c of Al(l)||[]){let u=Cn.join(l,c);if(!o3.test(c)||!a3(u))return i(u);s.files.push(u)}}}return s.files.sort((r,o)=>Number(Cn.basename(r).split("-")[0])-Number(Cn.basename(o).split("-")[0])||r.localeCompare(o)),s}function c3(n){try{return String(i3("git",["-C",n,"ls-files","--","null/"],{encoding:"utf8",timeout:5e3,stdio:["ignore","pipe","pipe"]})).split(`
206
- `).filter(Boolean)}catch(e){return/not a git repository/i.test(String(e.stderr||""))?[]:null}}function u3(n){try{let e=JSON.parse(_l.readFileSync(n,"utf8"));if(e&&Array.isArray(e.events))return e.events.filter(t=>t&&typeof t=="object");if(e&&e.type&&e.sessionId)return[e]}catch{}return null}function d3(n){let e=t=>{for(let i of Al(t)||[]){let r=Cn.join(t,i);od(r)&&e(r)}let s=Al(t);if(s&&!s.length)try{_l.rmdirSync(t)}catch{}};e(n)}function Yp({dirs:n,ingest:e,lsFiles:t=c3,dryRun:s=!1,log:i=()=>{}}){let r={found:0,cleaned:0,events:0,files:0,pending:[],tracked:[],foreign:[],unchecked:[]};for(let o of n||[]){let a=l3(o);if(!a)continue;if(r.found++,a.foreign){r.foreign.push({dir:o,path:a.foreign});continue}let l=t(o);if(l===null){r.unchecked.push(o);continue}if(l.length){r.tracked.push(o);continue}if(s){r.pending.push({dir:o,files:a.files.length});continue}let c=0;for(let u of a.files){let d=u3(u);try{d&&d.length&&(r.events+=e(d)||0),_l.unlinkSync(u),r.files++}catch(h){c++,i("stray spool file kept: "+u+" "+h.message)}}d3(a.nullDir),c||r.cleaned++}return r}function GE(n){let e=[];if(!n)return e;n.files&&e.push("✓ removed "+n.files+" stray event file"+(n.files===1?"":"s")+" an older mod left in null/ ("+n.cleaned+" folder"+(n.cleaned===1?"":"s")+")");for(let t of n.pending||[])e.push("· an older mod left a null/ folder in "+Kp(t.dir)+" ("+t.files+" file"+(t.files===1?"":"s")+"); the daemon cleans it up when it starts");for(let t of n.tracked||[])e.push("! an older mod's null/ folder is committed in "+Kp(t)+": git rm -r null/");for(let t of n.foreign||[])e.push("· left "+Kp(Cn.join(t.dir,"null"))+" alone: it holds more than old Leftoff spool files");for(let t of n.unchecked||[])e.push("· left "+Kp(Cn.join(t,"null"))+" alone: couldn't ask git whether it is tracked");return e}var r3,o3,od,a3,Al,Kp,Rk=K(()=>{r3=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,o3=/^\d+-[0-9a-f]{8}\.json$/;od=n=>{try{return _l.lstatSync(n).isDirectory()}catch{return!1}},a3=n=>{try{return _l.lstatSync(n).isFile()}catch{return!1}},Al=n=>{try{return _l.readdirSync(n)}catch{return null}};Kp=n=>{let e=s3.homedir();return e&&(n===e||n.startsWith(e+Cn.sep))?"~"+n.slice(e.length):n}});var Dk=K(()=>{});function $E(n){let e={indent:-1,children:[]},t=[e],s=null;for(let r of String(n||"").split(/\r?\n/)){let o=r.match(/^(\s*)[-*+]\s+(.*)$/);if(o){let a=o[1].replace(/\t/g," ").length;for(;t.length>1&&a<=t[t.length-1].indent;)t.pop();s={indent:a,text:o[2].trim(),children:[]},t[t.length-1].children.push(s),t.push(s)}else if(s&&/^\s+\S/.test(r))s.text+=" "+r.trim();else if(r.trim())s=null,t.length=1;else continue}let i=r=>r.map(({text:o,children:a})=>({text:o,children:i(a)}));return i(e.children)}var qp=K(()=>{});var h3,Fk,$V,KV,Uk=K(()=>{h3="★✶✦✩☆⭐",Fk="─━═\\-",$V=new RegExp("^(`*)\\s*(["+h3+"])\\uFE0F?\\s+([^`"+Fk.replace("\\-","")+"]{1,40}?)\\s*(["+Fk+"]{3,})?\\s*\\1$"),KV=new RegExp("^`*\\s*["+Fk+"]{3,}\\s*`*$")});var Hk=K(()=>{});var Jp=K(()=>{});var WE=K(()=>{Jp()});var YE=K(()=>{});var qE=K(()=>{YE()});function m3(n){let e=n.match(/limit reached\|(\d{9,13})/i);if(e){let s=new Date(Number(e[1])*(e[1].length>11?1:1e3));if(!Number.isNaN(s.getTime()))return"resets "+s.toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}let t=n.match(/\bresets?\s+(?:at\s+)?([^·|\n.]{1,40})/i);return t?"resets "+JE(t[1]).replace(/\s*\(.*$/,""):""}function qo(n,{subtype:e=null,code:t=null,signal:s=null,endReason:i=null}={}){let r=JE(n).slice(0,p3),o=l=>({label:l,raw:r||null});if(r&&/^\[?Request interrupted by user/i.test(r)||!r&&i==="aborted")return null;if(/usage limit|hit your (usage )?limit|limit reached|out of (extra )?usage|weekly limit|session limit/i.test(r)){let l=m3(r);return o("Claude’s usage limit is reached"+(l?" · "+l:""))}if(/rate[ _-]?limit|\b429\b|too many requests/i.test(r))return o("Claude is rate limited right now · try again in a minute");if(/prompt is too long|context (length|window)|too many tokens|maximum context|input is too long/i.test(r))return o("The conversation is too long for Claude · run /compact in its terminal, then retry");if(/overloaded|\b529\b/i.test(r))return o("Claude’s servers are overloaded · try again in a minute");if(/credit balance|billing|payment required|\b402\b/i.test(r))return o("Claude’s account is out of credit");if(/invalid api key|run \/login|please (log|sign) ?in|not logged in|oauth token|token (has )?expired|authentication|\b401\b|\b403\b|unauthori[sz]ed|forbidden/i.test(r))return o(VE);if(/timed? ?out|ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|fetch failed|network|socket hang up|connection (error|refused|reset)/i.test(r))return o("Claude couldn’t reach its servers · check this Mac’s connection");if(/no conversation found|session .*not found/i.test(r))return o("Claude Code couldn’t reopen this conversation");let a=r.match(/API Error:?\s*(\d{3})?/i);return a?o("Claude’s API returned an error"+(a[1]?" ("+a[1]+")":"")):e==="error_max_turns"?o("Claude stopped at its turn limit"):i==="refusal"?o("Claude declined to answer this one"):t!=null||s?o("Claude Code exited"+(t!=null?" (code "+t+")":" ("+s+")")+" before answering"):r?o("Claude Code ended the turn with an error"):i==="error"?o("Claude Code ended the turn with an error (it wrote no details)"):null}function Vp(n=0){return{phase:"sent",at:n,last:n,tool:null,waiting:null,ran:[],endedAt:null}}function Ge(n,e={}){let t={...n||Vp(e.at||0),ran:[...n&&n.ran||[]]},s=e.at||t.last;if(f3.has(t.phase)&&!(t.phase==="replied"&&(e.type==="tool_done"||e.type==="why")))return t.queued&&(delete t.queued,delete t.cancellable,delete t.sendNow),t;switch(t.queued&&!g3.has(e.type)&&(delete t.queued,delete t.cancellable,delete t.sendNow),e.type){case"queued":if(t.phase==="sent"||t.phase==="received")t.queued=!0,t.cancellable=!!e.cancellable,e.cancellable&&e.sendNow?t.sendNow=!0:delete t.sendNow;else return t;break;case"unqueued":break;case"delivered":t.phase==="sent"&&(t.phase="received");break;case"failed":t.phase==="sent"&&(t.phase="failed",t.error=e.error||null,t.endedAt=s);break;case"started":case"text":t.phase!=="replied"&&(t.phase="working"),e.type==="text"&&(t.waiting=null);break;case"tool":t.phase="working",t.tool={name:Tl(e.tool,40),detail:Tl(e.detail,300)},t.waiting=null;break;case"tool_done":{let i=Tl(e.tool||t.tool&&t.tool.name,40);i&&t.ran.push({tool:i,detail:Tl(e.detail||t.tool&&t.tool.detail,300),asked:!!e.asked,...typeof e.id=="string"&&e.id&&e.id.length<=120?{id:e.id}:{}}),t.ran.length>20&&(t.ran=t.ran.slice(-20)),t.tool=null,t.waiting=null;break}case"ask":t.phase="working",t.waiting={tool:Tl(e.tool,40),detail:Tl(e.detail,300)};break;case"ask_done":t.waiting=null;break;case"reply":t.phase="replied",t.tool=null,t.waiting=null,t.endedAt=s;break;case"ended":t.tool=null,t.waiting=null,t.endedAt=s,t.phase=e.text?"replied":"stopped",e.why&&(t.why=e.why);break;case"why":if(e.why&&!(t.why&&t.why.raw&&!e.why.raw))t.why=e.why;else return t;break;case"folded":(t.phase==="sent"||t.phase==="received")&&(t.phase="working"),t.folded=e.owner||!0,t.tool=null,t.waiting=null;break;case"answered":t.phase="replied",t.folded=e.owner||t.folded||!0,t.tool=null,t.waiting=null,t.endedAt=s;break;case"lost":t.tool=null,t.waiting=null,t.endedAt=s,t.phase="stopped",t.lost=!0,e.why&&(t.why=e.why);break;default:return t}return t.last=s,t}function Xp(n){let e=new Set,t=[];for(let s of n&&n.ran||[])s.asked||e.has(s.tool)||(e.add(s.tool),t.push(s.tool));return t}var f3,Tl,p3,JE,VE,XE,g3,Zp=K(()=>{f3=new Set(["replied","failed"]),Tl=(n,e)=>{let t=String(n??"").replace(/\s+/g," ").trim();return t.length>e?t.slice(0,e-1)+"…":t},p3=600,JE=n=>String(n||"").replace(/\s+/g," ").trim();VE="Claude Code isn’t signed in · run /login in a terminal on this Mac",XE=n=>!!n&&n.label===VE;g3=new Set(["delivered","queued","ask_done","noop","why"])});var ZE=K(()=>{});function zk(n){return String(n||"").split(/[\\/]+/).filter(Boolean)}function QE(n){let e=zk(n);return e.length?e[e.length-1]:""}function ad(n){if(!n)return"no-repo";if(n.repoKey)return n.repoKey;let e=n.repo||{};return n.repoRoot||e.root||n.cwd||e.name||n.repoName||"no-repo"}function El(n,e=null){let t=String(n||"").replace(/\/+$/,"");return!t||t==="~"||n==="/"||/^[A-Za-z]:\\?$/.test(t)||e&&t===String(e).replace(/\/+$/,"")?!0:/^\/(Users|home)\/[^/]+$/.test(t)||t==="/root"||t==="/var/root"}function xs(n,{names:e=null}={}){let t=[...new Set([...n].filter(Boolean))],s=new Map(t.map(a=>[a,1])),i=a=>e&&e.get(a)||null,r=new Map;for(let a of t){let l=i(a);l&&r.set(l,(r.get(l)||0)+1)}let o=a=>{if(a==="no-repo"||El(a))return Qp;let l=i(a);if(l&&r.get(l)===1&&s.get(a)===1&&!t.some(u=>u!==a&&!i(u)&&QE(u)===l))return l;let c=zk(a);return c.length?c.slice(-Math.min(s.get(a),c.length)).join("/"):a};for(let a=0;a<12;a++){let l=new Map;for(let u of t){let d=o(u);l.set(d,[...l.get(d)||[],u])}let c=!1;for(let u of l.values())if(!(u.length<2))for(let d of u)s.get(d)<zk(d).length&&(s.set(d,s.get(d)+1),c=!0);if(!c)break}return new Map(t.map(a=>[a,o(a)]))}function em(n){let e=String(n&&n.repoLabel||"").trim(),t=String(n&&n.repoName||"").trim();return!e&&!t?{name:Qp,sub:null}:e===Qp||t==="no-repo"||n&&n.repoKey==="no-repo"?{name:Qp,sub:null}:t?!e||e===t?{name:t,sub:null}:{name:t,sub:e}:{name:e,sub:null}}function Gk(n,{countIn:e}={}){let t=new Map;for(let i of n){let r=ad(i),o=t.get(r)||{key:r,label:i.repoLabel||null,count:0,total:0,last:0};o.total++,o.last=Math.max(o.last,y3(i)),!o.label&&i.repoLabel&&(o.label=i.repoLabel),t.set(r,o)}if(e)for(let i of e){let r=t.get(ad(i));r&&r.count++}else for(let i of t.values())i.count=i.total;let s=xs(t.keys());for(let i of t.values())i.label||(i.label=s.get(i.key));return[...t.values()].sort((i,r)=>r.last-i.last||i.label.localeCompare(r.label))}function Bn(n,e,{loose:t=!1}={}){let s=String(e||"").trim().toLowerCase().replace(/\/+$/,"");if(!s)return!1;let i=ad(n),r=[i,n.repoLabel,n.repoName,QE(i)].filter(Boolean).map(o=>String(o).toLowerCase());return r.includes(s)||s.includes("/")&&String(i).toLowerCase().endsWith("/"+s)||t&&r.some(o=>o.includes(s))?!0:Array.isArray(n.alsoRepos)&&n.alsoRepos.some(o=>o&&o.key&&Bn({repoKey:o.key,repoLabel:o.label},e,{loose:t}))}function tm(n,e){if(!e)return n;let t=n.filter(s=>Bn(s,e));return t.length?t:n.filter(s=>Bn(s,e,{loose:!0}))}function ld(n,e,t=[]){let s=String(e||"").toLowerCase().trim().split(/\s+/).filter(Boolean);if(!s.length)return!0;let i=n.lastCheckpoint||null,r=[n.title,n.repoLabel,n.repoName,n.repoProject&&n.repoProject.name,n.repo&&n.repo.branch,n.repo&&n.repo.github,n.worktree&&n.worktree.name,n.worktree&&n.worktree.branch,n.cwd,n.lastPreview,n.firstPrompt,n.machine,i&&i.doing,i&&i.next,i&&i.stoppedAt,...t].filter(Boolean).map(l=>String(l).toLowerCase()),o=String(n.id||"").toLowerCase(),a=String(n.shortId||"").toLowerCase();return s.every(l=>{let c=l.replace(/^cp:/,"");return c.length>=4&&(o.startsWith(c)||a&&a===c)?!0:l.startsWith("cp:")?!1:r.some(u=>u.includes(l))})}var Qp,Bk,y3,Ws=K(()=>{Qp="No repo";Bk=n=>{let e=Date.parse(n||"");return isNaN(e)?0:e},y3=n=>Math.max(Bk(n.lastActivityAt),Bk(n.endedAt),Bk(n.startedAt))});var cd=K(()=>{Hn();Jp()});var eC=K(()=>{Zp();ZE();Hn();Ws();cd()});var $k=K(()=>{cd();Jp()});var Kk=K(()=>{});function ud(n){let s=(String(n||"").replace(/\s+/g," ").trim().split(/(?<=[.!?])\s+(?=\S)/).filter(r=>/\?\s*$/.test(r)).pop()||"").replace(/[*_`]+/g,"").match(/^(.*?)(?::|\s[—–-]\s)\s*(.+?)\s*\?\s*$/);if(!s||!/\bor\b/i.test(s[2]))return[];let i=s[2].split(/\s*,\s*(?:or\s+|and\s+)?|\s+or\s+/i).map(r=>r.trim().replace(/[.;:]$/,"")).filter(Boolean);return i.length<2||i.length>6||i.some(r=>r.length>60)||/^(not|no|neither|something else|anything else)\b/i.test(i[i.length-1])?[]:i.map(N3)}var N3,Wk=K(()=>{Dk();qp();Uk();Hk();WE();qE();eC();cd();$k();Kk();N3=n=>n.charAt(0).toUpperCase()+n.slice(1)});import I3 from"node:path";function tC(n){let e=[],t=!1;for(let s of Yk(n).split(`
205
+ `)}aliveMachines(){let e=[],t=ge.join(this.p.digests,".machines"),s=[];try{s=Se.readdirSync(t).filter(i=>i.endsWith(".json")&&!i.startsWith(".")&&!Ko(i))}catch{}for(let i of s)try{let r=JSON.parse(Se.readFileSync(ge.join(t,i),"utf8"));r&&r.machine&&e.push(r)}catch{}return e}writeCatchup(e,t){Se.mkdirSync(this.p.catchups,{recursive:!0});let s=String(e).replace(/\.md$/,"");for(let i=0;i<50;i++){let r=i?s+"-"+(i+1):s,o=ge.join(this.p.catchups,r+".md");try{let a=ge.join(this.p.catchups,"."+r+"."+process.pid+"."+Pk.randomBytes(4).toString("hex")+".tmp");Se.writeFileSync(a,t);try{try{Se.linkSync(a,o)}catch(l){if(l.code==="EEXIST")throw l;Se.writeFileSync(o,t,{flag:"wx"})}}finally{try{Se.unlinkSync(a)}catch{}}return{name:r,file:o}}catch(a){if(a.code!=="EEXIST")throw a}}throw new Error("could not find a free catch-up file name")}readCatchup(e){if(!/^\d{4}-\d{2}-\d{2}T\d{4}(?:-\d+)?$/.test(String(e||"")))return null;try{return{name:e,markdown:Se.readFileSync(ge.join(this.p.catchups,e+".md"),"utf8")}}catch{return null}}listCatchups(){let e=[];try{e=Se.readdirSync(this.p.catchups).filter(i=>/^\d{4}-\d{2}-\d{2}T\d{4}(?:-\d+)?\.md$/.test(i))}catch{return[]}let t=[];for(let i of e){let r={};try{let o=Se.openSync(ge.join(this.p.catchups,i),"r");try{let a=Buffer.alloc(8192),l=Se.readSync(o,a,0,a.length,0);r=Tt(a.slice(0,l).toString("utf8")).data||{}}finally{Se.closeSync(o)}}catch{}t.push({name:i.slice(0,-3),generatedAt:r.generated_at?Z(r.generated_at):null,from:r.window_from?Z(r.window_from):null,to:r.window_to?Z(r.window_to):null,label:r.window_label||null,sessions:typeof r.sessions=="number"?r.sessions:null,needsYou:Array.isArray(r.needs_you)?r.needs_you.length:0,repos:r.repos==="all"||r.repos==null?"all":[].concat(r.repos).map(String),machine:r.made_on==null?null:String(r.made_on),model:r.model==null?null:String(r.model)})}let s=i=>Date.parse(i.generatedAt||"")||0;return t.sort((i,r)=>s(r)-s(i)||r.name.localeCompare(i.name))}lastCatchupAt(){let e=this.listCatchups()[0];if(!e)return null;let t=Date.parse(e.to||e.generatedAt||"");return isNaN(t)?null:t}readSpool(){let e=[];for(let t of Mi(this.mySpool)){let s=ge.join(this.mySpool,t),i=[];try{i=Se.readdirSync(s)}catch{}for(let r of i){if(!r.endsWith(".json"))continue;let o=ge.join(s,r),a=null;try{a=Se.readFileSync(o,"utf8")}catch{continue}e.push({file:o,t:Number(r.split("-")[0])||0,body:a})}}return e.sort((t,s)=>t.t-s.t||t.file.localeCompare(s.file))}spoolCount(){let e=0;for(let t of Mi(this.mySpool))try{e+=Se.readdirSync(ge.join(this.mySpool,t)).filter(s=>s.endsWith(".json")).length}catch{}return e}}});import _l from"node:fs";import sU from"node:os";import Cn from"node:path";import{execFileSync as iU}from"node:child_process";function Wp(n){let e=new Set;for(let t of n||[])for(let s of[t&&t.cwd,t&&t.repo&&t.repo.root])typeof s=="string"&&Cn.isAbsolute(s)&&e.add(Cn.resolve(s));return[...e]}function lU(n){let e=Cn.join(n,"null"),t=Cn.join(e,".spool");if(!od(e)||!od(t))return null;let s={dir:n,nullDir:e,files:[],foreign:null},i=r=>(s.foreign=s.foreign||r,s);for(let r of Al(e)||[])if(r!==".spool")return i(Cn.join(e,r));for(let r of Al(t)||[]){let o=Cn.join(t,r);if(!od(o))return i(o);for(let a of Al(o)||[]){let l=Cn.join(o,a);if(!rU.test(a)||!od(l))return i(l);for(let c of Al(l)||[]){let u=Cn.join(l,c);if(!oU.test(c)||!aU(u))return i(u);s.files.push(u)}}}return s.files.sort((r,o)=>Number(Cn.basename(r).split("-")[0])-Number(Cn.basename(o).split("-")[0])||r.localeCompare(o)),s}function cU(n){try{return String(iU("git",["-C",n,"ls-files","--","null/"],{encoding:"utf8",timeout:5e3,stdio:["ignore","pipe","pipe"]})).split(`
206
+ `).filter(Boolean)}catch(e){return/not a git repository/i.test(String(e.stderr||""))?[]:null}}function uU(n){try{let e=JSON.parse(_l.readFileSync(n,"utf8"));if(e&&Array.isArray(e.events))return e.events.filter(t=>t&&typeof t=="object");if(e&&e.type&&e.sessionId)return[e]}catch{}return null}function dU(n){let e=t=>{for(let i of Al(t)||[]){let r=Cn.join(t,i);od(r)&&e(r)}let s=Al(t);if(s&&!s.length)try{_l.rmdirSync(t)}catch{}};e(n)}function Yp({dirs:n,ingest:e,lsFiles:t=cU,dryRun:s=!1,log:i=()=>{}}){let r={found:0,cleaned:0,events:0,files:0,pending:[],tracked:[],foreign:[],unchecked:[]};for(let o of n||[]){let a=lU(o);if(!a)continue;if(r.found++,a.foreign){r.foreign.push({dir:o,path:a.foreign});continue}let l=t(o);if(l===null){r.unchecked.push(o);continue}if(l.length){r.tracked.push(o);continue}if(s){r.pending.push({dir:o,files:a.files.length});continue}let c=0;for(let u of a.files){let d=uU(u);try{d&&d.length&&(r.events+=e(d)||0),_l.unlinkSync(u),r.files++}catch(h){c++,i("stray spool file kept: "+u+" "+h.message)}}dU(a.nullDir),c||r.cleaned++}return r}function GE(n){let e=[];if(!n)return e;n.files&&e.push("✓ removed "+n.files+" stray event file"+(n.files===1?"":"s")+" an older mod left in null/ ("+n.cleaned+" folder"+(n.cleaned===1?"":"s")+")");for(let t of n.pending||[])e.push("· an older mod left a null/ folder in "+Kp(t.dir)+" ("+t.files+" file"+(t.files===1?"":"s")+"); the daemon cleans it up when it starts");for(let t of n.tracked||[])e.push("! an older mod's null/ folder is committed in "+Kp(t)+": git rm -r null/");for(let t of n.foreign||[])e.push("· left "+Kp(Cn.join(t.dir,"null"))+" alone: it holds more than old Leftoff spool files");for(let t of n.unchecked||[])e.push("· left "+Kp(Cn.join(t,"null"))+" alone: couldn't ask git whether it is tracked");return e}var rU,oU,od,aU,Al,Kp,Rk=K(()=>{rU=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,oU=/^\d+-[0-9a-f]{8}\.json$/;od=n=>{try{return _l.lstatSync(n).isDirectory()}catch{return!1}},aU=n=>{try{return _l.lstatSync(n).isFile()}catch{return!1}},Al=n=>{try{return _l.readdirSync(n)}catch{return null}};Kp=n=>{let e=sU.homedir();return e&&(n===e||n.startsWith(e+Cn.sep))?"~"+n.slice(e.length):n}});var Dk=K(()=>{});function $E(n){let e={indent:-1,children:[]},t=[e],s=null;for(let r of String(n||"").split(/\r?\n/)){let o=r.match(/^(\s*)[-*+]\s+(.*)$/);if(o){let a=o[1].replace(/\t/g," ").length;for(;t.length>1&&a<=t[t.length-1].indent;)t.pop();s={indent:a,text:o[2].trim(),children:[]},t[t.length-1].children.push(s),t.push(s)}else if(s&&/^\s+\S/.test(r))s.text+=" "+r.trim();else if(r.trim())s=null,t.length=1;else continue}let i=r=>r.map(({text:o,children:a})=>({text:o,children:i(a)}));return i(e.children)}var qp=K(()=>{});var hU,Fk,$V,KV,Uk=K(()=>{hU="★✶✦✩☆⭐",Fk="─━═\\-",$V=new RegExp("^(`*)\\s*(["+hU+"])\\uFE0F?\\s+([^`"+Fk.replace("\\-","")+"]{1,40}?)\\s*(["+Fk+"]{3,})?\\s*\\1$"),KV=new RegExp("^`*\\s*["+Fk+"]{3,}\\s*`*$")});var Hk=K(()=>{});var Jp=K(()=>{});var WE=K(()=>{Jp()});var YE=K(()=>{});var qE=K(()=>{YE()});function mU(n){let e=n.match(/limit reached\|(\d{9,13})/i);if(e){let s=new Date(Number(e[1])*(e[1].length>11?1:1e3));if(!Number.isNaN(s.getTime()))return"resets "+s.toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}let t=n.match(/\bresets?\s+(?:at\s+)?([^·|\n.]{1,40})/i);return t?"resets "+JE(t[1]).replace(/\s*\(.*$/,""):""}function qo(n,{subtype:e=null,code:t=null,signal:s=null,endReason:i=null}={}){let r=JE(n).slice(0,pU),o=l=>({label:l,raw:r||null});if(r&&/^\[?Request interrupted by user/i.test(r)||!r&&i==="aborted")return null;if(/usage limit|hit your (usage )?limit|limit reached|out of (extra )?usage|weekly limit|session limit/i.test(r)){let l=mU(r);return o("Claude’s usage limit is reached"+(l?" · "+l:""))}if(/rate[ _-]?limit|\b429\b|too many requests/i.test(r))return o("Claude is rate limited right now · try again in a minute");if(/prompt is too long|context (length|window)|too many tokens|maximum context|input is too long/i.test(r))return o("The conversation is too long for Claude · run /compact in its terminal, then retry");if(/overloaded|\b529\b/i.test(r))return o("Claude’s servers are overloaded · try again in a minute");if(/credit balance|billing|payment required|\b402\b/i.test(r))return o("Claude’s account is out of credit");if(/invalid api key|run \/login|please (log|sign) ?in|not logged in|oauth token|token (has )?expired|authentication|\b401\b|\b403\b|unauthori[sz]ed|forbidden/i.test(r))return o(VE);if(/timed? ?out|ECONNRESET|ECONNREFUSED|ENOTFOUND|EAI_AGAIN|fetch failed|network|socket hang up|connection (error|refused|reset)/i.test(r))return o("Claude couldn’t reach its servers · check this Mac’s connection");if(/no conversation found|session .*not found/i.test(r))return o("Claude Code couldn’t reopen this conversation");let a=r.match(/API Error:?\s*(\d{3})?/i);return a?o("Claude’s API returned an error"+(a[1]?" ("+a[1]+")":"")):e==="error_max_turns"?o("Claude stopped at its turn limit"):i==="refusal"?o("Claude declined to answer this one"):t!=null||s?o("Claude Code exited"+(t!=null?" (code "+t+")":" ("+s+")")+" before answering"):r?o("Claude Code ended the turn with an error"):i==="error"?o("Claude Code ended the turn with an error (it wrote no details)"):null}function Vp(n=0){return{phase:"sent",at:n,last:n,tool:null,waiting:null,ran:[],endedAt:null}}function Ge(n,e={}){let t={...n||Vp(e.at||0),ran:[...n&&n.ran||[]]},s=e.at||t.last;if(fU.has(t.phase)&&!(t.phase==="replied"&&(e.type==="tool_done"||e.type==="why")))return t.queued&&(delete t.queued,delete t.cancellable,delete t.sendNow),t;switch(t.queued&&!gU.has(e.type)&&(delete t.queued,delete t.cancellable,delete t.sendNow),e.type){case"queued":if(t.phase==="sent"||t.phase==="received")t.queued=!0,t.cancellable=!!e.cancellable,e.cancellable&&e.sendNow?t.sendNow=!0:delete t.sendNow;else return t;break;case"unqueued":break;case"delivered":t.phase==="sent"&&(t.phase="received");break;case"failed":t.phase==="sent"&&(t.phase="failed",t.error=e.error||null,t.endedAt=s);break;case"started":case"text":t.phase!=="replied"&&(t.phase="working"),e.type==="text"&&(t.waiting=null);break;case"tool":t.phase="working",t.tool={name:Tl(e.tool,40),detail:Tl(e.detail,300)},t.waiting=null;break;case"tool_done":{let i=Tl(e.tool||t.tool&&t.tool.name,40);i&&t.ran.push({tool:i,detail:Tl(e.detail||t.tool&&t.tool.detail,300),asked:!!e.asked,...typeof e.id=="string"&&e.id&&e.id.length<=120?{id:e.id}:{}}),t.ran.length>20&&(t.ran=t.ran.slice(-20)),t.tool=null,t.waiting=null;break}case"ask":t.phase="working",t.waiting={tool:Tl(e.tool,40),detail:Tl(e.detail,300)};break;case"ask_done":t.waiting=null;break;case"reply":t.phase="replied",t.tool=null,t.waiting=null,t.endedAt=s;break;case"ended":t.tool=null,t.waiting=null,t.endedAt=s,t.phase=e.text?"replied":"stopped",e.why&&(t.why=e.why);break;case"why":if(e.why&&!(t.why&&t.why.raw&&!e.why.raw))t.why=e.why;else return t;break;case"folded":(t.phase==="sent"||t.phase==="received")&&(t.phase="working"),t.folded=e.owner||!0,t.tool=null,t.waiting=null;break;case"answered":t.phase="replied",t.folded=e.owner||t.folded||!0,t.tool=null,t.waiting=null,t.endedAt=s;break;case"lost":t.tool=null,t.waiting=null,t.endedAt=s,t.phase="stopped",t.lost=!0,e.why&&(t.why=e.why);break;default:return t}return t.last=s,t}function Xp(n){let e=new Set,t=[];for(let s of n&&n.ran||[])s.asked||e.has(s.tool)||(e.add(s.tool),t.push(s.tool));return t}var fU,Tl,pU,JE,VE,XE,gU,Zp=K(()=>{fU=new Set(["replied","failed"]),Tl=(n,e)=>{let t=String(n??"").replace(/\s+/g," ").trim();return t.length>e?t.slice(0,e-1)+"…":t},pU=600,JE=n=>String(n||"").replace(/\s+/g," ").trim();VE="Claude Code isn’t signed in · run /login in a terminal on this Mac",XE=n=>!!n&&n.label===VE;gU=new Set(["delivered","queued","ask_done","noop","why"])});var ZE=K(()=>{});function zk(n){return String(n||"").split(/[\\/]+/).filter(Boolean)}function QE(n){let e=zk(n);return e.length?e[e.length-1]:""}function ad(n){if(!n)return"no-repo";if(n.repoKey)return n.repoKey;let e=n.repo||{};return n.repoRoot||e.root||n.cwd||e.name||n.repoName||"no-repo"}function El(n,e=null){let t=String(n||"").replace(/\/+$/,"");return!t||t==="~"||n==="/"||/^[A-Za-z]:\\?$/.test(t)||e&&t===String(e).replace(/\/+$/,"")?!0:/^\/(Users|home)\/[^/]+$/.test(t)||t==="/root"||t==="/var/root"}function xs(n,{names:e=null}={}){let t=[...new Set([...n].filter(Boolean))],s=new Map(t.map(a=>[a,1])),i=a=>e&&e.get(a)||null,r=new Map;for(let a of t){let l=i(a);l&&r.set(l,(r.get(l)||0)+1)}let o=a=>{if(a==="no-repo"||El(a))return Qp;let l=i(a);if(l&&r.get(l)===1&&s.get(a)===1&&!t.some(u=>u!==a&&!i(u)&&QE(u)===l))return l;let c=zk(a);return c.length?c.slice(-Math.min(s.get(a),c.length)).join("/"):a};for(let a=0;a<12;a++){let l=new Map;for(let u of t){let d=o(u);l.set(d,[...l.get(d)||[],u])}let c=!1;for(let u of l.values())if(!(u.length<2))for(let d of u)s.get(d)<zk(d).length&&(s.set(d,s.get(d)+1),c=!0);if(!c)break}return new Map(t.map(a=>[a,o(a)]))}function em(n){let e=String(n&&n.repoLabel||"").trim(),t=String(n&&n.repoName||"").trim();return!e&&!t?{name:Qp,sub:null}:e===Qp||t==="no-repo"||n&&n.repoKey==="no-repo"?{name:Qp,sub:null}:t?!e||e===t?{name:t,sub:null}:{name:t,sub:e}:{name:e,sub:null}}function Gk(n,{countIn:e}={}){let t=new Map;for(let i of n){let r=ad(i),o=t.get(r)||{key:r,label:i.repoLabel||null,count:0,total:0,last:0};o.total++,o.last=Math.max(o.last,yU(i)),!o.label&&i.repoLabel&&(o.label=i.repoLabel),t.set(r,o)}if(e)for(let i of e){let r=t.get(ad(i));r&&r.count++}else for(let i of t.values())i.count=i.total;let s=xs(t.keys());for(let i of t.values())i.label||(i.label=s.get(i.key));return[...t.values()].sort((i,r)=>r.last-i.last||i.label.localeCompare(r.label))}function Bn(n,e,{loose:t=!1}={}){let s=String(e||"").trim().toLowerCase().replace(/\/+$/,"");if(!s)return!1;let i=ad(n),r=[i,n.repoLabel,n.repoName,QE(i)].filter(Boolean).map(o=>String(o).toLowerCase());return r.includes(s)||s.includes("/")&&String(i).toLowerCase().endsWith("/"+s)||t&&r.some(o=>o.includes(s))?!0:Array.isArray(n.alsoRepos)&&n.alsoRepos.some(o=>o&&o.key&&Bn({repoKey:o.key,repoLabel:o.label},e,{loose:t}))}function tm(n,e){if(!e)return n;let t=n.filter(s=>Bn(s,e));return t.length?t:n.filter(s=>Bn(s,e,{loose:!0}))}function ld(n,e,t=[]){let s=String(e||"").toLowerCase().trim().split(/\s+/).filter(Boolean);if(!s.length)return!0;let i=n.lastCheckpoint||null,r=[n.title,n.repoLabel,n.repoName,n.repoProject&&n.repoProject.name,n.repo&&n.repo.branch,n.repo&&n.repo.github,n.worktree&&n.worktree.name,n.worktree&&n.worktree.branch,n.cwd,n.lastPreview,n.firstPrompt,n.machine,i&&i.doing,i&&i.next,i&&i.stoppedAt,...t].filter(Boolean).map(l=>String(l).toLowerCase()),o=String(n.id||"").toLowerCase(),a=String(n.shortId||"").toLowerCase();return s.every(l=>{let c=l.replace(/^cp:/,"");return c.length>=4&&(o.startsWith(c)||a&&a===c)?!0:l.startsWith("cp:")?!1:r.some(u=>u.includes(l))})}var Qp,Bk,yU,Ws=K(()=>{Qp="No repo";Bk=n=>{let e=Date.parse(n||"");return isNaN(e)?0:e},yU=n=>Math.max(Bk(n.lastActivityAt),Bk(n.endedAt),Bk(n.startedAt))});var cd=K(()=>{Hn();Jp()});var eC=K(()=>{Zp();ZE();Hn();Ws();cd()});var $k=K(()=>{cd();Jp()});var Kk=K(()=>{});function ud(n){let s=(String(n||"").replace(/\s+/g," ").trim().split(/(?<=[.!?])\s+(?=\S)/).filter(r=>/\?\s*$/.test(r)).pop()||"").replace(/[*_`]+/g,"").match(/^(.*?)(?::|\s[—–-]\s)\s*(.+?)\s*\?\s*$/);if(!s||!/\bor\b/i.test(s[2]))return[];let i=s[2].split(/\s*,\s*(?:or\s+|and\s+)?|\s+or\s+/i).map(r=>r.trim().replace(/[.;:]$/,"")).filter(Boolean);return i.length<2||i.length>6||i.some(r=>r.length>60)||/^(not|no|neither|something else|anything else)\b/i.test(i[i.length-1])?[]:i.map(NU)}var NU,Wk=K(()=>{Dk();qp();Uk();Hk();WE();qE();eC();cd();$k();Kk();NU=n=>n.charAt(0).toUpperCase()+n.slice(1)});import IU from"node:path";function tC(n){let e=[],t=!1;for(let s of Yk(n).split(`
207
207
  `)){if(/^\s*(```|~~~)/.test(s)){t=!t;continue}t||e.push(s)}return e.join(`
208
- `)}function L3(n,e){let t=Yk(n).trimEnd(),s=Jo(e).replace(/[*_`]+/g,"");if(!s)return t;let i=s.split(`
208
+ `)}function LU(n,e){let t=Yk(n).trimEnd(),s=Jo(e).replace(/[*_`]+/g,"");if(!s)return t;let i=s.split(`
209
209
  `)[0].slice(0,40).toLowerCase(),r=[],o="";for(let c=0;c<t.length;c++){let u=t[c];if(!/[*_`]/.test(u)){if(/\s/.test(u)){if(o.endsWith(" ")||!o)continue;o+=" ",r.push(c);continue}o+=u.toLowerCase(),r.push(c)}}let a=o.lastIndexOf(i);if(a>=0)return t.slice(0,r[a]).trimEnd();let l=t.split(/\n\s*\n/);return/[??][\s*_`)"'”’]*$/.test(l[l.length-1]||"")&&l.pop(),l.join(`
210
210
 
211
- `).trimEnd()}function nC(n=[],{question:e=null,max:t=3,width:s=280}={}){let i=[],r=[],o=!0;for(let a=n.length-1;a>=0&&i.length<t;a--){let l=n[a];if(j3(l))break;if(!l||l.role!=="assistant"||!l.text||!l.text.trim())continue;let c=l.text;if(o){let d=e?ud(e):[],h=e?L3(c,e):c;r=d.length?d:!e||qk.test(e)?Jk(h,{trailing:!!e}):[],e&&(c=h),o=!1}let u=tC(c).split(`
211
+ `).trimEnd()}function nC(n=[],{question:e=null,max:t=3,width:s=280}={}){let i=[],r=[],o=!0;for(let a=n.length-1;a>=0&&i.length<t;a--){let l=n[a];if(jU(l))break;if(!l||l.role!=="assistant"||!l.text||!l.text.trim())continue;let c=l.text;if(o){let d=e?ud(e):[],h=e?LU(c,e):c;r=d.length?d:!e||qk.test(e)?Jk(h,{trailing:!!e}):[],e&&(c=h),o=!1}let u=tC(c).split(`
212
212
  `).map(d=>d.trim()).filter(d=>d&&!/^#{1,6}\s*$/.test(d)&&!/^[-*_]{3,}$/.test(d));for(let d=u.length-1;d>=0&&i.length<t;d--)i.unshift(Ys(u[d].replace(/^#{1,6}\s+/,""),s))}return!i.length&&!r.length?null:{lines:i,options:r}}function Jk(n,{trailing:e=!1}={}){let t=tC(n).split(`
213
- `).map(l=>l.trim()).filter(Boolean),s=[],i=[];for(let l of t){let c=l.match(/^(?:\*\*)?(?:option\s+)?([0-9]{1,2}|[a-fA-F])[.):](?:\*\*)?\s+(.+)$/i);if(c)s.push({key:c[1],text:c[2]});else{if(s.length&&e&&/^[-*+•]\s/.test(l))continue;s.length&&(i.splice(0,i.length,...s),s=[])}}if(e&&!s.length)return[];let r=s.length?s:i;if(r.length<2||r.length>6)return[];let o=r.map(l=>l.key.toLowerCase());return o.every((l,c)=>/\d/.test(l)?Number(l)===Number(o[0])+c:l.charCodeAt(0)===o[0].charCodeAt(0)+c)?r.map(l=>Ys(l.key+". "+l.text.replace(/\*\*/g,"").replace(/\s+[—–-]\s+.*$/,"").replace(/[:.]$/,"").trim(),60)):[]}function Vk(n={},{cwd:e}={}){let t=n.input||{},s=String(n.tool||"tool"),i=P3(t.file_path||t.notebook_path||t.path,e);switch(s){case"Edit":case"MultiEdit":case"NotebookEdit":return"Edited "+(i||"a file");case"Write":return"Wrote "+(i||"a file");case"Read":return"Read "+(i||"a file");case"Bash":{let r=Jo(t.command);return R3.test(r)?"Ran tests":/^git\s+commit\b/.test(r)?"Committed":/^git\s+push\b/.test(r)?"Pushed":"Ran "+Ys(t.description?Jo(t.description):r||"a command",48)}case"Grep":return"Searched “"+Ys(Jo(t.pattern),32)+"”";case"Glob":return"Listed "+Ys(Jo(t.pattern),32);case"LS":return"Listed "+(i||"a folder");case"WebFetch":{let r="";try{r=new URL(t.url).hostname}catch{}return"Fetched "+(r||"a page")}case"WebSearch":return"Searched the web for “"+Ys(Jo(t.query),32)+"”";case"TodoWrite":return"Updated the to-do list";case"Task":case"Agent":return"Ran an agent"+(t.description?": "+Ys(Jo(t.description),36):"");case"AskUserQuestion":return"Asked you";case"ExitPlanMode":return"Proposed a plan";default:return"Used "+Ys(s.replace(/^mcp__/,"").replace(/__/g," "),40)}}function Vo(n=[],{limit:e=20,cwd:t=null,textMax:s=6e3}={}){let i=[];for(let r of n){if(!r)continue;if(r.role==="user"){if(!r.text||!r.text.trim())continue;i.push({role:"user",text:Ys(r.text.trim(),s),chips:[]});continue}let o=(r.text||"").trim(),a=(r.toolUses||[]).map(c=>({label:Vk(c,{cwd:t}),error:!!c.isError})),l=i[i.length-1];(!l||l.role!=="assistant"||o&&l.chips.length)&&(l={role:"assistant",text:"",chips:[]},i.push(l)),o&&(l.text=Ys(l.text?l.text+`
213
+ `).map(l=>l.trim()).filter(Boolean),s=[],i=[];for(let l of t){let c=l.match(/^(?:\*\*)?(?:option\s+)?([0-9]{1,2}|[a-fA-F])[.):](?:\*\*)?\s+(.+)$/i);if(c)s.push({key:c[1],text:c[2]});else{if(s.length&&e&&/^[-*+•]\s/.test(l))continue;s.length&&(i.splice(0,i.length,...s),s=[])}}if(e&&!s.length)return[];let r=s.length?s:i;if(r.length<2||r.length>6)return[];let o=r.map(l=>l.key.toLowerCase());return o.every((l,c)=>/\d/.test(l)?Number(l)===Number(o[0])+c:l.charCodeAt(0)===o[0].charCodeAt(0)+c)?r.map(l=>Ys(l.key+". "+l.text.replace(/\*\*/g,"").replace(/\s+[—–-]\s+.*$/,"").replace(/[:.]$/,"").trim(),60)):[]}function Vk(n={},{cwd:e}={}){let t=n.input||{},s=String(n.tool||"tool"),i=PU(t.file_path||t.notebook_path||t.path,e);switch(s){case"Edit":case"MultiEdit":case"NotebookEdit":return"Edited "+(i||"a file");case"Write":return"Wrote "+(i||"a file");case"Read":return"Read "+(i||"a file");case"Bash":{let r=Jo(t.command);return RU.test(r)?"Ran tests":/^git\s+commit\b/.test(r)?"Committed":/^git\s+push\b/.test(r)?"Pushed":"Ran "+Ys(t.description?Jo(t.description):r||"a command",48)}case"Grep":return"Searched “"+Ys(Jo(t.pattern),32)+"”";case"Glob":return"Listed "+Ys(Jo(t.pattern),32);case"LS":return"Listed "+(i||"a folder");case"WebFetch":{let r="";try{r=new URL(t.url).hostname}catch{}return"Fetched "+(r||"a page")}case"WebSearch":return"Searched the web for “"+Ys(Jo(t.query),32)+"”";case"TodoWrite":return"Updated the to-do list";case"Task":case"Agent":return"Ran an agent"+(t.description?": "+Ys(Jo(t.description),36):"");case"AskUserQuestion":return"Asked you";case"ExitPlanMode":return"Proposed a plan";default:return"Used "+Ys(s.replace(/^mcp__/,"").replace(/__/g," "),40)}}function Vo(n=[],{limit:e=20,cwd:t=null,textMax:s=6e3}={}){let i=[];for(let r of n){if(!r)continue;if(r.role==="user"){if(!r.text||!r.text.trim())continue;i.push({role:"user",text:Ys(r.text.trim(),s),chips:[]});continue}let o=(r.text||"").trim(),a=(r.toolUses||[]).map(c=>({label:Vk(c,{cwd:t}),error:!!c.isError})),l=i[i.length-1];(!l||l.role!=="assistant"||o&&l.chips.length)&&(l={role:"assistant",text:"",chips:[]},i.push(l)),o&&(l.text=Ys(l.text?l.text+`
214
214
 
215
- `+o:o,s));for(let c of a){let u=l.chips[l.chips.length-1];u&&u.label===c.label&&u.error===c.error?u.n=(u.n||1)+1:l.chips.push(c)}}return i.slice(-Math.max(1,e))}var Ys,Yk,Jo,qk,j3,P3,R3,dd=K(()=>{Wk();Ys=(n,e)=>(n=String(n??""),n.length>e?n.slice(0,e-1).trimEnd()+"…":n),Yk=n=>String(n??"").replace(/\r\n?/g,`
216
- `),Jo=n=>Yk(n).replace(/\s+/g," ").trim();qk=/\b(which|or|options?|prefer|pick|choose|one of)\b/i,j3=n=>n&&n.role==="user"&&n.text&&n.text.trim();P3=(n,e)=>{let t=String(n||"");return t?e&&t.startsWith(String(e).replace(/\/$/,"")+"/")?t.slice(String(e).replace(/\/$/,"").length+1):t.includes("/")?I3.basename(t):t:""},R3=/(^|[\s;&|(])((p?npm|yarn|pnpm|bun)\s+(run\s+)?test\b|node\s+--test\b|(npx\s+)?(jest|vitest|mocha|pytest|playwright\s+test)\b|go\s+test\b|cargo\s+test\b|rspec\b|make\s+test\b|swift\s+test\b|xcodebuild\s+test\b|node\s+test\/)/});function sC(n,e,{start:t=1,context:s=3,maxLines:i=2e3}={}){let r=String(n??"").split(`
215
+ `+o:o,s));for(let c of a){let u=l.chips[l.chips.length-1];u&&u.label===c.label&&u.error===c.error?u.n=(u.n||1)+1:l.chips.push(c)}}return i.slice(-Math.max(1,e))}var Ys,Yk,Jo,qk,jU,PU,RU,dd=K(()=>{Wk();Ys=(n,e)=>(n=String(n??""),n.length>e?n.slice(0,e-1).trimEnd()+"…":n),Yk=n=>String(n??"").replace(/\r\n?/g,`
216
+ `),Jo=n=>Yk(n).replace(/\s+/g," ").trim();qk=/\b(which|or|options?|prefer|pick|choose|one of)\b/i,jU=n=>n&&n.role==="user"&&n.text&&n.text.trim();PU=(n,e)=>{let t=String(n||"");return t?e&&t.startsWith(String(e).replace(/\/$/,"")+"/")?t.slice(String(e).replace(/\/$/,"").length+1):t.includes("/")?IU.basename(t):t:""},RU=/(^|[\s;&|(])((p?npm|yarn|pnpm|bun)\s+(run\s+)?test\b|node\s+--test\b|(npx\s+)?(jest|vitest|mocha|pytest|playwright\s+test)\b|go\s+test\b|cargo\s+test\b|rspec\b|make\s+test\b|swift\s+test\b|xcodebuild\s+test\b|node\s+test\/)/});function sC(n,e,{start:t=1,context:s=3,maxLines:i=2e3}={}){let r=String(n??"").split(`
217
217
  `),o=String(e??"").split(`
218
218
  `);if(r.length>i||o.length>i)return null;r.length>1&&o.length>1&&r[r.length-1]===""&&o[o.length-1]===""&&(r.pop(),o.pop());let a=0;for(;a<r.length&&a<o.length&&r[a]===o[a];)a++;let l=0;for(;l<r.length-a&&l<o.length-a&&r[r.length-1-l]===o[o.length-1-l];)l++;let c=r.slice(a,r.length-l),u=o.slice(a,o.length-l),d=c.length,h=u.length,f=[];for(let v=0;v<a;v++)f.push([" ",r[v]]);if(d*h>4e6){for(let v of c)f.push(["-",v]);for(let v of u)f.push(["+",v])}else{let v=h+1,x=new Uint32Array((d+1)*v);for(let T=d-1;T>=0;T--)for(let g=h-1;g>=0;g--)x[T*v+g]=c[T]===u[g]?x[(T+1)*v+g+1]+1:Math.max(x[(T+1)*v+g],x[T*v+g+1]);let E=0,A=0;for(;E<d||A<h;)E<d&&A<h&&c[E]===u[A]?(f.push([" ",c[E]]),E++,A++):A<h&&(E>=d||x[E*v+A+1]>=x[(E+1)*v+A])?(f.push(["+",u[A]]),A++):(f.push(["-",c[E]]),E++)}for(let v=r.length-l;v<r.length;v++)f.push([" ",r[v]]);for(let v=0;v<f.length;v++){if(f[v][0]===" ")continue;let x=v;for(;x<f.length&&f[x][0]!==" ";)x++;let E=f.slice(v,x),A=[...E.filter(T=>T[0]==="-"),...E.filter(T=>T[0]==="+")];f.splice(v,x-v,...A),v=x-1}let p=f.map((v,x)=>v[0]!==" "?x:-1).filter(v=>v>=0);if(!p.length)return"";let m=[];for(let v of p){let x=Math.max(0,v-s),E=Math.min(f.length-1,v+s),A=m[m.length-1];A&&x<=A[1]+1?A[1]=E:m.push([x,E])}let y="",w=t,S=t,k=0;for(let[v,x]of m){for(;k<v;k++)f[k][0]!=="+"&&w++,f[k][0]!=="-"&&S++;let E=0,A=0,T="";for(let g=v;g<=x;g++){let[b,C]=f[g];b!=="+"&&E++,b!=="-"&&A++,T+=b+C+`
219
219
  `}for(y+="@@ -"+(E?w:w-1)+","+E+" +"+(A?S:S-1)+","+A+` @@
220
- `+T;k<=x;k++)f[k][0]!=="+"&&w++,f[k][0]!=="-"&&S++}return y}var iC=K(()=>{});import D3 from"node:path";function Ni(n){let e=D3.posix.basename(String(n||"").replace(/\\/g,"/").replace(/\/+$/,""));return e?!!(/^\.env(\..*)?$/i.test(e)||/\.(pem|key|p12|pfx)$/i.test(e)||/^id_[a-z0-9_-]+(\.pub)?$/i.test(e)):!1}function oC(n){for(let e of String(n||"").split(/[\s'"`;|&<>()=]+/))if(e&&Ni(e))return!0;return!1}function U3(n){return n.replace(/^([^\s:]+?)([:-]\d+[:-]|:)(.*)$/gm,(e,t,s,i)=>i&&Ni(t)?t+s+" "+cn:e)}function Vt(n,e=[]){let t=String(n??"");if(!t)return t;t=U3(t);for(let[s,i]of F3)t=t.replace(s,i);return e&&e.length&&(t=is(t,e)),t}function aC(n){return String(n??"").replace(/\u001b\[[0-?]*[ -/]*[@-~]|\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)|\u001b[@-Z\\-_]/g,"").replace(/\r(?!\n)/g,`
220
+ `+T;k<=x;k++)f[k][0]!=="+"&&w++,f[k][0]!=="-"&&S++}return y}var iC=K(()=>{});import DU from"node:path";function Ni(n){let e=DU.posix.basename(String(n||"").replace(/\\/g,"/").replace(/\/+$/,""));return e?!!(/^\.env(\..*)?$/i.test(e)||/\.(pem|key|p12|pfx)$/i.test(e)||/^id_[a-z0-9_-]+(\.pub)?$/i.test(e)):!1}function oC(n){for(let e of String(n||"").split(/[\s'"`;|&<>()=]+/))if(e&&Ni(e))return!0;return!1}function UU(n){return n.replace(/^([^\s:]+?)([:-]\d+[:-]|:)(.*)$/gm,(e,t,s,i)=>i&&Ni(t)?t+s+" "+cn:e)}function Vt(n,e=[]){let t=String(n??"");if(!t)return t;t=UU(t);for(let[s,i]of FU)t=t.replace(s,i);return e&&e.length&&(t=is(t,e)),t}function aC(n){return String(n??"").replace(/\u001b\[[0-?]*[ -/]*[@-~]|\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)|\u001b[@-Z\\-_]/g,"").replace(/\r(?!\n)/g,`
221
221
  `)}function Cl(n){let e=String(n||"").slice(0,4096);if(!e)return!1;if(e.includes("\0"))return!0;let t=0;for(let s=0;s<e.length;s++){let i=e.charCodeAt(s);(i<32&&i!==9&&i!==10&&i!==13&&i!==27||i===65533)&&t++}return t/e.length>.1}function lC(n,e){if(n=String(n??""),n.length<=e)return{text:n,clipped:!1,cut:0};let t=Math.floor(e/4),s=e-t,i=n.slice(0,t),r=i.lastIndexOf(`
222
222
  `);r>t/2&&(i=i.slice(0,r+1));let o=n.slice(n.length-s),a=o.indexOf(`
223
223
  `);a>=0&&a<s/2&&(o=o.slice(a+1));let l=n.length-i.length-o.length,c=n.slice(i.length,n.length-o.length).split(`
224
224
  `).length-1;return{text:i+(i.endsWith(`
225
225
  `)?"":`
226
226
  `)+"… "+(c>0?c+" lines":l+" characters")+` cut …
227
- `+o,clipped:!0,cut:l}}var cn,rC,F3,hd=K(()=>{Te();cn="[REDACTED]";rC="(?:[A-Za-z_][A-Za-z0-9_.-]*?)?(?:SECRET|TOKEN|PASSWORD|PASSWD|PASSPHRASE|API_?KEY|ACCESS_?KEY|PRIVATE_?KEY|CREDENTIALS?|AUTH)[A-Za-z0-9_]*",F3=[[/-----BEGIN [A-Z0-9 ]*PRIVATE KEY( BLOCK)?-----[\s\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY( BLOCK)?-----|$)/g,"-----BEGIN PRIVATE KEY----- "+cn+" -----END PRIVATE KEY-----"],[new RegExp("^([+\\- ]?[ \\t]*(?:export[ \\t]+)?"+rC+"[ \\t]*=[ \\t]*)(?![^\\n]*\\()([^\\s{\\[].*)$","gim"),"$1"+cn],[new RegExp("^([+\\- ]?[ \\t]*"+rC+":[ \\t]+)([A-Za-z0-9_+/=-]{6,})[ \\t]*$","gim"),"$1"+cn],[/((?:secret|token|passw(?:or)?d|passphrase|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]*["']?[ \t]*[:=][ \t]*)(["'])([^"'\n]{6,})\2/gi,"$1$2"+cn+"$2"],[/\b(Bearer|Basic|token)[ \t]+[A-Za-z0-9._~+/-]{16,}=*/g,"$1 "+cn],[/([a-z][a-z0-9+.-]*:\/\/[^\s:@/]+:)[^\s@/]+@/gi,"$1"+cn+"@"],[/(_auth(?:Token)?[ \t]*=[ \t]*)\S+/g,"$1"+cn],[/\b(?:gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,})\b/g,cn],[/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,cn],[/\bxox[abposr]-[A-Za-z0-9-]{10,}/g,cn],[/\b[sr]k_(?:live|test)_[A-Za-z0-9]{16,}/g,cn],[/\bsk-[A-Za-z0-9_-]{20,}/g,cn],[/\bAIza[0-9A-Za-z_-]{35}\b/g,cn],[/\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,cn]]});function G3(n,e){let t=String(n||"");if(!t)return"";let s=String(e||"").replace(/\/+$/,"");return s&&t.startsWith(s+"/")?t.slice(s.length+1):t}function Xk(n){let e=n&&n.input||{};return e.file_path||e.notebook_path||(n.tool==="Read"||n.tool==="LS"?e.path:null)||null}function $3(n={},{cwd:e=null,patterns:t=[]}={}){let s=n&&n.input&&typeof n.input=="object"?n.input:{},i="";return n.tool==="Bash"?i=s.command:Xk(n)?i=G3(Xk(n),e):i=s.pattern||s.path||s.url||s.query||s.description||"",Vt(z3(i).slice(0,300),t)}function K3(n={}){let e=Xk(n);return e&&Ni(e)||n.tool==="Bash"&&oC(n.input&&n.input.command)?"secret_file":null}function W3(n,e){let t=String(n??"").split(`
227
+ `+o,clipped:!0,cut:l}}var cn,rC,FU,hd=K(()=>{Te();cn="[REDACTED]";rC="(?:[A-Za-z_][A-Za-z0-9_.-]*?)?(?:SECRET|TOKEN|PASSWORD|PASSWD|PASSPHRASE|API_?KEY|ACCESS_?KEY|PRIVATE_?KEY|CREDENTIALS?|AUTH)[A-Za-z0-9_]*",FU=[[/-----BEGIN [A-Z0-9 ]*PRIVATE KEY( BLOCK)?-----[\s\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY( BLOCK)?-----|$)/g,"-----BEGIN PRIVATE KEY----- "+cn+" -----END PRIVATE KEY-----"],[new RegExp("^([+\\- ]?[ \\t]*(?:export[ \\t]+)?"+rC+"[ \\t]*=[ \\t]*)(?![^\\n]*\\()([^\\s{\\[].*)$","gim"),"$1"+cn],[new RegExp("^([+\\- ]?[ \\t]*"+rC+":[ \\t]+)([A-Za-z0-9_+/=-]{6,})[ \\t]*$","gim"),"$1"+cn],[/((?:secret|token|passw(?:or)?d|passphrase|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]*["']?[ \t]*[:=][ \t]*)(["'])([^"'\n]{6,})\2/gi,"$1$2"+cn+"$2"],[/\b(Bearer|Basic|token)[ \t]+[A-Za-z0-9._~+/-]{16,}=*/g,"$1 "+cn],[/([a-z][a-z0-9+.-]*:\/\/[^\s:@/]+:)[^\s@/]+@/gi,"$1"+cn+"@"],[/(_auth(?:Token)?[ \t]*=[ \t]*)\S+/g,"$1"+cn],[/\b(?:gh[pousr]_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{22,})\b/g,cn],[/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,cn],[/\bxox[abposr]-[A-Za-z0-9-]{10,}/g,cn],[/\b[sr]k_(?:live|test)_[A-Za-z0-9]{16,}/g,cn],[/\bsk-[A-Za-z0-9_-]{20,}/g,cn],[/\bAIza[0-9A-Za-z_-]{35}\b/g,cn],[/\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g,cn]]});function GU(n,e){let t=String(n||"");if(!t)return"";let s=String(e||"").replace(/\/+$/,"");return s&&t.startsWith(s+"/")?t.slice(s.length+1):t}function Xk(n){let e=n&&n.input||{};return e.file_path||e.notebook_path||(n.tool==="Read"||n.tool==="LS"?e.path:null)||null}function $U(n={},{cwd:e=null,patterns:t=[]}={}){let s=n&&n.input&&typeof n.input=="object"?n.input:{},i="";return n.tool==="Bash"?i=s.command:Xk(n)?i=GU(Xk(n),e):i=s.pattern||s.path||s.url||s.query||s.description||"",Vt(zU(i).slice(0,300),t)}function KU(n={}){let e=Xk(n);return e&&Ni(e)||n.tool==="Bash"&&oC(n.input&&n.input.command)?"secret_file":null}function WU(n,e){let t=String(n??"").split(`
228
228
  `),s=t.findIndex(r=>r.trim().length>=3);if(s<0)return null;let i=t[s];for(let r of String(e||"").split(`
229
- `)){let o=/^\s*(\d+)[→\t](.*)$/.exec(r);if(o&&o[2].includes(i.trim())&&(o[2]===i||o[2].endsWith(i)||o[2].startsWith(i)))return Math.max(1,+o[1]-s)}return null}function Y3(n={},e=Zk){let t=n&&n.input||{},s=n.tool==="Edit"?[t]:n.tool==="MultiEdit"&&Array.isArray(t.edits)?t.edits:null;if(!s||!s.length||s.length>50)return null;let i=0;for(let a of s){if(!a||typeof a.old_string!="string"||typeof a.new_string!="string")return null;i+=a.old_string.length+a.new_string.length}if(i>uC)return null;let r=s.length===1&&!t.replace_all&&!n.isError?W3(s[0].new_string,n.text):null,o=s.map(a=>sC(a.old_string,a.new_string,{start:r||1})||"").join("");return!o||o.length>e?null:{patch:o,patchAt:r}}function dC(n={},{cwd:e=null,patterns:t=[],max:s=Zk,ts:i=null}={}){let r={id:n.tool_use_id||null,tool:String(n.tool||"tool"),label:Vk(n,{cwd:e}),what:$3(n,{cwd:e,patterns:t}),error:!!n.isError,ts:i||null,running:n.text===void 0,output:null,chars:0,clipped:!1,hidden:null};if(r.running)return r;let o=K3(n);if(o)return r.hidden=o,r;let a=n.isError?null:Y3(n,s);a&&(r.patch=Vt(a.patch,t),r.patchAt=a.patchAt);let l=aC(n.text==null?"":String(n.text));if(r.chars=l.length,Cl(l))return r.hidden="binary",r;l=Vt(l,t);let c=lC(l,s);return r.output=c.text,r.clipped=c.clipped,r}function Qk(n=[],{limit:e=cC,cwd:t=null,patterns:s=[]}={}){let i=Math.max(1,Math.min(H3,Number(e)||cC)),r=[];for(let o=n.length-1;o>=0&&r.length<i;o--){let a=n[o];if(!(!a||a.role!=="assistant"||!Array.isArray(a.toolUses)))for(let l=a.toolUses.length-1;l>=0&&r.length<i;l--){let c=a.toolUses[l];!c||B3.has(c.tool)||r.push(dC(c,{cwd:t,patterns:s,max:Zk,ts:a.ts||null}))}}return r}function hC(n=[],e,{cwd:t=null,patterns:s=[]}={}){if(!e)return null;for(let i=n.length-1;i>=0;i--){let r=n[i];if(!r||r.role!=="assistant"||!Array.isArray(r.toolUses))continue;let o=r.toolUses.find(a=>a&&a.tool_use_id===e);if(o)return dC(o,{cwd:t,patterns:s,max:uC,ts:r.ts||null})}return null}var Zk,uC,cC,H3,B3,z3,fC=K(()=>{dd();iC();hd();Zk=8*1024,uC=64*1024,cC=5,H3=20,B3=new Set(["TodoWrite"]),z3=n=>String(n??"").replace(/\s+/g," ").trim()});import{execFile as q3}from"node:child_process";import eS from"node:fs";import pC from"node:path";function nH(n=process.env){let e={};for(let[t,s]of Object.entries(n))tH.test(t)||(e[t]=s);return{...e,GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GIT_PAGER:"cat",PAGER:"cat",LC_ALL:"C"}}function sH(n,e){if(n=String(n??""),n.length<=e)return{text:n,clipped:!1};let t=n.slice(0,e),s=t.lastIndexOf(`
229
+ `)){let o=/^\s*(\d+)[→\t](.*)$/.exec(r);if(o&&o[2].includes(i.trim())&&(o[2]===i||o[2].endsWith(i)||o[2].startsWith(i)))return Math.max(1,+o[1]-s)}return null}function YU(n={},e=Zk){let t=n&&n.input||{},s=n.tool==="Edit"?[t]:n.tool==="MultiEdit"&&Array.isArray(t.edits)?t.edits:null;if(!s||!s.length||s.length>50)return null;let i=0;for(let a of s){if(!a||typeof a.old_string!="string"||typeof a.new_string!="string")return null;i+=a.old_string.length+a.new_string.length}if(i>uC)return null;let r=s.length===1&&!t.replace_all&&!n.isError?WU(s[0].new_string,n.text):null,o=s.map(a=>sC(a.old_string,a.new_string,{start:r||1})||"").join("");return!o||o.length>e?null:{patch:o,patchAt:r}}function dC(n={},{cwd:e=null,patterns:t=[],max:s=Zk,ts:i=null}={}){let r={id:n.tool_use_id||null,tool:String(n.tool||"tool"),label:Vk(n,{cwd:e}),what:$U(n,{cwd:e,patterns:t}),error:!!n.isError,ts:i||null,running:n.text===void 0,output:null,chars:0,clipped:!1,hidden:null};if(r.running)return r;let o=KU(n);if(o)return r.hidden=o,r;let a=n.isError?null:YU(n,s);a&&(r.patch=Vt(a.patch,t),r.patchAt=a.patchAt);let l=aC(n.text==null?"":String(n.text));if(r.chars=l.length,Cl(l))return r.hidden="binary",r;l=Vt(l,t);let c=lC(l,s);return r.output=c.text,r.clipped=c.clipped,r}function Qk(n=[],{limit:e=cC,cwd:t=null,patterns:s=[]}={}){let i=Math.max(1,Math.min(HU,Number(e)||cC)),r=[];for(let o=n.length-1;o>=0&&r.length<i;o--){let a=n[o];if(!(!a||a.role!=="assistant"||!Array.isArray(a.toolUses)))for(let l=a.toolUses.length-1;l>=0&&r.length<i;l--){let c=a.toolUses[l];!c||BU.has(c.tool)||r.push(dC(c,{cwd:t,patterns:s,max:Zk,ts:a.ts||null}))}}return r}function hC(n=[],e,{cwd:t=null,patterns:s=[]}={}){if(!e)return null;for(let i=n.length-1;i>=0;i--){let r=n[i];if(!r||r.role!=="assistant"||!Array.isArray(r.toolUses))continue;let o=r.toolUses.find(a=>a&&a.tool_use_id===e);if(o)return dC(o,{cwd:t,patterns:s,max:uC,ts:r.ts||null})}return null}var Zk,uC,cC,HU,BU,zU,fC=K(()=>{dd();iC();hd();Zk=8*1024,uC=64*1024,cC=5,HU=20,BU=new Set(["TodoWrite"]),zU=n=>String(n??"").replace(/\s+/g," ").trim()});import{execFile as qU}from"node:child_process";import eS from"node:fs";import pC from"node:path";function nH(n=process.env){let e={};for(let[t,s]of Object.entries(n))tH.test(t)||(e[t]=s);return{...e,GIT_OPTIONAL_LOCKS:"0",GIT_TERMINAL_PROMPT:"0",GIT_PAGER:"cat",PAGER:"cat",LC_ALL:"C"}}function sH(n,e){if(n=String(n??""),n.length<=e)return{text:n,clipped:!1};let t=n.slice(0,e),s=t.lastIndexOf(`
230
230
  `);s>e/2&&(t=t.slice(0,s+1));let i=n.slice(t.length).split(`
231
231
  `).filter(Boolean).length;return{text:t+(t.endsWith(`
232
232
  `)?"":`
233
- `)+"… "+i+" more lines, too big to show here",clipped:!0}}function Dt(n,e,{deadline:t,maxBuffer:s=Z3,okCodes:i=[0],gitBin:r="git",env:o}={}){let a=Math.max(1,(t||Date.now()+nm)-Date.now());return new Promise((l,c)=>{q3(r,[...eH,...e],{cwd:n,timeout:a,maxBuffer:s,killSignal:"SIGKILL",env:nH(o),encoding:"buffer",windowsHide:!0},(u,d,h)=>{if(!u)return l({code:0,stdout:d.toString("utf8")});if(u.code==="ERR_CHILD_PROCESS_STDIO_MAXBUFFER")return c(new un("too_big","too big to show here"));if(u.killed||u.signal)return c(new un("timeout","git took longer than "+Math.round(nm/1e3)+" s"));if(u.code==="ENOENT")return c(new un("no_git","git isn’t installed on this Mac"));if(typeof u.code=="number"&&i.includes(u.code))return l({code:u.code,stdout:d.toString("utf8")});let f=String(h||"").trim().split(`
234
- `)[0];if(/not a git repository/i.test(f))return c(new un("not_a_repo","this folder isn’t a git repository"));c(new un("git_failed",f||"git failed"))})})}function gC(n){let e=new Map;for(let t of sm(n)){let s=/^(-|\d+)\t(-|\d+)\t([\s\S]+)$/.exec(t);if(!s)continue;let i=s[1]==="-"&&s[2]==="-";e.set(s[3],{add:i?0:Number(s[1]),del:i?0:Number(s[2]),binary:i})}return e}function yC(n){let e=new Map,t=sm(n);for(let s=0;s+1<t.length;s+=2){let i=t[s][0];!i||!t[s+1]||e.set(t[s+1],i==="A"?"added":i==="D"?"deleted":i==="T"?"typechange":"modified")}return e}async function wC(n,e){let s=(await Dt(n,["rev-parse","-q","--verify","HEAD^{commit}"],{...e,okCodes:[0,1]})).stdout.trim();return/^[0-9a-f]{40,64}$/.test(s)?s:null}function kC(n){let e;try{e=eS.lstatSync(n)}catch{return{add:0,del:0,binary:!1,gone:!0}}if(e.isSymbolicLink())return{add:1,del:0,binary:!1,symlink:!0};if(!e.isFile())return{add:0,del:0,binary:!1,gone:!0};if(e.size>X3)return{add:0,del:0,binary:!1,big:!0,bytes:e.size};let t;try{t=eS.readFileSync(n)}catch{return{add:0,del:0,binary:!1,gone:!0}}let s=t.toString("utf8");return Cl(s)?{add:0,del:0,binary:!0}:{add:s?s.split(`
233
+ `)+"… "+i+" more lines, too big to show here",clipped:!0}}function Dt(n,e,{deadline:t,maxBuffer:s=ZU,okCodes:i=[0],gitBin:r="git",env:o}={}){let a=Math.max(1,(t||Date.now()+nm)-Date.now());return new Promise((l,c)=>{qU(r,[...eH,...e],{cwd:n,timeout:a,maxBuffer:s,killSignal:"SIGKILL",env:nH(o),encoding:"buffer",windowsHide:!0},(u,d,h)=>{if(!u)return l({code:0,stdout:d.toString("utf8")});if(u.code==="ERR_CHILD_PROCESS_STDIO_MAXBUFFER")return c(new un("too_big","too big to show here"));if(u.killed||u.signal)return c(new un("timeout","git took longer than "+Math.round(nm/1e3)+" s"));if(u.code==="ENOENT")return c(new un("no_git","git isn’t installed on this Mac"));if(typeof u.code=="number"&&i.includes(u.code))return l({code:u.code,stdout:d.toString("utf8")});let f=String(h||"").trim().split(`
234
+ `)[0];if(/not a git repository/i.test(f))return c(new un("not_a_repo","this folder isn’t a git repository"));c(new un("git_failed",f||"git failed"))})})}function gC(n){let e=new Map;for(let t of sm(n)){let s=/^(-|\d+)\t(-|\d+)\t([\s\S]+)$/.exec(t);if(!s)continue;let i=s[1]==="-"&&s[2]==="-";e.set(s[3],{add:i?0:Number(s[1]),del:i?0:Number(s[2]),binary:i})}return e}function yC(n){let e=new Map,t=sm(n);for(let s=0;s+1<t.length;s+=2){let i=t[s][0];!i||!t[s+1]||e.set(t[s+1],i==="A"?"added":i==="D"?"deleted":i==="T"?"typechange":"modified")}return e}async function wC(n,e){let s=(await Dt(n,["rev-parse","-q","--verify","HEAD^{commit}"],{...e,okCodes:[0,1]})).stdout.trim();return/^[0-9a-f]{40,64}$/.test(s)?s:null}function kC(n){let e;try{e=eS.lstatSync(n)}catch{return{add:0,del:0,binary:!1,gone:!0}}if(e.isSymbolicLink())return{add:1,del:0,binary:!1,symlink:!0};if(!e.isFile())return{add:0,del:0,binary:!1,gone:!0};if(e.size>XU)return{add:0,del:0,binary:!1,big:!0,bytes:e.size};let t;try{t=eS.readFileSync(n)}catch{return{add:0,del:0,binary:!1,gone:!0}}let s=t.toString("utf8");return Cl(s)?{add:0,del:0,binary:!0}:{add:s?s.split(`
235
235
  `).length-(s.endsWith(`
236
- `)?1:0):0,del:0,binary:!1}}async function SC(n,e){if(!n)throw new un("no_folder","this session has no folder");try{if(!eS.statSync(n).isDirectory())throw new Error("x")}catch{throw new un("no_folder","this session’s folder isn’t on this Mac any more")}let s=(await Dt(n,["rev-parse","--show-toplevel"],e)).stdout.trim();if(!s)throw new un("not_a_repo","this folder isn’t a git repository");return s}async function im(n,{gitBin:e="git",env:t,timeoutMs:s=nm,maxFiles:i=J3}={}){let r=Date.now(),o={deadline:r+s,gitBin:e,env:t},a=await SC(n,o),l=await wC(a,o),c=l||mC,[u,d,h]=await Promise.all([Dt(a,["diff",c,"--numstat","-z",...Ol,"--"],o),Dt(a,["diff",c,"--name-status","-z",...Ol,"--"],o),Dt(a,["ls-files","--others","--exclude-standard","-z","--"],o)]),f=gC(u.stdout),p=yC(d.stdout),m=[];for(let[k,v]of f)m.push({path:k,status:p.get(k)||"modified",add:v.add,del:v.del,binary:v.binary});for(let k of sm(h.stdout))k&&!f.has(k)&&m.push({path:k,status:"untracked",add:0,del:0,binary:!1,_u:!0});m.sort((k,v)=>k.path<v.path?-1:k.path>v.path?1:0);let y=m.length>i,w=m.slice(0,i);for(let k of w){if(k._u){delete k._u;let v=kC(pC.join(a,k.path));k.add=v.add,k.binary=v.binary,v.big&&(k.big=!0),v.symlink&&(k.symlink=!0)}Ni(k.path)&&(k.hidden="secret_file")}let S={files:m.length,add:0,del:0};for(let k of w)S.add+=k.add,S.del+=k.del;return{top:a,head:l,files:w,totals:S,truncated:y,ms:Date.now()-r}}async function bC(n,e,{gitBin:t="git",env:s,timeoutMs:i=nm,patterns:r=[]}={}){let o=String(e||"");if(!o||o.includes("\0")||o.length>4096||o.startsWith("/")||o.split("/").includes(".."))throw new un("not_changed","that file has no uncommitted changes");let a={deadline:Date.now()+i,gitBin:t,env:s},l=await SC(n,a),u=await wC(l,a)||mC,d=":(literal)"+o,[h,f]=await Promise.all([Dt(l,["diff",u,"--numstat","-z",...Ol,"--",d],a),Dt(l,["diff",u,"--name-status","-z",...Ol,"--",d],a)]),p=gC(h.stdout).get(o),m;if(p)m={path:o,status:yC(f.stdout).get(o)||"modified",add:p.add,del:p.del,binary:p.binary};else{let E=await Dt(l,["ls-files","--others","--exclude-standard","-z","--",d],a);if(!sm(E.stdout).includes(o))throw new un("not_changed","that file has no uncommitted changes");let A=kC(pC.join(l,o));m={path:o,status:"untracked",add:A.add,del:0,binary:A.binary,...A.big?{big:!0}:{}}}let y={path:m.path,status:m.status,add:m.add,del:m.del,lines:null,clipped:!1};if(Ni(m.path))return y.hidden="secret_file",y;if(m.binary)return y.binary=!0,y;if(m.big)return y.big=!0,y;let w={...a,maxBuffer:Q3},S;try{m.status==="untracked"?S=(await Dt(l,["diff","--no-index",...Ol,"--","/dev/null",o],{...w,okCodes:[0,1]})).stdout:S=(await Dt(l,["diff",u,...Ol,"--",d],w)).stdout}catch(E){if(E.code==="too_big")return y.big=!0,y;throw E}let k=S.indexOf(`
237
- @@`),v=k>=0?S.slice(k+1):S.startsWith("@@")?S:"";if(!v)return/^Binary files/m.test(S)&&(y.binary=!0),y;let x=sH(Vt(v,r),V3);return y.lines=x.text,y.clipped=x.clipped,y}var nm,J3,V3,X3,Z3,Q3,mC,eH,Ol,un,tH,sm,tS=K(()=>{hd();nm=3e3,J3=300,V3=64*1024,X3=1024*1024,Z3=2*1024*1024,Q3=4*1024*1024,mC="4b825dc642cb6eb9a060e54bf8d69288fbee4904",eH=["-c","core.fsmonitor=false","-c","core.quotepath=off","-c","core.pager=cat","-c","color.ui=false"],Ol=["--no-ext-diff","--no-textconv","--no-color","--no-renames"],un=class extends Error{constructor(e,t){super(t||e),this.code=e}},tH=/^GIT_(DIR|WORK_TREE|INDEX_FILE|OBJECT_DIRECTORY|ALTERNATE_OBJECT_DIRECTORIES|COMMON_DIR|NAMESPACE|EXTERNAL_DIFF|DIFF_OPTS|PREFIX)$/;sm=n=>String(n||"").split("\0")});import iS from"node:fs";import nS from"node:os";import Ot from"node:path";function lS(n,{cwd:e=null,home:t=nS.homedir()}={}){let s=String(n??"");if(!s||s.length>1e3||s.includes("\0"))return null;if(s==="~"||s.startsWith("~/")){if(!t)return null;s=Ot.join(t,s.slice(1))}else{if(s.startsWith("~"))return null;if(!Ot.isAbsolute(s)){if(!e||!Ot.isAbsolute(e))return null;s=Ot.join(e,s)}}return Ot.normalize(s)}function rm(n){let e=String(n||"").split("/").filter(Boolean);for(let s of e.slice(0,-1))if(iH.has(s.toLowerCase()))return!0;let t=(e[e.length-1]||"").toLowerCase();return t?!!(/^\.env(\.|$)/.test(t)||/^\.?env\.(local|production|prod|secret)/.test(t)||/\.(pem|key|p12|pfx|keystore|jks|keychain|keychain-db|kdbx|asc|gpg|ovpn)$/.test(t)||/^\.?credentials?(\.|$|[-_])/.test(t)||/credentials/.test(t)||/^id_(rsa|dsa|ecdsa|ed25519)/.test(t)||/^\.(netrc|npmrc|pypirc|pgpass|git-credentials|htpasswd)$/.test(t)||/(^|[^a-z])(api|private|secret|access|signing|ssh|gpg|pgp|service[-_]?account|master)?[-_.]?keys?([^a-z]|$)/.test(t)||/(^|[^a-z])(secrets?|tokens?|passwords?)([^a-z]|$)/.test(t)):!1}function cS({cwd:n=null,repoRoot:e=null,worktree:t=null,home:s=nS.homedir(),tmpdir:i=nS.tmpdir(),real:r=AC}={}){let o=[];for(let a of[n,e,t])if(a&&Ot.isAbsolute(a)){let l=r(a);l&&l!=="/"&&l!==s&&l!==r(s)&&o.push(l)}if(s){let a=r(Ot.join(s,".claude","plans"));a&&o.push(a)}return{roots:[...new Set(o)],tmp:[...new Set(["/tmp","/private/tmp",i,i&&r(i)].filter(Boolean).map(a=>a.replace(/\/+$/,"")))]}}function vC(n,e){for(let t of e)if(sS(n,t)&&/^claude-[^/]+\/./.test(n.slice(t.length+1)))return!0;return!1}function AC(n){try{return iS.realpathSync(n)}catch{return null}}function rH(n,e){for(let t=Ot.dirname(n),s=Ot.basename(n);;s=Ot.join(Ot.basename(t),s),t=Ot.dirname(t)){let i=e(t);if(i)return Ot.join(i,s);if(t===Ot.dirname(t))return n}}function uS(n,e,{real:t=AC}={}){if(typeof n!="string"||!Ot.isAbsolute(n)||n.includes("\0")||Ot.normalize(n)!==n)return{ok:!1,reason:"bad_path"};if(rm(n))return{ok:!1,reason:"secret"};let{roots:s=[],tmp:i=[]}=e||{},r=a=>s.some(l=>sS(a,l))||vC(a,i),o=t(n);return o?rm(o)?{ok:!1,reason:"secret"}:s.some(a=>sS(o,a))||vC(o,i)?{ok:!0,real:o}:{ok:!1,reason:"outside"}:r(n)||r(rH(n,t))?{ok:!1,missing:!0,reason:"missing"}:{ok:!1,reason:"outside"}}function cH(n){let e=Ot.basename(String(n||"")).toLowerCase(),t=e.includes(".")?e.slice(e.lastIndexOf(".")+1):"";return lH.has(t)?{type:"markdown",mime:"text/markdown"}:xC[t]?{type:"image",mime:xC[t]}:t==="pdf"?{type:"pdf",mime:"application/pdf"}:t==="html"||t==="htm"?{type:"code",mime:"text/html",lang:"html"}:t==="txt"||t==="csv"?{type:"code",mime:"text/plain",lang:t}:oH.has(t)?{type:"code",mime:"text/plain",lang:t}:aH.has(t?e.slice(0,e.lastIndexOf(".")):e)&&(!t||t==="txt")?{type:"code",mime:"text/plain",lang:""}:{type:"other",mime:"application/octet-stream"}}function _C(n,{textMax:e=rS,binMax:t=oS,fsImpl:s=iS}={}){let i;try{i=s.statSync(n)}catch{return{missing:!0}}if(!i.isFile())return{missing:!0,notFile:!0};let r=cH(n),o=r.type==="image"&&r.mime!=="image/svg+xml"||r.type==="pdf",a=o?t:e;if(i.size>a)return{tooBig:!0,size:i.size,type:r.type,mime:r.mime};let l=s.readFileSync(n);return o?{...r,size:i.size,base64:l.toString("base64")}:r.type==="image"?{...r,size:i.size,text:l.toString("utf8")}:uH(l)?{binary:!0,size:i.size,type:"other",mime:r.mime}:{...r.type==="other"?{type:"code",mime:"text/plain",lang:""}:r,size:i.size,text:l.toString("utf8")}}function TC({how:n,real:e,line:t=null,exists:s=i=>iS.existsSync(i)}={}){if(!e||!Ot.isAbsolute(e))return null;if(n==="reveal")return["open",["-R",e]];if(n!=="editor")return null;let i=dH.find(o=>s(o.app)),r=e.split("/").map(encodeURIComponent).join("/");return i?["open",[i.scheme+"://file"+r+(t?":"+Math.max(1,Math.floor(t)):"")]]:["open",["-t",e]]}var rS,oS,aS,iH,sS,oH,aH,lH,xC,uH,dH,dS=K(()=>{rS=2*1024*1024,oS=20*1024*1024,aS="Leftoff only opens files in this session’s folder or Claude’s scratch folders, and never keys or credentials.";iH=new Set([".ssh",".gnupg",".aws",".azure",".kube",".docker","keychains",".password-store",".1password"]);sS=(n,e)=>!!e&&(n===e||n.startsWith(e.endsWith("/")?e:e+"/"));oH=new Set(["js","mjs","cjs","jsx","ts","tsx","json","jsonc","json5","yml","yaml","toml","ini","cfg","conf","sh","bash","zsh","fish","py","rb","go","rs","java","kt","kts","swift","c","h","cc","cpp","hpp","m","mm","cs","php","pl","lua","sql","css","scss","less","vue","svelte","xml","plist","gradle","r","scala","ex","exs","erl","hs","clj","dart","zig","nim","tf","hcl","proto","graphql","gql","diff","patch","log","lock","gitignore","dockerignore","editorconfig","rst","adoc","org","tex","srt","vtt","tsv"]),aH=new Set(["makefile","dockerfile","gemfile","rakefile","procfile","brewfile","justfile","license","readme","changelog","contributing","codeowners","agents","claude"]),lH=new Set(["md","mdx","markdown"]),xC={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"};uH=n=>n.subarray(0,8192).includes(0);dH=[{app:"/Applications/Cursor.app",scheme:"cursor"},{app:"/Applications/Visual Studio Code.app",scheme:"vscode"},{app:"/Applications/Zed.app",scheme:"zed"}]});import gS from"node:crypto";import fS from"node:path";function cm(n){return Ni(n)||rm(n)}function LC(n,e=""){let t=String(n||"");return gH.test(t)||yH.test(t)?!0:wH.test(String(e||"").split(`
236
+ `)?1:0):0,del:0,binary:!1}}async function SC(n,e){if(!n)throw new un("no_folder","this session has no folder");try{if(!eS.statSync(n).isDirectory())throw new Error("x")}catch{throw new un("no_folder","this session’s folder isn’t on this Mac any more")}let s=(await Dt(n,["rev-parse","--show-toplevel"],e)).stdout.trim();if(!s)throw new un("not_a_repo","this folder isn’t a git repository");return s}async function im(n,{gitBin:e="git",env:t,timeoutMs:s=nm,maxFiles:i=JU}={}){let r=Date.now(),o={deadline:r+s,gitBin:e,env:t},a=await SC(n,o),l=await wC(a,o),c=l||mC,[u,d,h]=await Promise.all([Dt(a,["diff",c,"--numstat","-z",...Ol,"--"],o),Dt(a,["diff",c,"--name-status","-z",...Ol,"--"],o),Dt(a,["ls-files","--others","--exclude-standard","-z","--"],o)]),f=gC(u.stdout),p=yC(d.stdout),m=[];for(let[k,v]of f)m.push({path:k,status:p.get(k)||"modified",add:v.add,del:v.del,binary:v.binary});for(let k of sm(h.stdout))k&&!f.has(k)&&m.push({path:k,status:"untracked",add:0,del:0,binary:!1,_u:!0});m.sort((k,v)=>k.path<v.path?-1:k.path>v.path?1:0);let y=m.length>i,w=m.slice(0,i);for(let k of w){if(k._u){delete k._u;let v=kC(pC.join(a,k.path));k.add=v.add,k.binary=v.binary,v.big&&(k.big=!0),v.symlink&&(k.symlink=!0)}Ni(k.path)&&(k.hidden="secret_file")}let S={files:m.length,add:0,del:0};for(let k of w)S.add+=k.add,S.del+=k.del;return{top:a,head:l,files:w,totals:S,truncated:y,ms:Date.now()-r}}async function bC(n,e,{gitBin:t="git",env:s,timeoutMs:i=nm,patterns:r=[]}={}){let o=String(e||"");if(!o||o.includes("\0")||o.length>4096||o.startsWith("/")||o.split("/").includes(".."))throw new un("not_changed","that file has no uncommitted changes");let a={deadline:Date.now()+i,gitBin:t,env:s},l=await SC(n,a),u=await wC(l,a)||mC,d=":(literal)"+o,[h,f]=await Promise.all([Dt(l,["diff",u,"--numstat","-z",...Ol,"--",d],a),Dt(l,["diff",u,"--name-status","-z",...Ol,"--",d],a)]),p=gC(h.stdout).get(o),m;if(p)m={path:o,status:yC(f.stdout).get(o)||"modified",add:p.add,del:p.del,binary:p.binary};else{let E=await Dt(l,["ls-files","--others","--exclude-standard","-z","--",d],a);if(!sm(E.stdout).includes(o))throw new un("not_changed","that file has no uncommitted changes");let A=kC(pC.join(l,o));m={path:o,status:"untracked",add:A.add,del:0,binary:A.binary,...A.big?{big:!0}:{}}}let y={path:m.path,status:m.status,add:m.add,del:m.del,lines:null,clipped:!1};if(Ni(m.path))return y.hidden="secret_file",y;if(m.binary)return y.binary=!0,y;if(m.big)return y.big=!0,y;let w={...a,maxBuffer:QU},S;try{m.status==="untracked"?S=(await Dt(l,["diff","--no-index",...Ol,"--","/dev/null",o],{...w,okCodes:[0,1]})).stdout:S=(await Dt(l,["diff",u,...Ol,"--",d],w)).stdout}catch(E){if(E.code==="too_big")return y.big=!0,y;throw E}let k=S.indexOf(`
237
+ @@`),v=k>=0?S.slice(k+1):S.startsWith("@@")?S:"";if(!v)return/^Binary files/m.test(S)&&(y.binary=!0),y;let x=sH(Vt(v,r),VU);return y.lines=x.text,y.clipped=x.clipped,y}var nm,JU,VU,XU,ZU,QU,mC,eH,Ol,un,tH,sm,tS=K(()=>{hd();nm=3e3,JU=300,VU=64*1024,XU=1024*1024,ZU=2*1024*1024,QU=4*1024*1024,mC="4b825dc642cb6eb9a060e54bf8d69288fbee4904",eH=["-c","core.fsmonitor=false","-c","core.quotepath=off","-c","core.pager=cat","-c","color.ui=false"],Ol=["--no-ext-diff","--no-textconv","--no-color","--no-renames"],un=class extends Error{constructor(e,t){super(t||e),this.code=e}},tH=/^GIT_(DIR|WORK_TREE|INDEX_FILE|OBJECT_DIRECTORY|ALTERNATE_OBJECT_DIRECTORIES|COMMON_DIR|NAMESPACE|EXTERNAL_DIFF|DIFF_OPTS|PREFIX)$/;sm=n=>String(n||"").split("\0")});import iS from"node:fs";import nS from"node:os";import Ot from"node:path";function lS(n,{cwd:e=null,home:t=nS.homedir()}={}){let s=String(n??"");if(!s||s.length>1e3||s.includes("\0"))return null;if(s==="~"||s.startsWith("~/")){if(!t)return null;s=Ot.join(t,s.slice(1))}else{if(s.startsWith("~"))return null;if(!Ot.isAbsolute(s)){if(!e||!Ot.isAbsolute(e))return null;s=Ot.join(e,s)}}return Ot.normalize(s)}function rm(n){let e=String(n||"").split("/").filter(Boolean);for(let s of e.slice(0,-1))if(iH.has(s.toLowerCase()))return!0;let t=(e[e.length-1]||"").toLowerCase();return t?!!(/^\.env(\.|$)/.test(t)||/^\.?env\.(local|production|prod|secret)/.test(t)||/\.(pem|key|p12|pfx|keystore|jks|keychain|keychain-db|kdbx|asc|gpg|ovpn)$/.test(t)||/^\.?credentials?(\.|$|[-_])/.test(t)||/credentials/.test(t)||/^id_(rsa|dsa|ecdsa|ed25519)/.test(t)||/^\.(netrc|npmrc|pypirc|pgpass|git-credentials|htpasswd)$/.test(t)||/(^|[^a-z])(api|private|secret|access|signing|ssh|gpg|pgp|service[-_]?account|master)?[-_.]?keys?([^a-z]|$)/.test(t)||/(^|[^a-z])(secrets?|tokens?|passwords?)([^a-z]|$)/.test(t)):!1}function cS({cwd:n=null,repoRoot:e=null,worktree:t=null,home:s=nS.homedir(),tmpdir:i=nS.tmpdir(),real:r=AC}={}){let o=[];for(let a of[n,e,t])if(a&&Ot.isAbsolute(a)){let l=r(a);l&&l!=="/"&&l!==s&&l!==r(s)&&o.push(l)}if(s){let a=r(Ot.join(s,".claude","plans"));a&&o.push(a)}return{roots:[...new Set(o)],tmp:[...new Set(["/tmp","/private/tmp",i,i&&r(i)].filter(Boolean).map(a=>a.replace(/\/+$/,"")))]}}function vC(n,e){for(let t of e)if(sS(n,t)&&/^claude-[^/]+\/./.test(n.slice(t.length+1)))return!0;return!1}function AC(n){try{return iS.realpathSync(n)}catch{return null}}function rH(n,e){for(let t=Ot.dirname(n),s=Ot.basename(n);;s=Ot.join(Ot.basename(t),s),t=Ot.dirname(t)){let i=e(t);if(i)return Ot.join(i,s);if(t===Ot.dirname(t))return n}}function uS(n,e,{real:t=AC}={}){if(typeof n!="string"||!Ot.isAbsolute(n)||n.includes("\0")||Ot.normalize(n)!==n)return{ok:!1,reason:"bad_path"};if(rm(n))return{ok:!1,reason:"secret"};let{roots:s=[],tmp:i=[]}=e||{},r=a=>s.some(l=>sS(a,l))||vC(a,i),o=t(n);return o?rm(o)?{ok:!1,reason:"secret"}:s.some(a=>sS(o,a))||vC(o,i)?{ok:!0,real:o}:{ok:!1,reason:"outside"}:r(n)||r(rH(n,t))?{ok:!1,missing:!0,reason:"missing"}:{ok:!1,reason:"outside"}}function cH(n){let e=Ot.basename(String(n||"")).toLowerCase(),t=e.includes(".")?e.slice(e.lastIndexOf(".")+1):"";return lH.has(t)?{type:"markdown",mime:"text/markdown"}:xC[t]?{type:"image",mime:xC[t]}:t==="pdf"?{type:"pdf",mime:"application/pdf"}:t==="html"||t==="htm"?{type:"code",mime:"text/html",lang:"html"}:t==="txt"||t==="csv"?{type:"code",mime:"text/plain",lang:t}:oH.has(t)?{type:"code",mime:"text/plain",lang:t}:aH.has(t?e.slice(0,e.lastIndexOf(".")):e)&&(!t||t==="txt")?{type:"code",mime:"text/plain",lang:""}:{type:"other",mime:"application/octet-stream"}}function _C(n,{textMax:e=rS,binMax:t=oS,fsImpl:s=iS}={}){let i;try{i=s.statSync(n)}catch{return{missing:!0}}if(!i.isFile())return{missing:!0,notFile:!0};let r=cH(n),o=r.type==="image"&&r.mime!=="image/svg+xml"||r.type==="pdf",a=o?t:e;if(i.size>a)return{tooBig:!0,size:i.size,type:r.type,mime:r.mime};let l=s.readFileSync(n);return o?{...r,size:i.size,base64:l.toString("base64")}:r.type==="image"?{...r,size:i.size,text:l.toString("utf8")}:uH(l)?{binary:!0,size:i.size,type:"other",mime:r.mime}:{...r.type==="other"?{type:"code",mime:"text/plain",lang:""}:r,size:i.size,text:l.toString("utf8")}}function TC({how:n,real:e,line:t=null,exists:s=i=>iS.existsSync(i)}={}){if(!e||!Ot.isAbsolute(e))return null;if(n==="reveal")return["open",["-R",e]];if(n!=="editor")return null;let i=dH.find(o=>s(o.app)),r=e.split("/").map(encodeURIComponent).join("/");return i?["open",[i.scheme+"://file"+r+(t?":"+Math.max(1,Math.floor(t)):"")]]:["open",["-t",e]]}var rS,oS,aS,iH,sS,oH,aH,lH,xC,uH,dH,dS=K(()=>{rS=2*1024*1024,oS=20*1024*1024,aS="Leftoff only opens files in this session’s folder or Claude’s scratch folders, and never keys or credentials.";iH=new Set([".ssh",".gnupg",".aws",".azure",".kube",".docker","keychains",".password-store",".1password"]);sS=(n,e)=>!!e&&(n===e||n.startsWith(e.endsWith("/")?e:e+"/"));oH=new Set(["js","mjs","cjs","jsx","ts","tsx","json","jsonc","json5","yml","yaml","toml","ini","cfg","conf","sh","bash","zsh","fish","py","rb","go","rs","java","kt","kts","swift","c","h","cc","cpp","hpp","m","mm","cs","php","pl","lua","sql","css","scss","less","vue","svelte","xml","plist","gradle","r","scala","ex","exs","erl","hs","clj","dart","zig","nim","tf","hcl","proto","graphql","gql","diff","patch","log","lock","gitignore","dockerignore","editorconfig","rst","adoc","org","tex","srt","vtt","tsv"]),aH=new Set(["makefile","dockerfile","gemfile","rakefile","procfile","brewfile","justfile","license","readme","changelog","contributing","codeowners","agents","claude"]),lH=new Set(["md","mdx","markdown"]),xC={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml"};uH=n=>n.subarray(0,8192).includes(0);dH=[{app:"/Applications/Cursor.app",scheme:"cursor"},{app:"/Applications/Visual Studio Code.app",scheme:"vscode"},{app:"/Applications/Zed.app",scheme:"zed"}]});import gS from"node:crypto";import fS from"node:path";function cm(n){return Ni(n)||rm(n)}function LC(n,e=""){let t=String(n||"");return gH.test(t)||yH.test(t)?!0:wH.test(String(e||"").split(`
238
238
  `).slice(0,5).join(`
239
239
  `))}function yS(n){let e=[],t=[],s=null,i=null,r=0,o=0,a=String(n??"").replace(/\r\n?/g,`
240
240
  `).split(`