@deskdev/cli 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +17 -17
  2. package/package.json +9 -2
package/dist/index.js CHANGED
@@ -1,31 +1,31 @@
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 Ya=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",Va=Object.keys(nr).filter(e=>qs(e)),zs=["planning","building"],Qa=["queued",...zs],Za=64*1024,Js=["github-copilot","openai-codex"],ec=[...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},tc=Object.keys(or).join(","),nc=[...Object.keys(Bt),...new Set(Object.values(Bt).map(e=>`.${e}`))].join(","),rc=Object.fromEntries(Object.entries(Bt).map(([e,t])=>[t,e])),oc=5*1024*1024,sc=20*1024*1024,Vs=["attachment","doc","skill","todo","project","machine","agent","member"],ic=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(`
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
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
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"),bi={darwin:"darwin",linux:"linux",win32:"windows",android:"linux"},vi={x64:"amd64",arm64:"arm64"};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 Ti(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 a of r)try{let i=require.resolve(`@deskdev/tunnel/${a}-${process.arch}`);return Dr(i),i}catch{}let o=bi[process.platform],s=vi[process.arch];if(o&&s){let a=(0,at.join)("vendor",`${o}-${s}`,`${e}${n}`),i=__dirname;for(let c=0;c<6;c++){let u=(0,at.join)(i,a);if((0,ke.existsSync)(u))return Dr(u),u;let l=(0,at.join)(i,"..");if(l===i)break;i=l}}if(process.env.DESK_DISABLE_TUNNEL!=="1"){let a=r.map(i=>`@deskdev/tunnel/${i}-${process.arch}`).join(", ");console.warn(`[bin] ${e} binary not found (none of ${a} 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=Ti("desk-tunnel");var ct=require("fs"),lt=require("path"),an=null;function Z(){return an||(an=xi())}function xi(){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,Ei=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,Ei),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 Ri=1e6,jr=[":(exclude)*.lock",":(exclude)package-lock.json",":(exclude)pnpm-lock.yaml",":(exclude)yarn.lock"];async function Gr(e,t,n,r=Ri){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:$i(s)}}catch(o){console.error(`[step] ${n} diff build failed:`,o.message);return}}var Br=e=>Buffer.byteLength(e,"utf8");function $i(e){return e.split(/(?=^diff --git )/m).flatMap(t=>{if(!t.startsWith("diff --git "))return[];let n=t.replace(/\n$/,"");return[{path:Pi(n),additions:n.match(/^(?!\+\+\+)\+/gm)?.length??0,deletions:n.match(/^(?!---)-/gm)?.length??0,patch:n}]})}function Pi(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 Mi(t)}var Mi=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 _i=(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 Ci(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 _i(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"?(Ci(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 Ii(e,t,n){let r=(0,K.readFileSync)(e,"utf-8").split(`
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
8
  `).filter(Boolean);if(r.length===0)return;let o=r[0];if(!t){(0,K.writeFileSync)(e,o+`
9
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
10
  `);return}(0,K.writeFileSync)(e,s.join(`
11
11
  `)+`
12
- `)}async function Zr(e,t,n,r){await Qr(e,t);let o=un(e);return o.mode!=="continue"?null:(Ii(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 Ai=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 Di(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 Di(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>Ai&&(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 Oi(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=Oi(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 Li=64;function Fi(e,t){return`mcp__${e}__${t}`.slice(0,Li)}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=>Ui(o,n.get(o.id))))).filter(o=>o!==null)}async function Ui(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=>Hi(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 Hi(e,t){let{ref:n,client:r}=e,o=Fi(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 Ni='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.',ji="[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=Bi(n.current,i.machine);if("error"in c)return ve(c.error,{closed:!0,truncated:!1});let u=c.machine,l=u.machineId,d=Wi(i),p=Date.now()+qi(i.timeout_ms);i.restart&&await e.restartShell(t,l,5e3);let m=await Ki(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
+ `)}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}
14
14
  [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 Bi(e,t){if(e.length===0)return{error:Ni};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 Wi(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 Ki(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 Gi(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 Gi(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 qi(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(ji),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 zi=[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}`,zi,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"],Ji=/^(-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 Xi(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 Xi(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=>Ji.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"),Yi=/^[a-z]:\\windows\\(?:system32|sysnative|syswow64)\\bash\.exe$/;function Vi(e){return Yi.test(e.replace(/\//g,"\\").toLowerCase())}function Qi(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&&!Vi(n)?n:null}function Zi(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=Qi({lookPath:Zi,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 ea(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:ea(n)))})}var bt=null;async function ta(){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 na(){let e=await import("undici"),t=vt;vt=new e.EnvHttpProxyAgent,t?.close().catch(()=>{})}function ra(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??=oa().catch(e=>(console.warn(`[machine] system proxy refresh failed: ${e instanceof Error?e.message:String(e)}`),!1)).finally(()=>{yn=null}),yn}async function oa(){if(bt===null)return!1;let e=await Eo();return e===null||!ra(bt,e,process.env)?!1:(bt=e,wn?await na():await Ro(),console.log(`[machine] System proxy moved: ${kn()??"none"}`),!0)}async function $o(e="[desk]"){await ta(),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 sa(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 ia=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,ia))}}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:sa(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 aa="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:aa}),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 ca=(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=ca(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 la=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>la){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 ua(){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,ua()]})}}var da=8e3;function ma(e){return`"${e}" is not a valid URL \u2014 include the scheme, e.g. "https://example.com/page".`}function pa(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 fa(e,t,n=da){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:ma(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:pa(s,l,f.webFetch)}],details:{truncated:!1}}}let{text:c,truncated:u}=fa(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 ha=`
18
- [truncated for compaction]`,$n=(e,t)=>e.length<=t?e:e.slice(0,t)+ha;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 ga(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 ya(e){return e.restore?Zr(e.conversationId,e.sessionRestoreUrl,e.restore.sessionLeafEntryId,e.stepId):null}var wa=7;function ka(e){(e.getProjectSettings().retry?.maxRetries??e.getGlobalSettings().retry?.maxRetries)===void 0&&e.applyOverrides({retry:{maxRetries:wa}})}function Sa(e,t){if(t===void 0)return;(e.getProjectSettings().transport??e.getGlobalSettings().transport)===void 0&&e.applyOverrides({transport:t})}function ba(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);ka(a),Sa(a,n.modelRuntime.transport),ba(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 ga(s,c,o),i({type:"stage",stage:"wrapup",state:"done"})),e.mode==="restore")return va(e,t,n);if(e.mode==="compact")return Ta(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(`
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(`
20
20
  [command interrupted: a user instruction arrived and takes effect now]
21
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(`
22
22
 
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 va(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 ya(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 Ta(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,xa=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,xa))}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 Ea="https://registry.npmjs.org/@deskdev/cli/latest",Ra=36e5,de=null,ts=0,Ne=null;function ns(){return de&&Date.now()-ts<Ra?Promise.resolve(de):Ne||(Ne=$a().finally(()=>{Ne=null}),Ne)}async function $a(){try{let e=await U(Ea,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 Pa=18e4,Ma=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>Pa?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>Ma?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 _a(e){let t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;(0,ls.exec)(t,()=>{})}var Ca=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"),_a(r);let o=Date.now()+18e4;for(;Date.now()<o;){await Ca(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{Ia(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 Da(r,o)}return Aa(e,t)}function Ia(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 Aa(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 Da(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 Oa=6e4,La=new Set(["--helper"]);async function Ss(e){let{bools:t}=he(e),n=Xe(e,La);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+Oa;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 Fa=200,Ua=256*1024,Ha=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 Na(e){let t=(0,X.fstatSync)(e).size,n=Math.max(0,t-Ua),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(-Fa);return o.length&&process.stdout.write(o.join(`
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(`
27
27
  `)+`
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=Na(r);for(;t.follow;){await oe(Ha);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]
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]
29
29
 
30
30
  Bring this machine online. By default it runs in the background (detached) and a
31
31
  supervisor keeps it alive across crashes \u2014 use 'desk status', 'desk logs', 'desk stop'.
@@ -77,4 +77,4 @@ Print the installed desk CLI version.`},provider:{run:async()=>{let e=q()?.serve
77
77
 
78
78
  Model providers (API keys, OAuth logins, custom endpoints) are configured on the
79
79
  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(ja);function ja(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')")}
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')")}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deskdev/cli",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Desk CLI: AI pair-programming agent, ships tunnel sidecar for all platforms.",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -18,13 +18,20 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@deskdev/types": "workspace:*",
21
- "@deskdev/tunnel": "workspace:*",
22
21
  "@earendil-works/pi-ai": "0.83.0",
23
22
  "@earendil-works/pi-coding-agent": "0.83.0",
24
23
  "@modelcontextprotocol/sdk": "^1.29.0",
25
24
  "eventsource": "^4.1.0",
26
25
  "undici": "^7"
27
26
  },
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:*"
34
+ },
28
35
  "devDependencies": {
29
36
  "esbuild": "^0.24.0",
30
37
  "tsx": "^4.19.2",