@deskdev/cli 2.0.1 → 2.0.3

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.
Files changed (2) hide show
  1. package/dist/index.js +40 -33
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -1,31 +1,38 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var As=Object.create;var Wn=Object.defineProperty;var Ds=Object.getOwnPropertyDescriptor;var Os=Object.getOwnPropertyNames;var Ls=Object.getPrototypeOf,Fs=Object.prototype.hasOwnProperty;var Us=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Os(t))!Fs.call(e,o)&&o!==n&&Wn(e,o,{get:()=>t[o],enumerable:!(r=Ds(t,o))||r.enumerable});return e};var Je=(e,t,n)=>(n=e!=null?As(Ls(e)):{},Us(t||!e||!e.__esModule?Wn(n,"default",{value:e,enumerable:!0}):n,e));var Kn=[22,19,0],Gn=([e,t,n])=>e*1e6+t*1e3+n,Hs=process.versions.node.split(".").map(e=>parseInt(e,10)||0);Gn(Hs)<Gn(Kn)&&(console.error(`desk requires Node.js >= ${Kn.join(".")} (found ${process.versions.node}).`),console.error("Upgrade Node, e.g. `nvm install 22 && nvm alias default 22`, then reinstall: npm i -g @deskdev/cli@latest"),process.exit(1));var Re=require("fs"),Ct=require("path");var Ns=new Set(["model"]);function Xe(e,t){return e.filter(n=>!t.has(n))}function he(e,t={}){let n={},r={},o={},s=[];for(let a=0;a<e.length;a++){let i=e[a];if(!i.startsWith("--")){let d=i.startsWith("-")?t[i.slice(1)]:void 0;if(d){o[d]=!0;continue}s.push(i);continue}let c=i.slice(2),u=c.indexOf("=");if(u!==-1){let d=c.slice(0,u),p=c.slice(u+1);qn(d,p,n,r);continue}if(c.startsWith("no-")){o[c.slice(3)]=!1;continue}let l=e[a+1];if(l===void 0||l.startsWith("--")){o[c]=!0;continue}qn(c,l,n,r),a++}return{flags:n,repeated:r,bools:o,positionals:s}}function qn(e,t,n,r){Ns.has(e)?(r[e]||(r[e]=[]),r[e].push(t)):n[e]=t}var Ht=require("child_process"),$=require("fs");var zn=!1;function ge(){if(zn)return;zn=!0;let e=()=>`[${new Date().toISOString()}]`;for(let t of["log","info","warn","error","debug"]){let n=console[t].bind(console);console[t]=(...r)=>n(e(),...r)}}var G=require("fs"),Jn=require("os"),Ft=require("path");function te(){return(0,Ft.join)((0,Jn.homedir)(),".desk")}function V(...e){return(0,Ft.join)(te(),...e)}function Ut(){return V("machine.json")}function q(){let e=Ut();if(!(0,G.existsSync)(e))return null;try{let t=JSON.parse((0,G.readFileSync)(e,"utf-8"));if(t.token&&t.machineId)return t}catch{}return null}function Xn(e){(0,G.mkdirSync)(te(),{recursive:!0}),(0,G.writeFileSync)(Ut(),JSON.stringify(e,null,2),{mode:384})}function Yn(){let e=Ut();try{(0,G.existsSync)(e)&&(0,G.rmSync)(e)}catch{}}var js=10*1024*1024,Nt=78;function jt(){return V("daemon.json")}function Ye(){return V("daemon.log")}function re(){let e=jt();if(!(0,$.existsSync)(e))return null;try{let t=JSON.parse((0,$.readFileSync)(e,"utf-8"));if(typeof t.pid=="number")return{pid:t.pid,startedAt:t.startedAt??0}}catch{}return null}function Qn(e){(0,$.mkdirSync)(te(),{recursive:!0}),(0,$.writeFileSync)(jt(),JSON.stringify(e,null,2))}function Ve(){try{(0,$.rmSync)(jt())}catch{}}function z(e){if(!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}var oe=e=>new Promise(t=>setTimeout(t,e));function Zn(e=js){let t=Ye();try{if(!(0,$.existsSync)(t)||(0,$.statSync)(t).size<e)return;(0,$.copyFileSync)(t,t+".1"),(0,$.truncateSync)(t,0)}catch{}}function Bs(){return(0,$.mkdirSync)(te(),{recursive:!0}),(0,$.openSync)(Ye(),"a")}var er=(e,...t)=>[...process.execArgv,process.argv[1],e,...t];function Qe(e,t){Zn();let n=Bs();try{let r=(0,Ht.spawn)(process.execPath,er(e,...t),{detached:!0,stdio:["ignore",n,n]});return r.unref(),r.pid}finally{(0,$.closeSync)(n)}}var Ws=new Set(["--supervisor","--foreground","-f"]),Ks=e=>Xe(e,Ws);function Vn(e,t){e?.on("data",n=>t.write(n)),e?.on("error",()=>{})}async function Gs(e){let t=n=>new Promise(r=>{!n||n.closed?r():n.once("close",r)});await Promise.race([Promise.all([t(e.stdout),t(e.stderr)]),oe(1e3)])}async function tr(e){ge();let t=Ks(e),n=3e4,r=6e4,o=!1,s=null,a=null,i=1e3,c=setInterval(()=>Zn(),5*6e4);c.unref();let u=()=>{if(!o&&(o=!0,clearInterval(c),s)){s.kill("SIGTERM");let l=s;setTimeout(()=>{try{l.kill("SIGKILL")}catch{}},5e3).unref()}};for(process.on("SIGTERM",u),process.on("SIGINT",u),console.log(`[supervisor] online (pid ${process.pid}); supervising worker`);!o;){let l=Date.now();s=(0,Ht.spawn)(process.execPath,er("start","--foreground",...t),{stdio:["ignore","pipe","pipe"],windowsHide:!0}),Vn(s.stdout,process.stdout),Vn(s.stderr,process.stderr);let d=await new Promise(p=>{s.on("exit",(m,h)=>p(m??(h?128:0)))});if(a=s,s=null,o)break;if(d===Nt){console.error("[supervisor] worker hit a terminal condition (not registered / revoked); not restarting.");break}Date.now()-l>=r&&(i=1e3),console.warn(`[supervisor] worker exited (code ${d}); restarting in ${Math.round(i/1e3)}s`),await oe(i),i=Math.min(i*2,n)}a&&await Gs(a),Ve(),console.log("[supervisor] stopped"),process.exit(0)}var br=require("node:child_process"),O=require("node:fs"),ue=require("node:fs/promises"),Qt=require("node:os"),W=require("node:path");var Ja=30*60*1e3,nr={plan:{track:"plan",sink:"chat",phase:{busy:"planning",rest:"confirm",notify:"plan_ready"}},plan_revision:{track:"plan",sink:"chat",phase:{busy:"planning",rest:"confirm",notify:"plan_ready"}},implement:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},implement_revision:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},merge:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},plan_review:{track:"plan",sink:"review"},implement_review:{track:"implement",sink:"review"},chief:{sink:"chief"}},qs=e=>nr[e].sink==="review",Xa=Object.keys(nr).filter(e=>qs(e)),zs=["planning","building"],Ya=["queued",...zs],Va=64*1024,Js=["github-copilot","openai-codex"],Qa=[...Js,"xai"];function rr(e){return{cost:{input:0,output:0,cacheRead:0,cacheWrite:0},...e,name:e.name??e.id,reasoning:e.reasoning??!1,input:e.input??["text"],contextWindow:e.contextWindow??128e3,maxTokens:e.maxTokens??16384}}var or={"image/jpeg":"jpg","image/png":"png","image/webp":"webp","image/gif":"gif","image/svg+xml":"svg","image/avif":"avif"},Xs={"text/x-markdown":"md","text/markdown":"md","text/plain":"txt","text/csv":"csv","text/tab-separated-values":"tsv","application/json":"json","application/x-yaml":"yaml","text/yaml":"yaml","text/xml":"xml","application/xml":"xml","text/html":"html","application/pdf":"pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","application/msword":"doc","application/vnd.ms-excel":"xls","application/vnd.ms-powerpoint":"ppt"},Ys={"audio/mpeg":"mp3","audio/wav":"wav","audio/ogg":"ogg","video/mp4":"mp4","video/quicktime":"mov","video/webm":"webm","application/zip":"zip","application/x-tar":"tar","application/gzip":"gz","application/x-gzip":"tgz","application/vnd.rar":"rar","application/x-7z-compressed":"7z"},Bt={...or,...Xs,...Ys},Za=Object.keys(or).join(","),ec=[...Object.keys(Bt),...new Set(Object.values(Bt).map(e=>`.${e}`))].join(","),tc=Object.fromEntries(Object.entries(Bt).map(([e,t])=>[t,e])),nc=5*1024*1024,rc=20*1024*1024,Vs=["attachment","doc","skill","todo","project","machine","agent","member"],oc=new RegExp(`\`(@?\\[[^\\]\`]*\\]\\((?:${Vs.join("|")}):[A-Za-z0-9_-]+\\))\``,"g"),ne=e=>`desk/conv-${e}`,Ze="remote branch diverged",sr="Branch push failed: ",Wt=/Authentication failed|Invalid username or (token|password)|authentication required|Bad credentials|could not read Username|Permission denied \(publickey\)/i,Kt=/SSL_ERROR_SYSCALL|SSL_connect|gnutls_handshake|GnuTLS|[Cc]ould not resolve host|Temporary failure in name resolution|Connection (timed out|reset|refused)|Operation timed out|Failed to connect|[Rr]ecv failure|[Ss]end failure|early EOF|RPC failed|unexpected disconnect|remote end hung up|The requested URL returned error: 5\d\d|was killed \(/,Gt=/stale info/;function et(e){return e.includes(Ze)?"diverged":Gt.test(e)?"stale_lease":Wt.test(e)?"auth":Kt.test(e)?"network":"other"}var Qs=1,Zs=100;function ir(e){let t=Number(e);return Number.isInteger(t)&&t>=Qs&&t<=Zs?t:null}var ar=3e3,cr="x-desk-version";function lr(e,t){return[".desk","sync",...e.split("/").filter(Boolean),String(t)].join("/")}var se=require("fs");function ur(){return V("settings.json")}var Me=null;function _e(){if(Me)return Me;let e=ur();if((0,se.existsSync)(e))try{let t=JSON.parse((0,se.readFileSync)(e,"utf-8"));t&&typeof t=="object"&&!Array.isArray(t)&&(Me=t)}catch{}return Me??={}}function dr(e){let t={..._e(),...e};(0,se.mkdirSync)(te(),{recursive:!0}),(0,se.writeFileSync)(ur(),JSON.stringify(t,null,2)),Me=t}var f={claim:6e4,stepPost:3e4,recover:15e3,presence:15e3,presenceOffline:2e3,statusProbe:8e3,enroll:15e3,enrollPoll:1e4,remoteTool:1e4,openRepo:3e4,r2Upload:1e4,r2UploadSession:6e4,r2Download:3e4,gitNetwork:3e5,gitNetworkInteractive:12e4,gitLocalInteractive:3e4,gitClone:18e5,streamFirstEvent:3e5,streamIdle:12e4,bashDefault:18e5,webFetch:1e4,mcpConnect:15e3,mcpToolCall:6e4,gitPushInline:6e4,deferredTurnWork:6e5};var mr=require("node:timers/promises"),ei=[2e3,4e3,8e3];function B(e){let t=e.httpStatus;return t===void 0||t>=500}async function F(e,t,n,r=ei,o,s){for(let a=0;;a++){o?.throwIfAborted();try{let i=await e();return a>0&&s?.(0,0),i}catch(i){if(o?.aborted)throw o.reason??i;if(a>=r.length||!t(i))throw i;let c=r[a],u=i instanceof Error?i.message:String(i);console.warn(`${n} transient failure (retry ${a+1}/${r.length}), waiting ${c/1e3}s: ${u}`),s?.(a+1,r.length),await(0,mr.setTimeout)(c,void 0,{signal:o})}}}var qt=require("node:child_process"),ye=require("node:fs"),pr=Je(require("node:path")),ti=100,ni=5e3;function zt(e){return new Promise((t,n)=>{let r=!1,o=!1,s={code:null,signal:null},a,i=0,c=!e.stdout,u=!e.stderr,l=()=>{a&&clearTimeout(a),e.off("error",P),e.off("exit",b),e.off("close",x),e.stdout?.off("end",h),e.stderr?.off("end",v),e.stdout?.off("data",m),e.stderr?.off("data",m)},d=()=>{r||(r=!0,l(),e.stdout?.destroy(),e.stderr?.destroy(),t(s))},p=()=>{a&&clearTimeout(a),i||=Date.now()+ni,a=setTimeout(d,Math.min(ti,Math.max(i-Date.now(),0)))},m=()=>{o&&p()},h=()=>{c=!0,o&&u&&d()},v=()=>{u=!0,o&&c&&d()},b=(E,M)=>{o=!0,s={code:E,signal:M},c&&u?d():p()},x=()=>d(),P=E=>{r||(r=!0,l(),n(E))};e.stdout?.on("error",()=>{}),e.stderr?.on("error",()=>{}),e.stdout?.on("data",m),e.stderr?.on("data",m),e.stdout?.once("end",h),e.stderr?.once("end",v),e.once("error",P),e.once("exit",b),e.once("close",x)})}var ri=5e3;function Jt(e){let t=e.pid;if(t===void 0)return;if(process.platform==="win32"){try{(0,qt.spawn)("taskkill",["/F","/T","/PID",String(t)],{stdio:"ignore",windowsHide:!0})}catch{}return}let n=r=>{try{process.kill(-t,r)}catch{try{process.kill(t,r)}catch{}}};n("SIGTERM"),setTimeout(()=>{e.exitCode===null&&e.signalCode===null&&n("SIGKILL")},ri).unref()}var oi=1e4;async function fr(e,t){if(process.platform==="win32")return;let n,r;try{r=(0,ye.realpathSync)(e),n=process.platform==="linux"?si(r):await ii(r)}catch(o){console.error(`[reap] ${t} could not list workspace processes:`,o.message);return}if(n.length){for(let o of n)try{process.kill(o,"SIGKILL")}catch{}console.warn(`[reap] ${t} killed ${n.length} stray process(es) under ${r}`)}}function hr(e,t){return e===t||e.startsWith(t+pr.default)}function si(e){let t=[];for(let n of(0,ye.readdirSync)("/proc")){let r=Number(n);if(!Number.isInteger(r)||r===process.pid)continue;let o;try{o=(0,ye.readlinkSync)(`/proc/${n}/cwd`)}catch{continue}hr(o,e)&&t.push(r)}return t}async function ii(e){let t=(0,qt.spawn)("lsof",["-d","cwd","-F","pn"],{stdio:["ignore","pipe","pipe"]}),n="";t.stdout.on("data",i=>{n+=i}),t.stderr.resume();let r=setTimeout(()=>Jt(t),oi);try{await zt(t)}finally{clearTimeout(r)}let o=[],s=new Set,a=0;for(let i of n.split(`
3
- `))i[0]==="p"?a=Number(i.slice(1)):i[0]==="n"&&a&&a!==process.pid&&!s.has(a)&&hr(i.slice(1),e)&&(s.add(a),o.push(a));return o}function T(e){if(!(e instanceof Error))return String(e);let t=e.cause;return t instanceof Error&&t.message&&!e.message.includes(t.message)?`${e.message}: ${T(t)}`:e.message}function tt(){return process.env.DESK_WORKSPACES_DIR||_e().workspacesDir}function Q(){return tt()??(0,W.join)((0,Qt.homedir)(),".desk","workspaces")}function Zt(){let e=tt();if(e&&!(0,O.existsSync)(e))throw new Error(`workspaces dir not found: ${e} \u2014 is the external drive mounted?`)}function en(e){return(0,W.join)(Q(),e,"repo")}function ai(e){let t=Object.entries({"credential.helper":"",...e}),n={...process.env,LC_ALL:"C",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_COUNT:String(t.length)};return t.forEach(([r,o],s)=>{n[`GIT_CONFIG_KEY_${s}`]=r,n[`GIT_CONFIG_VALUE_${s}`]=o}),n}var ci="https://github.com";function vr(e){return(e?process.env.DESK_GIT_HOST??e:ci).replace(/\/$/,"")}function we(e,t){let n=vr(t);return{[`url.${n.replace(/^(https?):\/\//,`$1://x-access-token:${e}@`)}/.insteadOf`]:`${n}/`}}async function Xt(e,t,n={},r){let o=(0,br.spawn)("git",e,{cwd:t,env:ai(n),stdio:["ignore","pipe","pipe"],windowsHide:!0,detached:process.platform!=="win32"}),s="",a="";o.stdout.on("data",u=>{s+=u}),o.stderr.on("data",u=>{a+=u});let i=!1,c=r?setTimeout(()=>{i=!0,Jt(o)},r):void 0;try{let{code:u,signal:l}=await zt(o);if(u===0)return s.trim();throw l||i?new Error(`git ${e[0]} was killed (${l??"timeout"})${r?` after ${r}ms`:""}`):Object.assign(new Error(`git ${e[0]} failed (exit ${u}): ${pi(a.trim())}`),{exitCode:u})}finally{c&&clearTimeout(c)}}var li=new Set(["fetch","push","ls-remote"]);function Tr(e){return Kt.test(e instanceof Error?e.message:String(e))}function g(e,t,n,r){if(!li.has(e[0]))return Xt(e,t,n,r?.timeoutMs);let o=r?.timeoutMs??f.gitNetwork;return F(()=>Xt(e,t,n,o),Tr,`[workspace] git ${e[0]}`,r?.retryDelays,void 0,r?.onRetry)}async function xr(){let e;try{e=await g(["--version"])}catch{throw new Error("git not found on PATH \u2014 install git \u2265 2.31 to run builds")}let t=e.match(/git version (\d+)\.(\d+)/);if(!t)return;let[n,r]=[Number(t[1]),Number(t[2])];if(n<2||n===2&&r<31)throw new Error(`${e} is too old \u2014 token injection needs git \u2265 2.31 (GIT_CONFIG_* env support)`)}var tn={"user.email":"noreply@desk.dev","user.name":"Desk"};async function Er(e,t){await g(["add","-A"],e),await mi(e,t)}async function Rr(e,t,n){let r=async()=>(await Er(e,t),await g(["commit","--allow-empty","--no-verify","-m",`checkpoint ${n}`],e,tn),await g(["rev-parse","HEAD"],e));try{return{sha:await r()}}catch(o){let s=o.message;if(/index\.lock/.test(s)&&await di(e))try{return{sha:await r()}}catch(a){s=a.message}return console.warn(`[step] ${n} checkpoint commit failed:`,s),{error:s.slice(0,500)}}}var ui=5*60*1e3;async function di(e){try{let t=await g(["rev-parse","--absolute-git-dir"],e),n=(0,W.join)(t,"index.lock");return Date.now()-(0,O.statSync)(n).mtimeMs<ui?!1:((0,O.rmSync)(n,{force:!0}),console.warn(`[workspace] removed stale index.lock: ${n}`),!0)}catch{return!1}}async function $r(e,t,n,r,o,s){await Er(e,t);let a=!!await g(["status","--porcelain"],e);a&&await g(["commit","--no-verify","-m",o],e,tn);let i=await nt(e,n,r,s);return{sha:a?i:null}}async function mi(e,t){try{let n=gr(await g(["ls-files","-z","-i","-c","--exclude-standard"],e));if(!n.length)return;let r=await g(["merge-base",`origin/${t}`,"HEAD"],e),o=new Set(gr(await g(["ls-tree","-r","-z","--name-only",r],e))),s=n.filter(a=>!o.has(a));for(let a=0;a<s.length;a+=500)await g(["rm","-r","--cached","--quiet","--",...s.slice(a,a+500)],e)}catch(n){console.warn("[workspace] prune ignored from index failed:",n.message)}}function gr(e){return e.split("\0").filter(Boolean)}function pi(e){return e.replace(/x-access-token:[^@]+@/g,"x-access-token:***@")}function yr(e,t){return`${vr(t)}/${e}.git`}var Ce=class extends Error{kind;staleLeaseRetried;constructor(t,n){let r=t instanceof Error?t.message:String(t);super(r),this.name="PushFailure",this.kind=et(r),this.staleLeaseRetried=n}},fi=e=>({current:()=>e});async function nt(e,t,n,r,o){let s=typeof t=="string"?fi(t):t,a=o?.quick?{timeoutMs:f.gitPushInline,retryDelays:[2e3]}:void 0,i=a&&{...a,retryDelays:[2e3,5e3,1e4]},c=o?.rewind?async()=>{}:wi,u=!1,l=!1,d=async p=>{let m=()=>g(["push","--no-verify","--force-with-lease","-u","origin",n],e,we(p,r),i);l||(await Pr(e,n)||await Yt(e,p,n,r,a),await c(e,n),l=!0);try{await m()}catch(h){if(!hi(h))throw h;u=!0,await Yt(e,p,n,r,a),await c(e,n),await m()}};try{try{await d(s.current())}catch(p){if(!s.refresh||!gi(p))throw p;try{await s.refresh()}catch(m){throw new Error(`${T(p)} (credential refresh also failed: ${T(m)})`)}await d(s.current())}}catch(p){throw new Ce(p,u)}return g(["rev-parse",`refs/heads/${n}`],e)}var nn=e=>`refs/remotes/origin/${e}`,Pr=(e,t)=>g(["rev-parse","--verify","--quiet",nn(t)],e).then(()=>!0,()=>!1),hi=e=>Gt.test(e instanceof Error?e.message:String(e));function gi(e){return e?.exitCode!==128?!1:Wt.test(e instanceof Error?e.message:String(e))}var yi={...tn,"core.hooksPath":(0,W.join)((0,Qt.homedir)(),".desk","no-hooks")};async function wi(e,t){if(!await Pr(e,t))return;let n=nn(t);if(!await g(["merge-base","--is-ancestor",n,`refs/heads/${t}`],e).then(()=>!0,()=>!1)){if(await g(["symbolic-ref","--quiet","--short","HEAD"],e).catch(()=>null)!==t)throw new Error(`${Ze}: origin/${t} has commits this machine does not, and the worktree is not on ${t} to merge them in`);try{await g(["merge","--no-edit",n],e,yi),console.log(`[workspace] merged outside commits from origin/${t}`)}catch(r){throw await g(["merge","--abort"],e).catch(()=>{}),new Error(`${Ze}: origin/${t} has commits this machine does not, and merging them in failed: ${r.message}`)}}}async function Yt(e,t,n,r,o){let s=we(t,r);return await g(["ls-remote","--exit-code","--heads","origin",`refs/heads/${n}`],e,s,o).then(()=>!0,i=>{if(i?.exitCode===2)return!1;throw i})?(await Vt(["fetch","origin",`+refs/heads/${n}:refs/remotes/origin/${n}`],e,s,o),!0):(await g(["update-ref","-d",nn(n)],e).catch(()=>{}),!1)}var ki=e=>{let t=e instanceof Error?e.message:String(e);return/bad object (refs\/[^\s'"]+)/.exec(t)?.[1]??/(refs\/[^\s'"]+) does not point to a valid object/.exec(t)?.[1]??null},Si=10;async function Vt(e,t,n,r){for(let o=0;;o++)try{return await g(e,t,n,r)}catch(s){let a=o<Si?ki(s):null;if(!a)throw s;console.warn(`[workspace] dropping corrupt ref ${a}, retrying fetch`),await g(["update-ref","-d",a],t).catch(()=>{throw s})}}var wr=new Map;function rt(e,t){let r=(wr.get(e)??Promise.resolve()).then(t,t);return wr.set(e,r.catch(()=>{})),r}var kr=`+refs/heads/${ne("*")}:refs/remotes/origin/${ne("*")}`;async function Sr(e){(await g(["config","--get-all","remote.origin.fetch"],e)).split(`
4
- `).includes(kr)||await g(["config","--add","remote.origin.fetch",kr],e)}async function rn(e,t,n,r,o={}){Zt();let{gitHost:s,onRetry:a}=o,i=we(r,s),c="+refs/tags/*:refs/tags/*";if(!(0,O.existsSync)((0,W.join)(e,".git"))){console.log(`[workspace] Cloning ${t} (branch: ${n})\u2026`),await F(()=>((0,O.rmSync)(e,{recursive:!0,force:!0}),(0,O.mkdirSync)(e,{recursive:!0}),Xt(["clone","--branch",n,"--single-branch",yr(t,s),e],void 0,i,f.gitClone)),Tr,"[workspace] git clone",void 0,void 0,a),await Sr(e),o.readCheckout&&await Vt(["fetch","origin",c],e,i,{onRetry:a});return}await g(["remote","set-url","origin",yr(t,s)],e),await Sr(e),!o.skipFetch&&(console.log(`[workspace] Fetching ${t} (branch: ${n})\u2026`),await Vt(["fetch","origin",`+refs/heads/${n}:refs/remotes/origin/${n}`,...o.readCheckout?[c]:[]],e,i,{onRetry:a}),o.readCheckout&&await g(["reset","--hard",`origin/${n}`],e))}async function Mr(e,t,n={}){let{projectId:r,repoFullName:o,defaultBranch:s,installationToken:a,gitHost:i,freshBase:c}=t;return rt(r,async()=>{let u=en(r),l=(0,W.join)(Q(),e),d=ne(e),{restoreTo:p,onRetry:m}=n,h=(0,O.existsSync)((0,W.join)(l,".git"));await rn(u,o,s,a,{skipFetch:h&&p===void 0&&!c,gitHost:i,onRetry:m});let v=p!==void 0&&!p.startsWith("origin/"),b=!1;if((v||!h||c)&&(b=await Yt(u,a,d,i,{onRetry:m})),v&&await g(["cat-file","-e",`${p}^{commit}`],u).catch(()=>{throw new Error("checkpoint commit no longer available \u2014 cannot restore code")}),h)return p!==void 0?(await g(["reset","--hard",p],l),await g(["clean","-fd"],l),console.log(`[workspace] Worktree restored: ${l} \u2192 ${p}`)):console.log(`[workspace] Worktree reused: ${l} (${d})`),l;(0,O.existsSync)(l)&&await g(["worktree","remove","--force",l],u).catch(()=>{(0,O.rmSync)(l,{recursive:!0,force:!0})}),await g(["worktree","prune"],u),await g(["branch","-D",d],u).catch(()=>{});let x=p??(b?`origin/${d}`:`origin/${s}`);return await g(["worktree","add","-b",d,l,x],u),console.log(`[workspace] Worktree ready: ${l} (${d}) from ${x}`),l})}async function _r(e=14*24*3600*1e3){let t=Q(),n;try{n=await(0,ue.readdir)(t)}catch{return}let r=Date.now()-e,o=[];for(let s of n){let a=(0,W.join)(t,s);try{if(!(await(0,ue.stat)((0,W.join)(a,".git"))).isFile()||(await(0,ue.stat)(a)).mtimeMs>=r)continue;await(0,ue.rm)(a,{recursive:!0,force:!0}),o.push(s)}catch{}}if(o.length!==0){for(let s of n){let a=(0,W.join)(t,s,"repo");(0,O.existsSync)((0,W.join)(a,".git"))&&g(["worktree","prune"],a).catch(()=>{})}console.log(`[workspace] Reaped ${o.length} orphan worktree(s)`)}}var on=require("node:os"),Cr=require("node:path");function ot(e){return e==="~"?(0,on.homedir)():e.startsWith("~/")||e.startsWith("~\\")?(0,Cr.join)((0,on.homedir)(),e.slice(2)):e}var it=require("node:fs"),Ir=require("node:os"),sn=require("node:path"),st=null;async function Ie(){if(st)return st;let e=(0,sn.join)((0,Ir.homedir)(),".desk","agent-runtime");(0,it.mkdirSync)(e,{recursive:!0});for(let n of["auth.json","models.json"])try{(0,it.rmSync)((0,sn.join)(e,n),{force:!0})}catch{}let t=await import("@earendil-works/pi-coding-agent");return st={agentDir:e,sdk:t},st}var Ur=require("node:child_process");function Ar(e){let t="";return n=>{t+=n;let r;for(;(r=t.indexOf(`
5
- `))!==-1;){let o=t.slice(0,r).trim();if(t=t.slice(r+1),!o)continue;let s;try{s=JSON.parse(o)}catch{continue}e(s)}}}var ke=require("node:fs"),at=require("node:path");function Dr(e){if(process.platform!=="win32")try{let t=(0,ke.statSync)(e).mode;(t&73)!==73&&(0,ke.chmodSync)(e,t|73)}catch{}}function bi(e){let t=process.env.DESK_TUNNEL_BIN;if(t)return t;let n=process.platform==="win32"?".exe":"",r=process.platform==="android"?["android","linux"]:[process.platform];for(let o of r)try{let s=require.resolve(`@deskdev/tunnel-${o}-${process.arch}`);return Dr(s),s}catch{}for(let o of r){let s=(0,at.join)("packages",`tunnel-${o}-${process.arch}`,"vendor",`${e}${n}`),a=__dirname;for(let i=0;i<8;i++){let c=(0,at.join)(a,s);if((0,ke.existsSync)(c))return Dr(c),c;let u=(0,at.join)(a,"..");if(u===a)break;a=u}}if(process.env.DESK_DISABLE_TUNNEL!=="1"){let o=r.map(s=>`@deskdev/tunnel-${s}-${process.arch}`).join(", ");console.warn(`[bin] ${e} binary not found (none of ${o} installed, no vendor/ tree near ${__dirname}) \u2014 falling back to PATH. Run \`bun run build:bins\` (dev) or reinstall the CLI.`)}return e}var Or=bi("desk-tunnel");var ct=require("fs"),lt=require("path"),an=null;function Z(){return an||(an=vi())}function vi(){let e=__dirname;for(let t=0;t<6;t++){let n=(0,lt.join)(e,"package.json");if((0,ct.existsSync)(n))try{let o=JSON.parse((0,ct.readFileSync)(n,"utf-8"));if(o.version)return o.version}catch{}let r=(0,lt.dirname)(e);if(r===e)break;e=r}return"unknown"}var Lr=1e3,Ti=6e4,Fr=e=>`desk-tunnel could not start (${e instanceof Error?e.message:String(e)}) \u2014 the bundled binary may be missing or blocked; reinstall the CLI`,Se=class{constructor(t,n,r,o){this.args=t;this.label=n;this.onExit=o;this.parse=Ar(r)}proc=null;stopped=!1;restartTimer=null;restartDelayMs=Lr;parse;onSpawnFailure;start(){this.stopped=!1,this.spawn()}stop(){this.stopped=!0,this.restartTimer&&(clearTimeout(this.restartTimer),this.restartTimer=null),this.proc?.kill(),this.proc=null}resetBackoff(){this.restartDelayMs=Lr}alive(){return!!(this.proc&&!this.proc.killed&&this.proc.stdin&&!this.proc.stdin.destroyed)}write(t){let n=this.proc?.stdin;if(!n||n.destroyed)return!1;try{return n.write(JSON.stringify(t)+`
6
- `),!0}catch{return!1}}spawn(){try{this.proc=(0,Ur.spawn)(Or,this.args,{stdio:["pipe","pipe","inherit"],env:{...process.env,DESK_CLI_VERSION:Z()}})}catch(t){console.warn(`[${this.label}] desk-tunnel not available \u2014 disabled`),this.onSpawnFailure?.(Fr(t));return}this.proc.on("error",t=>{console.warn(`[${this.label}] sidecar failed to start \u2014 disabled`),this.proc=null,this.onSpawnFailure?.(Fr(t))}),this.proc.on("exit",()=>{this.proc=null,this.onExit?.(),this.scheduleRestart()}),this.proc.stdout?.on("data",t=>this.parse(String(t))),this.proc.stdin?.on("error",()=>{})}scheduleRestart(){if(this.stopped||this.restartTimer)return;let t=this.restartDelayMs;this.restartDelayMs=Math.min(this.restartDelayMs*2,Ti),console.warn(`[${this.label}] sidecar exited \u2014 restarting in ${Math.round(t/1e3)}s`),this.restartTimer=setTimeout(()=>{this.restartTimer=null,this.spawn()},t)}};var Hr=256*1024,cn=Buffer.alloc(0),ut=class e{node=null;onChange=null;lastErr=null;sidecar;shells=new Map;constructor(t,n){this.sidecar=new Se(["serve","--server",t,"--token",n],"tunnel",r=>this.onEvent(r),()=>{this.node=null,this.closeAllShells(),this.onChange?.()}),this.sidecar.onSpawnFailure=r=>{this.lastErr=r,this.onChange?.()}}setNodeChangeHandler(t){this.onChange=t,this.node&&t()}start(){this.sidecar.start()}static shellKey(t,n){return`${t}\0${n}`}onEvent(t){if(t.event==="ready"&&t.tailnetAddr&&t.sshHostKey)this.node={tailnetAddr:t.tailnetAddr,sshHostKey:t.sshHostKey},this.lastErr=null,this.sidecar.resetBackoff(),console.log(`[tunnel] ready (tailnet ${t.tailnetAddr})`),this.onChange?.();else if((t.event==="shell-opened"||t.event==="shell-output"||t.event==="shell-closed")&&t.build){let n=this.shellState(e.shellKey(t.build,t.machine??""));if(t.event==="shell-opened"){n.connected=!0,n.gen++;for(let r of[...n.listeners])r.onOpened?.()}else if(t.event==="shell-output"){n.connected=!0;let r=Buffer.concat([n.buffer,Buffer.from(t.data??"","base64")]);r.length>Hr&&(r=r.subarray(r.length-Hr)),n.buffer=r;for(let o of n.listeners)o.onActivity?.()}else{n.connected=!1;for(let r of[...n.listeners])r.onClosed()}}else t.event==="error"&&(this.lastErr=t.message??"unknown error",console.warn(`[tunnel] ${this.lastErr}`),this.onChange?.())}shellAvailable(){return this.sidecar.alive()}shellSendInput(t,n,r){return this.sidecar.write({cmd:"shell-input",build:t,machine:n,data:Buffer.from(r,"utf8").toString("base64")})}ensureShell(t,n,r){let o=this.shellState(e.shellKey(t,n));return o.connected?Promise.resolve("connected"):this.sidecar.write({cmd:"shell-open",build:t,machine:n})?this.waitShell(o,r,s=>({onOpened:()=>s(!0),onActivity:()=>s(!0),onClosed:()=>s(!1)})).then(s=>s?"opened":"failed"):Promise.resolve("failed")}async restartShell(t,n,r){let o=this.shellState(e.shellKey(t,n));this.sidecar.write({cmd:"shell-close",build:t,machine:n})&&(o.connected=!1,await this.waitShell(o,r,s=>({onClosed:()=>s(!0)}))),o.buffer=cn}waitShell(t,n,r){return new Promise(o=>{let s,a=c=>{clearTimeout(s),t.listeners.delete(i),o(c)},i=r(a);s=setTimeout(()=>a(!1),n),t.listeners.add(i)})}hasEverOpened(t,n){return(this.shells.get(e.shellKey(t,n))?.gen??0)>0}consumeShellReconnect(t,n){let r=this.shells.get(e.shellKey(t,n));if(!r)return!1;let o=r.reportedGen>=1&&r.gen>r.reportedGen;return r.reportedGen=r.gen,o}subscribeShell(t,n,r){let o=this.shellState(e.shellKey(t,n));return o.listeners.add(r),()=>{o.listeners.delete(r)}}drainShell(t,n){let r=this.shells.get(e.shellKey(t,n));if(!r)return"";let o=r.buffer.toString("utf8");return r.buffer=cn,o}shellState(t){let n=this.shells.get(t);return n||(n={buffer:cn,gen:0,reportedGen:0,listeners:new Set},this.shells.set(t,n)),n}closeAllShells(){for(let t of this.shells.values()){t.connected=!1;for(let n of[...t.listeners])n.onClosed()}}current(){return this.node}lastError(){return this.lastErr}stop(){this.sidecar.stop(),this.node=null,this.closeAllShells()}};var Nr=new Set;function Ae(...e){for(let t of e)t.aborted||(Nr.add(t),t.addEventListener("abort",()=>Nr.delete(t),{once:!0}))}function U(e,t,n={}){let r=AbortSignal.timeout(t);return Ae(r),fetch(e,{...n,signal:r})}function be(e,t){return Object.assign(new Error(`HTTP ${e.status}${t?` ${t}`:""}`),{httpStatus:e.status})}function dt(e){let t={[cr]:Z()};return e&&(t.Authorization=`Bearer ${e}`),t}function I(e,t,n){let{token:r,body:o,timeoutMs:s,signal:a}=n,i=AbortSignal.timeout(s),c=a?AbortSignal.any([a,i]):i;return Ae(c,i),fetch(`${e}${t}`,{method:n.method??(o!==void 0?"POST":"GET"),headers:o!==void 0?{"Content-Type":"application/json",...dt(r)}:dt(r),body:o!==void 0?JSON.stringify(o):void 0,signal:c})}var Wr=require("node:crypto"),Kr=require("node:zlib");async function ln(e,t,n){try{let r=await g(["diff","--raw",`origin/${t}...HEAD`],e);return r.trim()?(0,Wr.createHash)("sha256").update(r).digest("hex"):null}catch(r){console.error(`[step] ${n} diffHash diff failed:`,r.message);return}}var xi=1e6,jr=[":(exclude)*.lock",":(exclude)package-lock.json",":(exclude)pnpm-lock.yaml",":(exclude)yarn.lock"];async function Gr(e,t,n,r=xi){try{let o=`origin/${t}...HEAD`,s=await g(["diff","-U100000",o,"--",...jr],e);Br(s)>r&&(s=await g(["diff","-U3",o,"--",...jr],e));let a=Br(s);return a>r?(console.error(`[step] ${n} diff too large: ${a} bytes > ${r} bytes`),{isGit:!0,files:[],unavailableReason:"too_large",limitBytes:r,actualBytes:a}):{isGit:!0,files:Ei(s)}}catch(o){console.error(`[step] ${n} diff build failed:`,o.message);return}}var Br=e=>Buffer.byteLength(e,"utf8");function Ei(e){return e.split(/(?=^diff --git )/m).flatMap(t=>{if(!t.startsWith("diff --git "))return[];let n=t.replace(/\n$/,"");return[{path:Ri(n),additions:n.match(/^(?!\+\+\+)\+/gm)?.length??0,deletions:n.match(/^(?!---)-/gm)?.length??0,patch:n}]})}function Ri(e){let t=e.match(/^\+\+\+ b\/(.+)$/m)?.[1]??e.match(/^--- a\/(.+)$/m)?.[1]??e.match(/^diff --git a\/(.+) b\/(.+)$/m)?.[2]??e.split(`
7
- `,1)[0].replace(/^diff --git /,"");return $i(t)}var $i=e=>e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;async function qr(e,t,n,r){try{let o=(0,Kr.gzipSync)(JSON.stringify(t)),s=i=>U(i,f.r2Upload,{method:"PUT",body:o,headers:{"Content-Type":"application/json","Content-Encoding":"gzip"}}),a=await s(e);if(!a.ok&&r){let i=await r();i&&(a=await s(i))}a.ok||console.error(`[step] ${n} diff upload failed: ${a.status}`)}catch(o){console.error(`[step] ${n} diff upload error:`,o.message)}}var K=require("node:fs"),pt=require("node:fs/promises"),zr=require("node:os"),ft=require("node:path"),Jr=require("node:buffer"),Xr=require("node:zlib"),Yr=require("node:util");var mt=require("node:fs");function De(e,t){let n=`${e}.tmp`;(0,mt.writeFileSync)(n,t),(0,mt.renameSync)(n,e)}var Pi=(0,Yr.promisify)(Xr.gzip);function Oe(){let e=process.env.DESK_CHAT_SESSIONS_DIR??(0,ft.join)((0,zr.homedir)(),".desk","chat-sessions");return(0,K.mkdirSync)(e,{recursive:!0}),e}function Vr(){return(0,ft.join)(Oe(),"index.json")}function ht(){try{return JSON.parse((0,K.readFileSync)(Vr(),"utf-8"))}catch{return{version:1,entries:{}}}}function gt(e){let t=Oe();(0,K.mkdirSync)(t,{recursive:!0}),De(Vr(),JSON.stringify(e))}function un(e){let t=ht(),n=t.entries[e];return n?(0,K.existsSync)(n.sessionFilePath)?{mode:"continue",sessionFilePath:n.sessionFilePath}:(delete t.entries[e],gt(t),{mode:"rebuild"}):{mode:"rebuild"}}function dn(e,t){let n=ht();n.entries[e]={sessionFilePath:t,lastUsedAt:Date.now()},gt(n)}function Mi(e){let t=ht(),n=t.entries[e];n&&(n.lastUsedAt=Date.now(),gt(t))}async function Qr(e,t){if(!t||un(e).mode==="continue")return;let n;try{let o=await U(t,f.r2Download);if(!o.ok)return;n=Jr.Buffer.from(await o.arrayBuffer())}catch(o){console.warn(`[session] hydrate fetch failed for ${e}:`,o.message);return}let r=(0,ft.join)(Oe(),`${e}.jsonl`);De(r,n),dn(e,r)}async function yt(e,t,n,r){if(!(!n||!t))try{let o=await Pi(await(0,pt.readFile)(t)),s=i=>U(i,f.r2UploadSession,{method:"PUT",body:o,headers:{"Content-Type":"application/x-ndjson","Content-Encoding":"gzip"}}),a=await s(n);if(!a.ok&&r){let i=await r();i&&(a=await s(i))}a.ok||console.warn(`[session] R2 backup failed for ${e}: HTTP ${a.status}`)}catch(o){console.warn(`[session] R2 backup failed for ${e}:`,o.message)}}async function mn(e){await Qr(e.sessionKey,e.restoreUrl);let t=un(e.sessionKey);return t.mode==="continue"?(Mi(e.sessionKey),{sessionManager:e.sdk.SessionManager.open(t.sessionFilePath,Oe(),e.cwd),isContinue:!0,sessionKeyForSave:null}):{sessionManager:e.sdk.SessionManager.create(e.cwd,Oe(),{id:e.sessionKey}),isContinue:!1,sessionKeyForSave:e.sessionKey}}function _i(e,t,n){let r=(0,K.readFileSync)(e,"utf-8").split(`
8
- `).filter(Boolean);if(r.length===0)return;let o=r[0];if(!t){(0,K.writeFileSync)(e,o+`
9
- `);return}let s=[o],a=!1;for(let i=1;i<r.length;i++){s.push(r[i]);try{if(JSON.parse(r[i]).id===t){a=!0;break}}catch{}}if(!a){console.warn(`[restore] ${n} session leaf ${t} not found \u2014 session drifted from history, resetting to empty`),(0,K.writeFileSync)(e,o+`
10
- `);return}(0,K.writeFileSync)(e,s.join(`
2
+ "use strict";var vi=Object.create;var cn=Object.defineProperty;var xi=Object.getOwnPropertyDescriptor;var Ti=Object.getOwnPropertyNames;var Ei=Object.getPrototypeOf,Ri=Object.prototype.hasOwnProperty;var B=(e,t)=>()=>(e&&(t=e(e=0)),t);var Pi=(e,t)=>{for(var n in t)cn(e,n,{get:t[n],enumerable:!0})},_i=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ti(t))!Ri.call(e,o)&&o!==n&&cn(e,o,{get:()=>t[o],enumerable:!(r=xi(t,o))||r.enumerable});return e};var Ke=(e,t,n)=>(n=e!=null?vi(Ei(e)):{},_i(t||!e||!e.__esModule?cn(n,"default",{value:e,enumerable:!0}):n,e));function oe(){return process.env.DESK_HOME||(0,ln.join)((0,xr.homedir)(),".desk")}function j(...e){return(0,ln.join)(oe(),...e)}function un(){return j("machine.json")}function se(){let e=un();if(!(0,re.existsSync)(e))return null;try{let t=JSON.parse((0,re.readFileSync)(e,"utf-8"));if(t.token&&t.machineId)return t}catch{}return null}function Tr(e){(0,re.mkdirSync)(oe(),{recursive:!0}),(0,re.writeFileSync)(un(),JSON.stringify(e,null,2),{mode:384})}function Er(){let e=un();try{(0,re.existsSync)(e)&&(0,re.rmSync)(e)}catch{}}var re,xr,ln,K=B(()=>{"use strict";re=require("fs"),xr=require("os"),ln=require("path")});var Ir=B(()=>{"use strict"});var fn,Cr,Or=B(()=>{"use strict";fn=e=>e?.mode==="branch_sync",Cr=e=>/^branch-sync-([a-zA-Z0-9_-]{8,100})$/.exec(e)?.[1]??null});function Ui(e){return e.trim().replace(/[/\\]+$/,"")}function Dr(e){if(!e.trim())return"is empty";if(/[\x00-\x1f]/.test(e))return"contains control characters";let t=Ui(e);if(!t)return"is the root of a whole drive or filesystem";if(t.startsWith("~")&&t!=="~"&&!t.startsWith("~/")&&!t.startsWith("~\\"))return'starts with "~" followed by a name \u2014 only "~/" is expanded to the home directory, so this would be taken literally';let n=/^[a-zA-Z]:([/\\]|$)/.test(t),r=t.startsWith("\\\\"),o=t.startsWith("/"),s=t==="~"||t.startsWith("~/")||t.startsWith("~\\");if(!s&&!o&&!n&&!r)return'is a relative path \u2014 it must be absolute, or start with "~/" for a folder under the home directory';let i=t.split(/[/\\]+/).filter(c=>c&&c!=="~"&&!/^[a-zA-Z]:$/.test(c));if(i.includes(".."))return'contains ".."';let a=t.toLowerCase();return o&&Hi.some(c=>a===c||a.startsWith(`${c}/`))||n&&i.length&&ji.has(i[0].toLowerCase())?"is inside a system directory":s?i.length?null:"is the home directory itself":r?i.length>=2?null:"names a whole network share rather than a folder inside it":i.length?Bi.has(i[0].toLowerCase())&&i.length<3?"names a whole home directory or volume rather than a folder inside it":null:"is the root of a whole drive or filesystem"}var Hi,ji,Bi,Lr=B(()=>{"use strict";Hi=["/etc","/usr","/bin","/sbin","/lib","/boot","/dev","/proc","/sys","/var","/system","/library","/applications"],ji=new Set(["windows","winnt","program files","program files (x86)","programdata"]),Bi=new Set(["volumes","mnt","media","users","home"])});function Fr(e){return{cost:{input:0,output:0,cacheRead:0,cacheWrite:0},...e,name:e.name??e.id,reasoning:e.reasoning??!1,input:e.input??["text"],contextWindow:e.contextWindow??128e3,maxTokens:e.maxTokens??qi(e.reasoning)}}function St(e){return e.includes(kt)?"diverged":yn.test(e)?"stale_lease":hn.test(e)?"auth":gn.test(e)?"network":"other"}function Br(e){let t=Number(e);return Number.isInteger(t)&&t>=Vi&&t<=Qi?t:null}var dl,ml,Nr,Wi,pl,Ki,fl,hl,Gi,gl,qi,Ur,zi,Ji,Hr,yl,Yi,wl,kl,Sl,Xi,bl,he,kt,jr,hn,gn,yn,Vi,Qi,Wr,Kr,ue=B(()=>{"use strict";Ir();Or();Lr();dl={free:{maxMembers:1,maxMachines:2,maxParallelBuilds:2,maxProjects:6,maxStorageBytes:1024**3},pro:{maxMembers:5,maxMachines:5,maxParallelBuilds:8,maxProjects:20,maxStorageBytes:20*1024**3}},ml=30*60*1e3,Nr={plan:{track:"plan",sink:"chat",phase:{busy:"planning",rest:"confirm",notify:"plan_ready"}},plan_revision:{track:"plan",sink:"chat",phase:{busy:"planning",rest:"confirm",notify:"plan_ready"}},implement:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},implement_revision:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},merge:{track:"implement",sink:"chat",phase:{busy:"building",rest:"review",notify:"build_review"}},plan_review:{track:"plan",sink:"review"},implement_review:{track:"implement",sink:"review"},chief:{sink:"chief"}},Wi=e=>Nr[e].sink==="review",pl=Object.keys(Nr).filter(e=>Wi(e)),Ki=["planning","building"],fl=["queued",...Ki],hl=64*1024,Gi=["github-copilot","openai-codex"],gl=[...Gi,"xai"],qi=e=>e?64e3:16384;Ur={"image/jpeg":"jpg","image/png":"png","image/webp":"webp","image/gif":"gif","image/svg+xml":"svg","image/avif":"avif"},zi={"text/x-markdown":"md","text/markdown":"md","text/plain":"txt","text/csv":"csv","text/tab-separated-values":"tsv","application/json":"json","application/x-yaml":"yaml","text/yaml":"yaml","text/xml":"xml","application/xml":"xml","text/html":"html","application/pdf":"pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"xlsx","application/vnd.openxmlformats-officedocument.presentationml.presentation":"pptx","application/msword":"doc","application/vnd.ms-excel":"xls","application/vnd.ms-powerpoint":"ppt"},Ji={"audio/mpeg":"mp3","audio/wav":"wav","audio/ogg":"ogg","video/mp4":"mp4","video/quicktime":"mov","video/webm":"webm","application/zip":"zip","application/x-tar":"tar","application/gzip":"gz","application/x-gzip":"tgz","application/vnd.rar":"rar","application/x-7z-compressed":"7z"},Hr={...Ur,...zi,...Ji},yl=Object.keys(Ur).join(","),Yi={...Object.fromEntries(Object.entries(Hr).map(([e,t])=>[t,e])),jpeg:"image/jpeg",htm:"text/html",yml:"text/yaml"},wl=[...Object.keys(Hr),...Object.keys(Yi).map(e=>`.${e}`)].join(","),kl=5*1024*1024,Sl=20*1024*1024,Xi=["attachment","doc","skill","todo","project","machine","agent","member"],bl=new RegExp(`\`(@?\\[[^\\]\`]*\\]\\((?:${Xi.join("|")}):[A-Za-z0-9_-]+\\))\``,"g"),he=e=>`desk/conv-${e}`,kt="remote branch diverged",jr="Branch push failed: ",hn=/Authentication failed|Invalid username or (token|password)|authentication required|Bad credentials|could not read Username|Permission denied \(publickey\)/i,gn=/SSL_ERROR_SYSCALL|SSL_connect|gnutls_handshake|GnuTLS|[Cc]ould not resolve host|Temporary failure in name resolution|Connection (timed out|reset|refused)|Operation timed out|Failed to connect|[Rr]ecv failure|[Ss]end failure|early EOF|RPC failed|unexpected disconnect|remote end hung up|The requested URL returned error: 5\d\d|was killed \(/,yn=/stale info/;Vi=1,Qi=100;Wr=3e3,Kr="x-desk-version"});function Gr(){return j("settings.json")}function qe(){if(Ge)return Ge;let e=Gr();if((0,be.existsSync)(e))try{let t=JSON.parse((0,be.readFileSync)(e,"utf-8"));t&&typeof t=="object"&&!Array.isArray(t)&&(Ge=t)}catch{}return Ge??={}}function qr(e){let t={...qe(),...e};(0,be.mkdirSync)(oe(),{recursive:!0}),(0,be.writeFileSync)(Gr(),JSON.stringify(t,null,2)),Ge=t}var be,Ge,wn=B(()=>{"use strict";be=require("fs");K();Ge=null});var f,U=B(()=>{"use strict";f={claim:6e4,stepPost:3e4,recover:15e3,presence:15e3,presenceOffline:2e3,statusProbe:8e3,enroll:15e3,enrollPoll:1e4,remoteTool:1e4,openRepo:3e4,r2Upload:1e4,r2UploadSession:6e4,r2Download:3e4,gitNetwork:3e5,gitNetworkInteractive:12e4,gitLocalInteractive:3e4,gitClone:18e5,streamFirstEvent:3e5,streamIdle:48e4,streamBodyTimeout:54e4,streamUsageTail:1e3,bashDefault:18e5,webFetch:1e4,mcpConnect:15e3,mcpToolCall:6e4,gitPushInline:6e4,deferredTurnWork:6e5}});function V(e){let t=e.httpStatus;return t===void 0||t===429||t>=500}async function G(e,t,n,r=Zi,o,s){for(let i=0;;i++){o?.throwIfAborted();try{let a=await e();return i>0&&s?.(0,0),a}catch(a){if(o?.aborted)throw o.reason??a;if(i>=r.length||!t(a))throw a;let c=r[i],l=a instanceof Error?a.message:String(a);console.warn(`${n} transient failure (retry ${i+1}/${r.length}), waiting ${c/1e3}s: ${l}`),s?.(i+1,r.length),await(0,zr.setTimeout)(c,void 0,{signal:o})}}}var zr,Zi,ve=B(()=>{"use strict";zr=require("node:timers/promises"),Zi=[2e3,4e3,8e3]});function Sn(e){return new Promise((t,n)=>{let r=!1,o=!1,s={code:null,signal:null},i,a=0,c=!e.stdout,l=!e.stderr,u=()=>{i&&clearTimeout(i),e.off("error",$),e.off("exit",A),e.off("close",T),e.stdout?.off("end",g),e.stderr?.off("end",x),e.stdout?.off("data",p),e.stderr?.off("data",p)},d=()=>{r||(r=!0,u(),e.stdout?.destroy(),e.stderr?.destroy(),t(s))},m=()=>{i&&clearTimeout(i),a||=Date.now()+ta,i=setTimeout(d,Math.min(ea,Math.max(a-Date.now(),0)))},p=()=>{o&&m()},g=()=>{c=!0,o&&l&&d()},x=()=>{l=!0,o&&c&&d()},A=(R,E)=>{o=!0,s={code:R,signal:E},c&&l?d():m()},T=()=>d(),$=R=>{r||(r=!0,u(),n(R))};e.stdout?.on("error",()=>{}),e.stderr?.on("error",()=>{}),e.stdout?.on("data",p),e.stderr?.on("data",p),e.stdout?.once("end",g),e.stderr?.once("end",x),e.once("error",$),e.once("exit",A),e.once("close",T)})}function bt(e){let t=e.pid;if(t===void 0)return;if(process.platform==="win32"){try{(0,kn.spawn)("taskkill",["/F","/T","/PID",String(t)],{stdio:"ignore",windowsHide:!0})}catch{}return}let n=r=>{try{process.kill(-t,r)}catch{try{process.kill(t,r)}catch{}}};n("SIGTERM"),setTimeout(()=>{e.exitCode===null&&e.signalCode===null&&n("SIGKILL")},na).unref()}async function Yr(e,t){if(process.platform==="win32")return;let n,r;try{r=(0,Ne.realpathSync)(e),n=process.platform==="linux"?oa(r):await sa(r)}catch(o){console.error(`[reap] ${t} could not list workspace processes:`,o.message);return}if(n.length){for(let o of n)try{process.kill(o,"SIGKILL")}catch{}console.warn(`[reap] ${t} killed ${n.length} stray process(es) under ${r}`)}}function Xr(e,t){return e===t||e.startsWith(t+Jr.default)}function oa(e){let t=[];for(let n of(0,Ne.readdirSync)("/proc")){let r=Number(n);if(!Number.isInteger(r)||r===process.pid)continue;let o;try{o=(0,Ne.readlinkSync)(`/proc/${n}/cwd`)}catch{continue}Xr(o,e)&&t.push(r)}return t}async function sa(e){let t=(0,kn.spawn)("lsof",["-d","cwd","-F","pn"],{stdio:["ignore","pipe","pipe"]}),n="";t.stdout.on("data",a=>{n+=a}),t.stderr.resume();let r=setTimeout(()=>bt(t),ra);try{await Sn(t)}finally{clearTimeout(r)}let o=[],s=new Set,i=0;for(let a of n.split(`
3
+ `))a[0]==="p"?i=Number(a.slice(1)):a[0]==="n"&&i&&i!==process.pid&&!s.has(i)&&Xr(a.slice(1),e)&&(s.add(i),o.push(i));return o}var kn,Ne,Jr,ea,ta,na,ra,bn=B(()=>{"use strict";kn=require("node:child_process"),Ne=require("node:fs"),Jr=Ke(require("node:path")),ea=100,ta=5e3;na=5e3;ra=1e4});function O(e){if(!(e instanceof Error))return String(e);let t=e.cause;return t instanceof Error&&t.message&&!e.message.includes(t.message)?`${e.message}: ${O(t)}`:e.message}var de=B(()=>{"use strict"});function vt(){return process.env.DESK_WORKSPACES_DIR||qe().workspacesDir}function Q(){return vt()??j("workspaces")}function En(){let e=vt();if(e&&!(0,W.existsSync)(e))throw new Error(`workspaces dir not found: ${e} \u2014 is the external drive mounted?`)}function Rn(e){return(0,me.join)(Q(),e,"repo")}function ia(e){let t=Object.entries({"credential.helper":"",...e}),n={...process.env,LC_ALL:"C",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_COUNT:String(t.length)};return t.forEach(([r,o],s)=>{n[`GIT_CONFIG_KEY_${s}`]=r,n[`GIT_CONFIG_VALUE_${s}`]=o}),n}function ro(e){return(e?process.env.DESK_GIT_HOST??e:aa).replace(/\/$/,"")}function xe(e,t){let n=ro(t);return{[`url.${n.replace(/^(https?):\/\//,`$1://x-access-token:${e}@`)}/.insteadOf`]:`${n}/`}}async function vn(e,t,n={},r,o){o?.signal?.throwIfAborted();let s=(0,no.spawn)("git",e,{cwd:t,env:ia(n),stdio:["ignore","pipe","pipe"],windowsHide:!0,detached:process.platform!=="win32"}),i=()=>bt(s);o?.signal?.addEventListener("abort",i,{once:!0});let a="",c="";s.stdout.on("data",d=>{a+=d}),s.stderr.on("data",d=>{c+=d});let l=!1,u=r?setTimeout(()=>{l=!0,bt(s)},r):void 0;try{let{code:d,signal:m}=await Sn(s);if(o?.signal?.throwIfAborted(),d===0)return o?.rawOutput?a:a.trim();throw m||l?new Error(`git ${e[0]} was killed (${m??"timeout"})${r?` after ${r}ms`:""}`):Object.assign(new Error(`git ${e[0]} failed (exit ${d}): ${ma(c.trim())}`),{exitCode:d})}finally{u&&clearTimeout(u),o?.signal?.removeEventListener("abort",i)}}function oo(e){return gn.test(e instanceof Error?e.message:String(e))}function h(e,t,n,r){if(!ca.has(e[0]))return vn(e,t,n,r?.timeoutMs,r);let o=r?.timeoutMs??f.gitNetwork;return G(()=>vn(e,t,n,o,r),oo,`[workspace] git ${e[0]}`,r?.retryDelays,r?.signal,r?.onRetry)}async function so(){let e;try{e=await h(["--version"])}catch{throw new Error("git not found on PATH \u2014 install git \u2265 2.31 to run builds")}let t=e.match(/git version (\d+)\.(\d+)/);if(!t)return;let[n,r]=[Number(t[1]),Number(t[2])];if(n<2||n===2&&r<31)throw new Error(`${e} is too old \u2014 token injection needs git \u2265 2.31 (GIT_CONFIG_* env support)`)}async function io(e,t){await h(["add","-A"],e),await da(e,t)}async function ao(e,t,n){let r=async()=>(await io(e,t),await h(["commit","--allow-empty","--no-verify","-m",`checkpoint ${n}`],e,Pn),await h(["rev-parse","HEAD"],e));try{return{sha:await r()}}catch(o){let s=o.message;if(/index\.lock/.test(s)&&await ua(e))try{return{sha:await r()}}catch(i){s=i.message}return console.warn(`[step] ${n} checkpoint commit failed:`,s),{error:s.slice(0,500)}}}async function ua(e){try{let t=await h(["rev-parse","--absolute-git-dir"],e),n=(0,me.join)(t,"index.lock");return Date.now()-(0,W.statSync)(n).mtimeMs<la?!1:((0,W.rmSync)(n,{force:!0}),console.warn(`[workspace] removed stale index.lock: ${n}`),!0)}catch{return!1}}async function co(e,t,n,r,o,s){await io(e,t);let i=!!await h(["status","--porcelain"],e);i&&await h(["commit","--no-verify","-m",o],e,Pn);let a=await xt(e,n,r,s);return{sha:i?a:null}}async function da(e,t){try{let n=Vr(await h(["ls-files","-z","-i","-c","--exclude-standard"],e));if(!n.length)return;let r=await h(["merge-base",`origin/${t}`,"HEAD"],e),o=new Set(Vr(await h(["ls-tree","-r","-z","--name-only",r],e))),s=n.filter(i=>!o.has(i));for(let i=0;i<s.length;i+=500)await h(["rm","-r","--cached","--quiet","--",...s.slice(i,i+500)],e)}catch(n){console.warn("[workspace] prune ignored from index failed:",n.message)}}function Vr(e){return e.split("\0").filter(Boolean)}function ma(e){return e.replace(/x-access-token:[^@]+@/g,"x-access-token:***@")}function Qr(e,t){return`${ro(t)}/${e}.git`}async function xt(e,t,n,r,o){let s=typeof t=="string"?pa(t):t,i=o?.quick?{timeoutMs:f.gitPushInline,retryDelays:[2e3]}:void 0,a=i&&{...i,retryDelays:[2e3,5e3,1e4]},c=o?.rewind?async()=>{}:ya,l=!1,u=!1,d=async m=>{let p=()=>h(["push","--no-verify","--force-with-lease","-u","origin",n],e,xe(m,r),a);u||(await lo(e,n)||await xn(e,m,n,r,i),await c(e,n),u=!0);try{await p()}catch(g){if(!fa(g))throw g;l=!0,await xn(e,m,n,r,i),await c(e,n),await p()}};try{try{await d(s.current())}catch(m){if(!s.refresh||!ha(m))throw m;try{await s.refresh()}catch(p){throw new Error(`${O(m)} (credential refresh also failed: ${O(p)})`)}await d(s.current())}}catch(m){throw new ze(m,l)}return h(["rev-parse",`refs/heads/${n}`],e)}function ha(e){return e?.exitCode!==128?!1:hn.test(e instanceof Error?e.message:String(e))}async function ya(e,t){if(!await lo(e,t))return;let n=_n(t);if(!await h(["merge-base","--is-ancestor",n,`refs/heads/${t}`],e).then(()=>!0,()=>!1)){if(await h(["symbolic-ref","--quiet","--short","HEAD"],e).catch(()=>null)!==t)throw new Error(`${kt}: origin/${t} has commits this machine does not, and the worktree is not on ${t} to merge them in`);try{await h(["merge","--no-edit",n],e,ga),console.log(`[workspace] merged outside commits from origin/${t}`)}catch(r){throw await h(["merge","--abort"],e).catch(()=>{}),new Error(`${kt}: origin/${t} has commits this machine does not, and merging them in failed: ${r.message}`)}}}async function xn(e,t,n,r,o){let s=xe(t,r);return await h(["ls-remote","--exit-code","--heads","origin",`refs/heads/${n}`],e,s,o).then(()=>!0,a=>{if(a?.exitCode===2)return!1;throw a})?(await Tn(["fetch","origin",`+refs/heads/${n}:refs/remotes/origin/${n}`],e,s,o),!0):(await h(["update-ref","-d",_n(n)],e).catch(()=>{}),!1)}async function Tn(e,t,n,r){for(let o=0;;o++)try{return await h(e,t,n,r)}catch(s){let i=o<ka?wa(s):null;if(!i)throw s;console.warn(`[workspace] dropping corrupt ref ${i}, retrying fetch`),await h(["update-ref","-d",i],t).catch(()=>{throw s})}}function Tt(e,t){let r=(Zr.get(e)??Promise.resolve()).then(t,t);return Zr.set(e,r.catch(()=>{})),r}async function to(e){(await h(["config","--get-all","remote.origin.fetch"],e)).split(`
4
+ `).includes(eo)||await h(["config","--add","remote.origin.fetch",eo],e)}async function $n(e,t,n,r,o={}){En();let{gitHost:s,onRetry:i}=o,a=xe(r,s),c="+refs/tags/*:refs/tags/*";if(!(0,W.existsSync)((0,me.join)(e,".git"))){console.log(`[workspace] Cloning ${t} (branch: ${n})\u2026`),await G(()=>((0,W.rmSync)(e,{recursive:!0,force:!0}),(0,W.mkdirSync)(e,{recursive:!0}),vn(["clone","--branch",n,"--single-branch",Qr(t,s),e],void 0,a,f.gitClone)),oo,"[workspace] git clone",void 0,void 0,i),await to(e),o.readCheckout&&await Tn(["fetch","origin",c],e,a,{onRetry:i});return}await h(["remote","set-url","origin",Qr(t,s)],e),await to(e),!o.skipFetch&&(console.log(`[workspace] Fetching ${t} (branch: ${n})\u2026`),await Tn(["fetch","origin",`+refs/heads/${n}:refs/remotes/origin/${n}`,...o.readCheckout?[c]:[]],e,a,{onRetry:i}),o.readCheckout&&await h(["reset","--hard",`origin/${n}`],e))}async function uo(e,t,n={}){let{projectId:r,repoFullName:o,defaultBranch:s,installationToken:i,gitHost:a,freshBase:c}=t;return Tt(r,async()=>{let l=Rn(r),u=(0,me.join)(Q(),e),d=he(e),{restoreTo:m,onRetry:p}=n,g=(0,W.existsSync)((0,me.join)(u,".git"));await $n(l,o,s,i,{skipFetch:g&&m===void 0&&!c,gitHost:a,onRetry:p});let x=m!==void 0&&!m.startsWith("origin/"),A=!1;if((x||!g||c)&&(A=await xn(l,i,d,a,{onRetry:p})),x&&await h(["cat-file","-e",`${m}^{commit}`],l).catch(()=>{throw new Error("checkpoint commit no longer available \u2014 cannot restore code")}),g)return m!==void 0?(await h(["reset","--hard",m],u),await h(["clean","-fd"],u),console.log(`[workspace] Worktree restored: ${u} \u2192 ${m}`)):console.log(`[workspace] Worktree reused: ${u} (${d})`),u;(0,W.existsSync)(u)&&await h(["worktree","remove","--force",u],l).catch(()=>{(0,W.rmSync)(u,{recursive:!0,force:!0})}),await h(["worktree","prune"],l),await h(["branch","-D",d],l).catch(()=>{});let T=m??(A?`origin/${d}`:`origin/${s}`);return await h(["worktree","add","-b",d,u,T],l),console.log(`[workspace] Worktree ready: ${u} (${d}) from ${T}`),u})}async function mo(e=7*24*3600*1e3){let t=Q(),n;try{n=await(0,_e.readdir)(t)}catch{return}let r=Date.now()-e,o=[];for(let s of n){let i=(0,me.join)(t,s);try{if(!(await(0,_e.stat)((0,me.join)(i,".git"))).isFile()||(await(0,_e.stat)(i)).mtimeMs>=r)continue;await(0,_e.rm)(i,{recursive:!0,force:!0}),o.push(s)}catch{}}if(o.length!==0){for(let s of n){let i=(0,me.join)(t,s,"repo");(0,W.existsSync)((0,me.join)(i,".git"))&&h(["worktree","prune"],i).catch(()=>{})}console.log(`[workspace] Reaped ${o.length} orphan worktree(s)`)}}var no,W,_e,me,aa,ca,Pn,la,ze,pa,_n,lo,fa,ga,wa,ka,Zr,eo,ge=B(()=>{"use strict";no=require("node:child_process"),W=require("node:fs"),_e=require("node:fs/promises"),me=require("node:path");ue();wn();K();U();ve();bn();de();aa="https://github.com";ca=new Set(["fetch","push","ls-remote"]);Pn={"user.email":"noreply@desk.dev","user.name":"Desk"};la=5*60*1e3;ze=class extends Error{kind;staleLeaseRetried;constructor(t,n){let r=t instanceof Error?t.message:String(t);super(r),this.name="PushFailure",this.kind=St(r),this.staleLeaseRetried=n}},pa=e=>({current:()=>e});_n=e=>`refs/remotes/origin/${e}`,lo=(e,t)=>h(["rev-parse","--verify","--quiet",_n(t)],e).then(()=>!0,()=>!1),fa=e=>yn.test(e instanceof Error?e.message:String(e));ga={...Pn,"core.hooksPath":j("no-hooks")};wa=e=>{let t=e instanceof Error?e.message:String(e);return/bad object (refs\/[^\s'"]+)/.exec(t)?.[1]??/(refs\/[^\s'"]+) does not point to a valid object/.exec(t)?.[1]??null},ka=10;Zr=new Map;eo=`+refs/heads/${he("*")}:refs/remotes/origin/${he("*")}`});function Je(e){return e==="~"?(0,Mn.homedir)():e.startsWith("~/")||e.startsWith("~\\")?(0,po.join)((0,Mn.homedir)(),e.slice(2)):e}var Mn,po,An=B(()=>{"use strict";Mn=require("node:os"),po=require("node:path")});function ye(e,t){let n=`${e}.tmp`;(0,It.writeFileSync)(n,t),(0,It.renameSync)(n,e)}var It,Ct=B(()=>{"use strict";It=require("node:fs")});var zs={};Pi(zs,{BranchCheckoutError:()=>Ce,checkoutBranch:()=>or,withBranchSyncLock:()=>Dc});function Oc(e,t){return e=fe(e.replace(/[\\/]+$/,"")),t=fe(t.replace(/[\\/]+$/,"")),e===t||e.startsWith(`${t}/`)||t.startsWith(`${e}/`)}async function Dc(e,t=j("branch-sync")){await(0,v.mkdir)(t,{recursive:!0});let n=(0,P.join)(t,"lock"),r=await(0,v.mkdtemp)((0,P.join)(t,"lock-candidate-")),o=`${process.pid}-${(0,Gs.randomUUID)()}`,s=async()=>{try{await(0,v.rmdir)(n)}catch(a){if(!["ENOENT","ENOTEMPTY","EEXIST"].includes(a.code??""))throw a}},i=!1;try{await(0,v.writeFile)((0,P.join)(r,o),"",{flag:"wx",mode:384});for(let a=0;a<8;a++){try{await(0,v.rename)(r,n),i=!0;break}catch(u){if(!["EEXIST","ENOTEMPTY","EPERM","ENOENT"].includes(u.code??""))throw u}let c=await(0,v.readdir)(n).catch(u=>{if(it(u))return[];throw u});if(c.length===0){await s();continue}if(c.length!==1||!/^\d+-[a-f0-9-]+$/.test(c[0]))return C("machine_busy");let l=c[0];try{return process.kill(Number(l.split("-")[0]),0),C("machine_busy")}catch(u){if(u.code!=="ESRCH")return C("machine_busy")}try{await(0,v.unlink)((0,P.join)(n,l))}catch(u){if(it(u))continue;throw u}await s()}return i?await e():C("machine_busy")}finally{i&&(await(0,v.unlink)((0,P.join)(n,o)),await s()),await(0,v.rm)(r,{recursive:!0,force:!0})}}async function Ks(e){if(Dr(e))return C("dest_invalid");let t=Je(e.trim());if(!(0,P.isAbsolute)(t))return C("dest_invalid");let n=(0,P.resolve)(t);if(fe(n)===fe((0,P.resolve)((0,qs.homedir)())))return C("dest_invalid");for(let o of[oe(),Q()]){let s=(0,P.resolve)(Je(o)),i=await(0,v.realpath)(s).catch(a=>{if(it(a))return s;throw a});if(Ws(n,s)||Ws(n,i))return C("dest_overlap")}let r=n;for(;;){let o=await st(r);if(o&&(o.isSymbolicLink()||!o.isDirectory()))return C("dest_invalid");if(r===(0,P.parse)(r).root)break;r=(0,P.dirname)(r)}return n}function Lc(e){if(!/^[^/\s]+\/[^/\s]+$/.test(e.repoFullName)||/[\\?#@:]/.test(e.repoFullName))return C("source_invalid");let t=new URL(e.gitHost?process.env.DESK_GIT_HOST??e.gitHost:"https://github.com");return!["https:","http:"].includes(t.protocol)||t.username||t.password||t.search||t.hash?C("source_invalid"):`${t.href.replace(/\/$/,"")}/${e.repoFullName}.git`}async function Nc(){return process.platform!=="linux"?[]:(await(0,v.readFile)("/proc/self/mountinfo","utf8")).split(`
5
+ `).flatMap(t=>{let n=t.split(" ")[4];return n?[n.replace(/\\([0-7]{3})/g,(r,o)=>String.fromCharCode(parseInt(o,8)))]:[]})}async function Fc(e,t){let n=(await(0,v.lstat)(e)).dev,r=await Nc();async function o(s){for(let i of await(0,v.readdir)(s,{withFileTypes:!0})){if(s===e&&i.name===".git")continue;let a=(0,P.join)(s,i.name),c=(0,P.relative)(e,a).split(P.sep).join("/");if(t.some(u=>u.endsWith("/")&&(fe(c)===fe(u.slice(0,-1))||fe(c).startsWith(fe(u)))))continue;if(i.name===".git")return C("nested_repo");let l=await(0,v.lstat)(a);if(!(l.isSymbolicLink()||!l.isDirectory())){if(l.dev!==n||r.includes(a))return C("nested_repo");await o(a)}}}await o(e)}function Uc(e,t){let n=new Set(t.map(fe)),r=[...n].sort();for(let o of e){let s=fe(o.replace(/\/$/,""));if(n.has(s))return!0;let i=`${s}/`,a=0,c=r.length;for(;a<c;){let u=a+c>>>1;r[u]<i?a=u+1:c=u}if(r[a]?.startsWith(i))return!0;let l=s.split("/");for(let u=1;u<l.length;u++)if(n.has(l.slice(0,u).join("/")))return!0}return!1}async function or(e,t={}){let{request:n}=e,{signal:r}=t;if(!/^[a-f0-9]{40}$/.test(n.sha))return C("source_invalid");let o=await Ks(n.destDir),s=t.origin??Lc(e),i=j("branch-sync","no-hooks");if(await(0,v.mkdir)(i,{recursive:!0}),(await(0,v.lstat)(i)).isSymbolicLink()||(await(0,v.readdir)(i)).length)return C("unsupported_checkout");let a={...xe(e.installationToken??"",e.gitHost),"core.hooksPath":i,"core.fsmonitor":"false","submodule.recurse":"false","core.sparseCheckout":"false","advice.detachedHead":"false"},c=(y,ee,w=!1)=>h(y,ee,a,{signal:r,rawOutput:w,timeoutMs:y[0]==="fetch"?f.gitNetwork:f.gitLocalInteractive}),l=async y=>{let ee=await c(["config","--name-only","--null","--get-regexp","^filter\\..*\\.(clean|smudge|process|required)$"],y,!0).catch(w=>{if(w.exitCode===1)return"";throw w});for(let w of ot(ee))a[w]=w.endsWith(".required")?"false":""},u=async y=>{if(await c(["rev-parse","--verify","--quiet",`${n.sha}^{commit}`],y).catch(k=>{if(k.exitCode===1)return"";throw k})===n.sha)return;try{await c(["fetch","--no-tags","--no-recurse-submodules","origin",n.sha],y)}catch(k){if(r?.throwIfAborted(),!n.branch)throw k;await c(["fetch","--no-tags","--no-recurse-submodules","origin",`refs/heads/${n.branch}`],y)}if(await c(["rev-parse","--verify",`${n.sha}^{commit}`],y)!==n.sha)return C("source_invalid")},d=async y=>{if(await c(["rev-parse","HEAD"],y)!==n.sha||await c(["diff","--no-ext-diff","--no-textconv","HEAD","--name-only"],y))return C("invalid_result")},m={projectId:n.projectId,teamId:n.teamId,machineId:n.machineId,sha:n.sha,requestId:n.requestId,todoId:n.todoId,branch:n.branch,origin:s},p=async()=>{r?.throwIfAborted(),await t.beforeWrite?.(),await Ks(o),r?.throwIfAborted()};if(!(await(0,v.readdir)(o).catch(y=>{if(it(y))return[];throw y})).length){await(0,v.mkdir)((0,P.dirname)(o),{recursive:!0});let y=await(0,v.mkdtemp)((0,P.join)((0,P.dirname)(o),".desk-branch-sync-"));try{await c(["init","--template="],y),await c(["remote","add","origin",s],y),await u(y),await l(y),await c(["checkout","--detach","--no-recurse-submodules",n.sha],y),await d(y),ye(Xt(y),JSON.stringify(m)),await p(),await st(o)&&await(0,v.rmdir)(o),await(0,v.rename)(y,o)}finally{await(0,v.rm)(y,{recursive:!0,force:!0})}return}let x=await st((0,P.join)(o,".git"));if(!x?.isDirectory()||x.isSymbolicLink()||await st((0,P.join)(o,".git","commondir")))return C("foreign_repo");let A=await st(Xt(o));if(!A?.isFile()||A.isSymbolicLink())return C("foreign_repo");let T;try{T=JSON.parse(await(0,v.readFile)(Xt(o),"utf8"))}catch{return C("foreign_repo")}if(T?.origin!==s||(0,P.resolve)(await c(["rev-parse","--show-toplevel"],o))!==o||(0,P.resolve)(await c(["rev-parse","--absolute-git-dir"],o))!==(0,P.join)(o,".git")||await c(["config","--get","remote.origin.url"],o)!==s)return C("foreign_repo");if(await l(o),ot(await c(["ls-files","-v","-z"],o,!0)).some(y=>y[0]==="S"||y[0]&&y[0]===y[0].toLowerCase()))return C("unsupported_checkout");let R=await c(["rev-parse","HEAD"],o);if(!n.force&&R!==T.sha)return C("head_changed");if(!n.force&&await c(["status","--porcelain","--untracked-files=all","--ignore-submodules=none"],o))return C("local_changes");await u(o);let E=new Set(ot(await c(["ls-tree","-r","--name-only","-z","HEAD"],o,!0))),b=ot(await c(["ls-files","--others","--ignored","--exclude-standard","--directory","-z"],o,!0)).filter(y=>!E.has(y)),I=ot(await c(["ls-tree","-r","--name-only","-z",n.sha],o,!0));if(Uc(b,I))return C("ignored_path_conflict");await Fc(o,b),await p(),n.force&&await c(["clean","-fd"],o),await c(["checkout","--detach","--no-recurse-submodules","--no-overwrite-ignore",...n.force?["--force"]:[],n.sha],o),await d(o),r?.throwIfAborted(),ye(Xt(o),JSON.stringify(m))}var Gs,v,qs,P,Ce,C,it,st,ot,fe,Ws,Xt,sr=B(()=>{"use strict";Gs=require("node:crypto"),v=require("node:fs/promises"),qs=require("node:os"),P=require("node:path");ue();Ct();An();K();U();ge();Ce=class extends Error{code;constructor(t){super(t),this.name="BranchCheckoutError",this.code=t}},C=e=>{throw new Ce(e)},it=e=>e.code==="ENOENT",st=async e=>(0,v.lstat)(e).catch(t=>{if(it(t))return null;throw t}),ot=e=>e.split("\0").filter(Boolean),fe=e=>process.platform==="win32"||process.platform==="darwin"?e.toLowerCase():e;Ws=(e,t)=>Oc(e.split(P.sep).join("/"),t.split(P.sep).join("/"));Xt=e=>(0,P.join)(e,".git","desk-branch-sync.json")});var kr=[22,19,0],Sr=([e,t,n])=>e*1e6+t*1e3+n,$i=process.versions.node.split(".").map(e=>parseInt(e,10)||0);Sr($i)<Sr(kr)&&(console.error(`desk requires Node.js >= ${kr.join(".")} (found ${process.versions.node}).`),console.error("Upgrade Node, e.g. `nvm install 22 && nvm alias default 22`, then reinstall: npm i -g @deskdev/cli@latest"),process.exit(1));var Be=require("fs"),tn=require("path");var Mi=new Set(["model"]);function ht(e,t){return e.filter(n=>!t.has(n))}function De(e,t={}){let n={},r={},o={},s=[];for(let i=0;i<e.length;i++){let a=e[i];if(!a.startsWith("--")){let d=a.startsWith("-")?t[a.slice(1)]:void 0;if(d){o[d]=!0;continue}s.push(a);continue}let c=a.slice(2),l=c.indexOf("=");if(l!==-1){let d=c.slice(0,l),m=c.slice(l+1);br(d,m,n,r);continue}if(c.startsWith("no-")){o[c.slice(3)]=!1;continue}let u=e[i+1];if(u===void 0||u.startsWith("--")){o[c]=!0;continue}br(c,u,n,r),i++}return{flags:n,repeated:r,bools:o,positionals:s}}function br(e,t,n,r){Mi.has(e)?(r[e]||(r[e]=[]),r[e].push(t)):n[e]=t}var dn=require("child_process"),L=require("fs");var vr=!1;function Le(){if(vr)return;vr=!0;let e=()=>`[${new Date().toISOString()}]`;for(let t of["log","info","warn","error","debug"]){let n=console[t].bind(console);console[t]=(...r)=>n(e(),...r)}}K();var Ai=10*1024*1024,mn=78;function pn(){return j("daemon.json")}function gt(){return j("daemon.log")}function ke(){let e=pn();if(!(0,L.existsSync)(e))return null;try{let t=JSON.parse((0,L.readFileSync)(e,"utf-8"));if(typeof t.pid=="number")return{pid:t.pid,startedAt:t.startedAt??0,runner:t.runner==="desktop"?"desktop":"cli"}}catch{}return null}function Pr(e){(0,L.mkdirSync)(oe(),{recursive:!0}),(0,L.writeFileSync)(pn(),JSON.stringify(e,null,2))}function yt(){try{(0,L.rmSync)(pn())}catch{}}function ie(e){if(!e||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}var Se=e=>new Promise(t=>setTimeout(t,e));function _r(e=Ai){let t=gt();try{if(!(0,L.existsSync)(t)||(0,L.statSync)(t).size<e)return;(0,L.copyFileSync)(t,t+".1"),(0,L.truncateSync)(t,0)}catch{}}function Ii(){return(0,L.mkdirSync)(oe(),{recursive:!0}),(0,L.openSync)(gt(),"a")}var $r=(e,...t)=>[...process.execArgv,process.argv[1],e,...t];function wt(e,t){_r();let n=Ii();try{let r=(0,dn.spawn)(process.execPath,$r(e,...t),{detached:!0,stdio:["ignore",n,n]});return r.unref(),r.pid}finally{(0,L.closeSync)(n)}}var Ci=new Set(["--supervisor","--foreground","-f"]),Oi=e=>ht(e,Ci);function Rr(e,t){e?.on("data",n=>t.write(n)),e?.on("error",()=>{})}async function Di(e){let t=n=>new Promise(r=>{!n||n.closed?r():n.once("close",r)});await Promise.race([Promise.all([t(e.stdout),t(e.stderr)]),Se(1e3)])}var Mr=1e3,Li=3e4,Ni=6e4;function Fi(e,t,n){if(e===mn)return{kind:"terminal"};let r=t>=Ni?Mr:n;return{kind:"restart",delayMs:r,nextBackoffMs:Math.min(r*2,Li)}}async function Ar(e){Le();let t=Oi(e),n=!1,r=null,o=null,s=Mr,i=setInterval(()=>_r(),5*6e4);i.unref();let a=()=>{if(!n&&(n=!0,clearInterval(i),r)){r.kill("SIGTERM");let c=r;setTimeout(()=>{try{c.kill("SIGKILL")}catch{}},5e3).unref()}};for(process.on("SIGTERM",a),process.on("SIGINT",a),console.log(`[supervisor] online (pid ${process.pid}); supervising worker`);!n;){let c=Date.now();r=(0,dn.spawn)(process.execPath,$r("start","--foreground",...t),{stdio:["ignore","pipe","pipe"],windowsHide:!0}),Rr(r.stdout,process.stdout),Rr(r.stderr,process.stderr);let l=await new Promise(d=>{r.on("exit",(m,p)=>d(m??(p?128:0)))});if(o=r,r=null,n)break;let u=Fi(l,Date.now()-c,s);if(u.kind==="terminal"){console.error("[supervisor] worker hit a terminal condition (not registered / revoked); not restarting.");break}console.warn(`[supervisor] worker exited (code ${l}); restarting in ${Math.round(u.delayMs/1e3)}s`),await Se(u.delayMs),s=u.nextBackoffMs}o&&await Di(o),yt(),console.log("[supervisor] stopped"),process.exit(0)}K();ge();wn();U();ve();An();var Rt=require("node:fs"),fo=require("node:os"),In=require("node:path"),Et=null;async function Ye(){if(Et)return Et;let e=(0,In.join)((0,fo.homedir)(),".desk","agent-runtime");(0,Rt.mkdirSync)(e,{recursive:!0});for(let n of["auth.json","models.json"])try{(0,Rt.rmSync)((0,In.join)(e,n),{force:!0})}catch{}let t=await import("@earendil-works/pi-coding-agent");return Et={agentDir:e,sdk:t},Et}var So=require("node:child_process");function ho(e){let t="";return n=>{t+=n;let r;for(;(r=t.indexOf(`
6
+ `))!==-1;){let o=t.slice(0,r).trim();if(t=t.slice(r+1),!o)continue;let s;try{s=JSON.parse(o)}catch{continue}e(s)}}}var Fe=require("node:fs"),Pt=require("node:path");function go(e){if(process.platform!=="win32")try{let t=(0,Fe.statSync)(e).mode;(t&73)!==73&&(0,Fe.chmodSync)(e,t|73)}catch{}}function Sa(e){let t=process.env.DESK_TUNNEL_BIN;if(t)return t;let n=process.platform==="win32"?".exe":"",r=process.platform==="android"?["android","linux"]:[process.platform];for(let o of r)try{let s=require.resolve(`@deskdev/tunnel-${o}-${process.arch}`);return go(s),s}catch{}for(let o of r){let s=(0,Pt.join)("packages",`tunnel-${o}-${process.arch}`,"vendor",`${e}${n}`),i=__dirname;for(let a=0;a<8;a++){let c=(0,Pt.join)(i,s);if((0,Fe.existsSync)(c))return go(c),c;let l=(0,Pt.join)(i,"..");if(l===i)break;i=l}}if(process.env.DESK_DISABLE_TUNNEL!=="1"){let o=r.map(s=>`@deskdev/tunnel-${s}-${process.arch}`).join(", ");console.warn(`[bin] ${e} binary not found (none of ${o} installed, no vendor/ tree near ${__dirname}) \u2014 falling back to PATH. Run \`bun run build:bins\` (dev) or reinstall the CLI.`)}return e}var yo=Sa("desk-tunnel");var _t=require("fs"),$t=require("path"),Cn=null;function pe(){return Cn||(Cn=ba())}function ba(){let e=__dirname;for(let t=0;t<6;t++){let n=(0,$t.join)(e,"package.json");if((0,_t.existsSync)(n))try{let o=JSON.parse((0,_t.readFileSync)(n,"utf-8"));if(o.version)return o.version}catch{}let r=(0,$t.dirname)(e);if(r===e)break;e=r}return"unknown"}var wo=1e3,va=6e4,ko=e=>`desk-tunnel could not start (${e instanceof Error?e.message:String(e)}) \u2014 the bundled binary may be missing or blocked; reinstall the CLI`,Ue=class{constructor(t,n,r,o){this.args=t;this.label=n;this.onExit=o;this.parse=ho(r)}proc=null;stopped=!1;restartTimer=null;restartDelayMs=wo;parse;onSpawnFailure;start(){this.stopped=!1,this.spawn()}stop(){this.stopped=!0,this.restartTimer&&(clearTimeout(this.restartTimer),this.restartTimer=null),this.proc?.kill(),this.proc=null}resetBackoff(){this.restartDelayMs=wo}alive(){return!!(this.proc&&!this.proc.killed&&this.proc.stdin&&!this.proc.stdin.destroyed)}write(t){let n=this.proc?.stdin;if(!n||n.destroyed)return!1;try{return n.write(JSON.stringify(t)+`
7
+ `),!0}catch{return!1}}spawn(){let t;try{t=(0,So.spawn)(yo,this.args,{stdio:["pipe","pipe","inherit"],env:{...process.env,DESK_CLI_VERSION:pe()}})}catch(r){console.warn(`[${this.label}] desk-tunnel not available \u2014 disabled`),this.onSpawnFailure?.(ko(r));return}this.proc=t;let n=()=>this.proc===t;t.on("error",r=>{console.warn(`[${this.label}] sidecar failed to start \u2014 disabled`),n()&&(this.proc=null,this.onSpawnFailure?.(ko(r)))}),t.on("exit",()=>{n()&&(this.proc=null,this.onExit?.(),this.scheduleRestart())}),t.stdout?.on("data",r=>{n()&&this.parse(String(r))}),t.stdin?.on("error",()=>{})}scheduleRestart(){if(this.stopped||this.restartTimer)return;let t=this.restartDelayMs;this.restartDelayMs=Math.min(this.restartDelayMs*2,va),console.warn(`[${this.label}] sidecar exited \u2014 restarting in ${Math.round(t/1e3)}s`),this.restartTimer=setTimeout(()=>{this.restartTimer=null,this.spawn()},t)}};var bo=256*1024,On=Buffer.alloc(0),vo=4e4,xa=3e5,Mt=class e{node=null;onChange=null;lastErr=null;sidecar;shells=new Map;wanted=!1;lastRejoinAt=0;rejoinDelayMs=vo;constructor(t,n){this.sidecar=new Ue(["serve","--server",t,"--token",n],"tunnel",r=>this.onEvent(r),()=>{this.node=null,this.closeAllShells(),this.onChange?.()}),this.sidecar.onSpawnFailure=r=>{this.lastErr=r,this.onChange?.()}}setNodeChangeHandler(t){this.onChange=t,this.node&&t()}start(){this.sidecar.start()}setWanted(t){t!==this.wanted&&(this.wanted=t,t?this.sidecar.start():(console.log("[tunnel] nothing on the team to serve \u2014 stopping the sidecar."),this.stop()))}rejoin(){if(!this.wanted)return;let t=Date.now();this.lastRejoinAt&&t-this.lastRejoinAt<this.rejoinDelayMs||(this.lastRejoinAt=t,this.rejoinDelayMs=Math.min(this.rejoinDelayMs*2,xa),console.log("[tunnel] node no longer registered \u2014 rejoining"),this.stop(),this.sidecar.start())}static shellKey(t,n){return`${t}\0${n}`}onEvent(t){if(t.event==="ready"&&t.tailnetAddr&&t.sshHostKey)this.node={tailnetAddr:t.tailnetAddr,sshHostKey:t.sshHostKey},this.lastErr=null,this.sidecar.resetBackoff(),this.lastRejoinAt=0,this.rejoinDelayMs=vo,console.log(`[tunnel] ready (tailnet ${t.tailnetAddr})`),this.onChange?.();else if((t.event==="shell-opened"||t.event==="shell-output"||t.event==="shell-closed")&&t.build){let n=this.shellState(e.shellKey(t.build,t.machine??""));if(t.event==="shell-opened"){n.connected=!0,n.gen++;for(let r of[...n.listeners])r.onOpened?.()}else if(t.event==="shell-output"){n.connected=!0;let r=Buffer.concat([n.buffer,Buffer.from(t.data??"","base64")]);r.length>bo&&(r=r.subarray(r.length-bo)),n.buffer=r;for(let o of n.listeners)o.onActivity?.()}else{n.connected=!1;for(let r of[...n.listeners])r.onClosed()}}else t.event==="error"&&(this.lastErr=t.message??"unknown error",console.warn(`[tunnel] ${this.lastErr}`),this.onChange?.())}shellAvailable(){return this.sidecar.alive()}shellSendInput(t,n,r){return this.sidecar.write({cmd:"shell-input",build:t,machine:n,data:Buffer.from(r,"utf8").toString("base64")})}ensureShell(t,n,r){let o=this.shellState(e.shellKey(t,n));return o.connected?Promise.resolve("connected"):this.sidecar.write({cmd:"shell-open",build:t,machine:n})?this.waitShell(o,r,s=>({onOpened:()=>s(!0),onActivity:()=>s(!0),onClosed:()=>s(!1)})).then(s=>s?"opened":"failed"):Promise.resolve("failed")}async restartShell(t,n,r){let o=this.shellState(e.shellKey(t,n));this.sidecar.write({cmd:"shell-close",build:t,machine:n})&&(o.connected=!1,await this.waitShell(o,r,s=>({onClosed:()=>s(!0)}))),o.buffer=On}waitShell(t,n,r){return new Promise(o=>{let s,i=c=>{clearTimeout(s),t.listeners.delete(a),o(c)},a=r(i);s=setTimeout(()=>i(!1),n),t.listeners.add(a)})}hasEverOpened(t,n){return(this.shells.get(e.shellKey(t,n))?.gen??0)>0}consumeShellReconnect(t,n){let r=this.shells.get(e.shellKey(t,n));if(!r)return!1;let o=r.reportedGen>=1&&r.gen>r.reportedGen;return r.reportedGen=r.gen,o}subscribeShell(t,n,r){let o=this.shellState(e.shellKey(t,n));return o.listeners.add(r),()=>{o.listeners.delete(r)}}drainShell(t,n){let r=this.shells.get(e.shellKey(t,n));if(!r)return"";let o=r.buffer.toString("utf8");return r.buffer=On,o}shellState(t){let n=this.shells.get(t);return n||(n={buffer:On,gen:0,reportedGen:0,listeners:new Set},this.shells.set(t,n)),n}closeAllShells(){for(let t of this.shells.values()){t.connected=!1;for(let n of[...t.listeners])n.onClosed()}}current(){return this.node}lastError(){return this.lastErr}stop(){this.sidecar.stop(),this.node=null,this.closeAllShells()}};ue();var xo=new Set;function Xe(...e){for(let t of e)t.aborted||(xo.add(t),t.addEventListener("abort",()=>xo.delete(t),{once:!0}))}function q(e,t,n={}){let r=AbortSignal.timeout(t);return Xe(r),fetch(e,{...n,signal:r})}function Te(e,t){return Object.assign(new Error(`HTTP ${e.status}${t?` ${t}`:""}`),{httpStatus:e.status})}function At(e){let t={[Kr]:pe()};return e&&(t.Authorization=`Bearer ${e}`),t}function N(e,t,n){let{token:r,body:o,timeoutMs:s,signal:i}=n,a=AbortSignal.timeout(s),c=i?AbortSignal.any([i,a]):a;return Xe(c,a),fetch(`${e}${t}`,{method:n.method??(o!==void 0?"POST":"GET"),headers:o!==void 0?{"Content-Type":"application/json",...At(r)}:At(r),body:o!==void 0?JSON.stringify(o):void 0,signal:c})}var Ro=require("node:crypto"),Po=require("node:zlib");ge();U();async function Dn(e,t,n){try{let r=await h(["diff","--raw",`origin/${t}...HEAD`],e);return r.trim()?(0,Ro.createHash)("sha256").update(r).digest("hex"):null}catch(r){console.error(`[step] ${n} diffHash diff failed:`,r.message);return}}var Ta=1e6,To=[":(exclude)*.lock",":(exclude)package-lock.json",":(exclude)pnpm-lock.yaml",":(exclude)yarn.lock"];async function _o(e,t,n,r=Ta){try{let o=`origin/${t}...HEAD`,s=await h(["diff","-U100000",o,"--",...To],e);Eo(s)>r&&(s=await h(["diff","-U3",o,"--",...To],e));let i=Eo(s);return i>r?(console.error(`[step] ${n} diff too large: ${i} bytes > ${r} bytes`),{isGit:!0,files:[],unavailableReason:"too_large",limitBytes:r,actualBytes:i}):{isGit:!0,files:Ea(s)}}catch(o){console.error(`[step] ${n} diff build failed:`,o.message);return}}var Eo=e=>Buffer.byteLength(e,"utf8");function Ea(e){return e.split(/(?=^diff --git )/m).flatMap(t=>{if(!t.startsWith("diff --git "))return[];let n=t.replace(/\n$/,"");return[{path:Ra(n),additions:n.match(/^(?!\+\+\+)\+/gm)?.length??0,deletions:n.match(/^(?!---)-/gm)?.length??0,patch:n}]})}function Ra(e){let t=e.match(/^\+\+\+ b\/(.+)$/m)?.[1]??e.match(/^--- a\/(.+)$/m)?.[1]??e.match(/^diff --git a\/(.+) b\/(.+)$/m)?.[2]??e.split(`
8
+ `,1)[0].replace(/^diff --git /,"");return Pa(t)}var Pa=e=>e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e;async function $o(e,t,n,r){try{let o=(0,Po.gzipSync)(JSON.stringify(t)),s=a=>q(a,f.r2Upload,{method:"PUT",body:o,headers:{"Content-Type":"application/json","Content-Encoding":"gzip"}}),i=await s(e);if(!i.ok&&r){let a=await r();a&&(i=await s(a))}i.ok||console.error(`[step] ${n} diff upload failed: ${i.status}`)}catch(o){console.error(`[step] ${n} diff upload error:`,o.message)}}var Z=require("node:fs"),Me=require("node:fs/promises"),Ao=require("node:os"),$e=require("node:path"),Ln=require("node:buffer"),Io=require("node:zlib"),Co=require("node:util");Ct();U();var _a=(0,Co.promisify)(Io.gzip);function Ve(){let e=process.env.DESK_CHAT_SESSIONS_DIR??(0,$e.join)((0,Ao.homedir)(),".desk","chat-sessions");return(0,Z.mkdirSync)(e,{recursive:!0}),e}function Oo(){return(0,$e.join)(Ve(),"index.json")}function Ot(){try{return JSON.parse((0,Z.readFileSync)(Oo(),"utf-8"))}catch{return{version:1,entries:{}}}}function Dt(e){let t=Ve();(0,Z.mkdirSync)(t,{recursive:!0}),ye(Oo(),JSON.stringify(e))}function Nn(e){let t=Ot(),n=t.entries[e];return n?(0,Z.existsSync)(n.sessionFilePath)?{mode:"continue",sessionFilePath:n.sessionFilePath}:(delete t.entries[e],Dt(t),{mode:"rebuild"}):{mode:"rebuild"}}function Fn(e,t){let n=Ot();n.entries[e]={sessionFilePath:t,lastUsedAt:Date.now()},Dt(n)}function $a(e){let t=Ot(),n=t.entries[e];n&&(n.lastUsedAt=Date.now(),Dt(t))}async function Do(e,t){if(!t||Nn(e).mode==="continue")return;let n;try{let o=await q(t,f.r2Download);if(!o.ok)return;n=Ln.Buffer.from(await o.arrayBuffer())}catch(o){console.warn(`[session] hydrate fetch failed for ${e}:`,o.message);return}let r=(0,$e.join)(Ve(),`${e}.jsonl`);ye(r,n),Fn(e,r)}async function Lt(e,t,n,r){if(!(!n||!t))try{let o=await _a(await(0,Me.readFile)(t)),s=a=>q(a,f.r2UploadSession,{method:"PUT",body:o,headers:{"Content-Type":"application/x-ndjson","Content-Encoding":"gzip"}}),i=await s(n);if(!i.ok&&r){let a=await r();a&&(i=await s(a))}i.ok||console.warn(`[session] R2 backup failed for ${e}: HTTP ${i.status}`)}catch(o){console.warn(`[session] R2 backup failed for ${e}:`,o.message)}}async function Un(e){await Do(e.sessionKey,e.restoreUrl);let t=Nn(e.sessionKey);return t.mode==="continue"?($a(e.sessionKey),await Aa(t.sessionFilePath),{sessionManager:e.sdk.SessionManager.open(t.sessionFilePath,Ve(),e.cwd),isContinue:!0,sessionKeyForSave:null}):{sessionManager:e.sdk.SessionManager.create(e.cwd,Ve(),{id:e.sessionKey}),isContinue:!1,sessionKeyForSave:e.sessionKey}}var Mo=1024*1024;function Ma(e){return(0,Z.readFileSync)(e,"utf-8").split(`
9
+ `).filter(Boolean)}function Lo(e){try{return JSON.parse(e)}catch{return null}}async function Aa(e){try{let t=(await(0,Me.stat)(e)).size;if(t<Mo)return;let n=(await(0,Me.readFile)(e,"utf-8")).split(`
10
+ `).filter(Boolean),r=n.map(Lo);if(r[0]?.type!=="session")return;let o=new Map;r.forEach((d,m)=>{m&&d?.id&&o.set(d.id,m)});let s=[];for(let d=r.length-1;d>0;){s.push(d);let m=o.get(r[d]?.parentId??"");if(m===void 0||m>=d)break;d=m}let i=s.filter(d=>r[d]?.type==="compaction")[1];if(i===void 0)return;let a=o.get(r[i]?.firstKeptEntryId??"")??i;if(a>i||n.slice(1,a).reduce((d,m)=>d+m.length+1,0)<Mo)return;let c=[];for(let d of["model_change","thinking_level_change"]){let m=s.find(p=>p<a&&r[p]?.type===d);m!==void 0&&c.push({...r[m],parentId:c[c.length-1]?.id??null})}let l={...r[a],parentId:c[c.length-1]?.id??null},u=[n[0],...c.map(d=>JSON.stringify(d)),JSON.stringify(l),...n.slice(a+1)].join(`
11
11
  `)+`
12
- `)}async function Zr(e,t,n,r){await Qr(e,t);let o=un(e);return o.mode!=="continue"?null:(_i(o.sessionFilePath,n,r),o.sessionFilePath)}async function eo(e=7*24*3600*1e3){let t=ht(),n=Date.now()-e,r=[];for(let[o,s]of Object.entries(t.entries))s.lastUsedAt<n&&(r.push(s.sessionFilePath),delete t.entries[o]);r.length&&(gt(t),await Promise.all(r.map(o=>(0,pt.rm)(o,{force:!0}).catch(()=>{}))),console.log("[machine] Cleaned up stale local session files"))}var w=require("node:fs"),J=require("node:path");var Ci=7*24*60*60*1e3;function pn(e,t,n){if((0,w.statSync)(e).isDirectory()){for(let o of(0,w.readdirSync)(e))pn((0,J.join)(e,o),t,n);(0,w.chmodSync)(e,t)}else(0,w.chmodSync)(e,n)}async function Ii(e,t){let n=`${t}.tmp.${process.pid}.${Date.now()}`;(0,w.mkdirSync)(n,{recursive:!0});try{await Promise.all(e.files.map(async r=>{if(r.name.includes(".."))throw new Error(`unsafe skill file name ${r.name}`);if(!r.url)throw new Error(`missing url for ${r.name}`);let o=await F(async()=>{let a=await U(r.url,f.r2Download);if(!a.ok)throw be(a,`for ${r.name}`);return Buffer.from(await a.arrayBuffer())},B,`[step] skill file ${r.name} fetch`),s=(0,J.join)(n,r.name);(0,w.mkdirSync)((0,J.dirname)(s),{recursive:!0}),(0,w.writeFileSync)(s,o)})),(0,w.mkdirSync)((0,J.dirname)(t),{recursive:!0}),(0,w.existsSync)(t)?(0,w.rmSync)(n,{recursive:!0,force:!0}):((0,w.renameSync)(n,t),pn(t,365,292))}catch(r){throw(0,w.rmSync)(n,{recursive:!0,force:!0}),r}}async function ro(e,t){if(!e?.length)return[];let n=[];for(let r of e){if(!r.files.some(a=>a.name==="SKILL.md"))continue;let o=(0,J.join)(t,"skills",r.id,String(r.updatedAt)),s=(0,J.join)(o,"SKILL.md");try{(0,w.existsSync)(s)?(0,w.utimesSync)(o,new Date,new Date):await Ii(r,o),n.push({name:r.name,description:r.description,filePath:s,baseDir:o,sourceInfo:{path:s,source:"desk-skill",scope:"temporary",origin:"top-level",baseDir:o},disableModelInvocation:!1})}catch(a){console.error(`[step] skill ${r.id} materialize failed:`,a instanceof Error?a.message:String(a))}}return n}function to(e){let t=(0,J.join)(e,"skills");if(!(0,w.existsSync)(t))return;let n=Date.now();for(let r of(0,w.readdirSync)(t)){let o=(0,J.join)(t,r),s;try{s=(0,w.readdirSync)(o)}catch{continue}for(let a of s){let i=(0,J.join)(o,a);try{n-(0,w.statSync)(i).mtimeMs>Ci&&(pn(i,493,420),(0,w.rmSync)(i,{recursive:!0,force:!0}))}catch{}}try{(0,w.readdirSync)(o).length===0&&(0,w.rmSync)(o,{recursive:!0,force:!0})}catch{}}}var no=!1;function oo(e){if(!no){no=!0;try{to(e)}catch{}setInterval(()=>{try{to(e)}catch{}},6*60*60*1e3).unref()}}function Ai(e){let t=new Map(Object.entries(e));return{async read(n){return t.get(n)},async list(){return[...t.entries()].map(([n,r])=>({providerId:n,type:r.type}))},async modify(n,r){let o=await r(t.get(n));return o!==void 0&&t.set(n,o),t.get(n)},async delete(n){t.delete(n)}}}async function fn(e,t){let{agent:n}=t,r=d=>({ok:!1,error:d});if(t.modelConfigError)return r(t.modelConfigError);let o=t.modelConfigs?.find(d=>d.providerId===n.provider);if(!o)return r(`Model ${n.provider}/${n.modelId} is unavailable on this machine: the server sent no provider configuration for this step (server and CLI versions may be out of sync).`);let s=t.modelConfigs??[],a=Ai(Object.fromEntries(s.filter(d=>d.credential.type==="oauth").map(d=>[d.providerId,d.credential]))),i=await e.ModelRuntime.create({credentials:a,modelsPath:null,allowModelNetwork:!1});for(let d of s){if(!d.provider)continue;let p=d.credential.type==="api_key"?d.credential.key:"-";i.registerProvider(d.providerId,{name:d.provider.name,baseUrl:d.provider.baseUrl,api:d.provider.api,apiKey:p,authHeader:d.provider.authHeader,headers:d.provider.headers,models:d.provider.models.map(m=>({...rr(m),compat:d.provider.compat??m.compat}))})}let c=i.getModel(n.provider,n.modelId);if(!c||!i.hasConfiguredAuth(n.provider))return r(`Configured model ${n.provider}/${n.modelId} is unavailable on this machine: this team's provider configuration does not offer it. Manage providers on the website (Resources > Providers).`);let u=o.compactionTrim,l=u?.provider&&u.modelId?i.getModel(u.provider,u.modelId)??void 0:void 0;return u?.modelId&&!l&&console.warn(`[step] compaction model ${u.provider}/${u.modelId} is unavailable on this machine \u2014 summarizing with the step's own model`),{ok:!0,runtime:{modelRuntime:i,model:c,transport:o.transport,compaction:o.compaction,compactionModel:l,compactionTrim:u}}}var io=require("@modelcontextprotocol/sdk/client/index.js"),wt=require("@modelcontextprotocol/sdk/client/stdio.js"),ao=require("@modelcontextprotocol/sdk/client/streamableHttp.js");var Di=64;function Oi(e,t){return`mcp__${e}__${t}`.slice(0,Di)}async function co(e,t){if(!e.length)return[];let n=new Map(t.map(o=>[o.id,o.credential]));return(await Promise.all(e.map(o=>Li(o,n.get(o.id))))).filter(o=>o!==null)}async function Li(e,t){if(!t)return console.warn(`[mcp] ${e.slug}: no credential resolved at claim \u2014 skipping`),null;let n;try{n=e.transport==="http"?new ao.StreamableHTTPClientTransport(new URL(e.url),{requestInit:{headers:t.type==="http"?t.headers:{}}}):new wt.StdioClientTransport({command:e.command,args:e.args??[],env:{...(0,wt.getDefaultEnvironment)(),...t.type==="stdio"?t.env:{}}});let r=new io.Client({name:"desk-executor",version:Z()},{capabilities:{}});return await mo(r.connect(n),f.mcpConnect,`${e.slug} connect`),{ref:e,client:r}}catch(r){return n?.close().catch(()=>{}),console.warn(`[mcp] ${e.slug}: connect failed \u2014 its tools are unavailable this turn: ${T(r)}`),null}}async function lo(e,t){let n=new Set(t),r=await Promise.all(e.map(async s=>{try{let{tools:a}=await mo(s.client.listTools(),f.mcpConnect,`${s.ref.slug} listTools`);return a.map(i=>Fi(s,i))}catch(a){return console.warn(`[mcp] ${s.ref.slug}: listTools failed \u2014 its tools are unavailable this turn: ${T(a)}`),[]}})),o=[];for(let s of r.flat()){if(n.has(s.name)){console.warn(`[mcp] dropping ${s.name}: name already taken in this session`);continue}n.add(s.name),o.push(s)}return o}function Fi(e,t){let{ref:n,client:r}=e,o=Oi(n.slug,t.name);return{name:o,label:`${n.label}: ${t.name}`,description:t.description||`Tool "${t.name}" from the MCP server "${n.label}".`,parameters:t.inputSchema??{type:"object",properties:{}},async execute(s,a,i){try{let c=await r.callTool({name:t.name,arguments:a??{}},void 0,{signal:i,timeout:f.mcpToolCall}),u=(Array.isArray(c.content)?c.content:[]).flatMap(l=>l.type==="text"?[{type:"text",text:String(l.text??"")}]:l.type==="image"?[{type:"image",data:String(l.data??""),mimeType:String(l.mimeType??"image/png")}]:[{type:"text",text:`[${o}: unsupported ${String(l.type)} content omitted]`}]);if(c.isError){let l=u.map(d=>d.type==="text"?d.text:"").join(`
13
- `).trim();return so(`${o} failed: ${l||"the server reported an error without details."}`)}return{content:u.length?u:[{type:"text",text:"(no content)"}],details:{}}}catch(c){if(i?.aborted)throw c;return so(`${o} returned no result: the call to the "${n.label}" MCP server failed (${T(c)}). This is a connection problem, not a rejection \u2014 the server may be down or slow.`)}}}}async function uo(e){await Promise.all(e.map(t=>t.client.close().catch(()=>{})))}function so(e){return{content:[{type:"text",text:e}],details:{}}}async function mo(e,t,n){let r;try{return await Promise.race([e,new Promise((o,s)=>{r=setTimeout(()=>s(new Error(`${n} timed out after ${t}ms`)),t)})])}finally{clearTimeout(r)}}var Ui='No remote machine is available for this build. Your remote_shell grant is fine \u2014 the tool would not be in your toolset otherwise \u2014 so do not report this as a missing permission on your side. What is missing is the machine half: the team needs a machine that is online (`desk start`) AND has the "Remote shell" toggle turned on (separate from your grant). The user can flip that toggle on the machine\'s own page in the web app, or just ask the Chief to turn it on for that machine. Tell the user exactly that.',Hi="[shell reconnected \u2014 the previous shell session was lost: cwd, env vars and background processes were reset]";function ho(e,t){let n=`Machine "${e.name}" is listed, but `;return e.online===!1?n+"it is offline (no presence heartbeat \u2014 `desk start` may have stopped, or the machine is asleep/disconnected). Wait a moment and retry; if this persists, ask the user to check that machine.":t?n+"its remote_shell channel dropped and is being redialed (network blip, or the machine's CLI restarted). Wait a moment and retry; if this persists for several minutes, ask the user to check that machine.":n+"its remote_shell channel has not come up yet. When shell access was only just enabled on that machine, its tunnel does a first-time setup (registering a network node) that can take several minutes; the channel then connects on its own. Be patient: keep retrying with a generous timeout_ms and waits in between for up to ~10 minutes before treating this as stuck \u2014 do not report failure or ask the user to intervene early. If it never comes up, the machine may be running an older CLI without remote_shell support."}function go(e,t,n){return{name:"remote_shell",label:"Remote Shell",description:"Run a command in a persistent interactive shell on a REMOTE MACHINE \u2014 a separate host on the team (typically the user's own machine). Use this (not bash) to run tests, start dev servers, or drive an environment that only exists there. The shell starts in that machine's home directory; when this build's worktree is mirrored onto it via sync, cd into that directory to work on the code. The shell is stateful: cwd, environment variables, and background processes persist across calls \u2014 but only while the connection holds. If it drops, the shell (and anything running in it) dies; a reconnect opens a fresh shell and the next result says so. Send a command with `input`; call again with empty input to read more output from a long-running command; set `interrupt` to send Ctrl-C. When a shell stops responding to input at all \u2014 Ctrl-C does not bring back a usable prompt, or a program left the terminal's line editing wedged \u2014 set `restart` to kill it and start a new one instead of trying more keystrokes. When several machines are available, pass `machine` to pick one. "+(n.current.length?`Available machines: ${n.current.map(o=>o.name).join(", ")}.`:"No machines are currently available \u2014 the team has no machine with shell access enabled on its machine page, which is a machine-side switch, not your grant. The set can change mid-conversation, so calling this tool still reports the current state."),parameters:{type:"object",properties:{machine:{type:"string",description:"Which machine to run on (its name or id). Optional when exactly one is available."},input:{type:"string",description:"Text to type into the shell (a command line, or keystrokes). Omit to just read pending output."},enter:{type:"boolean",description:"Append Enter after input to submit it. Default true; set false to send keystrokes without submitting."},interrupt:{type:"boolean",description:"Send Ctrl-C to interrupt the foreground command before sending input."},restart:{type:"boolean",description:"Kill this shell and open a fresh one before sending input. Everything the old session held (cwd, env vars, background processes) is lost \u2014 use it when the shell is wedged, not to clean up."},timeout_ms:{type:"number",description:"Overall budget for the call \u2014 waiting to (re)connect counts against it too (default 15000, max 120000)."}},required:[],additionalProperties:!1},async execute(o,s,a){let i=s??{};if(!e.shellAvailable())return ve("Reverse shell is unavailable: the tunnel sidecar is not running on this machine.",{closed:!0,truncated:!1});let c=Ni(n.current,i.machine);if("error"in c)return ve(c.error,{closed:!0,truncated:!1});let u=c.machine,l=u.machineId,d=ji(i),p=Date.now()+Ki(i.timeout_ms);i.restart&&await e.restartShell(t,l,5e3);let m=await Bi(e,t,l,u.online,p,a);if(m==="failed"){let v=e.drainShell(t,l),b=ho(u,e.hasEverOpened(t,l));return ve(v.trim()?`${v}
12
+ `;ye(e,u),console.log(`[session] pruned ${(0,$e.basename)(e)}: ${t} -> ${Ln.Buffer.byteLength(u)} bytes`)}catch(t){console.warn(`[session] prune failed for ${(0,$e.basename)(e)}:`,t.message)}}function Ia(e,t,n){let r=Ma(e);if(r.length===0)return;let o=r[0];if(!t){(0,Z.writeFileSync)(e,o+`
13
+ `);return}let s=[o],i=!1;for(let a=1;a<r.length;a++)if(s.push(r[a]),Lo(r[a])?.id===t){i=!0;break}if(!i){console.warn(`[restore] ${n} session leaf ${t} not found \u2014 session pruned or drifted from history, resetting to empty`),(0,Z.writeFileSync)(e,o+`
14
+ `);return}(0,Z.writeFileSync)(e,s.join(`
15
+ `)+`
16
+ `)}async function No(e,t,n,r){await Do(e,t);let o=Nn(e);return o.mode!=="continue"?null:(Ia(o.sessionFilePath,n,r),o.sessionFilePath)}async function Fo(e=7*24*3600*1e3){let t=Ot(),n=Date.now()-e,r=[];for(let[o,s]of Object.entries(t.entries))s.lastUsedAt<n&&(r.push(s.sessionFilePath),delete t.entries[o]);r.length&&(Dt(t),await Promise.all(r.map(o=>(0,Me.rm)(o,{force:!0}).catch(()=>{}))),console.log("[machine] Cleaned up stale local session files"))}var M=require("node:fs"),ae=require("node:path");ve();U();var Ca=7*24*60*60*1e3;function Hn(e,t,n){if((0,M.statSync)(e).isDirectory()){for(let o of(0,M.readdirSync)(e))Hn((0,ae.join)(e,o),t,n);(0,M.chmodSync)(e,t)}else(0,M.chmodSync)(e,n)}async function Oa(e,t){let n=`${t}.tmp.${process.pid}.${Date.now()}`;(0,M.mkdirSync)(n,{recursive:!0});try{await Promise.all(e.files.map(async r=>{if(r.name.includes(".."))throw new Error(`unsafe skill file name ${r.name}`);if(!r.url)throw new Error(`missing url for ${r.name}`);let o=await G(async()=>{let i=await q(r.url,f.r2Download);if(!i.ok)throw Te(i,`for ${r.name}`);return Buffer.from(await i.arrayBuffer())},V,`[step] skill file ${r.name} fetch`),s=(0,ae.join)(n,r.name);(0,M.mkdirSync)((0,ae.dirname)(s),{recursive:!0}),(0,M.writeFileSync)(s,o)})),(0,M.mkdirSync)((0,ae.dirname)(t),{recursive:!0}),(0,M.existsSync)(t)?(0,M.rmSync)(n,{recursive:!0,force:!0}):((0,M.renameSync)(n,t),Hn(t,365,292))}catch(r){throw(0,M.rmSync)(n,{recursive:!0,force:!0}),r}}async function jo(e,t){if(!e?.length)return[];let n=[];for(let r of e){if(!r.files.some(i=>i.name==="SKILL.md"))continue;let o=(0,ae.join)(t,"skills",r.id,String(r.updatedAt)),s=(0,ae.join)(o,"SKILL.md");try{(0,M.existsSync)(s)?(0,M.utimesSync)(o,new Date,new Date):await Oa(r,o),n.push({name:r.name,description:r.description,filePath:s,baseDir:o,sourceInfo:{path:s,source:"desk-skill",scope:"temporary",origin:"top-level",baseDir:o},disableModelInvocation:!1})}catch(i){console.error(`[step] skill ${r.id} materialize failed:`,i instanceof Error?i.message:String(i))}}return n}function Uo(e){let t=(0,ae.join)(e,"skills");if(!(0,M.existsSync)(t))return;let n=Date.now();for(let r of(0,M.readdirSync)(t)){let o=(0,ae.join)(t,r),s;try{s=(0,M.readdirSync)(o)}catch{continue}for(let i of s){let a=(0,ae.join)(o,i);try{n-(0,M.statSync)(a).mtimeMs>Ca&&(Hn(a,493,420),(0,M.rmSync)(a,{recursive:!0,force:!0}))}catch{}}try{(0,M.readdirSync)(o).length===0&&(0,M.rmSync)(o,{recursive:!0,force:!0})}catch{}}}var Ho=!1;function Bo(e){if(!Ho){Ho=!0;try{Uo(e)}catch{}setInterval(()=>{try{Uo(e)}catch{}},6*60*60*1e3).unref()}}ue();function Da(e){let t=new Map(Object.entries(e));return{async read(n){return t.get(n)},async list(){return[...t.entries()].map(([n,r])=>({providerId:n,type:r.type}))},async modify(n,r){let o=await r(t.get(n));return o!==void 0&&t.set(n,o),t.get(n)},async delete(n){t.delete(n)}}}async function jn(e,t){let{agent:n}=t,r=d=>({ok:!1,error:d});if(t.modelConfigError)return r(t.modelConfigError);let o=t.modelConfigs?.find(d=>d.providerId===n.provider);if(!o)return r(`Model ${n.provider}/${n.modelId} is unavailable on this machine: the server sent no provider configuration for this step (server and CLI versions may be out of sync).`);let s=t.modelConfigs??[],i=Da(Object.fromEntries(s.filter(d=>d.credential.type==="oauth").map(d=>[d.providerId,d.credential]))),a=await e.ModelRuntime.create({credentials:i,modelsPath:null,allowModelNetwork:!1});for(let d of s){if(!d.provider)continue;let m=d.credential.type==="api_key"?d.credential.key:"-";a.registerProvider(d.providerId,{name:d.provider.name,baseUrl:d.provider.baseUrl,api:d.provider.api,apiKey:m,authHeader:d.provider.authHeader,headers:d.provider.headers,models:d.provider.models.map(p=>({...Fr(p),compat:d.provider.compat??p.compat}))})}let c=a.getModel(n.provider,n.modelId);if(!c||!a.hasConfiguredAuth(n.provider))return r(`Configured model ${n.provider}/${n.modelId} is unavailable on this machine: this team's provider configuration does not offer it. Manage providers on the website (Resources > Providers).`);let l=o.compactionTrim,u=l?.provider&&l.modelId?a.getModel(l.provider,l.modelId)??void 0:void 0;return l?.modelId&&!u&&console.warn(`[step] compaction model ${l.provider}/${l.modelId} is unavailable on this machine \u2014 summarizing with the step's own model`),{ok:!0,runtime:{modelRuntime:a,model:c,transport:o.transport,compaction:o.compaction,compactionModel:u,compactionTrim:l}}}var Ko=require("@modelcontextprotocol/sdk/client/index.js"),Nt=require("@modelcontextprotocol/sdk/client/stdio.js"),Go=require("@modelcontextprotocol/sdk/client/streamableHttp.js");U();de();var La=64;function Na(e,t){return`mcp__${e}__${t}`.slice(0,La)}async function qo(e,t){if(!e.length)return[];let n=new Map(t.map(o=>[o.id,o.credential]));return(await Promise.all(e.map(o=>Fa(o,n.get(o.id))))).filter(o=>o!==null)}async function Fa(e,t){if(!t)return console.warn(`[mcp] ${e.slug}: no credential resolved at claim \u2014 skipping`),null;let n;try{n=e.transport==="http"?new Go.StreamableHTTPClientTransport(new URL(e.url),{requestInit:{headers:t.type==="http"?t.headers:{}}}):new Nt.StdioClientTransport({command:e.command,args:e.args??[],env:{...(0,Nt.getDefaultEnvironment)(),...t.type==="stdio"?t.env:{}}});let r=new Ko.Client({name:"desk-executor",version:pe()},{capabilities:{}});return await Yo(r.connect(n),f.mcpConnect,`${e.slug} connect`),{ref:e,client:r}}catch(r){return n?.close().catch(()=>{}),console.warn(`[mcp] ${e.slug}: connect failed \u2014 its tools are unavailable this turn: ${O(r)}`),null}}async function zo(e,t){let n=new Set(t),r=await Promise.all(e.map(async s=>{try{let{tools:i}=await Yo(s.client.listTools(),f.mcpConnect,`${s.ref.slug} listTools`);return i.map(a=>Ua(s,a))}catch(i){return console.warn(`[mcp] ${s.ref.slug}: listTools failed \u2014 its tools are unavailable this turn: ${O(i)}`),[]}})),o=[];for(let s of r.flat()){if(n.has(s.name)){console.warn(`[mcp] dropping ${s.name}: name already taken in this session`);continue}n.add(s.name),o.push(s)}return o}function Ua(e,t){let{ref:n,client:r}=e,o=Na(n.slug,t.name);return{name:o,label:`${n.label}: ${t.name}`,description:t.description||`Tool "${t.name}" from the MCP server "${n.label}".`,parameters:t.inputSchema??{type:"object",properties:{}},async execute(s,i,a){try{let c=await r.callTool({name:t.name,arguments:i??{}},void 0,{signal:a,timeout:f.mcpToolCall}),l=(Array.isArray(c.content)?c.content:[]).flatMap(u=>u.type==="text"?[{type:"text",text:String(u.text??"")}]:u.type==="image"?[{type:"image",data:String(u.data??""),mimeType:String(u.mimeType??"image/png")}]:[{type:"text",text:`[${o}: unsupported ${String(u.type)} content omitted]`}]);if(c.isError){let u=l.map(d=>d.type==="text"?d.text:"").join(`
17
+ `).trim();return Wo(`${o} failed: ${u||"the server reported an error without details."}`)}return{content:l.length?l:[{type:"text",text:"(no content)"}],details:{}}}catch(c){if(a?.aborted)throw c;return Wo(`${o} returned no result: the call to the "${n.label}" MCP server failed (${O(c)}). This is a connection problem, not a rejection \u2014 the server may be down or slow.`)}}}}async function Jo(e){await Promise.all(e.map(t=>t.client.close().catch(()=>{})))}function Wo(e){return{content:[{type:"text",text:e}],details:{}}}async function Yo(e,t,n){let r;try{return await Promise.race([e,new Promise((o,s)=>{r=setTimeout(()=>s(new Error(`${n} timed out after ${t}ms`)),t)})])}finally{clearTimeout(r)}}de();var Ha='No remote machine is available for this build. Your remote_shell grant is fine \u2014 the tool would not be in your toolset otherwise \u2014 so do not report this as a missing permission on your side. What is missing is the machine half: the team needs a machine that is online (`desk start`) AND has the "Remote shell" toggle turned on (separate from your grant). The user can flip that toggle on the machine\'s own page in the web app, or just ask the Chief to turn it on for that machine. Tell the user exactly that.',ja="[shell reconnected \u2014 the previous shell session was lost: cwd, env vars and background processes were reset]";function Qo(e,t){let n=`Machine "${e.name}" is listed, but `;return e.online===!1?n+"it is offline (no presence heartbeat \u2014 `desk start` may have stopped, or the machine is asleep/disconnected). Wait a moment and retry; if this persists, ask the user to check that machine.":t?n+"its remote_shell channel dropped and is being redialed (network blip, or the machine's CLI restarted). Wait a moment and retry; if this persists for several minutes, ask the user to check that machine.":n+"its remote_shell channel has not come up yet. When shell access was only just enabled on that machine, its tunnel does a first-time setup (registering a network node) that can take several minutes; the channel then connects on its own. Be patient: keep retrying with a generous timeout_ms and waits in between for up to ~10 minutes before treating this as stuck \u2014 do not report failure or ask the user to intervene early. If it never comes up, the machine may be running an older CLI without remote_shell support."}function Ba(e){let t="This build machine has no tunnel node yet, so no remote machine can reach it: ";return e?t+`its tunnel sidecar keeps failing with "${e}". Retrying will not help \u2014 report this to the user as a problem on the BUILD machine, not on the remote one.`:t+"its tunnel is still joining the network. Wait a moment and retry."}function Zo(e,t,n){return{name:"remote_shell",label:"Remote Shell",description:"Run a command in a persistent interactive shell on a REMOTE MACHINE \u2014 a separate host on the team (typically the user's own machine). Use this (not bash) to run tests, start dev servers, or drive an environment that only exists there. The shell starts in that machine's home directory. Build files are not copied there automatically; use an existing checkout and cd into it before working on the code. The shell is stateful: cwd, environment variables, and background processes persist across calls \u2014 but only while the connection holds. If it drops, the shell (and anything running in it) dies; a reconnect opens a fresh shell and the next result says so. Send a command with `input`; call again with empty input to read more output from a long-running command; set `interrupt` to send Ctrl-C. When a shell stops responding to input at all \u2014 Ctrl-C does not bring back a usable prompt, or a program left the terminal's line editing wedged \u2014 set `restart` to kill it and start a new one instead of trying more keystrokes. When several machines are available, pass `machine` to pick one. "+(n.current.length?`Available machines: ${n.current.map(o=>o.name).join(", ")}.`:"No machines are currently available \u2014 the team has no machine with shell access enabled on its machine page, which is a machine-side switch, not your grant. The set can change mid-conversation, so calling this tool still reports the current state."),parameters:{type:"object",properties:{machine:{type:"string",description:"Which machine to run on (its name or id). Optional when exactly one is available."},input:{type:"string",description:"Text to type into the shell (a command line, or keystrokes). Omit to just read pending output."},enter:{type:"boolean",description:"Append Enter after input to submit it. Default true; set false to send keystrokes without submitting."},interrupt:{type:"boolean",description:"Send Ctrl-C to interrupt the foreground command before sending input."},restart:{type:"boolean",description:"Kill this shell and open a fresh one before sending input. Everything the old session held (cwd, env vars, background processes) is lost \u2014 use it when the shell is wedged, not to clean up."},timeout_ms:{type:"number",description:"Overall budget for the call \u2014 waiting to (re)connect counts against it too (default 15000, max 120000)."}},required:[],additionalProperties:!1},async execute(o,s,i){let a=s??{};if(!e.shellAvailable())return Ae("Reverse shell is unavailable: the tunnel sidecar is not running on this machine.",{closed:!0,truncated:!1});let c=Wa(n.current,a.machine);if("error"in c)return Ae(c.error,{closed:!0,truncated:!1});let l=c.machine,u=l.machineId;if(!e.current())return Ae(Ba(e.lastError()),{closed:!0,truncated:!1});let d=Ka(a),m=Date.now()+za(a.timeout_ms);a.restart&&await e.restartShell(t,u,5e3);let p=await Ga(e,t,u,l.online,m,i);if(p==="failed"){let x=e.drainShell(t,u),A=Qo(l,e.hasEverOpened(t,u));return Ae(x.trim()?`${x}
14
18
  [shell disconnected]
15
- ${b}`:b,{closed:!0,truncated:!1})}if(m==="opened"&&d!==""&&await po(e,t,l,{quietMs:300,capMs:Math.min(2500,Math.max(p-Date.now(),0)),signal:a}),a?.aborted)return fo(e,t,u,!1);if(d!==""&&!e.shellSendInput(t,l,d))return ve("Reverse shell is unavailable: failed to write to the sidecar.",{closed:!0,truncated:!1});let h=await po(e,t,l,{quietMs:800,capMs:Math.max(p-Date.now(),1e3),armed:!0,signal:a});return fo(e,t,u,h)}}}function Ni(e,t){if(e.length===0)return{error:Ui};if(t){let n=t.trim().toLowerCase(),r=e.find(o=>o.machineId.toLowerCase()===n||o.name.toLowerCase()===n);return r?{machine:r}:{error:`Unknown machine "${t}". Available: ${e.map(o=>o.name).join(", ")}.`}}return e.length===1?{machine:e[0]}:{error:`Several machines are available \u2014 pass "machine" to pick one: ${e.map(n=>n.name).join(", ")}.`}}function ji(e){let t=e.interrupt?"":"";if(typeof e.input!="string"||e.input==="")return t;let n=e.input.replace(/\r?\n/g,"\r");return t+(e.enter===!1?n:n.replace(/\r$/,"")+"\r")}async function Bi(e,t,n,r,o,s,a=2e3){let i=()=>e.ensureShell(t,n,Math.max(1e3,Math.min(5e3,o-Date.now()))),c=await i();for(;c==="failed"&&r!==!1&&!s?.aborted&&Date.now()+a<o;)await Wi(a,s),c=await i();return c}function po(e,t,n,r){let{quietMs:o,capMs:s,armed:a,signal:i}=r;return new Promise(c=>{let u,l=()=>{clearTimeout(u),u=setTimeout(()=>h(!1),o)},d=setTimeout(()=>h(!1),s),p=e.subscribeShell(t,n,{onActivity:l,onClosed:()=>h(!0)}),m=()=>h(!1);i?.addEventListener("abort",m,{once:!0}),a&&l(),i?.aborted&&h(!1);function h(v){clearTimeout(d),clearTimeout(u),p(),i?.removeEventListener("abort",m),c(v)}})}function Wi(e,t){return new Promise(n=>{let r=setTimeout(o,e);t?.addEventListener("abort",o,{once:!0});function o(){clearTimeout(r),t?.removeEventListener("abort",o),n()}})}function Ki(e){return Math.min(Math.max(Number(e)||15e3,1e3),12e4)}function fo(e,t,n,r){let o=e.consumeShellReconnect(t,n.machineId),s=e.drainShell(t,n.machineId),a=s.length>6e4;if(a&&(s=s.slice(-6e4)),r&&s.trim()===""&&!o)return ve(ho(n,e.hasEverOpened(t,n.machineId)),{closed:!0,truncated:!1});let i=[];return o&&i.push(Hi),a&&i.push("[output truncated to the last 60000 characters]"),i.push(s||"(no output)"),r&&i.push("[shell session closed]"),ve(i.join(`
16
- `),{closed:r,truncated:a})}function ve(e,t){return{content:[{type:"text",text:e}],details:t}}var Gi=[500,2e3];function Le(e){let t=e?.name;return t==="TimeoutError"||t==="AbortError"}async function Fe(e,t,n,r,o={}){let s=o.timeoutMs??f.remoteTool,a=async()=>{let i=await I(e,t,{token:n,body:r,timeoutMs:s,signal:o.signal}),c=await i.json().catch(()=>null),u={ok:i.ok,status:i.status,body:c},l=c?.transient,d=l===!0||l===void 0&&i.status>=500;if(o.replaySafe&&!i.ok&&d)throw Object.assign(be(i,typeof c?.error=="string"?c.error:void 0),{reply:u});return u};if(!o.replaySafe)return a();try{return await F(a,i=>!!i?.reply||B(i),`[tool] ${o.label??t}`,Gi,o.signal)}catch(i){let c=i?.reply;if(c)return c;throw i}}function kt(e,t){if(!e.ok)throw new Error(typeof e.body?.error=="string"?e.body.error:`${t} failed (HTTP ${e.status})`);if(typeof e.body?.text!="string")throw new Error(`${t} returned no JSON body`);return JSON.parse(e.body.text)}function A(e){return{content:[{type:"text",text:e}],details:{}}}function yo(e,t,n){return(n.remoteTools??[]).map(r=>({name:r.name,label:r.label,description:r.description,parameters:r.parameters,async execute(o,s,a){let i=Date.now();try{let c=await Fe(e,`/api/machine/tool/${n.stepId}`,t,{name:r.name,params:s},{replaySafe:r.replaySafe,label:r.name,signal:a});if(!c.ok){console.warn(`[tool] ${r.name} rejected: HTTP ${c.status} in ${Date.now()-i}ms`);let u=c.body?.error;return A(typeof u=="string"?u:`${r.name} failed (HTTP ${c.status}).`)}return A(typeof c.body?.text=="string"?c.body.text:"")}catch(c){if(a?.aborted)throw c;let u=Date.now()-i,l=Le(c)?`timed out after ${u}ms`:`failed after ${u}ms: ${T(c)}`;return console.warn(`[tool] ${r.name} transport failure: ${l}`),A(`${r.name} returned no result: the call to the Desk server ${l}. This is a connection problem, not a rejection \u2014 this machine's own network or proxy is as likely at fault as the server. `+(r.replaySafe?"This is a read, so calling it again is safe.":"It may or may not have taken effect server-side \u2014 check the current state before calling it again."))}}}))}function wo(e,t,n){return{name:"push_branch",label:"Push Branch",description:"Commit all work in the worktree and push this conversation's own working branch (desk/conv-*) to the remote repo. The branch is normally pushed only when a turn ends, so the remote does not have changes from the current turn until you call this. Call it before any tool that reads the branch from the remote \u2014 e.g. merge_branch on your own branch, or a CI run you want to pick the work up. `message` becomes the commit message for the staged work; when nothing changed since the last commit it just pushes.",parameters:{type:"object",properties:{message:{type:"string",description:'Commit message for the work being committed, e.g. "Release cli v0.2.0".'}},required:["message"],additionalProperties:!1},async execute(r,o){let s=o?.message,a=typeof s=="string"&&s.trim()?s.trim():null;if(!a)return A("A commit message is required.");if(!t.workspace||!n)return A("This turn has no repository workspace \u2014 push_branch is unavailable.");let i=ne(t.conversationId);try{let{sha:c}=await $r(e,t.workspace.defaultBranch,n,i,a,t.workspace.gitHost);return A(c?`Committed ${c.slice(0,12)} and pushed "${i}" \u2014 the remote now has all work up to this point.`:`Nothing new to commit \u2014 pushed "${i}" so the remote is current with the last commit.`)}catch(c){return A(`push_branch failed: ${c.message}`)}}}}var ko=8e3,hn=["log","show","diff","grep","ls-files","ls-tree","cat-file","rev-parse","describe","shortlog","blame","tag","branch","ls-remote","fetch"],qi=/^(-o$|--output|--ext-diff$|--textconv$|-O$|--open-files-in-pager|--no-index$|--upload-pack)/;function So(e){return e.length>ko?`${e.slice(0,ko)}
17
- \u2026(truncated)`:e}async function zi(e,t,n,r,o){let s=await Fe(e,`/api/machine/tool/${n}`,t,{name:"open_repo",params:{projectId:r}},{timeoutMs:f.openRepo,replaySafe:!0,label:"open_repo",signal:o}).catch(a=>{if(o?.aborted)throw a;let i=Le(a)?"timed out":`failed (${T(a)})`;throw new Error(`Could not reach the Desk server to open this project's repository: the credential lookup ${i}. No git command ran and the repository is fine. Try again.`)});if(!s.ok)throw new Error(typeof s.body?.error=="string"?s.body.error:`open_repo failed (HTTP ${s.status})`);return kt(s,"open_repo")}function bo(e,t,n){let r=new Map;function o(s,a){let i=r.get(s);return i||(i=(async()=>{let c=await zi(e,t,n.stepId,s,a),u=en(s);return await rt(s,()=>rn(u,c.repoFullName,c.defaultBranch,c.installationToken,{readCheckout:!0,gitHost:c.gitHost})),{repo:c,baseDir:u}})(),i.catch(()=>r.delete(s)),r.set(s,i)),i}return{name:"git",label:"Git",description:`Read-only git against a project's repository, on a local clone kept fresh on this machine (the very first use of a project clones it \u2014 that call can take a while). The default branch is checked out and tags are fetched; other branches and PR heads are not local: list remote refs with ["ls-remote", "origin"], or ["fetch", "origin", "<ref>"] (e.g. a branch name or pull/<n>/head) and then reference FETCH_HEAD. Allowed subcommands: ${hn.join(", ")}; anything that writes is rejected. Examples: ["grep", "-n", "handleLogin"], ["log", "--oneline", "-20"], ["show", "HEAD:package.json"], ["tag", "--list"], ["show", "FETCH_HEAD:src/app.ts"].`,parameters:{type:"object",properties:{projectId:{type:"string",description:"Which project's repo to run against (ids are in the project listing)."},args:{type:"array",items:{type:"string"},description:'git arguments as an array, starting with the subcommand, e.g. ["log", "--oneline", "-20"].'}},required:["projectId","args"],additionalProperties:!1},async execute(s,a,i){let c=a??{},u=typeof c.projectId=="string"?c.projectId.trim():"",l=Array.isArray(c.args)?c.args.map(String):[];if(!u||!l.length)return A('git needs { projectId, args } \u2014 e.g. args: ["log", "--oneline", "-20"].');let d=l[0];if(!hn.includes(d))return A(`git ${d} is not available \u2014 this tool is read-only. Allowed subcommands: ${hn.join(", ")}.`);let p=l.find(m=>qi.test(m));if(p)return A(`The ${p} flag is not allowed here.`);try{let{repo:m,baseDir:h}=await o(u,i);if(i?.throwIfAborted(),d==="fetch"){let x=l.length===3&&l[1]==="origin"&&!l[2].startsWith("-")?l[2]:null;return x?(await rt(u,()=>g(["fetch","origin",x],h,we(m.installationToken,m.gitHost),{timeoutMs:f.gitNetworkInteractive})),A(`Fetched ${x} \u2014 reference it as FETCH_HEAD, e.g. ["log", "--oneline", "-10", "FETCH_HEAD"].`)):A('fetch is limited to exactly: ["fetch", "origin", "<ref>"] \u2014 e.g. a branch name or pull/<n>/head.')}if(d==="ls-remote"){let x=await g(l,h,we(m.installationToken,m.gitHost),{timeoutMs:f.gitNetworkInteractive});return A(So(x)||"(no output)")}let v=(d==="tag"||d==="branch")&&!l.some(x=>x==="--list"||x==="-l")?[d,"--list",...l.slice(1)]:l,b=await g(v,h,{},{timeoutMs:f.gitLocalInteractive});return A(So(b)||"(no output)")}catch(m){if(i?.aborted)throw m;return A(m.message)}}}}var St=require("node:fs"),vo=require("node:child_process"),Ue=require("node:path"),Ji=/^[a-z]:\\windows\\(?:system32|sysnative|syswow64)\\bash\.exe$/;function Xi(e){return Ji.test(e.replace(/\//g,"\\").toLowerCase())}function Yi(e){let t=e.lookPath("git");if(t){let r=Ue.win32.join(Ue.win32.dirname(Ue.win32.dirname(t)),"bin","bash.exe");if(e.isFile(r))return r}for(let r of[e.getenv("ProgramFiles"),e.getenv("ProgramFiles(x86)")]){if(!r)continue;let o=Ue.win32.join(r,"Git","bin","bash.exe");if(e.isFile(o))return o}let n=e.lookPath("bash.exe");return n&&!Xi(n)?n:null}function Vi(e){let t=(0,vo.spawnSync)("where",[e],{encoding:"utf-8",timeout:5e3,windowsHide:!0});if(t.status!==0||!t.stdout)return null;let n=t.stdout.trim().split(/\r?\n/)[0];return n&&(0,St.existsSync)(n)?n:null}var Te;function gn(){if(process.platform==="win32")return Te!=null&&!(0,St.existsSync)(Te)&&(Te=void 0),Te===void 0&&(Te=Yi({lookPath:Vi,isFile:St.existsSync,getenv:e=>process.env[e]})),Te??void 0}function To(){if(process.platform!=="win32")return;let e=gn();if(e){console.log(`[machine] Agent shell: ${e}`);return}console.warn("[machine] No Git Bash found \u2014 the agent's shell will fall back to whatever bash.exe is on PATH. If that is C:\\Windows\\System32\\bash.exe (Windows' WSL launcher), every shell command in a build will fail. Install Git for Windows, or put a real bash ahead of System32 on PATH.")}var xo=require("node:child_process");function Qi(e){let t={},n=/HTTPEnable\s*:\s*1/.test(e),r=/HTTPSEnable\s*:\s*1/.test(e),o=e.match(/HTTPProxy\s*:\s*(\S+)/)?.[1],s=e.match(/HTTPPort\s*:\s*(\d+)/)?.[1],a=e.match(/HTTPSProxy\s*:\s*(\S+)/)?.[1],i=e.match(/HTTPSPort\s*:\s*(\d+)/)?.[1];if(n&&o&&s){let d=`http://${o}:${s}`;t.HTTP_PROXY=d,t.http_proxy=d}if(r&&a&&i){let d=`http://${a}:${i}`;t.HTTPS_PROXY=d,t.https_proxy=d}if(Object.keys(t).length===0)return t;let u=[...(e.match(/ExceptionsList\s*:\s*<array>\s*\{([^}]*)\}/)?.[1]??"").matchAll(/\d+\s*:\s*(\S+)/g)].map(d=>d[1]),l=[...new Set([...u,"localhost","127.0.0.1","::1"])].join(",");return t.NO_PROXY=l,t.no_proxy=l,t}function kn(){return process.env.HTTPS_PROXY||process.env.https_proxy||process.env.HTTP_PROXY||process.env.http_proxy||void 0}function Eo(){return new Promise(e=>{(0,xo.execFile)("scutil",["--proxy"],{encoding:"utf8"},(t,n)=>e(t||!n?null:Qi(n)))})}var bt=null;async function Zi(){if(kn())return;let e=await Eo();e!==null&&(bt=e,Object.keys(e).length!==0&&(Object.assign(process.env,e),console.log(`[machine] System proxy: ${e.HTTPS_PROXY??e.HTTP_PROXY}`)))}var wn=!1,vt;async function Ro(e){if(wn)return!0;let t=kn();if(!t)return!1;let n=await import("undici");vt=new n.EnvHttpProxyAgent;let r=async(o,s)=>n.fetch(o,{...s,dispatcher:vt});return globalThis.fetch=r,wn=!0,e&&console.log(`${e} Proxy: ${t}`),!0}async function ea(){let e=await import("undici"),t=vt;vt=new e.EnvHttpProxyAgent,t?.close().catch(()=>{})}function ta(e,t,n){let r=Object.keys(e);if(r.length===Object.keys(t).length&&r.every(o=>e[o]===t[o]))return!1;for(let o of r)delete n[o];return Object.assign(n,t),!0}var yn=null;function Tt(){return yn??=na().catch(e=>(console.warn(`[machine] system proxy refresh failed: ${e instanceof Error?e.message:String(e)}`),!1)).finally(()=>{yn=null}),yn}async function na(){if(bt===null)return!1;let e=await Eo();return e===null||!ta(bt,e,process.env)?!1:(bt=e,wn?await ea():await Ro(),console.log(`[machine] System proxy moved: ${kn()??"none"}`),!0)}async function $o(e="[desk]"){await Zi(),await Ro(e)}var xt=new Map;function Mo(e){let t=e&&xt.get(e);if(t)return t();for(let n of xt.values())n()}function Sn(e,t){let{input:n,output:r,cacheRead:o,cacheWrite:s,cost:a}=e.usage;return{provider:e.provider,modelId:e.responseModel??e.model,thinkingLevel:t,at:e.timestamp,usage:{inputTokens:n,outputTokens:r,cacheReadTokens:o,cacheWriteTokens:s,costUsd:a.total}}}function ra(e,t){if(!t)return"";switch(e){case"read":case"write":case"edit":case"ls":return String(t.path??"");case"bash":return String(t.command??"").slice(0,100);case"grep":return`"${t.pattern??""}"${t.path?` in ${t.path}`:""}`;case"find":return String(t.path??t.pattern??"");case"web_fetch":return String(t.url??"");case"web_search":return String(t.query??t.input??"");default:{let n=Object.values(t)[0];return n?String(n).slice(0,100):""}}}async function _o(e,t,n,r){let o=await I(e,t,{token:r,body:n,timeoutMs:f.stepPost});if(!o.ok)throw be(o);return await o.json()}async function bn(e,t,n,r){try{return await _o(e,t,n,r)}catch(o){return console.error(`[machine] POST ${t} failed:`,o.message),{}}}async function xe(e,t,n,r){return F(()=>_o(e,t,n,r),B,`[machine] POST ${t}`)}function vn(e,t,n,r,o,s=60*1e3,a){let i=!0,c=!1,u=async()=>{if(!(!i||c)){c=!0;try{let d=await bn(e,`/api/machine/heartbeat/${t}`,{},r);i&&d.stop&&n(),i&&Array.isArray(d.steer)&&a?.(d.steer),i&&Array.isArray(d.remoteMachines)&&o?.(d.remoteMachines)}finally{c=!1}}};u();let l=setInterval(u,s);return xt.set(t,()=>void u()),()=>{i=!1,clearInterval(l),xt.delete(t)}}var oa=50;function Po(e){return typeof e.text!="string"?null:e.type===void 0?"text":e.type==="thinking"?"thinking":null}function Co(e,t,n,r,o,s){let a=new AbortController;a.signal.addEventListener("abort",()=>{try{e.dispose()}catch{}});let i="",c="",u,l,d=[],p=[],m,h=[],v=Promise.resolve(),b=!1,x=async()=>{try{for(;h.length;){let y=await n(h.shift());y.stop&&r(),Array.isArray(y.steer)&&o?.(y.steer),h.length&&await new Promise(R=>setTimeout(R,oa))}}finally{b=!1}},P=s,E=y=>{P&&(h.push(P),P=void 0);let R=Po(y),k=h[h.length-1];if(R&&k&&Po(k)===R){k.text=k.text+y.text;return}h.push(y),b||(b=!0,v=x())},M=e.subscribe(y=>{if(y.type==="message_end"){if(y.message.role==="assistant"){d.push(Sn(y.message,e.thinkingLevel));let R=y.message.content.map(pe=>pe.type==="text"?pe.text:"").join("");R!==c&&(console.warn(`[${t}] message_end text reconcile: deltas=${c.length} content=${R.length} chars`),R.startsWith(c)&&E({text:R.slice(c.length)})),i+=R||c,c="";let{stopReason:k,errorMessage:C}=y.message;l=k,k!=="stop"&&k!=="toolUse"&&(console.warn(`[${t}] message_end stopReason=${k}${C?` error=${C}`:""}`),C&&(u=C))}return}if(y.type==="auto_retry_start"){console.warn(`[${t}] auto_retry attempt=${y.attempt}/${y.maxAttempts} error=${y.errorMessage}`),Tt(),E({type:"retry",attempt:y.attempt,maxAttempts:y.maxAttempts});return}if(y.type==="auto_retry_end"){y.success||console.error(`[${t}] auto_retry_end failed finalError=${y.finalError}`),E({type:"retry",attempt:0,maxAttempts:0});return}if(y.type==="compaction_start"){m=Date.now(),E({type:"compact",active:!0});return}if(y.type==="compaction_end"){E({type:"compact",active:!1});let R=m===void 0?void 0:Date.now()-m;if(m=void 0,y.errorMessage)console.warn(`[${t}] auto-compaction failed: ${y.errorMessage}`);else if(!y.aborted&&y.result){let k=y.result.usage;p.push({tokensBefore:y.result.tokensBefore,usage:k&&{inputTokens:k.input,outputTokens:k.output,cacheReadTokens:k.cacheRead,cacheWriteTokens:k.cacheWrite,costUsd:k.cost.total},durationMs:R})}return}if(y.type==="message_update"){let R=y.assistantMessageEvent;if(R.type==="text_delta"){let k=R.delta;k&&(c+=k,E({text:k}))}else if(R.type==="thinking_delta"){let k=R.delta;k&&E({type:"thinking",text:k})}else if(R.type==="toolcall_end"){let{name:k,arguments:C}=R.toolCall;k&&E({type:"tool_start",toolName:k,detail:ra(k,C)})}}}),L=!1;return{abort:a,getFullText:()=>i+c,getLastModelError:()=>u,getLastStopReason:()=>l,getModelCalls:()=>d.length?d:void 0,getCompactions:()=>p.length?p:void 0,idle:()=>v,dispose:()=>{if(!L){L=!0,M();try{e.dispose()}catch{}}}}}function Io(e){return e.stopReason!=="stop"&&e.stopReason!=="toolUse"?!1:!e.content.some(t=>t.type==="text"&&t.text.trim()!==""||t.type==="toolCall")}var sa="empty response: provider stream ended without content (no text, no tool call)";function Ao(e,t){let n,r=s=>(n||(console.warn(`[${t}] empty assistant frame \u2014 rewriting as retryable provider error`),n={...s,stopReason:"error",errorMessage:sa}),n);return{async*[Symbol.asyncIterator](){for await(let s of e)yield s.type==="done"&&Io(s.message)?{type:"error",reason:"error",error:r(s.message)}:s},result:async()=>{let s=await e.result();return Io(s)?r(s):s}}}var ia=(e,t)=>`stream idle timeout: no provider events for ${Math.round(e/1e3)}s${t?" waiting for first event":""}`;function Do(e,t,n,r={firstEventMs:f.streamFirstEvent,idleMs:f.streamIdle}){let o,s,a,i=new Promise(l=>{a=l}),c=(l,d)=>{let p=ia(l,d);return console.warn(`[${t}] stream idle watchdog fired: ${p} \u2014 rewriting as retryable provider error`),o=s?{...s,stopReason:"error",errorMessage:p}:{role:"assistant",content:[],api:n.api,provider:n.provider,model:n.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"error",errorMessage:p,timestamp:Date.now()},a(o),o};return{async*[Symbol.asyncIterator](){let l=e[Symbol.asyncIterator](),d=!0;for(;;){let p=d?r.firstEventMs:r.idleMs,m,h=await new Promise(b=>{m=setTimeout(()=>b({kind:"timeout"}),p),l.next().then(x=>b({kind:"next",r:x}),x=>b({kind:"threw",err:x}))}).finally(()=>clearTimeout(m));if(h.kind==="timeout"){let b=c(p,d);Promise.resolve(l.return?.()).catch(()=>{}),yield{type:"error",reason:"error",error:b};return}if(h.kind==="threw")throw h.err;if(h.r.done)return;let v=h.r.value;d=!1,"partial"in v&&(s=v.partial),yield v}},result:async()=>{let l=await Promise.race([e.result(),i]);return o??l}}}var H=require("node:fs"),Oo=require("node:path");var aa=48*60*60*1e3;function Lo(){let e=process.env.DESK_OUTBOX_DIR??V("outbox");return(0,H.mkdirSync)(e,{recursive:!0}),e}var Et=e=>(0,Oo.join)(Lo(),`${e}.json`);function xn(e){(0,H.rmSync)(Et(e),{force:!0})}function Fo(e){let t=Et(e);try{return JSON.parse((0,H.readFileSync)(t,"utf8"))}catch(n){if(n.code==="ENOENT")return null;console.error(`[outbox] moving corrupt entry aside: ${t}:`,n.message);try{(0,H.renameSync)(t,`${t}.corrupt`)}catch{(0,H.rmSync)(t,{force:!0})}return null}}var Tn=new Set;async function En(e,t,n,r,o){if(!Tn.has(n)){Tn.add(n);try{await o(e,`/api/machine/done/${n}`,r,t),xn(n)}catch(s){if(!B(s)){console.error(`[outbox] server refused done for step ${n} (${s.message}) \u2014 dropping entry`),xn(n);return}console.warn(`[outbox] done for step ${n} not delivered (${s.message}) \u2014 kept for retry`)}finally{Tn.delete(n)}}}async function Uo(e,t,n,r,o=xe){try{De(Et(n),JSON.stringify(r))}catch(s){console.error(`[outbox] spool failed for step ${n}:`,s.message)}await En(e,t,n,r,o)}async function Ho(e,t,n,r=xe){let o=Fo(n);return o?(await En(e,t,n,o,r),!0):!1}async function Rn(e,t,n=xe){let r;try{r=(0,H.readdirSync)(Lo()).filter(o=>o.endsWith(".json"))}catch{return}await Promise.all(r.map(async o=>{let s=o.slice(0,-5),a=(0,H.statSync)(Et(s),{throwIfNoEntry:!1})?.mtimeMs;if(a===void 0)return;if(Date.now()-a>aa){console.warn(`[outbox] dropping expired entry for step ${s} (${Math.round((Date.now()-a)/36e5)}h old)`),xn(s);return}let i=Fo(s);i&&await En(e,t,s,i,n)}))}function ca(){let e=async(...r)=>{let s=r[0].payload;if(!(!s||!Array.isArray(s.input)))return{...s,tools:[{type:"web_search"},...s.tools??[]]}},t=new Map;t.set("before_provider_request",[e]);let n={path:__filename,source:"local",scope:"temporary",origin:"top-level"};return{path:__filename,resolvedPath:__filename,sourceInfo:n,handlers:t,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}function No(e){return{...e,extensionsOverride:t=>({...t,extensions:[...t.extensions,ca()]})}}var la=8e3;function ua(e){return`"${e}" is not a valid URL \u2014 include the scheme, e.g. "https://example.com/page".`}function da(e,t,n){let r=Le(t)?`timed out after ${Math.round(n/1e3)}s`:T(t);return`Could not fetch ${e} \u2014 ${r}. Check the URL is reachable, or retry if this may be transient.`}function ma(e,t,n=la){return{text:`${e.ok?"":`[HTTP ${e.status} ${e.statusText}] `}${t.slice(0,n)}`,truncated:t.length>n}}var jo={name:"web_fetch",label:"Web Fetch",description:"Fetch the text content of a URL. Returns up to 8000 characters of the response body.",parameters:{type:"object",properties:{url:{type:"string",description:"The URL to fetch"}},required:["url"],additionalProperties:!1},async execute(e,t,n,r,o){let{url:s}=t;try{new URL(s)}catch{return{content:[{type:"text",text:ua(s)}],details:{truncated:!1}}}let a,i;try{a=await U(s,f.webFetch,{headers:{"User-Agent":"Mozilla/5.0"}}),i=await a.text()}catch(l){return{content:[{type:"text",text:da(s,l,f.webFetch)}],details:{truncated:!1}}}let{text:c,truncated:u}=ma(a,i);return{content:[{type:"text",text:c}],details:{truncated:u}}}};function Bo(e,t){let n=null;return{exec:async(r,o,s)=>{let a=new AbortController;n={ctl:a,onData:s.onData};let i=s.signal?AbortSignal.any([s.signal,a.signal]):a.signal;Ae(i);try{return await e.exec(r,o,{...s,signal:i,timeout:s.timeout??t})}finally{n?.ctl===a&&(n=null),a.abort()}},interrupt:r=>{if(!n)return!1;try{n.onData(Buffer.from(r))}catch{}return n.ctl.abort(),!0}}}function Wo(e,t,n,r){let o=r;return{current:()=>o,async refresh(){let s=await Fe(e,`/api/machine/tool/${n}`,t,{name:"push_credential",params:{}},{replaySafe:!0,label:"push credential"}),{installationToken:a}=kt(s,"push_credential");if(typeof a!="string"||!a)throw new Error("push credential refresh returned an invalid token");o=a}}}var pa=`
18
- [truncated for compaction]`,$n=(e,t)=>e.length<=t?e:e.slice(0,t)+pa;function Ko(e,t){let{toolResultKeepChars:n,textKeepChars:r}=t;return e.map(o=>{if(o.role==="toolResult"&&Array.isArray(o.content)){if(!n)return o;let s=o.content;if(s.every(i=>i.type==="text")&&s.reduce((i,c)=>i+(c.text?.length??0),0)<=n)return o;let a=s.filter(i=>i.type==="text").map(i=>i.text??"").join(`
19
- `);return{...o,content:[{type:"text",text:$n(a,n)}]}}if(!r)return o;if(o.role==="user"&&typeof o.content=="string")return o.content.length<=r?o:{...o,content:$n(o.content,r)};if((o.role==="user"||o.role==="assistant")&&Array.isArray(o.content)){let s=o.content;if(!s.some(i=>i.type==="thinking"||i.type==="text"&&(i.text?.length??0)>r))return o;let a=s.filter(i=>i.type!=="thinking").map(i=>i.type==="text"&&(i.text?.length??0)>r?{...i,text:$n(i.text,r)}:i);return{...o,content:a}}return o})}function Go(e,t,n={}){return{name:"compaction-trim",factory:r=>{r.on("session_before_compact",async(o,s)=>{if(!(!n.trim&&!n.compactionModel)&&s.model)try{let a=n.compactionModel??s.model,i=await s.modelRegistry.getApiKeyAndHeaders(a);if(!i.ok&&a!==s.model&&(a=s.model,i=await s.modelRegistry.getApiKeyAndHeaders(a)),!i.ok)return;let c=n.trim??{},u={...o.preparation,messagesToSummarize:Ko(o.preparation.messagesToSummarize,c),turnPrefixMessages:Ko(o.preparation.turnPrefixMessages,c)},l={...a,...c.summaryMaxTokens?{maxTokens:c.summaryMaxTokens}:{},...i.baseUrl?{baseUrl:i.baseUrl}:{}},d=i.headers?Object.fromEntries(Object.entries(i.headers).filter(m=>m[1]!=null)):void 0;return{compaction:await e.compact(u,l,i.apiKey,d,void 0,o.signal,void 0,void 0,i.env,t.getRetrySettings())}}catch(a){if(o.signal.aborted)throw a;console.warn("[compaction-trim] falling back to pi default:",a.message)}})}}}var zo=e=>({pushed:e?.ok?!0:void 0,pushError:(e&&!e.ok?e:void 0)?.error});function Mn(e,t,n){let{stepId:r,conversationId:o,mode:s}=e;return a=>{let i={conversationId:o,mode:s,...a};return s==="restore"||s==="compact"?xe(t,`/api/machine/done/${r}`,i,n).catch(c=>console.error(`[step] ${r} done report failed:`,c.message)):Uo(t,n,r,i)}}function Jo(e,t,n){return async()=>{try{let r=await I(e,`/api/machine/upload-urls/${n}`,{token:t,timeoutMs:f.recover});return r.ok?await r.json():void 0}catch{return}}}var ie=new Map;function qo(e,t){let n=(ie.get(e)??Promise.resolve()).then(t).catch(r=>console.error(`[step] deferred turn work failed (conv ${e}):`,r.message));return ie.set(e,n),n.finally(()=>{ie.get(e)===n&&ie.delete(e)}),n}async function fa(e,t,n,r=f.deferredTurnWork){let o=new AbortController,s=await Promise.race([t.then(()=>!0,()=>!0),new Promise(a=>{let i=setTimeout(()=>a(!1),r);o.signal.addEventListener("abort",()=>clearTimeout(i),{once:!0})})]);o.abort(),!s&&(console.error(`[step] ${n} deferred turn work still pending after ${r}ms \u2014 abandoning it (conv ${e})`),ie.get(e)===t&&ie.delete(e))}async function Xo(e,t){let n=e.workspace;return n?Mr(e.conversationId,n,e.mode==="restore"&&e.restore?{restoreTo:e.restore.commitSha??`origin/${n.defaultBranch}`,onRetry:t}:{onRetry:t}):null}async function ha(e){return e.restore?Zr(e.conversationId,e.sessionRestoreUrl,e.restore.sessionLeafEntryId,e.stepId):null}var ga=7;function ya(e){(e.getProjectSettings().retry?.maxRetries??e.getGlobalSettings().retry?.maxRetries)===void 0&&e.applyOverrides({retry:{maxRetries:ga}})}function wa(e,t){if(t===void 0)return;(e.getProjectSettings().transport??e.getGlobalSettings().transport)===void 0&&e.applyOverrides({transport:t})}function ka(e,t){if(t===void 0)return;(e.getProjectSettings().compaction??e.getGlobalSettings().compaction)===void 0&&e.applyOverrides({compaction:t})}async function Yo({sdk:e,agentDir:t},n){let r=n.skills?.length?{noSkills:!0,skillsOverride:()=>({skills:n.skills,diagnostics:[]})}:{},o=n.appendSystemPrompt,s=o?{appendSystemPromptOverride:l=>[...l,o]}:{},a=e.SettingsManager.create(n.cwd,t);ya(a),wa(a,n.modelRuntime.transport),ka(a,n.modelRuntime.compaction);let i={cwd:n.cwd,agentDir:t,noExtensions:!0,noPromptTemplates:!0,noThemes:!0,noContextFiles:!0,extensionFactories:[Go(e,a,{compactionModel:n.modelRuntime.compactionModel,trim:n.modelRuntime.compactionTrim})],...r,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},...s},c=new e.DefaultResourceLoader(n.webSearch!==!1?No(i):i);await c.reload();let{session:u}=await e.createAgentSession({cwd:n.cwd,agentDir:t,model:n.modelRuntime.model,modelRuntime:n.modelRuntime.modelRuntime,resourceLoader:c,tools:n.tools,customTools:[jo,...n.extraCustomTools??[]],sessionManager:n.sessionManager,settingsManager:a,thinkingLevel:n.thinkingLevel||void 0});return u}async function Pn(e,t){return e?.length?(await Promise.all(e.map(async r=>{if(!r.url)return null;try{let o=await U(r.url,f.r2Download);if(!o.ok)throw new Error(`HTTP ${o.status}`);return{type:"image",data:Buffer.from(await o.arrayBuffer()).toString("base64"),mimeType:r.mimeType}}catch(o){return console.error(`[step] ${t} image download failed for ${r.key}:`,o instanceof Error?o.message:String(o)),null}}))).filter(r=>r!==null):[]}async function Vo(e,t,n,r){let{stepId:o,conversationId:s}=e,a=Promise.resolve(),i=M=>{let L=a.then(()=>bn(t,`/api/machine/token/${o}`,M,n));return a=L.catch(()=>({})),L},c=ie.get(s);if(c&&(i({type:"stage",stage:"wrapup",state:"start"}),await fa(s,c,o),i({type:"stage",stage:"wrapup",state:"done"})),e.mode==="restore")return Sa(e,t,n);if(e.mode==="compact")return ba(e,t,n);if(await Ho(t,n,o)){console.log(`[step] ${o} outcome already spooled \u2014 resent recorded /done, skipping re-run`);return}console.log(`[step] ${o} start (conv ${s})`),i({type:"stage",stage:"prepare",state:"start"});let u=Jo(t,n,o),l=!1,d=null,p=()=>{l=!0,d?.abort()},m=[],h=M=>{m.push(...M)},v=M=>h(M),b={current:e.remoteMachines??[]},x=vn(t,o,p,n,M=>{b.current=M},void 0,v),P=[],E=Mn(e,t,n);try{let M=await Ie(),{sdk:L,agentDir:ce}=M;oo(ce);let y=await fn(L,e);if(!y.ok){await E({error:y.error});return}let R=y.runtime;console.log(`[step] ${o} using model ${R.model.provider}/${R.model.id}`);let k=(S,_)=>void i({type:"retry",attempt:S,maxAttempts:_}),C;try{C=await Xo(e,k)??ce}catch(S){await E({error:`Workspace preparation failed: ${S.message}`});return}let pe=e.mode==="ephemeral_turn",Pe=pe?{sessionManager:L.SessionManager.inMemory(C),isContinue:!1,sessionKeyForSave:null}:await mn({sdk:L,sessionKey:s,cwd:C,restoreUrl:e.sessionRestoreUrl});console.log(Pe.isContinue?`[step] ${o} continue session ${s}`:`[step] ${o} new session ${s}`);let Ms=await ro(e.skills,ce),An=e.secretEnv,Dt={},Dn=gn();An&&(Dt.spawnHook=({command:S,cwd:_,env:D})=>({command:S,cwd:_,env:{...D,...An}}));let _s=L.createLocalBashOperations(Dn?{shellPath:Dn}:void 0),On=Bo(_s,f.bashDefault/1e3);Dt.operations={exec:On.exec},P=e.mcpServers?.length?await co(e.mcpServers,e.mcpServerCredentials??[]):[];let Ln=P.length?await lo(P,[...e.tools,...(e.remoteTools??[]).map(S=>S.name)]):[],Fn=L.createBashToolDefinition(C,Dt);Fn.description+=` Commands run with a default timeout of ${f.bashDefault/6e4} minutes; pass an explicit timeout for longer commands, and run indefinite processes (servers, watchers) in the background instead of the foreground.`;let Un=e.workspace?Wo(t,n,o,e.workspace.installationToken):void 0,Cs=[go(r,s,b),wo(C,e,Un),bo(t,n,e),...yo(t,n,e),...Ln,Fn],N=await Yo(M,{modelRuntime:R,cwd:C,tools:[...e.tools,...(e.remoteTools??[]).map(S=>S.name),...Ln.map(S=>S.name)],sessionManager:Pe.sessionManager,thinkingLevel:e.agent.thinkingLevel??"",webSearch:!0,skills:Ms,extraCustomTools:Cs,systemPrompt:e.systemPrompt,appendSystemPrompt:e.appendSystemPrompt});Pe.sessionKeyForSave&&N.sessionFile&&dn(Pe.sessionKeyForSave,N.sessionFile);let Is=N.agent.streamFunction;N.agent.streamFunction=async(S,_,D)=>Do(Ao(await Is(S,_,D),`step:${o}`),`step:${o}`,S);let j=Co(N,`step:${o}`,i,p,v,{type:"stage",stage:"model",state:"done"});d=j.abort,l&&j.abort.abort();let Be=Promise.resolve();h=S=>{for(let _ of S)Be=Be.then(async()=>{let D=await Pn(_.images,o);await N.steer(_.text,D.length?D:void 0),_.interrupt&&On.interrupt(`
19
+ ${A}`:A,{closed:!0,truncated:!1})}if(p==="opened"&&d!==""&&await Xo(e,t,u,{quietMs:300,capMs:Math.min(2500,Math.max(m-Date.now(),0)),signal:i}),i?.aborted)return Vo(e,t,l,!1);if(d!==""&&!e.shellSendInput(t,u,d))return Ae("Reverse shell is unavailable: failed to write to the sidecar.",{closed:!0,truncated:!1});let g=await Xo(e,t,u,{quietMs:800,capMs:Math.max(m-Date.now(),1e3),armed:!0,signal:i});return Vo(e,t,l,g)}}}function Wa(e,t){if(e.length===0)return{error:Ha};if(t){let n=t.trim().toLowerCase(),r=e.find(o=>o.machineId.toLowerCase()===n||o.name.toLowerCase()===n);return r?{machine:r}:{error:`Unknown machine "${t}". Available: ${e.map(o=>o.name).join(", ")}.`}}return e.length===1?{machine:e[0]}:{error:`Several machines are available \u2014 pass "machine" to pick one: ${e.map(n=>n.name).join(", ")}.`}}function Ka(e){let t=e.interrupt?"":"";if(typeof e.input!="string"||e.input==="")return t;let n=e.input.replace(/\r?\n/g,"\r");return t+(e.enter===!1?n:n.replace(/\r$/,"")+"\r")}async function Ga(e,t,n,r,o,s,i=2e3){let a=()=>e.ensureShell(t,n,Math.max(1e3,Math.min(5e3,o-Date.now()))),c=await a();for(;c==="failed"&&r!==!1&&!s?.aborted&&Date.now()+i<o;)await qa(i,s),c=await a();return c}function Xo(e,t,n,r){let{quietMs:o,capMs:s,armed:i,signal:a}=r;return new Promise(c=>{let l,u=()=>{clearTimeout(l),l=setTimeout(()=>g(!1),o)},d=setTimeout(()=>g(!1),s),m=e.subscribeShell(t,n,{onActivity:u,onClosed:()=>g(!0)}),p=()=>g(!1);a?.addEventListener("abort",p,{once:!0}),i&&u(),a?.aborted&&g(!1);function g(x){clearTimeout(d),clearTimeout(l),m(),a?.removeEventListener("abort",p),c(x)}})}function qa(e,t){return new Promise(n=>{let r=setTimeout(o,e);t?.addEventListener("abort",o,{once:!0});function o(){clearTimeout(r),t?.removeEventListener("abort",o),n()}})}function za(e){return Math.min(Math.max(Number(e)||15e3,1e3),12e4)}function Vo(e,t,n,r){let o=e.consumeShellReconnect(t,n.machineId),s=e.drainShell(t,n.machineId),i=s.length>6e4;if(i&&(s=s.slice(-6e4)),r&&s.trim()===""&&!o)return Ae(Qo(n,e.hasEverOpened(t,n.machineId)),{closed:!0,truncated:!1});let a=[];return o&&a.push(ja),i&&a.push("[output truncated to the last 60000 characters]"),a.push(s||"(no output)"),r&&a.push("[shell session closed]"),Ae(a.join(`
20
+ `),{closed:r,truncated:i})}function Ae(e,t){return{content:[{type:"text",text:e}],details:t}}ve();U();de();var Ja=[500,2e3];function Qe(e){let t=e?.name;return t==="TimeoutError"||t==="AbortError"}async function Ze(e,t,n,r,o={}){let s=o.timeoutMs??f.remoteTool,i=async()=>{let a=await N(e,t,{token:n,body:r,timeoutMs:s,signal:o.signal}),c=await a.json().catch(()=>null),l={ok:a.ok,status:a.status,body:c},u=c?.transient,d=u===!0||u===void 0&&a.status>=500;if(o.replaySafe&&!a.ok&&d)throw Object.assign(Te(a,typeof c?.error=="string"?c.error:void 0),{reply:l});return l};if(!o.replaySafe)return i();try{return await G(i,a=>!!a?.reply||V(a),`[tool] ${o.label??t}`,Ja,o.signal)}catch(a){let c=a?.reply;if(c)return c;throw a}}function Ft(e,t){if(!e.ok)throw new Error(typeof e.body?.error=="string"?e.body.error:`${t} failed (HTTP ${e.status})`);if(typeof e.body?.text!="string")throw new Error(`${t} returned no JSON body`);return JSON.parse(e.body.text)}function H(e){return{content:[{type:"text",text:e}],details:{}}}function es(e,t,n){return(n.remoteTools??[]).map(r=>({name:r.name,label:r.label,description:r.description,parameters:r.parameters,async execute(o,s,i){let a=Date.now();try{let c=await Ze(e,`/api/machine/tool/${n.stepId}`,t,{name:r.name,params:s},{replaySafe:r.replaySafe,label:r.name,signal:i});if(!c.ok){console.warn(`[tool] ${r.name} rejected: HTTP ${c.status} in ${Date.now()-a}ms`);let l=c.body?.error;return H(typeof l=="string"?l:`${r.name} failed (HTTP ${c.status}).`)}return H(typeof c.body?.text=="string"?c.body.text:"")}catch(c){if(i?.aborted)throw c;let l=Date.now()-a,u=Qe(c)?`timed out after ${l}ms`:`failed after ${l}ms: ${O(c)}`;return console.warn(`[tool] ${r.name} transport failure: ${u}`),H(`${r.name} returned no result: the call to the Desk server ${u}. This is a connection problem, not a rejection \u2014 this machine's own network or proxy is as likely at fault as the server. `+(r.replaySafe?"This is a read, so calling it again is safe.":"It may or may not have taken effect server-side \u2014 check the current state before calling it again."))}}}))}ue();ge();function ts(e,t,n){return{name:"push_branch",label:"Push Branch",description:"Commit all work in the worktree and push this conversation's own working branch (desk/conv-*) to the remote repo. The branch is normally pushed only when a turn ends, so the remote does not have changes from the current turn until you call this. Call it before any tool that reads the branch from the remote \u2014 e.g. merge_branch on your own branch, or a CI run you want to pick the work up. `message` becomes the commit message for the staged work; when nothing changed since the last commit it just pushes.",parameters:{type:"object",properties:{message:{type:"string",description:'Commit message for the work being committed, e.g. "Release cli v0.2.0".'}},required:["message"],additionalProperties:!1},async execute(r,o){let s=o?.message,i=typeof s=="string"&&s.trim()?s.trim():null;if(!i)return H("A commit message is required.");if(!t.workspace||!n)return H("This turn has no repository workspace \u2014 push_branch is unavailable.");let a=he(t.conversationId);try{let{sha:c}=await co(e,t.workspace.defaultBranch,n,a,i,t.workspace.gitHost);return H(c?`Committed ${c.slice(0,12)} and pushed "${a}" \u2014 the remote now has all work up to this point.`:`Nothing new to commit \u2014 pushed "${a}" so the remote is current with the last commit.`)}catch(c){return H(`push_branch failed: ${c.message}`)}}}}ge();U();de();var ns=8e3,Bn=["log","show","diff","grep","ls-files","ls-tree","cat-file","rev-parse","describe","shortlog","blame","tag","branch","ls-remote","fetch"],Ya=/^(-o$|--output|--ext-diff$|--textconv$|-O$|--open-files-in-pager|--no-index$|--upload-pack)/;function rs(e){return e.length>ns?`${e.slice(0,ns)}
21
+ \u2026(truncated)`:e}async function Xa(e,t,n,r,o){let s=await Ze(e,`/api/machine/tool/${n}`,t,{name:"open_repo",params:{projectId:r}},{timeoutMs:f.openRepo,replaySafe:!0,label:"open_repo",signal:o}).catch(i=>{if(o?.aborted)throw i;let a=Qe(i)?"timed out":`failed (${O(i)})`;throw new Error(`Could not reach the Desk server to open this project's repository: the credential lookup ${a}. No git command ran and the repository is fine. Try again.`)});if(!s.ok)throw new Error(typeof s.body?.error=="string"?s.body.error:`open_repo failed (HTTP ${s.status})`);return Ft(s,"open_repo")}function os(e,t,n){let r=new Map;function o(s,i){let a=r.get(s);return a||(a=(async()=>{let c=await Xa(e,t,n.stepId,s,i),l=Rn(s);return await Tt(s,()=>$n(l,c.repoFullName,c.defaultBranch,c.installationToken,{readCheckout:!0,gitHost:c.gitHost})),{repo:c,baseDir:l}})(),a.catch(()=>r.delete(s)),r.set(s,a)),a}return{name:"git",label:"Git",description:`Read-only git against a project's repository, on a local clone kept fresh on this machine (the very first use of a project clones it \u2014 that call can take a while). The default branch is checked out and tags are fetched; other branches and PR heads are not local: list remote refs with ["ls-remote", "origin"], or ["fetch", "origin", "<ref>"] (e.g. a branch name or pull/<n>/head) and then reference FETCH_HEAD. Allowed subcommands: ${Bn.join(", ")}; anything that writes is rejected. Examples: ["grep", "-n", "handleLogin"], ["log", "--oneline", "-20"], ["show", "HEAD:package.json"], ["tag", "--list"], ["show", "FETCH_HEAD:src/app.ts"].`,parameters:{type:"object",properties:{projectId:{type:"string",description:"Which project's repo to run against (ids are in the project listing)."},args:{type:"array",items:{type:"string"},description:'git arguments as an array, starting with the subcommand, e.g. ["log", "--oneline", "-20"].'}},required:["projectId","args"],additionalProperties:!1},async execute(s,i,a){let c=i??{},l=typeof c.projectId=="string"?c.projectId.trim():"",u=Array.isArray(c.args)?c.args.map(String):[];if(!l||!u.length)return H('git needs { projectId, args } \u2014 e.g. args: ["log", "--oneline", "-20"].');let d=u[0];if(!Bn.includes(d))return H(`git ${d} is not available \u2014 this tool is read-only. Allowed subcommands: ${Bn.join(", ")}.`);let m=u.find(p=>Ya.test(p));if(m)return H(`The ${m} flag is not allowed here.`);try{let{repo:p,baseDir:g}=await o(l,a);if(a?.throwIfAborted(),d==="fetch"){let T=u.length===3&&u[1]==="origin"&&!u[2].startsWith("-")?u[2]:null;return T?(await Tt(l,()=>h(["fetch","origin",T],g,xe(p.installationToken,p.gitHost),{timeoutMs:f.gitNetworkInteractive})),H(`Fetched ${T} \u2014 reference it as FETCH_HEAD, e.g. ["log", "--oneline", "-10", "FETCH_HEAD"].`)):H('fetch is limited to exactly: ["fetch", "origin", "<ref>"] \u2014 e.g. a branch name or pull/<n>/head.')}if(d==="ls-remote"){let T=await h(u,g,xe(p.installationToken,p.gitHost),{timeoutMs:f.gitNetworkInteractive});return H(rs(T)||"(no output)")}let x=(d==="tag"||d==="branch")&&!u.some(T=>T==="--list"||T==="-l")?[d,"--list",...u.slice(1)]:u,A=await h(x,g,{},{timeoutMs:f.gitLocalInteractive});return H(rs(A)||"(no output)")}catch(p){if(a?.aborted)throw p;return H(p.message)}}}}var Ut=require("node:fs"),ss=require("node:child_process"),et=require("node:path"),Va=/^[a-z]:\\windows\\(?:system32|sysnative|syswow64)\\bash\.exe$/;function Qa(e){return Va.test(e.replace(/\//g,"\\").toLowerCase())}function Za(e){let t=e.lookPath("git");if(t){let r=et.win32.join(et.win32.dirname(et.win32.dirname(t)),"bin","bash.exe");if(e.isFile(r))return r}for(let r of[e.getenv("ProgramFiles"),e.getenv("ProgramFiles(x86)")]){if(!r)continue;let o=et.win32.join(r,"Git","bin","bash.exe");if(e.isFile(o))return o}let n=e.lookPath("bash.exe");return n&&!Qa(n)?n:null}function ec(e){let t=(0,ss.spawnSync)("where",[e],{encoding:"utf-8",timeout:5e3,windowsHide:!0});if(t.status!==0||!t.stdout)return null;let n=t.stdout.trim().split(/\r?\n/)[0];return n&&(0,Ut.existsSync)(n)?n:null}var He;function Wn(){if(process.platform==="win32")return He!=null&&!(0,Ut.existsSync)(He)&&(He=void 0),He===void 0&&(He=Za({lookPath:ec,isFile:Ut.existsSync,getenv:e=>process.env[e]})),He??void 0}function is(){if(process.platform!=="win32")return;let e=Wn();if(e){console.log(`[machine] Agent shell: ${e}`);return}console.warn("[machine] No Git Bash found \u2014 the agent's shell will fall back to whatever bash.exe is on PATH. If that is C:\\Windows\\System32\\bash.exe (Windows' WSL launcher), every shell command in a build will fail. Install Git for Windows, or put a real bash ahead of System32 on PATH.")}U();ve();var as=require("node:child_process");U();function tc(e){let t={},n=/HTTPEnable\s*:\s*1/.test(e),r=/HTTPSEnable\s*:\s*1/.test(e),o=e.match(/HTTPProxy\s*:\s*(\S+)/)?.[1],s=e.match(/HTTPPort\s*:\s*(\d+)/)?.[1],i=e.match(/HTTPSProxy\s*:\s*(\S+)/)?.[1],a=e.match(/HTTPSPort\s*:\s*(\d+)/)?.[1];if(n&&o&&s){let d=`http://${o}:${s}`;t.HTTP_PROXY=d,t.http_proxy=d}if(r&&i&&a){let d=`http://${i}:${a}`;t.HTTPS_PROXY=d,t.https_proxy=d}if(Object.keys(t).length===0)return t;let l=[...(e.match(/ExceptionsList\s*:\s*<array>\s*\{([^}]*)\}/)?.[1]??"").matchAll(/\d+\s*:\s*(\S+)/g)].map(d=>d[1]),u=[...new Set([...l,"localhost","127.0.0.1","::1"])].join(",");return t.NO_PROXY=u,t.no_proxy=u,t}function qn(){return process.env.HTTPS_PROXY||process.env.https_proxy||process.env.HTTP_PROXY||process.env.http_proxy||void 0}function cs(){return new Promise(e=>{(0,as.execFile)("scutil",["--proxy"],{encoding:"utf8"},(t,n)=>e(t||!n?null:tc(n)))})}var Ht=null;async function nc(){if(qn())return;let e=await cs();e!==null&&(Ht=e,Object.keys(e).length!==0&&(Object.assign(process.env,e),console.log(`[machine] System proxy: ${e.HTTPS_PROXY??e.HTTP_PROXY}`)))}var Gn=!1,tt;async function ls(e){if(Gn)return!0;let t=qn();if(!t)return!1;let n=await import("undici");await ds();let r=async(o,s)=>n.fetch(o,{...s,dispatcher:tt});return globalThis.fetch=r,Gn=!0,e&&console.log(`${e} Proxy: ${t}`),!0}var us=async(e,t)=>{let n=await import("undici");tt??=new n.EnvHttpProxyAgent;let r=tt.compose(o=>(s,i)=>o({...s,bodyTimeout:f.streamBodyTimeout},i));return n.fetch(e,{...t,dispatcher:r})};async function ds(){let e=await import("undici"),t=tt;tt=new e.EnvHttpProxyAgent,t?.close().catch(()=>{})}function rc(e,t,n){let r=Object.keys(e);if(r.length===Object.keys(t).length&&r.every(o=>e[o]===t[o]))return!1;for(let o of r)delete n[o];return Object.assign(n,t),!0}var Kn=null;function jt(){return Kn??=oc().catch(e=>(console.warn(`[machine] system proxy refresh failed: ${e instanceof Error?e.message:String(e)}`),!1)).finally(()=>{Kn=null}),Kn}async function oc(){if(Ht===null)return!1;let e=await cs();return e===null||!rc(Ht,e,process.env)?!1:(Ht=e,Gn?await ds():await ls(),console.log(`[machine] System proxy moved: ${qn()??"none"}`),!0)}async function ms(e="[desk]"){await nc(),await ls(e)}var Bt=new Map;function Wt(e){let t=e&&Bt.get(e);if(t)return t();for(let n of Bt.values())n()}function zn(e,t){let{input:n,output:r,cacheRead:o,cacheWrite:s,cost:i}=e.usage;return{provider:e.provider,modelId:e.responseModel??e.model,thinkingLevel:t,at:e.timestamp,usage:{inputTokens:n,outputTokens:r,cacheReadTokens:o,cacheWriteTokens:s,costUsd:i.total}}}function sc(e,t){if(!t)return"";switch(e){case"read":case"write":case"edit":case"ls":return String(t.path??"");case"bash":return String(t.command??"").slice(0,100);case"grep":return`"${t.pattern??""}"${t.path?` in ${t.path}`:""}`;case"find":return String(t.path??t.pattern??"");case"web_fetch":return String(t.url??"");case"web_search":return String(t.query??t.input??"");default:{let n=Object.values(t)[0];return n?String(n).slice(0,100):""}}}async function fs(e,t,n,r){let o=await N(e,t,{token:r,body:n,timeoutMs:f.stepPost});if(!o.ok)throw Te(o);return await o.json()}async function Jn(e,t,n,r){try{return await fs(e,t,n,r)}catch(o){return console.error(`[machine] POST ${t} failed:`,o.message),{}}}async function Kt(e,t,n,r){return G(()=>fs(e,t,n,r),V,`[machine] POST ${t}`)}function Yn(e,t,n,r,o,s=60*1e3,i){let a=!0,c=!1,l=async()=>{if(!(!a||c)){c=!0;try{let d=await Jn(e,`/api/machine/heartbeat/${t}`,{},r);a&&d.stop&&n(),a&&Array.isArray(d.steer)&&i?.(d.steer),a&&Array.isArray(d.remoteMachines)&&o?.(d.remoteMachines)}finally{c=!1}}};l();let u=setInterval(l,s);return Bt.set(t,()=>void l()),()=>{a=!1,clearInterval(u),Bt.delete(t)}}var ic=50;function ps(e){return typeof e.text!="string"?null:e.type===void 0?"text":e.type==="thinking"?"thinking":null}function hs(e,t,n,r,o,s){let i=new AbortController;i.signal.addEventListener("abort",()=>{try{e.dispose()}catch{}});let a="",c="",l,u,d=[],m=[],p,g=!1,x=[],A=Promise.resolve(),T=!1,$=async()=>{try{for(;x.length;){let w=await n(x.shift());w.stop&&r(),Array.isArray(w.steer)&&o?.(w.steer),x.length&&await new Promise(k=>setTimeout(k,ic))}}finally{T=!1}},R=s,E=w=>{R&&(x.push(R),R=void 0);let k=ps(w),_=x[x.length-1];if(k&&_&&ps(_)===k){_.text=_.text+w.text;return}x.push(w),T||(T=!0,A=$())},b=()=>{g&&(g=!1,E({type:"retry",attempt:0,maxAttempts:0}))},I=e.subscribe(w=>{if(w.type==="message_end"){if(w.message.role==="assistant"){d.push(zn(w.message,e.thinkingLevel));let k=w.message.content.map(ct=>ct.type==="text"?ct.text:"").join("");k!==c&&(console.warn(`[${t}] message_end text reconcile: deltas=${c.length} content=${k.length} chars`),k.startsWith(c)&&E({text:k.slice(c.length)})),a+=k||c,c="";let{stopReason:_,errorMessage:J}=w.message;u=_,_!=="stop"&&_!=="toolUse"&&(console.warn(`[${t}] message_end stopReason=${_}${J?` error=${J}`:""}`),J&&(l=J))}return}if(w.type==="auto_retry_start"){console.warn(`[${t}] auto_retry attempt=${w.attempt}/${w.maxAttempts} error=${w.errorMessage}`),jt(),g=!0,E({type:"retry",attempt:w.attempt,maxAttempts:w.maxAttempts});return}if(w.type==="auto_retry_end"){w.success||console.error(`[${t}] auto_retry_end failed finalError=${w.finalError}`),b();return}if(w.type==="compaction_start"){p=Date.now(),E({type:"compact",active:!0});return}if(w.type==="compaction_end"){E({type:"compact",active:!1});let k=p===void 0?void 0:Date.now()-p;if(p=void 0,w.errorMessage)console.warn(`[${t}] auto-compaction failed: ${w.errorMessage}`);else if(!w.aborted&&w.result){let _=w.result.usage;m.push({tokensBefore:w.result.tokensBefore,usage:_&&{inputTokens:_.input,outputTokens:_.output,cacheReadTokens:_.cacheRead,cacheWriteTokens:_.cacheWrite,costUsd:_.cost.total},durationMs:k})}return}if(w.type==="message_update"){let k=w.assistantMessageEvent;if(("delta"in k&&k.delta||k.type==="toolcall_end")&&b(),k.type==="text_delta"){let _=k.delta;_&&(c+=_,E({text:_}))}else if(k.type==="thinking_delta"){let _=k.delta;_&&E({type:"thinking",text:_})}else if(k.type==="toolcall_end"){let{name:_,arguments:J}=k.toolCall;_&&E({type:"tool_start",toolName:_,detail:sc(_,J)})}}}),y=!1;return{abort:i,getFullText:()=>a+c,getLastModelError:()=>l,getLastStopReason:()=>u,getModelCalls:()=>d.length?d:void 0,getCompactions:()=>m.length?m:void 0,idle:()=>A,dispose:()=>{if(!y){y=!0,I();try{e.dispose()}catch{}}}}}function gs(e){return e.stopReason!=="stop"&&e.stopReason!=="toolUse"?!1:!e.content.some(t=>t.type==="text"&&t.text.trim()!==""||t.type==="toolCall")}var ac="empty response: provider stream ended without content (no text, no tool call)";function ys(e,t){let n,r=s=>(n||(console.warn(`[${t}] empty assistant frame \u2014 rewriting as retryable provider error`),n={...s,stopReason:"error",errorMessage:ac}),n);return{async*[Symbol.asyncIterator](){for await(let s of e)yield s.type==="done"&&gs(s.message)?{type:"error",reason:"error",error:r(s.message)}:s},result:async()=>{let s=await e.result();return gs(s)?r(s):s}}}U();var cc=(e,t)=>`stream stalled: no provider progress for ${Math.round(e/1e3)}s ${t?"waiting for first event":"while generating"}`;function ws(e,t,n,{firstEventMs:r=f.streamFirstEvent,idleMs:o=f.streamIdle,onTimeout:s}={}){let i,a,c,l=new Promise(m=>{c=m}),u=m=>{let p=cc(m?r:o,m);return console.warn(`[${t}] ${p} \u2014 cancelling without replay`),i=a?{...structuredClone(a),stopReason:"error",errorMessage:p}:{role:"assistant",content:[],api:n.api,provider:n.provider,model:n.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"error",errorMessage:p,timestamp:Date.now()},c(i),i};return{async*[Symbol.asyncIterator](){let m=e[Symbol.asyncIterator](),p=!0,g=r;for(;;){let x=performance.now(),A,T=await new Promise(R=>{if(g<=0){R({kind:"timeout"});return}A=setTimeout(()=>R({kind:"timeout"}),g),m.next().then(E=>R({kind:"next",r:E}),E=>R({kind:"threw",err:E}))}).finally(()=>clearTimeout(A));if(g-=performance.now()-x,T.kind==="timeout"){let R=u(p);s?.(),Promise.resolve(m.return?.()).catch(()=>{}),yield{type:"error",reason:"error",error:R};return}if(T.kind==="threw")throw T.err;if(T.r.done)return;let $=T.r.value;if((p||$.type.endsWith("_end")||"delta"in $&&$.delta.length>0)&&(g=o),p=!1,"partial"in $&&(a=$.partial),yield $,$.type==="done"||$.type==="error"){Promise.resolve(m.return?.()).catch(()=>{});return}}},result:async()=>{let m=await Promise.race([e.result(),l]);return i??m}}}var z=require("node:fs"),ks=require("node:path");Ct();K();ve();var lc=48*60*60*1e3,Gt=[3e4,6e4,12e4,3e5],uc=3;function Ss(){let e=process.env.DESK_OUTBOX_DIR??j("outbox");return(0,z.mkdirSync)(e,{recursive:!0}),e}var qt=e=>(0,ks.join)(Ss(),`${e}.json`);function Vn(e){(0,z.rmSync)(qt(e),{force:!0})}function dc(e){return!e||typeof e!="object"?null:typeof e.body=="object"&&e.body!==null?{body:e.body,nextAttemptAt:Number(e.nextAttemptAt??0),attempt:Number(e.attempt??0)}:{body:e,nextAttemptAt:0,attempt:0}}function Qn(e){let t=qt(e),n;try{n=JSON.parse((0,z.readFileSync)(t,"utf8"))}catch(r){if(r.code==="ENOENT")return null;console.error(`[outbox] moving corrupt entry aside: ${t}:`,r.message);try{(0,z.renameSync)(t,`${t}.corrupt`)}catch{(0,z.rmSync)(t,{force:!0})}return null}return dc(n)}function bs(e,t){try{ye(qt(e),JSON.stringify(t))}catch(n){console.error(`[outbox] spool write failed for step ${e}:`,n.message)}}var Xn=new Set;async function Zn(e,t,n,r,o){if(!Xn.has(n)){Xn.add(n);try{let s=await o(e,`/api/machine/done/${n}`,r,t);return Vn(n),s}catch(s){let i=s.httpStatus;if(!(r?.mode==="branch_sync"&&i===403)&&!V(s)&&i!==void 0){console.error(`[outbox] server refused done for step ${n} (${s.message}) \u2014 dropping entry`),Vn(n);return}let c=Qn(n),l=(c?.attempt??0)+1;bs(n,{body:c?.body??r,nextAttemptAt:Date.now()+Gt[Math.min(l,Gt.length-1)],attempt:l}),console.warn(`[outbox] done for step ${n} not delivered (${s.message}) \u2014 kept for retry (backoff ${Math.round(Gt[Math.min(l,Gt.length-1)]/1e3)}s)`);return}finally{Xn.delete(n)}}}async function zt(e,t,n,r,o=Kt){return bs(n,{body:r,nextAttemptAt:0,attempt:0}),Zn(e,t,n,r,o)}async function Jt(e,t,n,r=Kt){let o=Qn(n);return o?(await Zn(e,t,n,o.body,r),!0):!1}async function mc(e,t,n){let r=0;async function o(){for(;r<e.length;){let i=r++;await n(e[i])}}let s=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(s)}async function er(e,t,n=Kt){let r;try{r=(0,z.readdirSync)(Ss()).filter(o=>o.endsWith(".json"))}catch{return}await mc(r,uc,async o=>{let s=o.slice(0,-5),i=(0,z.statSync)(qt(s),{throwIfNoEntry:!1})?.mtimeMs;if(i===void 0)return;if(Date.now()-i>lc){console.warn(`[outbox] dropping expired entry for step ${s} (${Math.round((Date.now()-i)/36e5)}h old)`),Vn(s);return}let a=Qn(s);a&&(Date.now()<a.nextAttemptAt||await Zn(e,t,s,a.body,n))})}U();de();function pc(){let e=async(...r)=>{let s=r[0].payload;if(!(!s||!Array.isArray(s.input)))return{...s,tools:[{type:"web_search"},...s.tools??[]]}},t=new Map;t.set("before_provider_request",[e]);let n={path:__filename,source:"local",scope:"temporary",origin:"top-level"};return{path:__filename,resolvedPath:__filename,sourceInfo:n,handlers:t,tools:new Map,messageRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}function vs(e){return{...e,extensionsOverride:t=>({...t,extensions:[...t.extensions,pc()]})}}var fc=8e3;function hc(e){return`"${e}" is not a valid URL \u2014 include the scheme, e.g. "https://example.com/page".`}function gc(e,t,n){let r=Qe(t)?`timed out after ${Math.round(n/1e3)}s`:O(t);return`Could not fetch ${e} \u2014 ${r}. Check the URL is reachable, or retry if this may be transient.`}function yc(e,t,n=fc){return{text:`${e.ok?"":`[HTTP ${e.status} ${e.statusText}] `}${t.slice(0,n)}`,truncated:t.length>n}}var xs={name:"web_fetch",label:"Web Fetch",description:"Fetch the text content of a URL. Returns up to 8000 characters of the response body.",parameters:{type:"object",properties:{url:{type:"string",description:"The URL to fetch"}},required:["url"],additionalProperties:!1},async execute(e,t,n,r,o){let{url:s}=t;try{new URL(s)}catch{return{content:[{type:"text",text:hc(s)}],details:{truncated:!1}}}let i,a;try{i=await q(s,f.webFetch,{headers:{"User-Agent":"Mozilla/5.0"}}),a=await i.text()}catch(u){return{content:[{type:"text",text:gc(s,u,f.webFetch)}],details:{truncated:!1}}}let{text:c,truncated:l}=yc(i,a);return{content:[{type:"text",text:c}],details:{truncated:l}}}};ue();ge();U();var wc=new Set(["openai-completions","openai-responses","azure-openai-responses","openai-codex-responses","anthropic-messages"]);function Ts(e,t,n=f.streamUsageTail){return wc.has(e)?async(r,o)=>{let s=await(t??us)(r,o);if(!s.ok||!s.body||!s.headers.get("content-type")?.includes("text/event-stream"))return s;let i=s.body.getReader(),a=new TextDecoder,c="",l=[],u=!1,d=!1,m,p,g=()=>{d=!0,clearTimeout(m),i.cancel().catch(()=>{}).finally(()=>i.releaseLock())},x=()=>{d||(p.close(),g())},A=b=>{if(b==="[DONE]")return!0;let I;try{I=JSON.parse(b)}catch{return!1}return!I||typeof I!="object"?!1:e==="openai-completions"?(I.choices?.[0]?.finish_reason&&(u=!0,m??=setTimeout(x,n)),u&&(I.usage!=null||I.choices?.[0]?.usage!=null)):e==="anthropic-messages"?I.type==="message_stop":["response.completed","response.done","response.incomplete","response.failed"].includes(I.type)},T=b=>{if(b===""){let I=l.join(`
22
+ `);if(l=[],I&&A(I))return!0}else(b==="data"||b.startsWith("data:"))&&l.push(b.slice(5).replace(/^ /,""));return!1},$=b=>{for(c+=a.decode(b,{stream:!0});;){let I=/\r\n|\r|\n/.exec(c);if(!I||I[0]==="\r"&&I.index===c.length-1)return!1;let y=c.slice(0,I.index);if(c=c.slice(I.index+I[0].length),T(y))return!0}},R=()=>{if(!c)return;let b=c;c="",T(b)},E=new ReadableStream({start(b){p=b},async pull(){try{let b=await i.read();if(d)return;b.done?(d=!0,clearTimeout(m),R(),p.close(),i.releaseLock()):(p.enqueue(b.value),$(b.value)&&x())}catch(b){if(d)return;p.error(b),g()}},cancel:g});return new Response(E,{status:s.status,statusText:s.statusText,headers:s.headers})}:t}function kc(e){let t=/\s*(?:[,}\]:]|$)/y,n="",r=!1;for(let o=0;o<e.length;o++){let s=e[o];r?s==="\\"?n+=s+(e[++o]??""):s!=='"'?n+=s:(t.lastIndex=o+1,r=!t.test(e),n+=r?'\\"':s):(r=s==='"',n+=s)}return n}function Es(e){try{return JSON.parse(e)}catch{}try{return JSON.parse(kc(e))}catch{return}}var Sc=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function Rs(e){return{...e,prepareArguments(t){let n=structuredClone(t);n&&typeof n.edits=="string"&&(n.edits=Es(n.edits)??n.edits);let r=e.prepareArguments?e.prepareArguments(n):n;return r&&Array.isArray(r.edits)&&(r.edits=r.edits.map(o=>{let s=typeof o=="string"?Es(o):o;return Sc(s)?s:o})),r}}}U();function Ps(e,t){let n=new Set;return{exec:async(r,o,s)=>{let i={ctl:new AbortController,onData:s.onData};n.add(i);let a=s.signal?AbortSignal.any([s.signal,i.ctl.signal]):i.ctl.signal;Xe(a);try{return await e.exec(r,o,{...s,signal:a,timeout:s.timeout??t})}finally{n.delete(i),i.ctl.abort()}},interrupt:r=>{if(!n.size)return!1;for(let{ctl:o,onData:s}of n){try{s(Buffer.from(r))}catch{}o.abort()}return!0}}}function _s(e,t,n,r){let o=r;return{current:()=>o,async refresh(){let s=await Ze(e,`/api/machine/tool/${n}`,t,{name:"push_credential",params:{}},{replaySafe:!0,label:"push credential"}),{installationToken:i}=Ft(s,"push_credential");if(typeof i!="string"||!i)throw new Error("push credential refresh returned an invalid token");o=i}}}var bc=`
23
+ [truncated for compaction]`,tr=(e,t)=>e.length<=t?e:e.slice(0,t)+bc;function $s(e,t){let{toolResultKeepChars:n,textKeepChars:r}=t;return e.map(o=>{if(o.role==="toolResult"&&Array.isArray(o.content)){if(!n)return o;let s=o.content;if(s.every(a=>a.type==="text")&&s.reduce((a,c)=>a+(c.text?.length??0),0)<=n)return o;let i=s.filter(a=>a.type==="text").map(a=>a.text??"").join(`
24
+ `);return{...o,content:[{type:"text",text:tr(i,n)}]}}if(!r)return o;if(o.role==="user"&&typeof o.content=="string")return o.content.length<=r?o:{...o,content:tr(o.content,r)};if((o.role==="user"||o.role==="assistant")&&Array.isArray(o.content)){let s=o.content;if(!s.some(a=>a.type==="thinking"||a.type==="text"&&(a.text?.length??0)>r))return o;let i=s.filter(a=>a.type!=="thinking").map(a=>a.type==="text"&&(a.text?.length??0)>r?{...a,text:tr(a.text,r)}:a);return{...o,content:i}}return o})}function Ms(e,t,n={}){return{name:"compaction-trim",factory:r=>{r.on("session_before_compact",async(o,s)=>{if(!(!n.trim&&!n.compactionModel)&&s.model)try{let i=n.compactionModel??s.model,a=await s.modelRegistry.getApiKeyAndHeaders(i);if(!a.ok&&i!==s.model&&(i=s.model,a=await s.modelRegistry.getApiKeyAndHeaders(i)),!a.ok)return;let c=n.trim??{},l={...o.preparation,messagesToSummarize:$s(o.preparation.messagesToSummarize,c),turnPrefixMessages:$s(o.preparation.turnPrefixMessages,c)},u={...i,...c.summaryMaxTokens?{maxTokens:c.summaryMaxTokens}:{},...a.baseUrl?{baseUrl:a.baseUrl}:{}},d=a.headers?Object.fromEntries(Object.entries(a.headers).filter(p=>p[1]!=null)):void 0;return{compaction:await e.compact(l,u,a.apiKey,d,void 0,o.signal,void 0,void 0,a.env,t.getRetrySettings())}}catch(i){if(o.signal.aborted)throw i;console.warn("[compaction-trim] falling back to pi default:",i.message)}})}}}bn();var Is=e=>({pushed:e?.ok?!0:void 0,pushError:(e&&!e.ok?e:void 0)?.error});function rr(e,t,n){let{stepId:r,conversationId:o,mode:s}=e;return i=>{let a={conversationId:o,mode:s,...i};return zt(t,n,r,a)}}function Cs(e,t,n){return async()=>{try{let r=await N(e,`/api/machine/upload-urls/${n}`,{token:t,timeoutMs:f.recover});return r.ok?await r.json():void 0}catch{return}}}var Ee=new Map;function As(e,t){let n=(Ee.get(e)??Promise.resolve()).then(t).catch(r=>console.error(`[step] deferred turn work failed (conv ${e}):`,r.message));return Ee.set(e,n),n.finally(()=>{Ee.get(e)===n&&Ee.delete(e)}),n}async function vc(e,t,n,r=f.deferredTurnWork){let o=new AbortController,s=await Promise.race([t.then(()=>!0,()=>!0),new Promise(i=>{let a=setTimeout(()=>i(!1),r);o.signal.addEventListener("abort",()=>clearTimeout(a),{once:!0})})]);o.abort(),!s&&(console.error(`[step] ${n} deferred turn work still pending after ${r}ms \u2014 abandoning it (conv ${e})`),Ee.get(e)===t&&Ee.delete(e))}async function Os(e,t){let n=e.workspace;return n?uo(e.conversationId,n,e.mode==="restore"&&e.restore?{restoreTo:e.restore.commitSha??`origin/${n.defaultBranch}`,onRetry:t}:{onRetry:t}):null}async function xc(e){return e.restore?No(e.conversationId,e.sessionRestoreUrl,e.restore.sessionLeafEntryId,e.stepId):null}var Tc=7;function Ec(e){(e.getProjectSettings().retry?.maxRetries??e.getGlobalSettings().retry?.maxRetries)===void 0&&e.applyOverrides({retry:{maxRetries:Tc}})}function Rc(e,t){if(t===void 0)return;(e.getProjectSettings().transport??e.getGlobalSettings().transport)===void 0&&e.applyOverrides({transport:t})}function Pc(e,t){if(t===void 0)return;(e.getProjectSettings().compaction??e.getGlobalSettings().compaction)===void 0&&e.applyOverrides({compaction:t})}async function Ds({sdk:e,agentDir:t},n){let r=n.skills?.length?{noSkills:!0,skillsOverride:()=>({skills:n.skills,diagnostics:[]})}:{},o=n.appendSystemPrompt,s=o?{appendSystemPromptOverride:u=>[...u,o]}:{},i=e.SettingsManager.create(n.cwd,t);Ec(i),Rc(i,n.modelRuntime.transport),Pc(i,n.modelRuntime.compaction);let a={cwd:n.cwd,agentDir:t,noExtensions:!0,noPromptTemplates:!0,noThemes:!0,noContextFiles:!0,extensionFactories:[Ms(e,i,{compactionModel:n.modelRuntime.compactionModel,trim:n.modelRuntime.compactionTrim})],...r,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},...s},c=new e.DefaultResourceLoader(n.webSearch!==!1?vs(a):a);await c.reload();let{session:l}=await e.createAgentSession({cwd:n.cwd,agentDir:t,model:n.modelRuntime.model,modelRuntime:n.modelRuntime.modelRuntime,resourceLoader:c,tools:n.tools,customTools:[xs,...n.extraCustomTools??[]],sessionManager:n.sessionManager,settingsManager:i,thinkingLevel:n.thinkingLevel||void 0});return l}async function nr(e,t){return e?.length?(await Promise.all(e.map(async r=>{if(!r.url)return null;try{let o=await q(r.url,f.r2Download);if(!o.ok)throw new Error(`HTTP ${o.status}`);return{type:"image",data:Buffer.from(await o.arrayBuffer()).toString("base64"),mimeType:r.mimeType}}catch(o){return console.error(`[step] ${t} image download failed for ${r.key}:`,o instanceof Error?o.message:String(o)),null}}))).filter(r=>r!==null):[]}async function Ls(e,t,n,r){let{stepId:o,conversationId:s}=e,i=Promise.resolve(),a=E=>{let b=i.then(()=>Jn(t,`/api/machine/token/${o}`,E,n));return i=b.catch(()=>({})),b},c=Ee.get(s);if(c&&(a({type:"stage",stage:"wrapup",state:"start"}),await vc(s,c,o),a({type:"stage",stage:"wrapup",state:"done"})),e.mode==="restore")return _c(e,t,n);if(e.mode==="compact")return $c(e,t,n);if(await Jt(t,n,o)){console.log(`[step] ${o} outcome already spooled \u2014 resent recorded /done, skipping re-run`);return}console.log(`[step] ${o} start (conv ${s})`),a({type:"stage",stage:"prepare",state:"start"});let l=Cs(t,n,o),u=!1,d=null,m=()=>{u=!0,d?.abort()},p=[],g=E=>{p.push(...E)},x=E=>g(E),A={current:e.remoteMachines??[]},T=Yn(t,o,m,n,E=>{A.current=E},void 0,x),$=[],R=rr(e,t,n);try{let E=await Ye(),{sdk:b,agentDir:I}=E;Bo(I);let y=await jn(b,e);if(!y.ok){await R({error:y.error});return}let ee=y.runtime;console.log(`[step] ${o} using model ${ee.model.provider}/${ee.model.id}`);let w=(S,D)=>void a({type:"retry",attempt:S,maxAttempts:D}),k;try{k=await Os(e,w)??I}catch(S){await R({error:`Workspace preparation failed: ${S.message}`});return}let _=e.mode==="ephemeral_turn",J=_?{sessionManager:b.SessionManager.inMemory(k),isContinue:!1,sessionKeyForSave:null}:await Un({sdk:b,sessionKey:s,cwd:k,restoreUrl:e.sessionRestoreUrl});console.log(J.isContinue?`[step] ${o} continue session ${s}`:`[step] ${o} new session ${s}`);let ct=await jo(e.skills,I),lr=e.secretEnv,on={},ur=Wn();lr&&(on.spawnHook=({command:S,cwd:D,env:F})=>({command:S,cwd:D,env:{...F,...lr}}));let wi=b.createLocalBashOperations(ur?{shellPath:ur}:void 0),dr=Ps(wi,f.bashDefault/1e3);on.operations={exec:dr.exec},$=e.mcpServers?.length?await qo(e.mcpServers,e.mcpServerCredentials??[]):[];let mr=$.length?await zo($,[...e.tools,...(e.remoteTools??[]).map(S=>S.name)]):[],pr=b.createBashToolDefinition(k,on);pr.description+=` Commands run with a default timeout of ${f.bashDefault/6e4} minutes; pass an explicit timeout for longer commands, and run indefinite processes (servers, watchers) in the background instead of the foreground.`;let fr=e.workspace?_s(t,n,o,e.workspace.installationToken):void 0,ki=[Zo(r,s,A),ts(k,e,fr),os(t,n,e),...es(t,n,e),...mr,pr,Rs(b.createEditToolDefinition(k))],Y=await Ds(E,{modelRuntime:ee,cwd:k,tools:[...e.tools,...(e.remoteTools??[]).map(S=>S.name),...mr.map(S=>S.name)],sessionManager:J.sessionManager,thinkingLevel:e.agent.thinkingLevel??"",webSearch:!0,skills:ct,extraCustomTools:ki,systemPrompt:e.systemPrompt,appendSystemPrompt:e.appendSystemPrompt});J.sessionKeyForSave&&Y.sessionFile&&Fn(J.sessionKeyForSave,Y.sessionFile);let Si=Y.agent.streamFunction;Y.agent.streamFunction=async(S,D,F)=>{let we=new AbortController,te=F?.signal?AbortSignal.any([F.signal,we.signal]):we.signal,ft=await Si(S,D,{...F,signal:te,fetch:Ts(S.api,F?.fetch)}),ne=()=>we.abort();return ws(ys(ft,`step:${o}`),`step:${o}`,S,{onTimeout:ne})};let X=hs(Y,`step:${o}`,a,m,x,{type:"stage",stage:"model",state:"done"});if(d=X.abort,u&&X.abort.abort(),e.gatherMs){Wt(o);let S=Date.now()+e.gatherMs;for(;!u&&Date.now()<S;)await new Promise(D=>setTimeout(D,250))}let hr=p.splice(0).filter(S=>typeof S.text=="string"&&S.text.length>0),lt=Promise.resolve();g=S=>{for(let D of S)lt=lt.then(async()=>{let F=await nr(D.images,o);await Y.steer(D.text,F.length?F:void 0),D.interrupt&&dr.interrupt(`
20
25
  [command interrupted: a user instruction arrived and takes effect now]
21
- `)}).catch(D=>console.error(`[step] ${o} steer inject failed:`,D.message))},m.length&&h(m.splice(0));let We,Ot,Hn,Ke,Ge,qe=async()=>{if(pe||(Hn=Pe.sessionManager.getLeafId()??void 0,!e.workspace))return;let S=e.workspace,{defaultBranch:_,syncPush:D,gitHost:ze}=S,fe=await Rr(C,_,o);We=fe.sha,Ot=fe.error;let Bn=ne(s);try{await nt(C,Un,Bn,ze,{quick:!D}),console.log(`[step] ${o} pushed ${Bn}`),Ge={ok:!0}}catch(ee){let le=ee instanceof Error?ee.message:String(ee);console.error(`[step] ${o} push failed:`,le),Ge=ee instanceof Ce?{ok:!1,error:le,kind:ee.kind,staleLeaseRetried:ee.staleLeaseRetried}:{ok:!1,error:le,kind:et(le),staleLeaseRetried:!1},D&&(Ot??=`${sr}${le}`)}if(We&&=await g(["rev-parse","HEAD"],C).catch(()=>We),Ke=await ln(C,_,o),Ke&&Ke!==e.prevDiffHash&&e.diffUploadUrl){let ee=await Gr(C,_,o);ee&&await qr(e.diffUploadUrl,ee,o,()=>u().then(le=>le?.diffUploadUrl))}},Lt=()=>({commitSha:We,checkpointError:Ot,pushOutcome:Ge,...zo(Ge),sessionLeafEntryId:Hn,diffHash:Ke,contextUsage:N.getContextUsage(),modelCalls:j.getModelCalls(),compactions:j.getCompactions()}),Nn=()=>({text:j.getFullText(),...Lt(),stopReason:j.getLastStopReason()}),jn=await Pn(e.images,o);i({type:"stage",stage:"prepare",state:"done"}),i({type:"stage",stage:"model",state:"start"});try{await N.prompt(e.prompt,jn.length?{images:jn}:void 0),await j.idle();let S=!j.getFullText()&&j.getLastModelError();if(S)await qe().catch(_=>console.error(`[step] ${o} failed-turn checkpoint:`,_.message)),await E({error:S,...Lt()});else{for(await Be;N.getSteeringMessages().length||m.length;){let _=N.clearQueue().steering,D=m.splice(0),ze=(await Promise.all(D.map(fe=>Pn(fe.images,o)))).flat();await N.prompt([..._,...D.map(fe=>fe.text)].join(`
26
+ `)}).catch(F=>console.error(`[step] ${o} steer inject failed:`,F.message))};let ut,sn,gr,dt,mt,pt=async()=>{if(_||(gr=J.sessionManager.getLeafId()??void 0,!e.workspace))return;let S=e.workspace,{defaultBranch:D,syncPush:F,gitHost:we}=S,te=await ao(k,D,o);ut=te.sha,sn=te.error;let ft=he(s);try{await xt(k,fr,ft,we,{quick:!F}),console.log(`[step] ${o} pushed ${ft}`),mt={ok:!0}}catch(ne){let Pe=ne instanceof Error?ne.message:String(ne);console.error(`[step] ${o} push failed:`,Pe),mt=ne instanceof ze?{ok:!1,error:Pe,kind:ne.kind,staleLeaseRetried:ne.staleLeaseRetried}:{ok:!1,error:Pe,kind:St(Pe),staleLeaseRetried:!1},F&&(sn??=`${jr}${Pe}`)}if(ut&&=await h(["rev-parse","HEAD"],k).catch(()=>ut),dt=await Dn(k,D,o),dt&&dt!==e.prevDiffHash&&e.diffUploadUrl){let ne=await _o(k,D,o);ne&&await $o(e.diffUploadUrl,ne,o,()=>l().then(Pe=>Pe?.diffUploadUrl))}},an=()=>({commitSha:ut,checkpointError:sn,pushOutcome:mt,...Is(mt),sessionLeafEntryId:gr,diffHash:dt,contextUsage:Y.getContextUsage(),modelCalls:X.getModelCalls(),compactions:X.getCompactions()}),yr=()=>({text:X.getFullText(),...an(),stopReason:X.getLastStopReason()}),bi=[e.prompt,...hr.map(S=>S.text)].join(`
27
+
28
+ `),wr=(await Promise.all([e.images,...hr.map(S=>S.images)].map(S=>nr(S,o)))).flat();a({type:"stage",stage:"prepare",state:"done"}),a({type:"stage",stage:"model",state:"start"});try{await Y.prompt(bi,wr.length?{images:wr}:void 0),await X.idle();let S=!X.getFullText()&&X.getLastModelError();if(S)await pt().catch(D=>console.error(`[step] ${o} failed-turn checkpoint:`,D.message)),await R({error:S,...an()});else{for(await lt;Y.getSteeringMessages().length||p.length;){let D=Y.clearQueue().steering,F=p.splice(0).filter(te=>typeof te.text=="string"&&te.text.length>0),we=(await Promise.all(F.map(te=>nr(te.images,o)))).flat();await Y.prompt([...D,...F.map(te=>te.text)].join(`
22
29
 
23
- `),ze.length?{images:ze}:void 0),await j.idle(),await Be}await qe(),await E(Nn())}}catch(S){if(await j.idle().catch(()=>{}),l)console.log(`[step] ${o} interrupted \u2014 saving partial content`),await qe(),await E(Nn());else{let _=S instanceof Error?S.message:String(S);console.error(`[step] ${o} failed:`,_),await qe().catch(D=>console.error(`[step] ${o} failed-turn checkpoint:`,D.message)),await E({error:_,...Lt()})}}finally{if(pe||qo(s,()=>yt(s,N.sessionFile,e.sessionBackupUrl,()=>u().then(S=>S?.sessionBackupUrl))),e.workspace){let S=qo(s,async()=>{ie.get(s)===S&&await fr(C,o)})}j.dispose()}}finally{x(),await uo(P)}}async function Sa(e,t,n){let{stepId:r,conversationId:o}=e;console.log(`[restore] ${r} start (conv ${o})`);let s=Mn(e,t,n),a,i,c=async()=>{let m=await Xo(e);if(!m||!e.workspace)return;let{defaultBranch:h,installationToken:v,gitHost:b}=e.workspace;await nt(m,v,ne(o),b,{rewind:!0}),i={ok:!0},a=await ln(m,h,r)},u=async()=>{let m=await ha(e);m&&await yt(o,m,e.sessionBackupUrl)},[l,d]=await Promise.allSettled([c(),u()]),p=[l,d].find(m=>m.status==="rejected");if(p){let m=p.reason instanceof Error?p.reason.message:String(p.reason);console.error(`[restore] ${r} failed:`,m),await s({error:m});return}await s({diffHash:a,pushOutcome:i,...zo(i)}),console.log(`[restore] ${r} done`)}async function ba(e,t,n){let{stepId:r,conversationId:o}=e;console.log(`[compact] ${r} start (conv ${o})`);let s=Mn(e,t,n),a=Jo(t,n,r),i=async()=>{};try{let c=await Ie(),{sdk:u,agentDir:l}=c,d=await fn(u,e);if(!d.ok){await s({error:d.error});return}let p=await mn({sdk:u,sessionKey:o,cwd:l,restoreUrl:e.sessionRestoreUrl});if(!p.isContinue){await s({contextUsage:void 0});return}let m=await Yo(c,{modelRuntime:d.runtime,cwd:l,tools:[],sessionManager:p.sessionManager,thinkingLevel:e.agent.thinkingLevel??"",webSearch:!1}),h=[],v=m.agent.streamFunction;m.agent.streamFunction=(P,E,M)=>{let L=m.thinkingLevel,ce=Promise.resolve(v(P,E,M));return h.push(ce.then(async y=>Sn(await y.result(),L)).catch(()=>null)),ce},i=async()=>{let P=(await Promise.all(h)).filter(E=>E!==null);return P.length?P:void 0};let b=!1,x=vn(t,r,()=>{b=!0,m.abortCompaction()},n,void 0,2e3);try{let P;try{P=await m.compact()}catch(M){if(!b)throw M;console.log(`[compact] ${r} cancelled (aborted)`),await s({error:"Cancelled",modelCalls:await i()});return}(await s({contextUsage:m.getContextUsage(),tokensBefore:P?.tokensBefore,modelCalls:await i()}))?.owned?(await yt(o,m.sessionFile,e.sessionBackupUrl,()=>a().then(M=>M?.sessionBackupUrl)),console.log(`[compact] ${r} done (before ~${P?.tokensBefore} tokens)`)):console.log(`[compact] ${r} superseded after compaction \u2014 discarding`)}finally{x()}}catch(c){let u=c instanceof Error?c.message:String(c);console.error(`[compact] ${r} failed:`,u),await s({error:u,modelCalls:await i()})}}function He(e){return e===401}var es=require("eventsource");var Qo=2e3,va=3e4,Zo=ar*5,Rt=class{constructor(t,n,r,o,s,a){this.serverUrl=t;this.token=n;this.onWake=r;this.onConfig=o;this.onHealthChange=s;this.onSteer=a}es=null;stopped=!0;healthy=!1;reconnectDelay=Qo;reconnectTimer=null;watchdog=null;start(){this.stopped&&(this.stopped=!1,this.connect())}stop(){this.stopped=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.es?.close(),this.es=null,this.setHealthy(!1)}isHealthy(){return this.healthy}connect(){let t=new es.EventSource(`${this.serverUrl}/api/machine/stream`,{fetch:(n,r)=>fetch(n,{...r,headers:{...r?.headers,...dt(this.token)}})});this.es=t,t.onopen=()=>{this.es===t&&(this.reconnectDelay=Qo,this.setHealthy(!0),this.onWake(),this.armWatchdog(t))},t.onmessage=n=>{if(this.es!==t)return;this.armWatchdog(t);let r;try{r=JSON.parse(n.data)}catch{return}r.type==="wake"?this.onWake():r.type==="config"?this.onConfig():r.type==="steer"&&this.onSteer(typeof r.stepId=="string"?r.stepId:void 0)},t.onerror=()=>{this.es===t&&this.dropAndRetry()}}armWatchdog(t){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{this.es===t&&(console.warn(`[wake] no frame in ${Zo/1e3}s \u2014 forcing reconnect`),this.dropAndRetry())},Zo)}dropAndRetry(){this.es?.close(),this.es=null,this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.setHealthy(!1),!this.stopped&&(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.stopped||this.connect()},this.reconnectDelay),this.reconnectDelay=Math.min(this.reconnectDelay*2,va))}setHealthy(t){this.healthy!==t&&(this.healthy=t,t?console.log("[wake] push channel connected"):this.stopped||console.log("[wake] push channel down \u2014 continuous long-poll fallback"),this.onHealthChange(t))}};var Ta="https://registry.npmjs.org/@deskdev/cli/latest",xa=36e5,de=null,ts=0,Ne=null;function ns(){return de&&Date.now()-ts<xa?Promise.resolve(de):Ne||(Ne=Ea().finally(()=>{Ne=null}),Ne)}async function Ea(){try{let e=await U(Ta,5e3);if(!e.ok)return de;let t=await e.json();if(typeof t.version=="string")return de=t.version,ts=Date.now(),de}catch{}return de}function rs(){return de}var $t=class e{constructor(t,n,r,o){this.serverUrl=t,this.machineId=n,this.token=r,this.tunnel=o}running=!1;abortController=new AbortController;runningTasks=new Map;presenceTimer=null;gcTimer=null;flushTimer=null;pokeTimer=null;lastSentTunnelKey;lastSentTunnelError;lastSentWorkspacesDir;sentPlatform=!1;revoked=!1;maxConcurrentTasks=null;wakeChannel=null;wakeResolve=null;wakePending=!1;getMountSync;getExecSync;onMounts;onExecTargets;lastPresenceWarnAt=0;start(){this.running=!0,this.abortController=new AbortController,this.tunnel.setNodeChangeHandler(()=>void this.reportPresence()),this.startPresenceHeartbeat(),this.wakeChannel||(this.wakeChannel=new Rt(this.serverUrl,this.token,()=>this.onWake(),()=>this.pokePresence(),()=>this.wakeResolve?.(),t=>Mo(t))),this.wakeChannel?.start(),console.log(`[machine] Online (machineId=${this.machineId}); polling ${this.serverUrl}`),this.startHousekeeping(),this.startOutboxFlush(),Rn(this.serverUrl,this.token).then(()=>this.recover()).then(()=>this.loop())}startOutboxFlush(){this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=setInterval(()=>void Rn(this.serverUrl,this.token),6e4)}pokePresence(){this.pokeTimer||(this.pokeTimer=setTimeout(()=>{this.pokeTimer=null,this.reportPresence()},250))}async recover(){try{let t=await I(this.serverUrl,"/api/machine/recover",{method:"POST",token:this.token,timeoutMs:f.recover});if(!t.ok){console.warn(`[recover] HTTP ${t.status}`);return}let n=await t.json();n.recovered>0?console.log(`[recover] re-queued ${n.recovered} step(s)`):console.log("[recover] no pending steps found")}catch(t){console.error("[recover] failed:",t.message)}}stop(){this.running=!1,this.abortController.abort(),this.wakeChannel?.stop(),this.presenceTimer&&(clearInterval(this.presenceTimer),this.presenceTimer=null),this.gcTimer&&(clearInterval(this.gcTimer),this.gcTimer=null),this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.pokeTimer&&(clearTimeout(this.pokeTimer),this.pokeTimer=null)}handleRevoked(t){this.revoked||(this.revoked=!0,console.error(`[machine] No longer registered (HTTP ${t}) \u2014 removed from team or token revoked. Shutting down.`),this.stop(),process.exit(Nt))}startPresenceHeartbeat(){this.presenceTimer&&clearInterval(this.presenceTimer);let t=()=>void this.reportPresence();t(),this.presenceTimer=setInterval(t,2e4)}startHousekeeping(){this.gcTimer&&clearInterval(this.gcTimer);let t=()=>{eo().catch(()=>{}),_r().catch(()=>{})};t(),this.gcTimer=setInterval(t,24*36e5)}tunnelSnapshot(){let t=this.tunnel.current();return{node:t,key:t?`${t.tailnetAddr}
24
- ${t.sshHostKey}`:null}}async reportPresence(){try{let t={load:this.runningTasks.size},n=rs();n&&(t.latestCliVersion=n);let r=this.getMountSync?.();r&&(t.mountSync=r);let o=this.getExecSync?.();o&&(t.execSync=o);let{node:s,key:a}=this.tunnelSnapshot();a!==this.lastSentTunnelKey&&(t.sshHostKey=s?.sshHostKey??null,t.tailnetAddr=s?.tailnetAddr??null);let i=s?null:this.tunnel.lastError();i!==this.lastSentTunnelError&&(t.tunnelError=i);let c=Q();c!==this.lastSentWorkspacesDir&&(t.workspacesDir=c),this.sentPlatform||(t.platform=process.platform,t.arch=process.arch);let u=await I(this.serverUrl,"/api/machine/presence",{token:this.token,body:t,timeoutMs:f.presence});if(He(u.status))return this.handleRevoked(u.status);if(u.ok){let l=await u.json().catch(()=>null),d=ir(l?.maxConcurrentTasks);d!=null&&d!==this.maxConcurrentTasks&&(console.log(`[machine] maxConcurrent changed ${this.maxConcurrentTasks} -> ${d}`),this.maxConcurrentTasks=d),Array.isArray(l?.mounts)&&this.onMounts?.(l.mounts),Array.isArray(l?.execTargets)&&this.onExecTargets?.(l.execTargets),this.lastSentTunnelKey=a,this.lastSentTunnelError=i,this.lastSentWorkspacesDir=c,this.sentPlatform=!0}}catch(t){Tt(),Date.now()-this.lastPresenceWarnAt>3e5&&(this.lastPresenceWarnAt=Date.now(),console.warn(`[machine] presence beat failed: ${t instanceof Error?t.message:String(t)}`))}}async reportOffline(){try{await I(this.serverUrl,"/api/machine/presence",{token:this.token,body:{offline:!0},timeoutMs:f.presenceOffline})}catch{}}runningCount(){return this.runningTasks.size}async loop(){let t=2e3;for(;this.running;)try{let n=this.maxConcurrentTasks??1;if(this.runningTasks.size>=n){await Promise.race([...this.runningTasks.values(),_n(2e3,this.abortController.signal)]);continue}let r=await this.claimOnce();t=2e3,!r&&this.wakeChannel?.isHealthy()&&await this.parkForWake()}catch(n){if(!this.running)break;let r=n instanceof Error?n.message:String(n);console.error(`[machine] Claim error: ${r} \u2014 retrying in ${t/1e3}s`),await _n(t,this.abortController.signal),t=Math.min(t*2,3e4)}}static PARK_MAX_MS=45e3;onWake(){this.wakeResolve?this.wakeResolve():this.wakePending=!0}async parkForWake(){if(this.wakePending){this.wakePending=!1;return}let t=new Promise(n=>{this.wakeResolve=n});try{await Promise.race([t,_n(e.PARK_MAX_MS,this.abortController.signal)])}finally{this.wakeResolve=null}}async claimOnce(){let t=await I(this.serverUrl,"/api/machine/tasks/claim",{token:this.token,body:{load:this.runningTasks.size},signal:this.abortController.signal,timeoutMs:f.claim});if(He(t.status))return this.handleRevoked(t.status),!1;if(!t.ok)throw new Error(`Claim HTTP ${t.status}`);let n=await t.json();if(console.log(`[machine] claim step=${n?n.stepId:"null"} (running=${this.runningTasks.size})`),!n)return!1;if(this.runningTasks.has(n.stepId))return console.warn(`[machine] step ${n.stepId} already running \u2014 skipping duplicate claim`),!0;let r=Vo(n,this.serverUrl,this.token,this.tunnel).catch(o=>{console.error(`[machine] step ${n.stepId} crashed:`,o instanceof Error?o.message:String(o))}).finally(()=>{this.runningTasks.get(n.stepId)===r&&this.runningTasks.delete(n.stepId),this.reportPresence(),console.log(`[machine] step ${n.stepId} finished (${this.runningTasks.size}/${this.maxConcurrentTasks} running)`)});return this.runningTasks.set(n.stepId,r),this.reportPresence(),console.log(`[machine] step ${n.stepId} for conv ${n.conversationId} (${this.runningTasks.size}/${this.maxConcurrentTasks} running)`),!0}};function _n(e,t){return new Promise(n=>{let r=()=>{clearTimeout(o),n()},o=setTimeout(()=>{t?.removeEventListener("abort",r),n()},e);t?.addEventListener("abort",r,{once:!0})})}var os=require("node:os"),ss=require("node:path");var Ra=18e4,$a=18e4,Pt=class{constructor(t,n,r){this.machineId=r,this.sidecar=new Se(["mirror","--server",t,"--token",n,"--machine",r],"sync",o=>this.onEvent(o),()=>this.markExecDown("tunnel daemon restarting")),this.sidecar.onSpawnFailure=o=>this.noteSidecarError(o)}sidecar;active=!1;desired=[];desiredExec=[];health=new Map;execHealth=new Map;sidecarError=null;onHealthChanged;stop(){this.active=!1,this.sidecar.stop()}reconcile(){let t=this.desired.length>0||this.desiredExec.length>0;t&&!this.active?(this.active=!0,console.log(`[machine] sync: managing worktree mirrors (machineId=${this.machineId})`),this.sidecar.start()):!t&&this.active&&(this.active=!1,console.log("[machine] sync: nothing to mirror or serve \u2014 stopping the sidecar."),this.sidecar.stop())}setMounts(t){let n=new Map(this.desired.map(o=>[o.mountId,JSON.stringify(o)]));this.desired=t.map(o=>({mountId:o.mountId,buildId:o.buildId,dest:o.destDir?ot(o.destDir):(0,ss.join)((0,os.homedir)(),lr(o.repoFullName,o.seqNum)),defaultBranch:o.defaultBranch}));let r=!1;for(let o of[...this.health.keys()]){let s=this.desired.find(a=>a.mountId===o);s&&JSON.stringify(s)===n.get(o)||(this.health.delete(o),s&&(r=!0))}this.reconcile(),this.sendMounts(),r&&this.onHealthChanged?.()}setExecTargets(t){this.desiredExec=t;let n=new Set(t.map(r=>r.machineId));for(let r of[...this.execHealth.keys()])n.has(r)||this.execHealth.delete(r);this.reconcile(),this.sendExec()}execStatus(){return this.desiredExec.length===0?null:[...new Set(this.desiredExec.map(n=>n.machineId))].map(n=>{let r=this.execHealth.get(n),o=r??this.sidecarError;return{builderMachineId:n,connected:r===null,...o?{error:o}:{}}})}markExecDown(t){let n=!1;for(let[r,o]of this.execHealth)o===null&&(this.execHealth.set(r,t),n=!0);n&&this.onHealthChanged?.()}status(){if(this.desired.length===0)return null;let t=Date.now();return this.desired.map(n=>{let r=this.health.get(n.mountId),o=r?.lastError??this.sidecarError;return{mountId:n.mountId,buildId:n.buildId,ageMs:r?.syncedAt?t-r.syncedAt:null,...o?{error:o}:{}}})}onEvent(t){if(!(t.mount&&this.desired.find(n=>n.mountId===t.mount)?.buildId!==t.build)){if(t.event==="up")this.sidecar.resetBackoff(),this.sidecarError&&(this.sidecarError=null,this.onHealthChanged?.()),this.sendMounts(),this.sendExec();else if((t.event==="exec-connected"||t.event==="exec-reconnecting")&&t.machine)this.execHealth.set(t.machine,t.event==="exec-connected"?null:t.message??"reconnecting"),this.onHealthChanged?.(),console.log(`[machine] shell: builder ${t.machine} ${t.event==="exec-connected"?"connected":`unreachable: ${t.message??""}`}`);else if(t.event==="synced"&&t.mount){let n=this.health.get(t.mount);this.health.set(t.mount,{syncedAt:Date.now(),lastError:null}),(!n?.syncedAt||n.lastError)&&this.onHealthChanged?.(),(t.changed||t.deleted)&&console.log(`[machine] sync: mount ${t.mount} \u2193 ${t.changed??0} changed, ${t.deleted??0} deleted`)}else if(t.event==="worktree-missing"&&t.mount){let n=this.health.get(t.mount),r=n?.missingSince??Date.now(),o=Date.now()-r>Ra?t.message??"worktree missing":null;this.health.set(t.mount,{syncedAt:0,lastError:o,missingSince:r}),(n?.syncedAt||(n?.lastError??null)!==o)&&this.onHealthChanged?.(),console.log(`[machine] sync: mount ${t.mount}: worktree missing \u2014 rebuild requested`)}else if(t.event==="reconnecting"&&t.mount){let n=this.health.get(t.mount),r=n?.downSince??Date.now(),o=Date.now()-r>$a?t.message??"reconnecting":n?.lastError??null;this.health.set(t.mount,{syncedAt:n?.syncedAt??0,lastError:o,downSince:r}),(n?.lastError??null)!==o&&this.onHealthChanged?.(),console.warn(`[machine] sync: mount ${t.mount}: reconnecting: ${t.message??""}`)}else if(t.event==="error")if(t.mount){let n=this.health.get(t.mount),r=t.message??"error";this.health.set(t.mount,{syncedAt:n?.syncedAt??0,lastError:r}),n?.lastError!==r&&this.onHealthChanged?.(),console.warn(`[machine] sync: mount ${t.mount}: ${r}`)}else console.warn(`[machine] sync: ${t.message??"error"}`),this.noteSidecarError(t.message??"error")}}noteSidecarError(t){this.sidecarError!==t&&(this.sidecarError=t,this.onHealthChanged?.())}sendMounts(){this.sidecar.write({cmd:"mounts",mounts:this.desired})}sendExec(){this.sidecar.write({cmd:"exec",targets:this.desiredExec})}};var is=require("node:child_process");function as(){if(process.platform==="darwin")try{let e=(0,is.spawn)("caffeinate",["-i","-w",String(process.pid)],{stdio:"ignore"});e.on("error",t=>console.warn(`[machine] idle-sleep prevention unavailable: ${t.message}`)),e.unref(),console.log("[machine] Idle-sleep prevention active (caffeinate)")}catch(e){console.warn(`[machine] idle-sleep prevention unavailable: ${e.message}`)}}var ls=require("child_process"),Ee=require("os");var Mt=require("crypto"),ae=require("fs"),cs=require("os");var Cn=V("device.json");function In(){if((0,ae.existsSync)(Cn))try{let n=JSON.parse((0,ae.readFileSync)(Cn,"utf-8"));if(n.deviceId)return n.deviceId}catch{}let e=(0,Mt.randomBytes)(16).toString("hex"),t=(0,Mt.createHash)("sha256").update(`${(0,cs.hostname)()}:${e}`).digest("hex").slice(0,32);return(0,ae.mkdirSync)(te(),{recursive:!0}),(0,ae.writeFileSync)(Cn,JSON.stringify({deviceId:t},null,2),{mode:384}),t}function Pa(e){let t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;(0,ls.exec)(t,()=>{})}var Ma=e=>new Promise(t=>setTimeout(t,e));async function us(e){return(await e.json().catch(()=>({}))).error??String(e.status)}function ds(e,t){Xn({machineId:t.machineId,token:t.token,teamId:t.teamId,serverUrl:e}),console.log(`[desk] Enrolled in team ${t.teamId} (machine ${t.machineId}).`)}async function ms(e,t,n,r,o){try{return await F(()=>I(e,t,{token:o,body:n,timeoutMs:f.enroll}),B,r)}catch(s){throw new Error(`cannot reach server at ${e} (${T(s)}) \u2014 check the --server URL or network/proxy`)}}async function ps(e){let t=await ms(e.serverUrl,"/api/machine/enroll",{deviceId:In(),name:e.name??(0,Ee.hostname)(),teamId:e.team},"[desk] enroll",e.apiKey);if(!t.ok)throw new Error(`Enroll failed: ${await us(t)}`);ds(e.serverUrl,await t.json())}async function fs(e){let t=await ms(e.serverUrl,"/api/machine/enroll/start",{deviceId:In(),name:e.name??(0,Ee.hostname)(),clientInfo:{platform:(0,Ee.platform)(),hostname:(0,Ee.hostname)()}},"[desk] enroll start");if(!t.ok)throw new Error(`Enroll start failed: ${await us(t)}`);let{requestId:n,verificationUrl:r}=await t.json();console.log(""),console.log("[desk] To authorize this machine, open this URL in a browser and pick your team:"),console.log(""),console.log(` ${r}`),console.log(""),console.log("[desk] Waiting for authorization (expires in 3 minutes)\u2026"),Pa(r);let o=Date.now()+18e4;for(;Date.now()<o;){await Ma(2e3);let s=await I(e.serverUrl,"/api/machine/enroll/poll",{body:{requestId:n},timeoutMs:f.enrollPoll}).catch(()=>null);if(!s?.ok)continue;let a=await s.json();if(a.status==="ready"&&a.machineId&&a.token&&a.teamId){ds(e.serverUrl,{machineId:a.machineId,teamId:a.teamId,token:a.token});return}if(a.status==="expired")break}throw new Error("Authorization timed out. Run `desk start` to try again.")}async function It(e){let{flags:t,bools:n}=he(e,{f:"foreground"});if(n.supervisor)return tr(e);if(!n.foreground){let r=re();r&&z(r.pid)&&(console.error(`[desk] Already running (pid ${r.pid}). Use 'desk restart' or 'desk stop'.`),process.exit(1))}try{_a(t,n),await xr(),Zt()}catch(r){console.error(`[desk] Cannot start: ${T(r)}`),process.exit(1)}if(n.foreground){ge();let{config:r,serverUrl:o}=await gs(t);return Ia(r,o)}return Ca(e,t)}function _a(e,t){if(t["workspaces-dir"])throw new Error("--workspaces-dir requires a path");let n=e["workspaces-dir"];if(n===void 0)return;let r=ot(n);if(!(0,Ct.isAbsolute)(r))throw new Error(`--workspaces-dir must be an absolute path (got: ${n})`);let o=process.env.DESK_WORKSPACES_DIR;if(o&&o!==r&&console.warn(`[desk] Note: DESK_WORKSPACES_DIR=${o} is set and takes precedence while present.`),r!==_e().workspacesDir){if(!(0,Re.existsSync)((0,Ct.dirname)(r)))throw new Error(`parent of ${r} does not exist \u2014 mount the drive (or create the parent) first`);try{(0,Re.mkdirSync)(r)}catch(s){if(s.code!=="EEXIST")throw s}if(!(0,Re.statSync)(r).isDirectory())throw new Error(`${r} exists and is not a directory`);dr({workspacesDir:r}),console.log(`[desk] Workspaces dir set to ${r} (persisted). Existing clones are not moved; the old location can be deleted manually.`)}}var _t=class extends Error{};async function gs(e){let t=q(),n=e.server??process.env.DESK_SERVER??t?.serverUrl??"https://desk-web-nu.vercel.app",r=e["api-key"]??process.env.DESK_API_KEY;return(!t||r)&&(t&&console.warn(`[machine] Overwriting existing registration (machine ${t.machineId}, team ${t.teamId}).`),t=await ys(n,e)),{config:t,serverUrl:n}}async function ys(e,t){let n=t["api-key"]??process.env.DESK_API_KEY,r=t.team??process.env.DESK_TEAM,o=t.name;return n?(r||(console.error("[machine] --api-key requires --team <id> (or set DESK_TEAM)."),process.exit(1)),await ps({serverUrl:e,apiKey:n,team:r,name:o})):await fs({serverUrl:e,name:o}),q()}async function hs(e,t){let n;try{n=await F(()=>I(e,"/api/machine/presence",{token:t,body:{load:0},timeoutMs:f.statusProbe}),B,"[desk] preflight")}catch(r){throw new Error(`cannot reach server at ${e} (${T(r)}) \u2014 check the --server URL or network/proxy`)}if(He(n.status))throw new _t(`server rejected this machine's token (HTTP ${n.status})`);if(!n.ok)throw new Error(`unexpected response from ${e} (HTTP ${n.status}) \u2014 is this the right --server URL?`)}async function Ca(e,t){let n=await gs(t),r=n.serverUrl,o=n.config;try{await hs(r,o.token)}catch(a){if(a instanceof _t){console.warn(`[desk] ${a.message} \u2014 logging in again.`),o=await ys(r,t);try{await hs(r,o.token)}catch(i){console.error(`[desk] Cannot start: ${T(i)}`),process.exit(1)}}else console.error(`[desk] Cannot start: ${T(a)}`),process.exit(1)}let s=Qe("start",["--supervisor",...e]);Qn({pid:s,startedAt:Date.now()}),console.log(`[desk] Started in background (pid ${s}).`),console.log("[desk] Logs: desk logs -f Status: desk status Stop: desk stop"),process.exit(0)}async function Ia(e,t){console.log(`[machine] Starting machine ${e.machineId}`),console.log(`[machine] Workspaces dir: ${Q()}`),To(),console.log("[machine] Loading pi runtime\u2026"),await Ie();let n=process.env.DESK_DISABLE_TUNNEL==="1",r=new ut(t,e.token);n||r.start();let o=new $t(t,e.machineId,e.token,r),s=n?null:new Pt(t,e.token,e.machineId);s&&(s.onHealthChanged=()=>o.pokePresence(),o.getMountSync=()=>s.status(),o.getExecSync=()=>s.execStatus(),o.onMounts=i=>s.setMounts(i),o.onExecTargets=i=>s.setExecTargets(i)),await ns(),o.start(),as();let a=async()=>{console.log(`
25
- [machine] Shutting down\u2026`);let i=o.runningCount();i>0&&console.warn(`[machine] ${i} task(s) still running \u2014 they will be interrupted`),o.stop(),r.stop(),s?.stop(),await o.reportOffline().catch(()=>{}),setTimeout(()=>process.exit(0),200)};process.on("SIGINT",()=>{a().catch(()=>process.exit(1))}),process.on("SIGTERM",()=>{a().catch(()=>process.exit(1))})}var ks=require("child_process");function ws(e,t){process.platform==="win32"?(0,ks.spawnSync)("taskkill",["/PID",String(e),"/T","/F"],{stdio:"ignore",windowsHide:!0}):process.kill(e,t?"SIGKILL":"SIGTERM")}async function $e(){let e=re();if(!e||!z(e.pid)){e&&Ve(),console.log("[desk] Not running.");return}try{ws(e.pid,!1)}catch{}let t=Date.now()+6e3;for(;Date.now()<t&&z(e.pid);)await oe(150);if(z(e.pid)){console.warn("[desk] Did not stop in time; force-killing.");try{ws(e.pid,!0)}catch{}}Ve(),console.log("[desk] Stopped.")}var Aa=6e4,Da=new Set(["--helper"]);async function Ss(e){let{bools:t}=he(e),n=Xe(e,Da);if(t.helper)return ge(),console.log("[desk] restart helper: stopping daemon"),await $e(),It(n);q()||(console.error("[desk] This machine is not enrolled yet \u2014 run 'desk start' instead."),process.exit(1));let r=Date.now(),o=Qe("restart",["--helper",...n]);console.log(`[desk] Restarting via detached helper (pid ${o}) \u2014 completes even if this shell dies with the daemon.`);let s=()=>{let i=re();return i&&i.startedAt>=r&&z(i.pid)?i:null},a=r+Aa;for(;Date.now()<a;){let i=z(o),c=s();if(c){console.log(`[desk] Restarted (pid ${c.pid}).`);return}i||(console.error("[desk] Restart failed \u2014 see the log: desk logs"),process.exit(1)),await oe(250)}console.warn("[desk] Restart is still in progress \u2014 check with: desk status / desk logs")}var X=require("fs");var Oa=200,La=256*1024,Fa=500;function bs(e,t,n){let r=Buffer.alloc(n-t),o=0;for(;o<r.length;){let s=(0,X.readSync)(e,r,o,r.length-o,t+o);if(s===0)break;o+=s}return r.subarray(0,o)}function Ua(e){let t=(0,X.fstatSync)(e).size,n=Math.max(0,t-La),r=bs(e,n,t).toString("utf8").split(`
26
- `);n>0&&(r=r.slice(1)),r[r.length-1]===""&&(r=r.slice(0,-1));let o=r.slice(-Oa);return o.length&&process.stdout.write(o.join(`
30
+ `),we.length?{images:we}:void 0),await X.idle(),await lt}await pt(),await R(yr())}}catch(S){if(await X.idle().catch(()=>{}),u)console.log(`[step] ${o} interrupted \u2014 saving partial content`),await pt(),await R(yr());else{let D=S instanceof Error?S.message:String(S);console.error(`[step] ${o} failed:`,D),await pt().catch(F=>console.error(`[step] ${o} failed-turn checkpoint:`,F.message)),await R({error:D,...an()})}}finally{if(_||As(s,()=>Lt(s,Y.sessionFile,e.sessionBackupUrl,()=>l().then(S=>S?.sessionBackupUrl))),e.workspace){let S=As(s,async()=>{Ee.get(s)===S&&await Yr(k,o)})}X.dispose()}}finally{T(),await Jo($)}}async function _c(e,t,n){let{stepId:r,conversationId:o}=e;console.log(`[restore] ${r} start (conv ${o})`);let s=rr(e,t,n),i,a,c=async()=>{let p=await Os(e);if(!p||!e.workspace)return;let{defaultBranch:g,installationToken:x,gitHost:A}=e.workspace;await xt(p,x,he(o),A,{rewind:!0}),a={ok:!0},i=await Dn(p,g,r)},l=async()=>{let p=await xc(e);p&&await Lt(o,p,e.sessionBackupUrl)},[u,d]=await Promise.allSettled([c(),l()]),m=[u,d].find(p=>p.status==="rejected");if(m){let p=m.reason instanceof Error?m.reason.message:String(m.reason);console.error(`[restore] ${r} failed:`,p),await s({error:p});return}await s({diffHash:i,pushOutcome:a,...Is(a)}),console.log(`[restore] ${r} done`)}async function $c(e,t,n){let{stepId:r,conversationId:o}=e;console.log(`[compact] ${r} start (conv ${o})`);let s=rr(e,t,n),i=Cs(t,n,r),a=async()=>{};try{let c=await Ye(),{sdk:l,agentDir:u}=c,d=await jn(l,e);if(!d.ok){await s({error:d.error});return}let m=await Un({sdk:l,sessionKey:o,cwd:u,restoreUrl:e.sessionRestoreUrl});if(!m.isContinue){await s({contextUsage:void 0});return}let p=await Ds(c,{modelRuntime:d.runtime,cwd:u,tools:[],sessionManager:m.sessionManager,thinkingLevel:e.agent.thinkingLevel??"",webSearch:!1}),g=[],x=p.agent.streamFunction;p.agent.streamFunction=($,R,E)=>{let b=p.thinkingLevel,I=Promise.resolve(x($,R,E));return g.push(I.then(async y=>zn(await y.result(),b)).catch(()=>null)),I},a=async()=>{let $=(await Promise.all(g)).filter(R=>R!==null);return $.length?$:void 0};let A=!1,T=Yn(t,r,()=>{A=!0,p.abortCompaction()},n,void 0,2e3);try{let $;try{$=await p.compact()}catch(E){if(!A)throw E;console.log(`[compact] ${r} cancelled (aborted)`),await s({error:"Cancelled",modelCalls:await a()});return}let R=await s({contextUsage:p.getContextUsage(),tokensBefore:$?.tokensBefore,modelCalls:await a()});R&&R.owned===!1?console.log(`[compact] ${r} superseded after compaction \u2014 discarding`):(await Lt(o,p.sessionFile,e.sessionBackupUrl,()=>i().then(E=>E?.sessionBackupUrl)),console.log(`[compact] ${r} done (before ~${$?.tokensBefore} tokens)`))}finally{T()}}catch(c){let l=c instanceof Error?c.message:String(c);console.error(`[compact] ${r} failed:`,l),await s({error:l,modelCalls:await a()})}}function nt(e){return e===401}var Us=require("eventsource");ue();var Ns=2e3,Mc=3e4,Fs=Wr*5,Yt=class{constructor(t,n,r,o,s,i){this.serverUrl=t;this.token=n;this.onWake=r;this.onConfig=o;this.onHealthChange=s;this.onSteer=i}es=null;stopped=!0;healthy=!1;reconnectDelay=Ns;reconnectTimer=null;watchdog=null;start(){this.stopped&&(this.stopped=!1,this.connect())}stop(){this.stopped=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.es?.close(),this.es=null,this.setHealthy(!1)}isHealthy(){return this.healthy}connect(){let t=new Us.EventSource(`${this.serverUrl}/api/machine/stream`,{fetch:(n,r)=>fetch(n,{...r,headers:{...r?.headers,...At(this.token)}})});this.es=t,t.onopen=()=>{this.es===t&&(this.reconnectDelay=Ns,this.setHealthy(!0),this.onWake(),this.armWatchdog(t))},t.onmessage=n=>{if(this.es!==t)return;this.armWatchdog(t);let r;try{r=JSON.parse(n.data)}catch{return}r.type==="wake"?this.onWake():r.type==="config"?this.onConfig():r.type==="steer"&&this.onSteer(typeof r.stepId=="string"?r.stepId:void 0)},t.onerror=()=>{this.es===t&&this.dropAndRetry()}}armWatchdog(t){this.watchdog&&clearTimeout(this.watchdog),this.watchdog=setTimeout(()=>{this.es===t&&(console.warn(`[wake] no frame in ${Fs/1e3}s \u2014 forcing reconnect`),this.dropAndRetry())},Fs)}dropAndRetry(){this.es?.close(),this.es=null,this.watchdog&&(clearTimeout(this.watchdog),this.watchdog=null),this.setHealthy(!1),!this.stopped&&(this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.stopped||this.connect()},this.reconnectDelay),this.reconnectDelay=Math.min(this.reconnectDelay*2,Mc))}setHealthy(t){this.healthy!==t&&(this.healthy=t,t?console.log("[wake] push channel connected"):this.stopped||console.log("[wake] push channel down \u2014 continuous long-poll fallback"),this.onHealthChange(t))}};ue();U();ge();var Ac="https://registry.npmjs.org/@deskdev/cli/latest",Ic=36e5,Ie=null,Hs=0,rt=null;function js(){return Ie&&Date.now()-Hs<Ic?Promise.resolve(Ie):rt||(rt=Cc().finally(()=>{rt=null}),rt)}async function Cc(){try{let e=await q(Ac,5e3);if(!e.ok)return Ie;let t=await e.json();if(typeof t.version=="string")return Ie=t.version,Hs=Date.now(),Ie}catch{}return Ie}function Bs(){return Ie}ue();sr();async function Js(e,t,n,r={}){if(Cr(e.stepId)!==e.requestId)throw new Error("invalid branch sync job");let o=new AbortController,s=r.signal?AbortSignal.any([r.signal,o.signal]):o.signal,i=r.send??(async(l,u,d)=>{let m=await N(t,l,{body:u,signal:d,token:n,timeoutMs:15e3});if(!m.ok)throw Te(m);return m.json()}),a=r.send?(l,u,d)=>i(u,d):void 0,c=await jc(async()=>{if(await Jt(t,n,e.stepId,a))return null;let l=e.claim;if(!l||l.request.requestId!==e.requestId||l.request.machineId!==e.machineId||l.request.teamId!==e.teamId)throw new Ce("request_not_running");let u=null,d=()=>u||(u=i(`/api/machine/heartbeat/${e.stepId}`,{},s).then(p=>{if(p?.stop)throw new Error("lease unavailable")}).catch(p=>{throw o.abort(),p}).finally(()=>{u=null}),u),m=setInterval(()=>{d().catch(()=>{})},2e4);try{return s.throwIfAborted(),await(r.checkout??or)(l,{signal:s,beforeWrite:d}),s.throwIfAborted(),{requestId:e.requestId,state:"succeeded"}}finally{clearInterval(m),u&&await Promise.resolve(u).catch(()=>{})}},r.lockRoot).catch(l=>({requestId:e.requestId,state:s.aborted?"interrupted":"failed",error:s.aborted?"lease_expired":l instanceof Ce?l.code:"sync_failed"}));return c&&await zt(t,n,e.stepId,{mode:"branch_sync",...c},a),c}async function jc(e,t){let{withBranchSyncLock:n}=await Promise.resolve().then(()=>(sr(),zs));return t===void 0?n(e):n(e,t)}var Vt=class e{constructor(t,n,r,o){this.serverUrl=t,this.machineId=n,this.token=r,this.tunnel=o}running=!1;abortController=new AbortController;runningTasks=new Map;presenceTimer=null;gcTimer=null;flushTimer=null;pokeTimer=null;lastSentTunnelKey;lastSentTunnelError;lastSentWorkspacesDir;sentPlatform=!1;revoked=!1;maxConcurrentTasks=null;wakeChannel=null;wakeResolve=null;wakePending=!1;getExecSync;onExecTargets;onServeWanted;lastPresenceWarnAt=0;start(){this.running=!0,this.abortController=new AbortController,this.tunnel.setNodeChangeHandler(()=>void this.reportPresence()),this.startPresenceHeartbeat(),this.wakeChannel||(this.wakeChannel=new Yt(this.serverUrl,this.token,()=>this.onWake(),()=>this.pokePresence(),()=>this.wakeResolve?.(),t=>Wt(t))),this.wakeChannel?.start(),console.log(`[machine] Online (machineId=${this.machineId}); polling ${this.serverUrl}`),this.startHousekeeping(),this.startOutboxFlush(),er(this.serverUrl,this.token).then(()=>this.recover()).then(()=>this.loop())}startOutboxFlush(){this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=setInterval(()=>void er(this.serverUrl,this.token),6e4)}pokePresence(){this.pokeTimer||(this.pokeTimer=setTimeout(()=>{this.pokeTimer=null,this.reportPresence()},250))}async recover(){try{let t=await N(this.serverUrl,"/api/machine/recover",{method:"POST",token:this.token,timeoutMs:f.recover});if(!t.ok){console.warn(`[recover] HTTP ${t.status}`);return}let n=await t.json();n.recovered>0?console.log(`[recover] re-queued ${n.recovered} step(s)`):console.log("[recover] no pending steps found")}catch(t){console.error("[recover] failed:",t.message)}}stop(){this.running=!1,this.abortController.abort(),this.wakeChannel?.stop(),this.presenceTimer&&(clearInterval(this.presenceTimer),this.presenceTimer=null),this.gcTimer&&(clearInterval(this.gcTimer),this.gcTimer=null),this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.pokeTimer&&(clearTimeout(this.pokeTimer),this.pokeTimer=null)}handleRevoked(t){this.revoked||(this.revoked=!0,console.error(`[machine] No longer registered (HTTP ${t}) \u2014 removed from team or token revoked. Shutting down.`),this.stop(),process.exit(mn))}startPresenceHeartbeat(){this.presenceTimer&&clearInterval(this.presenceTimer);let t=()=>void this.reportPresence();t(),this.presenceTimer=setInterval(t,2e4)}startHousekeeping(){this.gcTimer&&clearInterval(this.gcTimer);let t=()=>{Fo().catch(()=>{}),mo().catch(()=>{})};t(),this.gcTimer=setInterval(t,24*36e5)}tunnelSnapshot(){let t=this.tunnel.current();return{node:t,key:t?`${t.tailnetAddr}
31
+ ${t.sshHostKey}`:null}}async reportPresence(){try{let t={load:this.runningTasks.size},n=Bs();n&&(t.latestCliVersion=n);let r=this.getExecSync?.();r&&(t.execSync=r);let{node:o,key:s}=this.tunnelSnapshot();s!==this.lastSentTunnelKey&&(t.sshHostKey=o?.sshHostKey??null,t.tailnetAddr=o?.tailnetAddr??null);let i=o?null:this.tunnel.lastError();i!==this.lastSentTunnelError&&(t.tunnelError=i);let a=Q();a!==this.lastSentWorkspacesDir&&(t.workspacesDir=a),this.sentPlatform||(t.platform=process.platform,t.arch=process.arch,t.runner=process.env.DESK_RUNNER==="desktop"?"desktop":"cli");let c=await N(this.serverUrl,"/api/machine/presence",{token:this.token,body:t,timeoutMs:f.presence});if(nt(c.status))return this.handleRevoked(c.status);if(c.ok){let l=await c.json().catch(()=>null),u=Br(l?.maxConcurrentTasks);u!=null&&u!==this.maxConcurrentTasks&&(console.log(`[machine] maxConcurrent changed ${this.maxConcurrentTasks} -> ${u}`),this.maxConcurrentTasks=u),Array.isArray(l?.execTargets)&&this.onExecTargets?.(l.execTargets),typeof l?.serveWanted=="boolean"&&this.onServeWanted?.(l.serveWanted),o&&s===this.lastSentTunnelKey&&l?.tailnetAddr===null&&this.tunnel.rejoin(),this.lastSentTunnelKey=s,this.lastSentTunnelError=i,this.lastSentWorkspacesDir=a,this.sentPlatform=!0}}catch(t){jt(),Date.now()-this.lastPresenceWarnAt>3e5&&(this.lastPresenceWarnAt=Date.now(),console.warn(`[machine] presence beat failed: ${t instanceof Error?t.message:String(t)}`))}}async reportOffline(){try{await N(this.serverUrl,"/api/machine/presence",{token:this.token,body:{offline:!0},timeoutMs:f.presenceOffline})}catch{}}runningCount(){return this.runningTasks.size}async loop(){let t=2e3;for(;this.running;)try{let n=this.maxConcurrentTasks??1;if(this.runningTasks.size>=n){await Promise.race([...this.runningTasks.values(),ir(2e3,this.abortController.signal)]);continue}let r=await this.claimOnce();t=2e3,!r&&this.wakeChannel?.isHealthy()&&await this.parkForWake()}catch(n){if(!this.running)break;let r=n instanceof Error?n.message:String(n);console.error(`[machine] Claim error: ${r} \u2014 retrying in ${t/1e3}s`),await ir(t,this.abortController.signal),t=Math.min(t*2,3e4)}}static PARK_MAX_MS=45e3;onWake(){this.wakeResolve?this.wakeResolve():this.wakePending=!0}async parkForWake(){if(this.wakePending){this.wakePending=!1;return}let t=new Promise(n=>{this.wakeResolve=n});try{await Promise.race([t,ir(e.PARK_MAX_MS,this.abortController.signal)])}finally{this.wakeResolve=null}}async claimOnce(){let t=await N(this.serverUrl,"/api/machine/tasks/claim",{token:this.token,body:{load:this.runningTasks.size},signal:this.abortController.signal,timeoutMs:f.claim});if(nt(t.status))return this.handleRevoked(t.status),!1;if(!t.ok)throw new Error(`Claim HTTP ${t.status}`);let n=await t.json();if(console.log(`[machine] claim step=${n?n.stepId:"null"} (running=${this.runningTasks.size})`),!n)return!1;if(this.runningTasks.has(n.stepId))return console.warn(`[machine] step ${n.stepId} already running \u2014 skipping duplicate claim`),!0;let o=(fn(n)?Js(n,this.serverUrl,this.token,{signal:this.abortController.signal}):Ls(n,this.serverUrl,this.token,this.tunnel)).catch(s=>{console.error(`[machine] step ${n.stepId} crashed:`,s instanceof Error?s.message:String(s))}).finally(()=>{this.runningTasks.get(n.stepId)===o&&this.runningTasks.delete(n.stepId),this.reportPresence(),console.log(`[machine] step ${n.stepId} finished (${this.runningTasks.size}/${this.maxConcurrentTasks} running)`)});return this.runningTasks.set(n.stepId,o),this.reportPresence(),console.log(`[machine] step ${n.stepId} for ${fn(n)?"branch sync":`conv ${n.conversationId}`} (${this.runningTasks.size}/${this.maxConcurrentTasks} running)`),!0}};function ir(e,t){return new Promise(n=>{let r=()=>{clearTimeout(o),n()},o=setTimeout(()=>{t?.removeEventListener("abort",r),n()},e);t?.addEventListener("abort",r,{once:!0})})}var Qt=class{sidecar;active=!1;targets=[];health=new Map;sidecarError=null;onHealthChanged=null;constructor(t,n,r){this.sidecar=new Ue(["mirror","--server",t,"--token",n,"--machine",r],"shell",o=>this.onEvent(o),()=>this.markDown("tunnel daemon restarting")),this.sidecar.onSpawnFailure=o=>this.noteError(o)}stop(){this.active=!1,this.sidecar.stop()}setExecTargets(t){this.targets=t;let n=new Set(t.map(r=>r.machineId));for(let r of this.health.keys())n.has(r)||this.health.delete(r);t.length&&!this.active?(this.active=!0,this.sidecar.start()):!t.length&&this.active&&(this.active=!1,this.sidecar.stop()),this.sendTargets()}execStatus(){return this.targets.length?[...new Set(this.targets.map(t=>t.machineId))].map(t=>{let n=this.health.get(t),r=n??this.sidecarError;return{builderMachineId:t,connected:n===null&&!this.sidecarError,...r?{error:r}:{}}}):null}markDown(t){let n=!1;for(let[r,o]of this.health)o===null&&(this.health.set(r,t),n=!0);n&&this.onHealthChanged?.()}noteError(t){this.sidecarError!==t&&(this.sidecarError=t,this.onHealthChanged?.())}onEvent(t){if(t.event==="up")this.sidecar.resetBackoff(),this.sidecarError&&(this.sidecarError=null,this.onHealthChanged?.()),this.sendTargets();else if((t.event==="exec-connected"||t.event==="exec-reconnecting")&&t.machine){if(!this.targets.some(n=>n.machineId===t.machine))return;this.health.set(t.machine,t.event==="exec-connected"?null:t.message??"reconnecting"),this.onHealthChanged?.()}else t.event==="error"&&this.noteError(t.message??"tunnel error")}sendTargets(){this.sidecar.write({cmd:"exec",targets:this.targets})}};var Ys=require("node:child_process");function Xs(){if(process.platform==="darwin")try{let e=(0,Ys.spawn)("caffeinate",["-i","-w",String(process.pid)],{stdio:"ignore"});e.on("error",t=>console.warn(`[machine] idle-sleep prevention unavailable: ${t.message}`)),e.unref(),console.log("[machine] Idle-sleep prevention active (caffeinate)")}catch(e){console.warn(`[machine] idle-sleep prevention unavailable: ${e.message}`)}}var Qs=require("child_process"),je=require("os");ve();U();var Zt=require("crypto"),Re=require("fs"),Vs=require("os");K();var ar=()=>j("device.json");function cr(){if((0,Re.existsSync)(ar()))try{let n=JSON.parse((0,Re.readFileSync)(ar(),"utf-8"));if(n.deviceId)return n.deviceId}catch{}let e=(0,Zt.randomBytes)(16).toString("hex"),t=(0,Zt.createHash)("sha256").update(`${(0,Vs.hostname)()}:${e}`).digest("hex").slice(0,32);return(0,Re.mkdirSync)(oe(),{recursive:!0}),(0,Re.writeFileSync)(ar(),JSON.stringify({deviceId:t},null,2),{mode:384}),t}K();de();function Bc(e){let t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;(0,Qs.exec)(t,()=>{})}var Wc=e=>new Promise(t=>setTimeout(t,e));async function Zs(e){return(await e.json().catch(()=>({}))).error??String(e.status)}function ei(e,t){Tr({machineId:t.machineId,token:t.token,teamId:t.teamId,serverUrl:e}),console.log(`[desk] Enrolled in team ${t.teamId} (machine ${t.machineId}).`)}async function ti(e,t,n,r,o){try{return await G(()=>N(e,t,{token:o,body:n,timeoutMs:f.enroll}),V,r)}catch(s){throw new Error(`cannot reach server at ${e} (${O(s)}) \u2014 check the --server URL or network/proxy`)}}async function ni(e){let t=await ti(e.serverUrl,"/api/machine/enroll",{deviceId:cr(),name:e.name??(0,je.hostname)(),teamId:e.team},"[desk] enroll",e.apiKey);if(!t.ok)throw new Error(`Enroll failed: ${await Zs(t)}`);ei(e.serverUrl,await t.json())}async function ri(e){let t=await ti(e.serverUrl,"/api/machine/enroll/start",{deviceId:cr(),name:e.name??(0,je.hostname)(),clientInfo:{platform:(0,je.platform)(),hostname:(0,je.hostname)()}},"[desk] enroll start");if(!t.ok)throw new Error(`Enroll start failed: ${await Zs(t)}`);let{requestId:n,verificationUrl:r}=await t.json();console.log(""),console.log("[desk] To authorize this machine, open this URL in a browser and pick your team:"),console.log(""),console.log(` ${r}`),console.log(""),console.log("[desk] Waiting for authorization (expires in 3 minutes)\u2026"),Bc(r);let o=Date.now()+18e4;for(;Date.now()<o;){await Wc(2e3);let s=await N(e.serverUrl,"/api/machine/enroll/poll",{body:{requestId:n},timeoutMs:f.enrollPoll}).catch(()=>null);if(!s?.ok)continue;let i=await s.json();if(i.status==="ready"&&i.machineId&&i.token&&i.teamId){ei(e.serverUrl,{machineId:i.machineId,teamId:i.teamId,token:i.token});return}if(i.status==="expired")break}throw new Error("Authorization timed out. Run `desk start` to try again.")}async function nn(e){let{flags:t,bools:n}=De(e,{f:"foreground"});if(n.supervisor)return Ar(e);if(!n.foreground){let r=ke();r&&ie(r.pid)&&(console.error(`[desk] Already running (pid ${r.pid}). Use 'desk restart' or 'desk stop'.`),process.exit(1))}try{Kc(t,n),await so(),En()}catch(r){console.error(`[desk] Cannot start: ${O(r)}`),process.exit(1)}if(n.foreground){Le();let{config:r,serverUrl:o}=await si(t);return qc(r,o)}return Gc(e,t)}function Kc(e,t){if(t["workspaces-dir"])throw new Error("--workspaces-dir requires a path");let n=e["workspaces-dir"];if(n===void 0)return;let r=Je(n);if(!(0,tn.isAbsolute)(r))throw new Error(`--workspaces-dir must be an absolute path (got: ${n})`);let o=process.env.DESK_WORKSPACES_DIR;if(o&&o!==r&&console.warn(`[desk] Note: DESK_WORKSPACES_DIR=${o} is set and takes precedence while present.`),r!==qe().workspacesDir){if(!(0,Be.existsSync)((0,tn.dirname)(r)))throw new Error(`parent of ${r} does not exist \u2014 mount the drive (or create the parent) first`);try{(0,Be.mkdirSync)(r)}catch(s){if(s.code!=="EEXIST")throw s}if(!(0,Be.statSync)(r).isDirectory())throw new Error(`${r} exists and is not a directory`);qr({workspacesDir:r}),console.log(`[desk] Workspaces dir set to ${r} (persisted). Existing clones are not moved; the old location can be deleted manually.`)}}var en=class extends Error{};async function si(e){let t=se(),n=e.server??process.env.DESK_SERVER??t?.serverUrl??"https://desk-web-nu.vercel.app",r=e["api-key"]??process.env.DESK_API_KEY;return(!t||r)&&(t&&console.warn(`[machine] Overwriting existing registration (machine ${t.machineId}, team ${t.teamId}).`),t=await ii(n,e)),{config:t,serverUrl:n}}async function ii(e,t){let n=t["api-key"]??process.env.DESK_API_KEY,r=t.team??process.env.DESK_TEAM,o=t.name;return n?(r||(console.error("[machine] --api-key requires --team <id> (or set DESK_TEAM)."),process.exit(1)),await ni({serverUrl:e,apiKey:n,team:r,name:o})):await ri({serverUrl:e,name:o}),se()}async function oi(e,t){let n;try{n=await G(()=>N(e,"/api/machine/presence",{token:t,body:{load:0},timeoutMs:f.statusProbe}),V,"[desk] preflight")}catch(r){throw new Error(`cannot reach server at ${e} (${O(r)}) \u2014 check the --server URL or network/proxy`)}if(nt(n.status))throw new en(`server rejected this machine's token (HTTP ${n.status})`);if(!n.ok)throw new Error(`unexpected response from ${e} (HTTP ${n.status}) \u2014 is this the right --server URL?`)}async function Gc(e,t){let n=await si(t),r=n.serverUrl,o=n.config;try{await oi(r,o.token)}catch(i){if(i instanceof en){console.warn(`[desk] ${i.message} \u2014 logging in again.`),o=await ii(r,t);try{await oi(r,o.token)}catch(a){console.error(`[desk] Cannot start: ${O(a)}`),process.exit(1)}}else console.error(`[desk] Cannot start: ${O(i)}`),process.exit(1)}let s=wt("start",["--supervisor",...e]);Pr({pid:s,startedAt:Date.now(),runner:"cli"}),console.log(`[desk] Started in background (pid ${s}).`),console.log("[desk] Logs: desk logs -f Status: desk status Stop: desk stop"),process.exit(0)}async function qc(e,t){console.log(`[machine] Starting machine ${e.machineId}`),console.log(`[machine] Workspaces dir: ${Q()}`),is(),console.log("[machine] Loading pi runtime\u2026"),await Ye();let n=process.env.DESK_DISABLE_TUNNEL==="1",r=new Mt(t,e.token),o=new Vt(t,e.machineId,e.token,r),s=n?null:new Qt(t,e.token,e.machineId);s&&(o.onServeWanted=l=>r.setWanted(l),s.onHealthChanged=()=>o.pokePresence(),o.getExecSync=()=>s.execStatus(),o.onExecTargets=l=>s.setExecTargets(l)),await js(),o.start(),Xs();let i=!1,a=async()=>{if(i)return;i=!0,console.log(`
32
+ [machine] Shutting down\u2026`);let l=o.runningCount();l>0&&console.warn(`[machine] ${l} task(s) still running \u2014 they will be interrupted`),o.stop(),r.stop(),s?.stop(),await o.reportOffline().catch(()=>{}),setTimeout(()=>process.exit(0),200)};process.on("SIGINT",()=>{a().catch(()=>process.exit(1))}),process.on("SIGTERM",()=>{a().catch(()=>process.exit(1))});let c=process.parentPort;c&&(c.postMessage({type:"ready",machineId:e.machineId}),setInterval(()=>c.postMessage({type:"load",running:o.runningCount()}),5e3).unref(),c.on("message",l=>{l.data?.type==="shutdown"&&a().catch(()=>process.exit(1))}))}var ci=require("child_process");function ai(e,t){process.platform==="win32"?(0,ci.spawnSync)("taskkill",["/PID",String(e),"/T","/F"],{stdio:"ignore",windowsHide:!0}):process.kill(e,t?"SIGKILL":"SIGTERM")}async function We(){let e=ke();if(!e||!ie(e.pid)){e&&yt(),console.log("[desk] Not running.");return}try{ai(e.pid,!1)}catch{}let t=Date.now()+6e3;for(;Date.now()<t&&ie(e.pid);)await Se(150);if(ie(e.pid)){console.warn("[desk] Did not stop in time; force-killing.");try{ai(e.pid,!0)}catch{}}yt(),console.log("[desk] Stopped.")}K();var zc=6e4,Jc=new Set(["--helper"]);async function li(e){let{bools:t}=De(e),n=ht(e,Jc);if(t.helper)return Le(),console.log("[desk] restart helper: stopping daemon"),await We(),nn(n);se()||(console.error("[desk] This machine is not enrolled yet \u2014 run 'desk start' instead."),process.exit(1));let r=Date.now(),o=wt("restart",["--helper",...n]);console.log(`[desk] Restarting via detached helper (pid ${o}) \u2014 completes even if this shell dies with the daemon.`);let s=()=>{let a=ke();return a&&a.startedAt>=r&&ie(a.pid)?a:null},i=r+zc;for(;Date.now()<i;){let a=ie(o),c=s();if(c){console.log(`[desk] Restarted (pid ${c.pid}).`);return}a||(console.error("[desk] Restart failed \u2014 see the log: desk logs"),process.exit(1)),await Se(250)}console.warn("[desk] Restart is still in progress \u2014 check with: desk status / desk logs")}var ce=require("fs");var Yc=200,Xc=256*1024,Vc=500;function ui(e,t,n){let r=Buffer.alloc(n-t),o=0;for(;o<r.length;){let s=(0,ce.readSync)(e,r,o,r.length-o,t+o);if(s===0)break;o+=s}return r.subarray(0,o)}function Qc(e){let t=(0,ce.fstatSync)(e).size,n=Math.max(0,t-Xc),r=ui(e,n,t).toString("utf8").split(`
33
+ `);n>0&&(r=r.slice(1)),r[r.length-1]===""&&(r=r.slice(0,-1));let o=r.slice(-Yc);return o.length&&process.stdout.write(o.join(`
27
34
  `)+`
28
- `),t}async function vs(e){let{bools:t}=he(e,{f:"follow"}),n=Ye();if(!(0,X.existsSync)(n)){console.log(`[desk] No log file yet (${n}). Run 'desk start' first.`);return}console.error(`[desk] ${n}`);let r=(0,X.openSync)(n,"r");try{let o=Ua(r);for(;t.follow;){await oe(Fa);let s=(0,X.fstatSync)(r).size;s<o&&(o=0),s>o&&(process.stdout.write(bs(r,o,s)),o=s)}}finally{(0,X.closeSync)(r)}}async function Ts(){let e=q();await $e(),Yn(),console.log(e?`[desk] Logged out (was machine ${e.machineId}, team ${e.teamId}).`:"[desk] No local registration found."),console.log("[desk] Run 'desk start' to enroll again.")}var xs=require("fs");async function Es(){let e=re();if(e&&z(e.pid)){let s=e.startedAt?new Date(e.startedAt).toLocaleString():"unknown";console.log(`[desk] Daemon: running (pid ${e.pid}, since ${s})`)}else console.log("[desk] Daemon: not running");let t=tt()&&!(0,xs.existsSync)(Q());console.log(`[desk] Workspaces: ${Q()}${t?" (not found \u2014 is the drive mounted?)":""}`);let n=q();if(!n){console.log("[desk] Not registered. Run: desk start");return}let r;try{r=await I(n.serverUrl,"/api/machine/me",{token:n.token,timeoutMs:f.statusProbe})}catch(s){console.log(`[desk] Machine: ${n.machineId}`),console.log(`[desk] Server: ${n.serverUrl} (unreachable: ${T(s)})`);return}if(!r.ok){console.log(`[desk] Machine: ${n.machineId}`),console.log(`[desk] Server: ${n.serverUrl} (unreachable: ${r.status})`);return}let o=await r.json();console.log(`[desk] Machine: ${o.name} (${o.machineId})`),console.log(`[desk] Team: ${o.teamId}`),console.log(`[desk] Agents: ${o.agentIds.length?o.agentIds.join(", "):"(none \u2014 create one in the web UI)"}`),console.log(`[desk] Server: ${n.serverUrl}`)}async function Rs(){console.log(`desk ${Z()}`)}var me={start:{run:It,longLived:!0,summary:"Bring this machine online in the background (enroll if needed)",help:`Usage: desk start [options]
35
+ `),t}async function di(e){let{bools:t}=De(e,{f:"follow"}),n=gt();if(!(0,ce.existsSync)(n)){console.log(`[desk] No log file yet (${n}). Run 'desk start' first.`);return}console.error(`[desk] ${n}`);let r=(0,ce.openSync)(n,"r");try{let o=Qc(r);for(;t.follow;){await Se(Vc);let s=(0,ce.fstatSync)(r).size;s<o&&(o=0),s>o&&(process.stdout.write(ui(r,o,s)),o=s)}}finally{(0,ce.closeSync)(r)}}K();async function mi(){let e=se();await We(),Er(),console.log(e?`[desk] Logged out (was machine ${e.machineId}, team ${e.teamId}).`:"[desk] No local registration found."),console.log("[desk] Run 'desk start' to enroll again.")}var pi=require("fs");ge();K();U();de();async function fi(){let e=ke();if(e&&ie(e.pid)){let s=e.startedAt?new Date(e.startedAt).toLocaleString():"unknown",i=e.runner==="desktop"?"the Desk app":"desk start";console.log(`[desk] Daemon: running (pid ${e.pid}, since ${s}, started by ${i})`)}else console.log("[desk] Daemon: not running");let t=vt()&&!(0,pi.existsSync)(Q());console.log(`[desk] Workspaces: ${Q()}${t?" (not found \u2014 is the drive mounted?)":""}`);let n=se();if(!n){console.log("[desk] Not registered. Run: desk start");return}let r;try{r=await N(n.serverUrl,"/api/machine/me",{token:n.token,timeoutMs:f.statusProbe})}catch(s){console.log(`[desk] Machine: ${n.machineId}`),console.log(`[desk] Server: ${n.serverUrl} (unreachable: ${O(s)})`);return}if(!r.ok){console.log(`[desk] Machine: ${n.machineId}`),console.log(`[desk] Server: ${n.serverUrl} (unreachable: ${r.status})`);return}let o=await r.json();console.log(`[desk] Machine: ${o.name} (${o.machineId})`),console.log(`[desk] Team: ${o.teamId}`),console.log(`[desk] Agents: ${o.agentIds.length?o.agentIds.join(", "):"(none \u2014 create one in the web UI)"}`),console.log(`[desk] Server: ${n.serverUrl}`)}async function hi(){console.log(`desk ${pe()}`)}de();K();var Oe={start:{run:nn,longLived:!0,summary:"Bring this machine online in the background (enroll if needed)",help:`Usage: desk start [options]
29
36
 
30
37
  Bring this machine online. By default it runs in the background (detached) and a
31
38
  supervisor keeps it alive across crashes \u2014 use 'desk status', 'desk logs', 'desk stop'.
@@ -33,9 +40,9 @@ On first run (no local registration) this enrolls the machine into a team:
33
40
  \u2022 no flags open a browser to log in and pick the team to authorize.
34
41
  \u2022 --api-key <k> enroll non-interactively into --team (handy for CI).
35
42
 
36
- Once online the machine claims builds for its agents; worktree syncs and agent shell
37
- access are managed from the machine's page in the web app \u2014 the daemon picks changes
38
- up within a few seconds, no restart needed.
43
+ Once online the machine claims builds for its agents; agent shell access is managed
44
+ from the machine's page in the web app \u2014 the daemon picks changes up within a few
45
+ seconds, no restart needed.
39
46
 
40
47
  Options:
41
48
  --foreground, -f Run attached in this terminal instead of in the background (no
@@ -52,29 +59,29 @@ Options:
52
59
  directory must already exist \u2014 handy for keeping heavy
53
60
  checkouts on an external drive; if that drive is unmounted
54
61
  desk refuses to start instead of cloning onto the boot disk.
55
- Existing clones are not moved when the dir changes.`},stop:{run:()=>$e(),summary:"Stop the background machine",help:`Usage: desk stop
62
+ Existing clones are not moved when the dir changes.`},stop:{run:()=>We(),summary:"Stop the background machine",help:`Usage: desk stop
56
63
 
57
64
  Stop the background daemon started by 'desk start'. Sends SIGTERM so in-flight tasks
58
- shut down cleanly; SIGKILLs only if it doesn't exit in time.`},restart:{run:Ss,longLived:!0,summary:"Restart the background machine",help:`Usage: desk restart [options]
65
+ shut down cleanly; SIGKILLs only if it doesn't exit in time.`},restart:{run:li,longLived:!0,summary:"Restart the background machine",help:`Usage: desk restart [options]
59
66
 
60
67
  Stop the background daemon (if running) and start it again in the background. The
61
68
  stop\u2192start sequence runs in a detached helper process, so it completes even if this
62
69
  shell dies with the daemon \u2014 including a shell the daemon itself hosts (an agent's
63
- remote shell). Takes the same options as 'desk start'.`},logs:{run:vs,summary:"Show the background machine's logs",help:`Usage: desk logs [-f]
70
+ remote shell). Takes the same options as 'desk start'.`},logs:{run:di,summary:"Show the background machine's logs",help:`Usage: desk logs [-f]
64
71
 
65
72
  Print the background daemon's log (~/.desk/daemon.log).
66
73
 
67
74
  Options:
68
- -f, --follow Follow the log as it grows (like 'tail -f')`},logout:{run:()=>Ts(),summary:"Forget this machine's local registration",help:`Usage: desk logout
75
+ -f, --follow Follow the log as it grows (like 'tail -f')`},logout:{run:()=>mi(),summary:"Forget this machine's local registration",help:`Usage: desk logout
69
76
 
70
77
  Stop the background daemon (if running), then clear ~/.desk/machine.json so the next
71
78
  'desk start' enrolls again. Local only \u2014 it does not remove the machine from the team
72
- (an admin does that in the web UI).`},status:{run:()=>Es(),summary:"Show this machine's registration and status",help:`Usage: desk status
79
+ (an admin does that in the web UI).`},status:{run:()=>fi(),summary:"Show this machine's registration and status",help:`Usage: desk status
73
80
 
74
- Show this machine's registration and current status.`},version:{run:()=>Rs(),summary:"Show the desk CLI version",help:`Usage: desk version
81
+ Show this machine's registration and current status.`},version:{run:()=>hi(),summary:"Show the desk CLI version",help:`Usage: desk version
75
82
 
76
- Print the installed desk CLI version.`},provider:{run:async()=>{let e=q()?.serverUrl??"https://desk-web-nu.vercel.app";console.log("Model providers are managed on the website now; this machine receives credentials per task."),console.log(` Manage providers: ${e}/resources/providers`),console.log(` How it works: ${e}/docs/providers`)},summary:"Providers are managed on the website",help:`Usage: desk provider
83
+ Print the installed desk CLI version.`},provider:{run:async()=>{let e=se()?.serverUrl??"https://desk-web-nu.vercel.app";console.log("Model providers are managed on the website now; this machine receives credentials per task."),console.log(` Manage providers: ${e}/resources/providers`),console.log(` How it works: ${e}/docs/providers`)},summary:"Providers are managed on the website",help:`Usage: desk provider
77
84
 
78
85
  Model providers (API keys, OAuth logins, custom endpoints) are configured on the
79
86
  website, per team: Resources > Providers. Machines receive credentials with each
80
- task, so there is nothing to set up here.`}},$s=process.argv.slice(2),Y=$s[0],je=$s.slice(1);(Y==="--version"||Y==="-v")&&(console.log(`desk ${Z()}`),process.exit(0));if(!Y||Y==="--help"||Y==="-h"||Y==="help"){let e=Y==="help"?je[0]:void 0;e&&me[e]&&(console.log(me[e].help),process.exit(0)),Ps(),process.exit(0)}me[Y]&&(je.includes("--help")||je.includes("-h"))&&(console.log(me[Y].help),process.exit(0));var At=me[Y];At||(console.error(`[desk] Unknown command: ${Y}`),Ps(),process.exit(1));$o().then(()=>At.longLived?At.run(je):At.run(je).then(()=>process.exit(0))).catch(Ha);function Ha(e){console.error("[desk] Fatal:",T(e)),process.exit(1)}function Ps(){console.log("Usage: desk <command> [options]"),console.log(""),console.log("Commands:");let e=Math.max(...Object.keys(me).map(t=>t.length));for(let[t,{summary:n}]of Object.entries(me))console.log(` ${t.padEnd(e)} ${n}`);console.log(""),console.log("Run 'desk <command> --help' for command-specific options."),console.log(""),console.log("Env vars:"),console.log(" DESK_SERVER Default server URL"),console.log(" DESK_API_KEY API key for non-interactive enroll"),console.log(" DESK_TEAM Team name/id for --api-key enroll"),console.log(" DESK_WORKSPACES_DIR One-shot override of the workspaces root (not persisted;"),console.log(" prefer 'desk start --workspaces-dir')")}
87
+ task, so there is nothing to set up here.`}},gi=process.argv.slice(2),le=gi[0],at=gi.slice(1);(le==="--version"||le==="-v")&&(console.log(`desk ${pe()}`),process.exit(0));if(!le||le==="--help"||le==="-h"||le==="help"){let e=le==="help"?at[0]:void 0;e&&Oe[e]&&(console.log(Oe[e].help),process.exit(0)),yi(),process.exit(0)}Oe[le]&&(at.includes("--help")||at.includes("-h"))&&(console.log(Oe[le].help),process.exit(0));var rn=Oe[le];rn||(console.error(`[desk] Unknown command: ${le}`),yi(),process.exit(1));ms().then(()=>rn.longLived?rn.run(at):rn.run(at).then(()=>process.exit(0))).catch(Zc);function Zc(e){console.error("[desk] Fatal:",O(e)),process.exit(1)}function yi(){console.log("Usage: desk <command> [options]"),console.log(""),console.log("Commands:");let e=Math.max(...Object.keys(Oe).map(t=>t.length));for(let[t,{summary:n}]of Object.entries(Oe))console.log(` ${t.padEnd(e)} ${n}`);console.log(""),console.log("Run 'desk <command> --help' for command-specific options."),console.log(""),console.log("Env vars:"),console.log(" DESK_SERVER Default server URL"),console.log(" DESK_API_KEY API key for non-interactive enroll"),console.log(" DESK_TEAM Team name/id for --api-key enroll"),console.log(" DESK_WORKSPACES_DIR One-shot override of the workspaces root (not persisted;"),console.log(" prefer 'desk start --workspaces-dir')"),console.log(" DESK_HOME Data dir for registration, daemon state and workspaces (default ~/.desk)")}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deskdev/cli",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Desk CLI: AI pair-programming agent, ships tunnel sidecar for all platforms.",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "access": "public"
18
18
  },
19
19
  "dependencies": {
20
- "@deskdev/types": "workspace:*",
20
+ "@deskdev/types": "^2.0.1",
21
21
  "@earendil-works/pi-ai": "0.83.0",
22
22
  "@earendil-works/pi-coding-agent": "0.83.0",
23
23
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -25,12 +25,12 @@
25
25
  "undici": "^7"
26
26
  },
27
27
  "optionalDependencies": {
28
- "@deskdev/tunnel-darwin-arm64": "workspace:*",
29
- "@deskdev/tunnel-darwin-x64": "workspace:*",
30
- "@deskdev/tunnel-linux-arm64": "workspace:*",
31
- "@deskdev/tunnel-linux-x64": "workspace:*",
32
- "@deskdev/tunnel-win32-arm64": "workspace:*",
33
- "@deskdev/tunnel-win32-x64": "workspace:*"
28
+ "@deskdev/tunnel-darwin-arm64": "^2.0.1",
29
+ "@deskdev/tunnel-darwin-x64": "^2.0.1",
30
+ "@deskdev/tunnel-linux-arm64": "^2.0.1",
31
+ "@deskdev/tunnel-linux-x64": "^2.0.1",
32
+ "@deskdev/tunnel-win32-arm64": "^2.0.1",
33
+ "@deskdev/tunnel-win32-x64": "^2.0.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "esbuild": "^0.24.0",