herdr-remote 0.3.33 → 0.3.34

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 (36) hide show
  1. package/dist/chunks/{VD54DF7R.js → 2IM3AVNW.js} +1 -1
  2. package/dist/chunks/{MCUVFSSK.js → 2RUREFQO.js} +1 -1
  3. package/dist/chunks/{RMHH3IAX.js → 6M7I477E.js} +1 -1
  4. package/dist/chunks/{KGOQKOHH.js → 72JMGTAK.js} +1 -1
  5. package/dist/chunks/{MEFDV375.js → FN6VM2O7.js} +1 -1
  6. package/dist/chunks/{O2LNVFUT.js → I6K6O3EE.js} +1 -1
  7. package/dist/chunks/{K5RFPHSF.js → IRV2W3ZL.js} +1 -1
  8. package/dist/chunks/J427SPKK.js +3 -0
  9. package/dist/chunks/{M52LJEES.js → MHS44P3Y.js} +1 -1
  10. package/dist/chunks/{CVJ4HBMP.js → MLSLOPR7.js} +1 -1
  11. package/dist/chunks/{QCSILMFB.js → MRXHG2UD.js} +1 -1
  12. package/dist/chunks/NKDFWWLU.js +3 -0
  13. package/dist/chunks/{LPR662JH.js → NY3SVG3W.js} +2 -2
  14. package/dist/chunks/{MKAEXKXG.js → QRQJLJWT.js} +1 -1
  15. package/dist/chunks/{WY7WHEJ4.js → QXMBBOKS.js} +1 -1
  16. package/dist/chunks/{H24ZP5D5.js → S3V2O6BK.js} +1 -1
  17. package/dist/chunks/{DGUZCGQN.js → S57VTPH5.js} +1 -1
  18. package/dist/chunks/{FONUO5O5.js → TSP3KNDA.js} +1 -1
  19. package/dist/chunks/{44IGVPMA.js → UK7XZS2G.js} +1 -1
  20. package/dist/chunks/{LY2ZGCXN.js → W24FRSKQ.js} +1 -1
  21. package/dist/chunks/W27D73NQ.js +3 -0
  22. package/dist/chunks/{B76DFI4H.js → WDPLLWBV.js} +1 -1
  23. package/dist/chunks/{AX4EPJCP.js → Y5CEFDIU.js} +1 -1
  24. package/dist/chunks/{PBRQ3HEG.js → ZZOEVJ3V.js} +1 -1
  25. package/dist/cli.js +4 -4
  26. package/dist/connector/main.js +12 -12
  27. package/herdr-plugin.toml +1 -1
  28. package/node_modules/herdr-remote-relay/bin/herdr-remote-relay.js +10 -10
  29. package/node_modules/herdr-remote-relay/package.json +1 -1
  30. package/node_modules/herdr-remote-relay/web/dist/assets/index-CnRQXj8k.js +61 -0
  31. package/node_modules/herdr-remote-relay/web/dist/index.html +1 -1
  32. package/package.json +2 -2
  33. package/dist/chunks/5LZFJ6UZ.js +0 -3
  34. package/dist/chunks/BYGDPZZD.js +0 -3
  35. package/dist/chunks/PBMBFWLQ.js +0 -3
  36. package/node_modules/herdr-remote-relay/web/dist/assets/index-DfycvWFA.js +0 -61
@@ -1,3 +1,3 @@
1
1
  import { createRequire as __herdrCreateRequire } from 'node:module';
2
2
  const require = __herdrCreateRequire(import.meta.url);
3
- import{a as g,c as S}from"./U6QAYG3E.js";import{d as p,f as b}from"./PBMBFWLQ.js";import f from"node:fs";import{spawnSync as O}from"node:child_process";var A=p.length,D="3",M=2,h=3e3,P=p;function v(e){if(typeof e!="string")return null;let n=/^rgba?:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i.exec(e.trim());if(!n)return null;let t=n.slice(1,4).map(r=>{let l=r.length;if(l===0||l>4)return null;let i=Math.round(parseInt(r,16)/(16**l-1)*255);return Math.max(0,Math.min(255,i))});return t.some(r=>r===null)?null:`#${t.map(r=>r.toString(16).padStart(2,"0")).join("")}`}function R(e,n){if(typeof e!="string")return null;let t=e.indexOf(`${n};`);if(t===-1)return null;let r=e.indexOf("\x1B\\",t),l=e.indexOf("\x07",t),i=-1,s=-1;if(r!==-1&&(l===-1||r<l))i=r,s=r+2;else if(l!==-1)i=l,s=l+1;else return null;let o=v(e.slice(t+n.length+1,i).trim());return o?{color:o,start:t,end:s}:null}function C(e,n){return R(e,n)?.color??null}var d=b;function T(e=process.env){let n=e.HERDR_TERM_PALETTE_JSON;if(!n)return null;try{return d(JSON.parse(n))}catch{return null}}function m(e,n){return O("stty",[...e,"-F",n],{encoding:"utf8",timeout:1e3,windowsHide:!0})}function y(e,n){let t=R(e.pending,n);return t?(e.pending=e.pending.slice(0,t.start)+e.pending.slice(t.end),t.color):null}var _=[{query:"\x1B]10;?\x1B\\",prefix:"\x1B]10",paletteKey:"foreground"},{query:"\x1B]11;?\x1B\\",prefix:"\x1B]11",paletteKey:"background"},{query:"\x1B]12;?\x1B\\",prefix:"\x1B]12",paletteKey:"cursor"},...P.map((e,n)=>({query:`\x1B]4;${n};?\x1B\\`,prefix:`\x1B]4;${n}`,paletteKey:"ansi",ansiKey:e}))];function x(e){let n={},t={};for(let r of _){let l=e(r.query,r.prefix);if(r.paletteKey==="ansi"){if(!l)break;t[r.ansiKey]=l}else l&&(n[r.paletteKey]=l)}return Object.keys(t).length===A&&(n.ansi=t),d(n)}function N(e,n,t,r){f.writeSync(e,n);let l=Buffer.alloc(256),i=0;for(;i<M&&Date.now()<r.overallDeadline;){let s=y(r,t);if(s)return s;let o=0;try{o=f.readSync(e,l,0,l.length,null)}catch(a){if(a.code==="EAGAIN"){i+=1;continue}return null}o>0?(r.pending+=l.toString("latin1",0,o),i=0):i+=1}return y(r,t)}function E({ttyPath:e="/dev/tty",timeoutMs:n=h}={}){if(process.platform==="win32")return null;let t=null,r=null;try{t=f.openSync(e,"r+")}catch{return null}try{let l=m(["-g"],e);if(l.status!==0||(r=l.stdout.trim(),m(["raw","-echo","min","0","time",D],e).status!==0))return null;let i={pending:"",overallDeadline:Date.now()+n},s=t;return x((o,a)=>N(s,o,a,i))}catch{return null}finally{if(r&&m([r],e),t!==null)try{f.closeSync(t)}catch{}}}async function I({input:e=process.stdin,output:n=process.stdout,timeoutMs:t=h}={}){if(!e.isTTY||!n.isTTY)return null;let r={pending:"",overallDeadline:Date.now()+t},l=null,i;try{return e.setRawMode(!0),await new Promise(s=>{let o=!1,a=()=>{o||(o=!0,s())};l=c=>{r.pending+=typeof c=="string"?c:c.toString("latin1"),/\x1b\[\?[\d;]*c/.test(r.pending)&&a()},e.on("data",l),e.resume(),i=setTimeout(a,Math.max(0,r.overallDeadline-Date.now())),n.write(`${_.map(({query:c})=>c).join("")}\x1B[c`)}),x((s,o)=>y(r,o))}catch{return null}finally{i&&clearTimeout(i),l&&e.removeListener("data",l);try{e.setRawMode(!1)}catch{}e.pause()}}function w(e){let n=d(e);if(!n)return null;try{S(t=>{t.terminalPalette=n})}catch{}return n}function K(){try{return d(g().terminalPalette)}catch{return null}}function J({env:e=process.env,probe:n=E}={}){return T(e)||n()||null}async function $({env:e=process.env,probe:n=E,platform:t=process.platform,consoleProbe:r=I}={}){if(e.HERDR_TERM_PALETTE_JSON)return T(e);if(!process.stdin.isTTY||!process.stdout.isTTY)return null;let l=t==="win32"?await r():n();return l?(e.HERDR_TERM_PALETTE_JSON=JSON.stringify(l),w(l),l):null}var u;function j({refresh:e=!1}={}){if(!e&&u!==void 0)return u;let n=T();if(n)return u=n,u;let t=E();return u=t?w(t):K(),u}export{A as a,P as b,v as c,C as d,d as e,T as f,y as g,x as h,E as i,I as j,w as k,K as l,J as m,$ as n,j as o};
3
+ import{a as g,c as S}from"./U6QAYG3E.js";import{d as p,f as b}from"./NKDFWWLU.js";import f from"node:fs";import{spawnSync as O}from"node:child_process";var A=p.length,D="3",M=2,h=3e3,P=p;function v(e){if(typeof e!="string")return null;let n=/^rgba?:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i.exec(e.trim());if(!n)return null;let t=n.slice(1,4).map(r=>{let l=r.length;if(l===0||l>4)return null;let i=Math.round(parseInt(r,16)/(16**l-1)*255);return Math.max(0,Math.min(255,i))});return t.some(r=>r===null)?null:`#${t.map(r=>r.toString(16).padStart(2,"0")).join("")}`}function R(e,n){if(typeof e!="string")return null;let t=e.indexOf(`${n};`);if(t===-1)return null;let r=e.indexOf("\x1B\\",t),l=e.indexOf("\x07",t),i=-1,s=-1;if(r!==-1&&(l===-1||r<l))i=r,s=r+2;else if(l!==-1)i=l,s=l+1;else return null;let o=v(e.slice(t+n.length+1,i).trim());return o?{color:o,start:t,end:s}:null}function C(e,n){return R(e,n)?.color??null}var d=b;function T(e=process.env){let n=e.HERDR_TERM_PALETTE_JSON;if(!n)return null;try{return d(JSON.parse(n))}catch{return null}}function m(e,n){return O("stty",[...e,"-F",n],{encoding:"utf8",timeout:1e3,windowsHide:!0})}function y(e,n){let t=R(e.pending,n);return t?(e.pending=e.pending.slice(0,t.start)+e.pending.slice(t.end),t.color):null}var _=[{query:"\x1B]10;?\x1B\\",prefix:"\x1B]10",paletteKey:"foreground"},{query:"\x1B]11;?\x1B\\",prefix:"\x1B]11",paletteKey:"background"},{query:"\x1B]12;?\x1B\\",prefix:"\x1B]12",paletteKey:"cursor"},...P.map((e,n)=>({query:`\x1B]4;${n};?\x1B\\`,prefix:`\x1B]4;${n}`,paletteKey:"ansi",ansiKey:e}))];function x(e){let n={},t={};for(let r of _){let l=e(r.query,r.prefix);if(r.paletteKey==="ansi"){if(!l)break;t[r.ansiKey]=l}else l&&(n[r.paletteKey]=l)}return Object.keys(t).length===A&&(n.ansi=t),d(n)}function N(e,n,t,r){f.writeSync(e,n);let l=Buffer.alloc(256),i=0;for(;i<M&&Date.now()<r.overallDeadline;){let s=y(r,t);if(s)return s;let o=0;try{o=f.readSync(e,l,0,l.length,null)}catch(a){if(a.code==="EAGAIN"){i+=1;continue}return null}o>0?(r.pending+=l.toString("latin1",0,o),i=0):i+=1}return y(r,t)}function E({ttyPath:e="/dev/tty",timeoutMs:n=h}={}){if(process.platform==="win32")return null;let t=null,r=null;try{t=f.openSync(e,"r+")}catch{return null}try{let l=m(["-g"],e);if(l.status!==0||(r=l.stdout.trim(),m(["raw","-echo","min","0","time",D],e).status!==0))return null;let i={pending:"",overallDeadline:Date.now()+n},s=t;return x((o,a)=>N(s,o,a,i))}catch{return null}finally{if(r&&m([r],e),t!==null)try{f.closeSync(t)}catch{}}}async function I({input:e=process.stdin,output:n=process.stdout,timeoutMs:t=h}={}){if(!e.isTTY||!n.isTTY)return null;let r={pending:"",overallDeadline:Date.now()+t},l=null,i;try{return e.setRawMode(!0),await new Promise(s=>{let o=!1,a=()=>{o||(o=!0,s())};l=c=>{r.pending+=typeof c=="string"?c:c.toString("latin1"),/\x1b\[\?[\d;]*c/.test(r.pending)&&a()},e.on("data",l),e.resume(),i=setTimeout(a,Math.max(0,r.overallDeadline-Date.now())),n.write(`${_.map(({query:c})=>c).join("")}\x1B[c`)}),x((s,o)=>y(r,o))}catch{return null}finally{i&&clearTimeout(i),l&&e.removeListener("data",l);try{e.setRawMode(!1)}catch{}e.pause()}}function w(e){let n=d(e);if(!n)return null;try{S(t=>{t.terminalPalette=n})}catch{}return n}function K(){try{return d(g().terminalPalette)}catch{return null}}function J({env:e=process.env,probe:n=E}={}){return T(e)||n()||null}async function $({env:e=process.env,probe:n=E,platform:t=process.platform,consoleProbe:r=I}={}){if(e.HERDR_TERM_PALETTE_JSON)return T(e);if(!process.stdin.isTTY||!process.stdout.isTTY)return null;let l=t==="win32"?await r():n();return l?(e.HERDR_TERM_PALETTE_JSON=JSON.stringify(l),w(l),l):null}var u;function j({refresh:e=!1}={}){if(!e&&u!==void 0)return u;let n=T();if(n)return u=n,u;let t=E();return u=t?w(t):K(),u}export{A as a,P as b,v as c,C as d,d as e,T as f,y as g,x as h,E as i,I as j,w as k,K as l,J as m,$ as n,j as o};
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createRequire as __herdrCreateRequire } from 'node:module';
2
2
  const require = __herdrCreateRequire(import.meta.url);
3
- import{a as y,b as A}from"./chunks/3FQAXVGC.js";import{f as S,h as w}from"./chunks/DGUZCGQN.js";import"./chunks/U6QAYG3E.js";import{f as m,l as v,n as $,o as k}from"./chunks/M52LJEES.js";import"./chunks/KRVF37OW.js";import"./chunks/QRGNEKME.js";import"./chunks/PBMBFWLQ.js";import{a as d,c as h,d as g}from"./chunks/TNLCNVA2.js";import"./chunks/I6NRCYLI.js";import U from"node:fs";import P from"node:os";import u from"node:path";var j=JSON.parse(U.readFileSync(u.join(d,"package.json"),"utf8")).version,f=`herdr-remote ${j} \u2014 browser access to Herdr workspaces
3
+ import{a as y,b as A}from"./chunks/3FQAXVGC.js";import{f as S,h as w}from"./chunks/S57VTPH5.js";import"./chunks/U6QAYG3E.js";import{f as m,l as v,n as $,o as k}from"./chunks/MHS44P3Y.js";import"./chunks/KRVF37OW.js";import"./chunks/QRGNEKME.js";import"./chunks/NKDFWWLU.js";import{a as d,c as h,d as g}from"./chunks/TNLCNVA2.js";import"./chunks/I6NRCYLI.js";import U from"node:fs";import P from"node:os";import u from"node:path";var j=JSON.parse(U.readFileSync(u.join(d,"package.json"),"utf8")).version,f=`herdr-remote ${j} \u2014 browser access to Herdr workspaces
4
4
 
5
5
  Usage: herdr-remote [command] [options]
6
6
 
@@ -28,10 +28,10 @@ Options:
28
28
  Self-hosting: docs/self-hosted-relay.md
29
29
  `;function E(n){let s=[],t={};for(let l=0;l<n.length;l+=1){let r=n[l];if(r==="--json"){t.json=!0;continue}if(r==="--daemon"){t.daemon=!0;continue}if(r==="--elevated"){t.elevated=!0;continue}if(r==="--help"||r==="-h"){t.help=!0;continue}if(r==="--version"||r==="-v"){t.version=!0;continue}if(r==="--lang"){t.lang=n[l+1],l+=1;continue}if(r.startsWith("--lang=")){t.lang=r.slice(7);continue}if(r.startsWith("-")){t.unknown=r;continue}s.push(r)}return{positional:s,flags:t}}function i(n){process.stdout.write(`${JSON.stringify(n,null,2)}
30
30
  `)}function b(n,s){let t=[];if(t.push(`${s("overview.mode")}: ${s(`mode.${n.mode}`)}`),n.relay.local?t.push(`${s("overview.relay")}: ${n.relay.alive?s("common.running"):s("common.stopped")} (${n.relay.bind}:${n.relay.port})`):t.push(`${s("overview.relay")}: ${n.relay.remoteUrl}`),t.push(`${s("overview.host")}: ${n.host.alive?s("common.running"):s("common.stopped")}`),t.push(`${s("overview.socket")}: ${n.host.socketPath}${n.host.socketExists?"":` (${s("overview.socketMissing")})`}`),t.push(`${s("overview.webUrl")}: ${n.publicUrl}`),n.keepalive){let l=n.keepalive.active?s("common.running"):n.keepalive.installed?s("common.installed"):s("common.notInstalled");t.push(`${s("overview.keepalive")}: ${n.keepalive.manager} \u2014 ${l}`)}return n.relay.health&&n.relay.health.ok===!1&&t.push(`${s("overview.relay")}: ${s("overview.unreachable",{message:n.relay.health.message??""})}`),t.join(`
31
- `)}async function B(n){let{startTui:s}=await import("./chunks/LPR662JH.js");await s(n)}async function O(n=process.argv.slice(2)){let{positional:s,flags:t}=E(n);if(process.platform==="win32"){let e=u.relative(d,process.cwd());(e===""||e!==".."&&!e.startsWith(`..${u.sep}`)&&!u.isAbsolute(e))&&process.chdir(P.homedir())}let l=s[0]||null;if(t.help){process.stdout.write(f);return}if(t.version){process.stdout.write(`${j}
31
+ `)}async function B(n){let{startTui:s}=await import("./chunks/NY3SVG3W.js");await s(n)}async function O(n=process.argv.slice(2)){let{positional:s,flags:t}=E(n);if(process.platform==="win32"){let e=u.relative(d,process.cwd());(e===""||e!==".."&&!e.startsWith(`..${u.sep}`)&&!u.isAbsolute(e))&&process.chdir(P.homedir())}let l=s[0]||null;if(t.help){process.stdout.write(f);return}if(t.version){process.stdout.write(`${j}
32
32
  `);return}if(t.unknown){process.stderr.write(`herdr-remote: unknown option "${t.unknown}"
33
33
 
34
- ${f}`),process.exitCode=2;return}$(),await(await import("./chunks/O2LNVFUT.js")).captureTerminalPalette(),(await import("./chunks/WY7WHEJ4.js")).captureTerminalFont();let r=k(),T=t.lang&&v.includes(t.lang)?t.lang:r.ui.language,a=A(y({preference:T})),c=await import("./chunks/5LZFJ6UZ.js"),C=await import("./chunks/BYGDPZZD.js");switch(l){case null:{if(process.stdin.isTTY&&process.stdout.isTTY){await B({language:t.lang||null});return}i(await c.fullStatus(r));return}case"start":{let e=c.startAll(r);t.json?i(e):process.stdout.write(`${a("services.started")}
34
+ ${f}`),process.exitCode=2;return}$(),await(await import("./chunks/I6K6O3EE.js")).captureTerminalPalette(),(await import("./chunks/QXMBBOKS.js")).captureTerminalFont();let r=k(),T=t.lang&&v.includes(t.lang)?t.lang:r.ui.language,a=A(y({preference:T})),c=await import("./chunks/J427SPKK.js"),C=await import("./chunks/W27D73NQ.js");switch(l){case null:{if(process.stdin.isTTY&&process.stdout.isTTY){await B({language:t.lang||null});return}i(await c.fullStatus(r));return}case"start":{let e=c.startAll(r);t.json?i(e):process.stdout.write(`${a("services.started")}
35
35
  ${b(await c.fullStatus(r),a)}
36
36
  `);return}case"stop":{let e=c.stopAll(r);t.json?i(e):process.stdout.write(`${a("services.stopped")}
37
37
  `);return}case"restart":{let e=c.restartAll(r);t.json?i(e):process.stdout.write(`${a("services.restarted")}
@@ -40,7 +40,7 @@ ${b(await c.fullStatus(r),a)}
40
40
  ${a("pair.url")}: ${p}
41
41
  ${a("pair.expires",{minutes:x,time:new Date(e.expiresAt).toLocaleTimeString()})}
42
42
  `);return}case"url":{process.stdout.write(`${m(r,w())}
43
- `);return}case"update":{let{runUpdate:e}=await import("./chunks/AX4EPJCP.js"),o=await e(a,{config:r,...t.json?{report:()=>{}}:{}});t.json&&i(o),o.ok||(process.exitCode=1);return}case"run":{let{runForeground:e}=await import("./chunks/K5RFPHSF.js");await e({logToFiles:!!t.daemon});return}case"admin-broker":{let e=await import("./connector/admin-broker.js"),o=s[1]||"status";if(o==="install")e.installAdminBroker(a),i({installed:!0,available:await e.waitForAdminBroker()});else if(o==="uninstall")e.uninstallAdminBroker(a),i({installed:!1});else if(o==="restart"){if(await e.stopAdminBroker()==="busy")throw new Error(a("adminBroker.busy"));e.startAdminBrokerTask(a),i({available:await e.waitForAdminBroker()})}else if(o==="status")i({available:await e.adminBrokerStatus()});else throw new Error(`unknown administrator broker action: ${o}`);return}case"admin-shell":{let{runAdminShell:e}=await import("./chunks/FONUO5O5.js");process.exitCode=await e(a);return}case"keepalive":{let e=await import("./chunks/QCSILMFB.js"),o=s[1]||"status";if(o==="install"&&t.elevated){let{completeServiceInstall:p}=await import("./chunks/B76DFI4H.js");process.exitCode=await p(a)}else if(o==="install")i(await e.install(r));else if(o==="uninstall")i(await e.uninstall(r));else if(o==="restart")i(e.restart(r));else if(o==="status")i(e.status(r));else throw new Error(`unknown keepalive action: ${o}`);return}case"plugin":{let e=await import("./chunks/LY2ZGCXN.js"),o=s[1]||"status";if(o==="link")i(e.register());else if(o==="unlink")i(e.unregister());else if(o==="status")i(e.registrationStatus());else throw new Error(`unknown plugin action: ${o}`);return}case"config":{i({configPath:g(),stateDir:h(),config:r});return}default:process.stderr.write(`herdr-remote: unknown command "${l}"
43
+ `);return}case"update":{let{runUpdate:e}=await import("./chunks/Y5CEFDIU.js"),o=await e(a,{config:r,...t.json?{report:()=>{}}:{}});t.json&&i(o),o.ok||(process.exitCode=1);return}case"run":{let{runForeground:e}=await import("./chunks/IRV2W3ZL.js");await e({logToFiles:!!t.daemon});return}case"admin-broker":{let e=await import("./connector/admin-broker.js"),o=s[1]||"status";if(o==="install")e.installAdminBroker(a),i({installed:!0,available:await e.waitForAdminBroker()});else if(o==="uninstall")e.uninstallAdminBroker(a),i({installed:!1});else if(o==="restart"){if(await e.stopAdminBroker()==="busy")throw new Error(a("adminBroker.busy"));e.startAdminBrokerTask(a),i({available:await e.waitForAdminBroker()})}else if(o==="status")i({available:await e.adminBrokerStatus()});else throw new Error(`unknown administrator broker action: ${o}`);return}case"admin-shell":{let{runAdminShell:e}=await import("./chunks/TSP3KNDA.js");process.exitCode=await e(a);return}case"keepalive":{let e=await import("./chunks/MRXHG2UD.js"),o=s[1]||"status";if(o==="install"&&t.elevated){let{completeServiceInstall:p}=await import("./chunks/WDPLLWBV.js");process.exitCode=await p(a)}else if(o==="install")i(await e.install(r));else if(o==="uninstall")i(await e.uninstall(r));else if(o==="restart")i(e.restart(r));else if(o==="status")i(e.status(r));else throw new Error(`unknown keepalive action: ${o}`);return}case"plugin":{let e=await import("./chunks/W24FRSKQ.js"),o=s[1]||"status";if(o==="link")i(e.register());else if(o==="unlink")i(e.unregister());else if(o==="status")i(e.registrationStatus());else throw new Error(`unknown plugin action: ${o}`);return}case"config":{i({configPath:g(),stateDir:h(),config:r});return}default:process.stderr.write(`herdr-remote: unknown command "${l}"
44
44
 
45
45
  ${f}`),process.exitCode=2}}function M(){O().catch(n=>{process.stderr.write(`herdr-remote: ${n.message}
46
46
  `),process.exitCode=1})}export{b as describeStatus,E as parseArgs,M as run};
@@ -1,20 +1,20 @@
1
1
  import { createRequire as __herdrCreateRequire } from 'node:module';
2
2
  const require = __herdrCreateRequire(import.meta.url);
3
- import"../chunks/C2UUZY6J.js";import{a as we,b as Te,d as Se}from"../chunks/MEFDV375.js";import"../chunks/3FQAXVGC.js";import{a as g}from"../chunks/42KARAL4.js";import{a as d}from"../chunks/7SMZ43LI.js";import{a as fe,b as me,c as pe,d as k}from"../chunks/JJGEV4EZ.js";import{a as ge,d as M,e as ye,i as _e}from"../chunks/H24ZP5D5.js";import{m as be}from"../chunks/PBRQ3HEG.js";import"../chunks/U6QAYG3E.js";import"../chunks/CVJ4HBMP.js";import{b as ne,e as ie,g as L,h as oe,i as ae,m as ce,n as he,o as le,p as de,q as ue}from"../chunks/KGOQKOHH.js";import{h as Q,i as Z,o as ee}from"../chunks/M52LJEES.js";import{b as re,c as se}from"../chunks/KRVF37OW.js";import{a as p,d as te}from"../chunks/QRGNEKME.js";import{a as G,b as Y,c as W,h as X,j as w,k as q,l as j,m as J}from"../chunks/PBMBFWLQ.js";import{a as K,c as b}from"../chunks/TNLCNVA2.js";import"../chunks/I6NRCYLI.js";import Pt from"node:os";import De from"node:path";import Ke from"node:crypto";import y from"node:fs";import C from"node:path";var Ge=20,Ye=50*1024*1024,We=1440*60*1e3;function ke(){let s=C.join(b(),"pasted");return p(s),s}function I({dir:s=ke(),maxFiles:e=Ge,maxBytes:t=Ye,maxAgeMs:r=We,now:n=Date.now()}={}){let i;try{i=y.readdirSync(s,{withFileTypes:!0})}catch{return}let o=[];for(let h of i){if(!h.isFile())continue;let l=C.join(s,h.name);try{let c=y.statSync(l);if(n-c.mtimeMs>r){try{y.unlinkSync(l)}catch{}continue}o.push({path:l,size:c.size,mtimeMs:c.mtimeMs})}catch{}}o.sort((h,l)=>h.mtimeMs-l.mtimeMs);let a=o.reduce((h,l)=>h+l.size,0);for(;o.length>e||a>t;){let h=o.shift();if(!h)break;try{y.unlinkSync(h.path),a-=h.size}catch{}}}function Ie({mime:s,dataBase64:e,dir:t=ke()}){if(!j(s))throw new Error(`unsupported MIME type: ${s}`);if(typeof e!="string")throw new Error("missing or invalid dataBase64 payload");let r=Buffer.from(e,"base64");if(r.length>3145728)throw new Error(`file size (${r.length} bytes) exceeds maximum limit of 3 MB`);if(r.length===0)throw new Error("file payload is empty");if(!J(s,r))throw new Error(`file magic bytes do not match declared MIME type ${s}`);I({dir:t});let n=`${Ke.randomUUID()}${q[s]}`,i=C.join(t,n);y.writeFileSync(i,r,{mode:384,flag:"wx"});try{y.chmodSync(i,384)}catch{}return I({dir:t}),i}var T=["blocked","done","working","idle","unknown"];function Ee(s,e=48){if(typeof s!="string")return null;let t=s.replace(/[\u0000-\u001F\u007F-\u009F]/g," ").replace(/\s+/g," ").trim();return t?t.length>e?t.slice(0,e):t:null}function Xe(s){return T.includes(s)?s:"unknown"}function qe(){return Object.fromEntries(T.map(s=>[s,0]))}function Ae(s){let e=Array.isArray(s?.agents)?s.agents:[],t=Array.isArray(s?.panes)?s.panes:[],r=typeof s?.focused_pane_id=="string"&&s.focused_pane_id?s.focused_pane_id:null,n=(r?t.find(c=>c?.pane_id===r):t.find(c=>c?.focused===!0))||null,i=(r?e.find(c=>c?.pane_id===r):e.find(c=>c?.focused===!0))||null,o=r||(typeof n?.pane_id=="string"?n.pane_id:null)||(typeof i?.pane_id=="string"?i.pane_id:null),a=typeof n?.agent=="string"?n.agent:typeof i?.agent=="string"?i.agent:null,h=qe(),l=[];for(let c of e){if(!c||typeof c.pane_id!="string")continue;let f=Xe(c.agent_status);h[f]+=1,l.push({paneId:c.pane_id,workspaceId:typeof c.workspace_id=="string"?c.workspace_id:null,agent:Ee(c.display_agent||c.agent,24),title:Ee(c.terminal_title_stripped||c.terminal_title),status:f,focused:c.focused===!0})}return l.sort((c,f)=>T.indexOf(c.status)-T.indexOf(f.status)),{focusedPaneId:o,focusedAgent:a,counts:h,total:l.length,agents:l.slice(0,16)}}function He(s,e){if(!s||!e)return s===e;if(s.focusedPaneId!==e.focusedPaneId||s.focusedAgent!==e.focusedAgent||s.total!==e.total)return!1;for(let t of T)if((s.counts?.[t]||0)!==(e.counts?.[t]||0))return!1;return s.agents.length!==e.agents.length?!1:s.agents.every((t,r)=>{let n=e.agents[r];return n&&t.paneId===n.paneId&&t.status===n.status&&t.agent===n.agent&&t.title===n.title})}var je=5e3,Je=150,Qe=[{type:"pane.focused"},{type:"tab.focused"},{type:"workspace.focused"},{type:"pane.agent_detected"}],E=class{socketPath;request;subscribe;send;pollTimer=null;debounceTimer=null;subscription=null;pending=!1;stale=!1;lastSummary=null;constructor(e,t){this.socketPath=e.socketPath,this.request=e.requestHerdr||we,this.subscribe=e.subscribeHerdr||Te,this.send=t}start(){if(!this.pollTimer){this.pollTimer=setInterval(()=>this.read(),je),this.pollTimer.unref?.();try{this.subscription=this.subscribe(this.socketPath,Qe,()=>this.scheduleRead(),{onStarted:()=>this.scheduleRead()})}catch{}this.read()}}stop(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.subscription&&(this.subscription.close(),this.subscription=null),this.stale=!1,this.lastSummary=null}scheduleRead(){this.pollTimer&&(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.read()},Je),this.debounceTimer.unref?.())}async read(){if(!this.pollTimer)return;if(this.pending){this.stale=!0;return}this.pending=!0,this.stale=!1;let e;try{let r=await this.request(this.socketPath,"session.snapshot",{});e=r?.snapshot||r}catch{return}finally{this.pending=!1,this.stale&&this.scheduleRead()}if(!this.pollTimer)return;let t=Ae(e);He(this.lastSummary,t)||(this.lastSummary=t,this.send({type:"agent_status",...t}))}};import it from"node:crypto";import ot from"node:fs";import{createRequire as Ze}from"node:module";import R from"node:fs";import et from"node:path";var tt=6e4,rt=16384,st=1,N=null;function nt(){if(!N){let s=et.join(K,"dist","harfbuzz-subset.wasm"),e=R.existsSync(s)?s:Ze(import.meta.url).resolve("harfbuzzjs/dist/harfbuzz-subset.wasm");N=new WebAssembly.Module(R.readFileSync(e))}return N}var A=class{idleMs;instance=null;faces=new Map;idleTimer=null;constructor({idleMs:e=tt}={}){this.idleMs=e}exports(){return this.instance||(this.instance=new WebAssembly.Instance(nt(),{}).exports,this.instance._initialize()),this.instance}face(e){let t=`${e.path}\0${e.index||0}`,r=this.faces.get(t);if(r)return r.face;let n=this.exports(),i=R.readFileSync(e.path),o=n.malloc(i.length);if(!o)throw new Error("out of memory loading font");new Uint8Array(n.memory.buffer).set(i,o);let a=n.hb_blob_create(o,i.length,st,0,0),h=n.hb_face_create(a,e.index||0);return n.hb_blob_destroy(a),this.faces.set(t,{pointer:o,face:h}),h}subset(e,t){let r=this.exports(),n=this.face(e),i=r.hb_subset_input_create_or_fail();if(!i)throw new Error("font subsetting is unavailable");let o=0,a=0;try{let h=r.hb_subset_input_unicode_set(i);for(let f of t.slice(0,rt))r.hb_set_add(h,f);if(a=r.hb_subset_or_fail(n,i),!a)throw new Error("the font could not be subset");o=r.hb_face_reference_blob(a);let l=r.hb_blob_get_length(o),c=r.hb_blob_get_data(o,0);return Buffer.from(new Uint8Array(r.memory.buffer,c,l))}finally{o&&r.hb_blob_destroy(o),a&&r.hb_face_destroy(a),r.hb_subset_input_destroy(i),this.scheduleRelease()}}scheduleRelease(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>this.release(),this.idleMs),this.idleTimer.unref?.()}release(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,this.faces.clear(),this.instance=null}};var at=48*1024*1024,ve="The terminal font changed or is no longer on this workstation",v=class{font;load;subsetter;subsets=new Map;send;constructor(e,t){this.load=e.loadTerminalFont||_e,this.font=e.terminalFont!==void 0?e.terminalFont:this.load(),this.subsetter=e.fontSubsetter||new A,this.send=t}publicFont(){return M(this.font)}pickUp(){if(this.font)return;let e=null;try{e=this.load()}catch{return}e&&(this.font=e,this.send({type:"terminal_font",terminalFont:M(e)}))}refresh(){try{let e=this.load({refresh:!0});e&&(this.font=e)}catch(e){process.stderr.write(`herdr-remote host connector: could not read the terminal font: ${e.message}
4
- `)}this.send({type:"terminal_font",terminalFont:this.publicFont()})}sendChunk(e,t){let r=this.subsetChunk(t.sha256,t.index)||ye(this.font,t.sha256,t.index);if(!r){this.send({type:"error",clientId:e,code:"host_font_unavailable",message:ve});return}this.send({type:"host_font_chunk",clientId:e,sha256:t.sha256,index:t.index,total:r.total,dataBase64:r.data.toString("base64")})}sendSubset(e,t){let r=(l,c)=>this.send({type:"error",clientId:e,code:l,message:c}),n=this.font?.subsets?.find(l=>l.sha256===t.sha256);if(!n||!this.unchanged(n)){r("host_font_unavailable",ve);return}let i=[...new Set(Array.from(String(t.text||""),l=>l.codePointAt(0)))],o;try{o=this.subsetter.subset(n,i)}catch(l){r("host_font_subset_failed",l.message||"The font could not be subset");return}let a=it.createHash("sha256").update(o).digest("hex"),h={type:"host_font_subset_ready",clientId:e,requestId:t.requestId,sha256:n.sha256,subsetSha:a,bytes:o.length};o.length<=262144?h.dataBase64=o.toString("base64"):this.hold(a,o),this.send(h)}unchanged(e){try{let t=ot.statSync(e.path);return t.size===e.bytes&&t.mtimeMs===e.mtimeMs}catch{return!1}}hold(e,t){this.subsets.delete(e),this.subsets.set(e,t);let r=[...this.subsets.values()].reduce((n,i)=>n+i.length,0);for(let[n,i]of this.subsets){if(r<=at||n===e)break;this.subsets.delete(n),r-=i.length}}subsetChunk(e,t){let r=this.subsets.get(e);if(!r)return null;let n=Math.ceil(r.length/262144);if(!Number.isInteger(t)||t<0||t>=n)return null;let i=t*262144;return{data:r.subarray(i,i+262144),total:n}}};import lt from"node:os";import ct from"node:fs";var Pe=["ctrl+b"];function Fe(s=process.env,e=process.platform){let t;try{t=ct.readFileSync(fe(s,e),"utf8")}catch{return[...Pe]}let r=ge(t)["keys.prefix"];return X(typeof r=="string"?[r]:r)??[...Pe]}function Oe(s){return{type:"host_hello",protocol:1,hostId:s.hostId,token:s.token,password:s.password||null,hostname:lt.hostname(),platform:process.platform,...process.platform==="win32"&&(process.env.MSYSTEM||/(?:^|[\\/])(?:bash|sh)(?:\.exe)?$/i.test(process.env.SHELL||""))?{shellProfile:"git-bash"}:{},arch:process.arch,version:s.version,terminalPalette:s.terminalPalette||null,terminalFont:s.terminalFont,herdrPrefixKeys:Fe(),capabilities:[w.hostHandoff,w.idleHeartbeat,w.binaryFrameV2,...process.platform==="win32"?[w.adminTabs]:[]]}}import _ from"node:fs";import dt from"node:path";function Le(s){try{return JSON.parse(_.readFileSync(s,"utf8"))}catch{return null}}function xe(s,e){let t=new Error(s);return t.code=e,t}function Me(s,e){p(dt.dirname(s));for(let t=0;t<2;t+=1)try{let r=_.openSync(s,"wx",384);return _.writeFileSync(r,`${JSON.stringify({pid:process.pid,processStart:re(process.pid),hostId:e,startedAt:new Date().toISOString()})}
5
- `),r}catch(r){if(r.code!=="EEXIST")throw r;let n=Le(s);if(n&&se([n]).length>0)throw xe(`another host connector is already running (pid ${n.pid})`,"HOST_ALREADY_RUNNING");try{_.rmSync(s,{force:!0})}catch{}}throw xe("could not acquire host connector lock","HOST_LOCK_FAILED")}function Ce(s,e){try{_.closeSync(e)}catch{}let t=Le(s);if(!(t&&t.pid!==process.pid))try{_.rmSync(s,{force:!0})}catch{}}import P from"node:fs";import ut from"node:net";import ft from"node:path";import{spawn as mt}from"node:child_process";var pt=1e3,gt=2e4,yt=200;function D(s,{connect:e=ut.connect,timeout:t=pt}={}){let r=k(s);return r.ok?new Promise(n=>{let i,o=h=>{clearTimeout(a),i&&(i.removeAllListeners(),i.on("error",()=>{}),i.destroy()),n(h)},a=setTimeout(()=>o({state:"running"}),t);typeof a.unref=="function"&&a.unref(),i=e(me(s)),i.once("connect",()=>o({state:"running"})),i.once("error",h=>o(h.code==="ECONNREFUSED"||h.code==="ENOENT"?{state:"stopped",stale:!0}:{state:"unavailable",reason:h.message}))}):Promise.resolve(r.missing?{state:"stopped"}:{state:"unavailable",reason:r.reason})}function _t({platform:s=process.platform,readCgroup:e=()=>P.readFileSync("/proc/self/cgroup","utf8")}={}){if(s!=="linux")return!1;try{let t=e().split(`
6
- `).find(r=>r.startsWith("0::"));return t!==void 0&&/\.service$/.test(t.trim())}catch{return!1}}function bt(s,e=process.env){let t={...e};for(let r of Object.keys(t))r.startsWith("HERDR_")&&delete t[r];return s&&(t.HERDR_SOCKET_PATH=s),t}function wt({command:s,args:e=[],inService:t=_t()}){let r=[s,...e,"server"];return t?{file:"systemd-run",args:["--user","--scope","--quiet","--collect","--description=Herdr server started by herdr-remote","--",...r]}:{file:r[0],args:r.slice(1)}}function Tt({command:s,args:e=[],socketPath:t,cwd:r,logPath:n,spawnProcess:i=mt,inService:o}){let{file:a,args:h}=wt({command:s,args:e,inService:o});p(ft.dirname(n));let l=P.openSync(n,"a"),c;try{c=i(a,h,{cwd:r,env:bt(t),detached:!0,windowsHide:!0,stdio:["ignore",l,l]})}finally{P.closeSync(l)}return c.on("error",()=>{}),c.unref(),c}function St(s,e=2e3){try{return P.readFileSync(s,"utf8").slice(-e).trim()}catch{return""}}async function Ne({command:s,args:e=[],socketPath:t,cwd:r,logPath:n,probe:i=D,launch:o=Tt,timeout:a=gt,interval:h=yt}){let l=await i(t);if(l.state==="running")return{started:!1};if(l.state==="unavailable")throw new Error(`Herdr socket at ${t} cannot be used: ${l.reason}`);let c=o({command:s,args:e,socketPath:t,cwd:r,logPath:n}),f=null;c.once("exit",(B,S)=>{f={code:B,signal:S}});let Ve=Date.now()+a;for(;;){if(await new Promise(Be=>setTimeout(Be,h)),(await i(t)).state==="running")return{started:!0};let S=St(n),z=S?`
7
- ${S}`:"";if(f)throw new Error(`Herdr server exited (${f.signal||`code ${f.code}`}) before opening ${t}.${z}`);if(Date.now()>=Ve)throw new Error(`Herdr server did not open ${t} within ${Math.round(a/1e3)}s.${z}`)}}function m(s,e){s&&s.readyState===d.default.OPEN&&s.send(JSON.stringify(e))}function Re(s,e="host connector stopping"){if(!(!s||s.readyState===d.default.CLOSED||s.readyState===d.default.CLOSING))try{s.close(1e3,e)}catch{}}function U(s){if(!s||s.readyState===d.default.CLOSED)return;let e=s;try{typeof e.terminate=="function"?e.terminate():typeof e.destroy=="function"?e.destroy():e.close?.()}catch{}}function u(s){let e=s.clientId||s.streamId;return typeof e=="string"&&e?e:null}var It=1500,Et=4,At=3,F=class{byStream=new Map;streamIndexToId=new Map;waitingForHerdr=new Map;probingStarts=new Map;herdrLaunch=null;herdrVersionWarned=!1;fastFailures=0;herdrCommand;herdrArgs;socketPath;cwd;herdrLookup;herdrLogPath;readHerdrVersion;Pty;probeHerdr;ensureHerdr;link;constructor(e,t){this.socketPath=e.socketPath,this.herdrLookup=e.herdrLookup||{},this.herdrCommand=e.herdrCommand||ce(this.herdrLookup),this.herdrArgs=e.herdrArgs,this.cwd=e.cwd,this.herdrLogPath=e.herdrLogPath,this.readHerdrVersion=e.readHerdrVersion||le,this.Pty=e.PtySession||g,this.probeHerdr=e.probeHerdr||D,this.ensureHerdr=e.ensureHerdr||Ne,this.link=t}sendError(e,t,r){this.link.send({type:"error",clientId:e,code:t,message:r})}ensureHerdrCommand(){let e=he(this.herdrCommand,this.herdrLookup);return e.found?(this.herdrCommand=e.command,this.warnIfHerdrOutdated(),null):ue(this.herdrLookup)}warnIfHerdrOutdated(){if(this.herdrVersionWarned)return;let e=this.readHerdrVersion({command:this.herdrCommand});if(e.supported){e.version&&(this.herdrVersionWarned=!0);return}this.herdrVersionWarned=!0,process.stderr.write(`herdr-remote host connector: ${de(e.version)}
3
+ import"../chunks/C2UUZY6J.js";import{a as Se,b as ke,d as Ie}from"../chunks/FN6VM2O7.js";import"../chunks/3FQAXVGC.js";import{a as g}from"../chunks/42KARAL4.js";import{a as d}from"../chunks/7SMZ43LI.js";import{a as pe,b as ye,c as ge,d as k}from"../chunks/JJGEV4EZ.js";import{a as _e,d as M,e as be,i as we}from"../chunks/S3V2O6BK.js";import{m as Te}from"../chunks/ZZOEVJ3V.js";import"../chunks/U6QAYG3E.js";import"../chunks/MLSLOPR7.js";import{b as oe,e as ae,g as L,h as ce,i as he,m as le,n as de,o as ue,p as fe,q as me}from"../chunks/72JMGTAK.js";import{h as ee,i as te,o as re}from"../chunks/MHS44P3Y.js";import{b as ne,c as ie}from"../chunks/KRVF37OW.js";import{a as y,d as se}from"../chunks/QRGNEKME.js";import{a as G,b as Y,c as W,h as X,j as p,k as q,l as j,m as J,n as Q,o as Z}from"../chunks/NKDFWWLU.js";import{a as K,c as w}from"../chunks/TNLCNVA2.js";import"../chunks/I6NRCYLI.js";import Ot from"node:os";import Ve from"node:path";import Ee from"node:crypto";import _ from"node:fs";import C from"node:path";var We=20,Xe=50*1024*1024,qe=1440*60*1e3;function Ae(){let s=C.join(w(),"pasted");return y(s),s}function I({dir:s=Ae(),maxFiles:e=We,maxBytes:t=Xe,maxAgeMs:r=qe,now:n=Date.now()}={}){let i;try{i=_.readdirSync(s,{withFileTypes:!0})}catch{return}let o=[];for(let h of i){if(!h.isFile())continue;let l=C.join(s,h.name);try{let c=_.statSync(l);if(n-c.mtimeMs>r){try{_.unlinkSync(l)}catch{}continue}o.push({path:l,size:c.size,mtimeMs:c.mtimeMs})}catch{}}o.sort((h,l)=>h.mtimeMs-l.mtimeMs);let a=o.reduce((h,l)=>h+l.size,0);for(;o.length>e||a>t;){let h=o.shift();if(!h)break;try{_.unlinkSync(h.path),a-=h.size}catch{}}}function He({mime:s,dataBase64:e,name:t,dir:r=Ae()}){let n=Q(s)?s:null;if(!n&&s!==q)throw new Error(`unsupported MIME type: ${s}`);if(typeof e!="string")throw new Error("missing or invalid dataBase64 payload");let i=Buffer.from(e,"base64");if(i.length>3145728)throw new Error(`file size (${i.length} bytes) exceeds maximum limit of 3 MB`);if(i.length===0)throw new Error("file payload is empty");if(n&&!Z(n,i))throw new Error(`file magic bytes do not match declared MIME type ${s}`);I({dir:r});let o=n?`${Ee.randomUUID()}${J[n]}`:`${Ee.randomUUID()}-${j(t)}`,a=C.join(r,o);_.writeFileSync(a,i,{mode:384,flag:"wx"});try{_.chmodSync(a,384)}catch{}return I({dir:r}),a}var T=["blocked","done","working","idle","unknown"];function ve(s,e=48){if(typeof s!="string")return null;let t=s.replace(/[\u0000-\u001F\u007F-\u009F]/g," ").replace(/\s+/g," ").trim();return t?t.length>e?t.slice(0,e):t:null}function je(s){return T.includes(s)?s:"unknown"}function Je(){return Object.fromEntries(T.map(s=>[s,0]))}function Pe(s){let e=Array.isArray(s?.agents)?s.agents:[],t=Array.isArray(s?.panes)?s.panes:[],r=typeof s?.focused_pane_id=="string"&&s.focused_pane_id?s.focused_pane_id:null,n=(r?t.find(c=>c?.pane_id===r):t.find(c=>c?.focused===!0))||null,i=(r?e.find(c=>c?.pane_id===r):e.find(c=>c?.focused===!0))||null,o=r||(typeof n?.pane_id=="string"?n.pane_id:null)||(typeof i?.pane_id=="string"?i.pane_id:null),a=typeof n?.agent=="string"?n.agent:typeof i?.agent=="string"?i.agent:null,h=Je(),l=[];for(let c of e){if(!c||typeof c.pane_id!="string")continue;let f=je(c.agent_status);h[f]+=1,l.push({paneId:c.pane_id,workspaceId:typeof c.workspace_id=="string"?c.workspace_id:null,agent:ve(c.display_agent||c.agent,24),title:ve(c.terminal_title_stripped||c.terminal_title),status:f,focused:c.focused===!0})}return l.sort((c,f)=>T.indexOf(c.status)-T.indexOf(f.status)),{focusedPaneId:o,focusedAgent:a,counts:h,total:l.length,agents:l.slice(0,16)}}function Fe(s,e){if(!s||!e)return s===e;if(s.focusedPaneId!==e.focusedPaneId||s.focusedAgent!==e.focusedAgent||s.total!==e.total)return!1;for(let t of T)if((s.counts?.[t]||0)!==(e.counts?.[t]||0))return!1;return s.agents.length!==e.agents.length?!1:s.agents.every((t,r)=>{let n=e.agents[r];return n&&t.paneId===n.paneId&&t.status===n.status&&t.agent===n.agent&&t.title===n.title})}var Qe=5e3,Ze=150,et=[{type:"pane.focused"},{type:"tab.focused"},{type:"workspace.focused"},{type:"pane.agent_detected"}],E=class{socketPath;request;subscribe;send;pollTimer=null;debounceTimer=null;subscription=null;pending=!1;stale=!1;lastSummary=null;constructor(e,t){this.socketPath=e.socketPath,this.request=e.requestHerdr||Se,this.subscribe=e.subscribeHerdr||ke,this.send=t}start(){if(!this.pollTimer){this.pollTimer=setInterval(()=>this.read(),Qe),this.pollTimer.unref?.();try{this.subscription=this.subscribe(this.socketPath,et,()=>this.scheduleRead(),{onStarted:()=>this.scheduleRead()})}catch{}this.read()}}stop(){this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.subscription&&(this.subscription.close(),this.subscription=null),this.stale=!1,this.lastSummary=null}scheduleRead(){this.pollTimer&&(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.read()},Ze),this.debounceTimer.unref?.())}async read(){if(!this.pollTimer)return;if(this.pending){this.stale=!0;return}this.pending=!0,this.stale=!1;let e;try{let r=await this.request(this.socketPath,"session.snapshot",{});e=r?.snapshot||r}catch{return}finally{this.pending=!1,this.stale&&this.scheduleRead()}if(!this.pollTimer)return;let t=Pe(e);Fe(this.lastSummary,t)||(this.lastSummary=t,this.send({type:"agent_status",...t}))}};import at from"node:crypto";import ct from"node:fs";import{createRequire as tt}from"node:module";import R from"node:fs";import rt from"node:path";var st=6e4,nt=16384,it=1,N=null;function ot(){if(!N){let s=rt.join(K,"dist","harfbuzz-subset.wasm"),e=R.existsSync(s)?s:tt(import.meta.url).resolve("harfbuzzjs/dist/harfbuzz-subset.wasm");N=new WebAssembly.Module(R.readFileSync(e))}return N}var A=class{idleMs;instance=null;faces=new Map;idleTimer=null;constructor({idleMs:e=st}={}){this.idleMs=e}exports(){return this.instance||(this.instance=new WebAssembly.Instance(ot(),{}).exports,this.instance._initialize()),this.instance}face(e){let t=`${e.path}\0${e.index||0}`,r=this.faces.get(t);if(r)return r.face;let n=this.exports(),i=R.readFileSync(e.path),o=n.malloc(i.length);if(!o)throw new Error("out of memory loading font");new Uint8Array(n.memory.buffer).set(i,o);let a=n.hb_blob_create(o,i.length,it,0,0),h=n.hb_face_create(a,e.index||0);return n.hb_blob_destroy(a),this.faces.set(t,{pointer:o,face:h}),h}subset(e,t){let r=this.exports(),n=this.face(e),i=r.hb_subset_input_create_or_fail();if(!i)throw new Error("font subsetting is unavailable");let o=0,a=0;try{let h=r.hb_subset_input_unicode_set(i);for(let f of t.slice(0,nt))r.hb_set_add(h,f);if(a=r.hb_subset_or_fail(n,i),!a)throw new Error("the font could not be subset");o=r.hb_face_reference_blob(a);let l=r.hb_blob_get_length(o),c=r.hb_blob_get_data(o,0);return Buffer.from(new Uint8Array(r.memory.buffer,c,l))}finally{o&&r.hb_blob_destroy(o),a&&r.hb_face_destroy(a),r.hb_subset_input_destroy(i),this.scheduleRelease()}}scheduleRelease(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>this.release(),this.idleMs),this.idleTimer.unref?.()}release(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=null,this.faces.clear(),this.instance=null}};var ht=48*1024*1024,Oe="The terminal font changed or is no longer on this workstation",v=class{font;load;subsetter;subsets=new Map;send;constructor(e,t){this.load=e.loadTerminalFont||we,this.font=e.terminalFont!==void 0?e.terminalFont:this.load(),this.subsetter=e.fontSubsetter||new A,this.send=t}publicFont(){return M(this.font)}pickUp(){if(this.font)return;let e=null;try{e=this.load()}catch{return}e&&(this.font=e,this.send({type:"terminal_font",terminalFont:M(e)}))}refresh(){try{let e=this.load({refresh:!0});e&&(this.font=e)}catch(e){process.stderr.write(`herdr-remote host connector: could not read the terminal font: ${e.message}
4
+ `)}this.send({type:"terminal_font",terminalFont:this.publicFont()})}sendChunk(e,t){let r=this.subsetChunk(t.sha256,t.index)||be(this.font,t.sha256,t.index);if(!r){this.send({type:"error",clientId:e,code:"host_font_unavailable",message:Oe});return}this.send({type:"host_font_chunk",clientId:e,sha256:t.sha256,index:t.index,total:r.total,dataBase64:r.data.toString("base64")})}sendSubset(e,t){let r=(l,c)=>this.send({type:"error",clientId:e,code:l,message:c}),n=this.font?.subsets?.find(l=>l.sha256===t.sha256);if(!n||!this.unchanged(n)){r("host_font_unavailable",Oe);return}let i=[...new Set(Array.from(String(t.text||""),l=>l.codePointAt(0)))],o;try{o=this.subsetter.subset(n,i)}catch(l){r("host_font_subset_failed",l.message||"The font could not be subset");return}let a=at.createHash("sha256").update(o).digest("hex"),h={type:"host_font_subset_ready",clientId:e,requestId:t.requestId,sha256:n.sha256,subsetSha:a,bytes:o.length};o.length<=262144?h.dataBase64=o.toString("base64"):this.hold(a,o),this.send(h)}unchanged(e){try{let t=ct.statSync(e.path);return t.size===e.bytes&&t.mtimeMs===e.mtimeMs}catch{return!1}}hold(e,t){this.subsets.delete(e),this.subsets.set(e,t);let r=[...this.subsets.values()].reduce((n,i)=>n+i.length,0);for(let[n,i]of this.subsets){if(r<=ht||n===e)break;this.subsets.delete(n),r-=i.length}}subsetChunk(e,t){let r=this.subsets.get(e);if(!r)return null;let n=Math.ceil(r.length/262144);if(!Number.isInteger(t)||t<0||t>=n)return null;let i=t*262144;return{data:r.subarray(i,i+262144),total:n}}};import ut from"node:os";import lt from"node:fs";var xe=["ctrl+b"];function Le(s=process.env,e=process.platform){let t;try{t=lt.readFileSync(pe(s,e),"utf8")}catch{return[...xe]}let r=_e(t)["keys.prefix"];return X(typeof r=="string"?[r]:r)??[...xe]}function Me(s){return{type:"host_hello",protocol:1,hostId:s.hostId,token:s.token,password:s.password||null,hostname:ut.hostname(),platform:process.platform,...process.platform==="win32"&&(process.env.MSYSTEM||/(?:^|[\\/])(?:bash|sh)(?:\.exe)?$/i.test(process.env.SHELL||""))?{shellProfile:"git-bash"}:{},arch:process.arch,version:s.version,terminalPalette:s.terminalPalette||null,terminalFont:s.terminalFont,herdrPrefixKeys:Le(),capabilities:[p.hostHandoff,p.idleHeartbeat,p.binaryFrameV2,p.pasteAnyFile,...process.platform==="win32"?[p.adminTabs]:[]]}}import b from"node:fs";import ft from"node:path";function Ne(s){try{return JSON.parse(b.readFileSync(s,"utf8"))}catch{return null}}function Ce(s,e){let t=new Error(s);return t.code=e,t}function Re(s,e){y(ft.dirname(s));for(let t=0;t<2;t+=1)try{let r=b.openSync(s,"wx",384);return b.writeFileSync(r,`${JSON.stringify({pid:process.pid,processStart:ne(process.pid),hostId:e,startedAt:new Date().toISOString()})}
5
+ `),r}catch(r){if(r.code!=="EEXIST")throw r;let n=Ne(s);if(n&&ie([n]).length>0)throw Ce(`another host connector is already running (pid ${n.pid})`,"HOST_ALREADY_RUNNING");try{b.rmSync(s,{force:!0})}catch{}}throw Ce("could not acquire host connector lock","HOST_LOCK_FAILED")}function De(s,e){try{b.closeSync(e)}catch{}let t=Ne(s);if(!(t&&t.pid!==process.pid))try{b.rmSync(s,{force:!0})}catch{}}import P from"node:fs";import mt from"node:net";import pt from"node:path";import{spawn as yt}from"node:child_process";var gt=1e3,_t=2e4,bt=200;function D(s,{connect:e=mt.connect,timeout:t=gt}={}){let r=k(s);return r.ok?new Promise(n=>{let i,o=h=>{clearTimeout(a),i&&(i.removeAllListeners(),i.on("error",()=>{}),i.destroy()),n(h)},a=setTimeout(()=>o({state:"running"}),t);typeof a.unref=="function"&&a.unref(),i=e(ye(s)),i.once("connect",()=>o({state:"running"})),i.once("error",h=>o(h.code==="ECONNREFUSED"||h.code==="ENOENT"?{state:"stopped",stale:!0}:{state:"unavailable",reason:h.message}))}):Promise.resolve(r.missing?{state:"stopped"}:{state:"unavailable",reason:r.reason})}function wt({platform:s=process.platform,readCgroup:e=()=>P.readFileSync("/proc/self/cgroup","utf8")}={}){if(s!=="linux")return!1;try{let t=e().split(`
6
+ `).find(r=>r.startsWith("0::"));return t!==void 0&&/\.service$/.test(t.trim())}catch{return!1}}function Tt(s,e=process.env){let t={...e};for(let r of Object.keys(t))r.startsWith("HERDR_")&&delete t[r];return s&&(t.HERDR_SOCKET_PATH=s),t}function St({command:s,args:e=[],inService:t=wt()}){let r=[s,...e,"server"];return t?{file:"systemd-run",args:["--user","--scope","--quiet","--collect","--description=Herdr server started by herdr-remote","--",...r]}:{file:r[0],args:r.slice(1)}}function kt({command:s,args:e=[],socketPath:t,cwd:r,logPath:n,spawnProcess:i=yt,inService:o}){let{file:a,args:h}=St({command:s,args:e,inService:o});y(pt.dirname(n));let l=P.openSync(n,"a"),c;try{c=i(a,h,{cwd:r,env:Tt(t),detached:!0,windowsHide:!0,stdio:["ignore",l,l]})}finally{P.closeSync(l)}return c.on("error",()=>{}),c.unref(),c}function It(s,e=2e3){try{return P.readFileSync(s,"utf8").slice(-e).trim()}catch{return""}}async function Ue({command:s,args:e=[],socketPath:t,cwd:r,logPath:n,probe:i=D,launch:o=kt,timeout:a=_t,interval:h=bt}){let l=await i(t);if(l.state==="running")return{started:!1};if(l.state==="unavailable")throw new Error(`Herdr socket at ${t} cannot be used: ${l.reason}`);let c=o({command:s,args:e,socketPath:t,cwd:r,logPath:n}),f=null;c.once("exit",(B,S)=>{f={code:B,signal:S}});let Ke=Date.now()+a;for(;;){if(await new Promise(Ge=>setTimeout(Ge,h)),(await i(t)).state==="running")return{started:!0};let S=It(n),z=S?`
7
+ ${S}`:"";if(f)throw new Error(`Herdr server exited (${f.signal||`code ${f.code}`}) before opening ${t}.${z}`);if(Date.now()>=Ke)throw new Error(`Herdr server did not open ${t} within ${Math.round(a/1e3)}s.${z}`)}}function m(s,e){s&&s.readyState===d.default.OPEN&&s.send(JSON.stringify(e))}function $e(s,e="host connector stopping"){if(!(!s||s.readyState===d.default.CLOSED||s.readyState===d.default.CLOSING))try{s.close(1e3,e)}catch{}}function U(s){if(!s||s.readyState===d.default.CLOSED)return;let e=s;try{typeof e.terminate=="function"?e.terminate():typeof e.destroy=="function"?e.destroy():e.close?.()}catch{}}function u(s){let e=s.clientId||s.streamId;return typeof e=="string"&&e?e:null}var At=1500,Ht=4,vt=3,F=class{byStream=new Map;streamIndexToId=new Map;waitingForHerdr=new Map;probingStarts=new Map;herdrLaunch=null;herdrVersionWarned=!1;fastFailures=0;herdrCommand;herdrArgs;socketPath;cwd;herdrLookup;herdrLogPath;readHerdrVersion;Pty;probeHerdr;ensureHerdr;link;constructor(e,t){this.socketPath=e.socketPath,this.herdrLookup=e.herdrLookup||{},this.herdrCommand=e.herdrCommand||le(this.herdrLookup),this.herdrArgs=e.herdrArgs,this.cwd=e.cwd,this.herdrLogPath=e.herdrLogPath,this.readHerdrVersion=e.readHerdrVersion||ue,this.Pty=e.PtySession||g,this.probeHerdr=e.probeHerdr||D,this.ensureHerdr=e.ensureHerdr||Ue,this.link=t}sendError(e,t,r){this.link.send({type:"error",clientId:e,code:t,message:r})}ensureHerdrCommand(){let e=de(this.herdrCommand,this.herdrLookup);return e.found?(this.herdrCommand=e.command,this.warnIfHerdrOutdated(),null):me(this.herdrLookup)}warnIfHerdrOutdated(){if(this.herdrVersionWarned)return;let e=this.readHerdrVersion({command:this.herdrCommand});if(e.supported){e.version&&(this.herdrVersionWarned=!0);return}this.herdrVersionWarned=!0,process.stderr.write(`herdr-remote host connector: ${fe(e.version)}
8
8
  `)}start(e){let t=u(e);if(!t)return;this.stop(t);let r=this.ensureHerdrCommand();if(r){process.stderr.write(`herdr-remote host connector: ${r}
9
9
  `),this.sendError(t,"herdr_not_found",r);return}let n=k(this.socketPath);if(!n.ok&&!n.missing){this.sendError(t,"herdr_socket_unavailable",n.reason);return}if(!n.ok){this.waitForHerdr(t,e);return}let i={message:e};return this.probingStarts.set(t,i),this.probeHerdr(this.socketPath).then(o=>{this.probingStarts.get(t)===i&&(this.probingStarts.delete(t),o.state==="running"?this.spawn(i.message):o.state==="stopped"?this.waitForHerdr(t,i.message):this.sendError(t,"herdr_socket_unavailable",o.reason))})}waitForHerdr(e,t){this.waitingForHerdr.set(e,t),this.sendError(e,"herdr_not_running",`Herdr is not running on this workstation (${this.socketPath}).`)}startHerdr(){return this.herdrLaunch||(this.herdrLaunch=Promise.resolve().then(()=>{let e=this.ensureHerdrCommand();if(e)throw new Error(e);return this.ensureHerdr({command:this.herdrCommand,args:this.herdrArgs,socketPath:this.socketPath,cwd:this.cwd,logPath:this.herdrLogPath})}).finally(()=>{this.herdrLaunch=null})),this.herdrLaunch}async startHerdrFor(e){try{(await this.startHerdr()).started&&process.stderr.write(`herdr-remote host connector: started Herdr at a browser's request
10
10
  `)}catch(r){let{message:n}=r;process.stderr.write(`herdr-remote host connector: could not start Herdr: ${n}
11
- `),e&&this.sendError(e,"herdr_start_failed",n);return}let t=[...this.waitingForHerdr.values()];this.waitingForHerdr.clear();for(let r of t)this.spawn(r)}spawn(e){let t=u(e),r=typeof e.streamIndex=="number"?e.streamIndex:null,n=new this.Pty({command:this.herdrCommand,args:this.herdrArgs,cwd:this.cwd,socketPath:this.socketPath}),i={id:t,streamIndex:r,pty:n,cols:Number(e.cols)||g.DEFAULT_COLS,rows:Number(e.rows)||g.DEFAULT_ROWS,createdAt:new Date().toISOString(),startedAtMs:Date.now(),pendingOutput:[],flushImmediate:null,flushTimeout:null},o=()=>{if(i.flushImmediate&&(clearImmediate(i.flushImmediate),i.flushImmediate=null),i.flushTimeout&&(clearTimeout(i.flushTimeout),i.flushTimeout=null),i.pendingOutput.length===0)return;let a=Buffer.concat(i.pendingOutput);i.pendingOutput=[],this.link.sendFrame(i.streamIndex!==null?Y(0,i.streamIndex,a):G("output",t,a))};try{n.start({cols:i.cols,rows:i.rows,onData:a=>{let h=Buffer.isBuffer(a)?a:Buffer.from(a,"utf8");h.length!==0&&(i.pendingOutput.push(h),!i.flushImmediate&&!i.flushTimeout&&(process.platform==="win32"?i.flushTimeout=setTimeout(o,Et):i.flushImmediate=setImmediate(o)))},onExit:({exitCode:a})=>{this.byStream.get(t)===i&&(this.forget(i),this.reportExit(i,a),this.link.changed())}})}catch(a){$(i),this.sendError(t,"pty_start_failed",a.message),n.kill();return}this.byStream.set(t,i),r!==null&&this.streamIndexToId.set(r,t),this.link.send({type:"session_ready",clientId:t}),this.link.changed()}reportExit(e,t){let r=e.id,n=Date.now()-e.startedAtMs,i=t!==0&&n<It;if(this.fastFailures=i?this.fastFailures+1:0,this.fastFailures<At){this.link.send({type:"session_exit",clientId:r,code:t});return}let o=`"${this.herdrCommand}" exited immediately with code ${t} on ${this.fastFailures} attempts in a row. Check that it runs from a terminal, and see the host connector log for what it printed.`;process.stderr.write(`herdr-remote host connector: ${o}
12
- `),this.sendError(r,"herdr_start_failed",o)}write(e,t){let r=e.streamIndex!==void 0?this.streamIndexToId.get(e.streamIndex):e.streamId;r&&this.byStream.get(r)?.pty.write(t)}resize(e){let t=u(e);if(!t)return;let r=this.waitingForHerdr.get(t)||this.probingStarts.get(t)?.message;r&&(Number.isInteger(e.cols)&&(r.cols=e.cols),Number.isInteger(e.rows)&&(r.rows=e.rows));let n=this.byStream.get(t);n&&(Number.isInteger(e.cols)&&(n.cols=g.clampDimension(e.cols,0)),Number.isInteger(e.rows)&&(n.rows=g.clampDimension(e.rows,0)),n.pty.resize(n.cols,n.rows))}stop(e){this.waitingForHerdr.delete(e),this.probingStarts.delete(e);let t=this.byStream.get(e);t&&(this.forget(t),t.pty.kill(),this.link.changed())}stopAll(){for(let e of this.byStream.values())$(e),e.pty.kill();this.byStream.clear(),this.streamIndexToId.clear(),this.waitingForHerdr.clear(),this.probingStarts.clear()}summaries(){return[...this.byStream.values()].map(e=>({id:e.id,pid:e.pty.terminal?.pid||null,command:e.pty.command,cols:e.cols,rows:e.rows,cwd:e.pty.cwd,createdAt:e.createdAt,activeClients:1}))}forget(e){this.byStream.delete(e.id),e.streamIndex!==null&&this.streamIndexToId.delete(e.streamIndex),$(e)}};function $(s){s.flushImmediate&&(clearImmediate(s.flushImmediate),s.flushImmediate=null),s.flushTimeout&&(clearTimeout(s.flushTimeout),s.flushTimeout=null),s.pendingOutput=[]}var Ht=6e4,O=class{checkUpdate;readInstalledVersion;runningVersion;send;checkedAt=0;pending=null;constructor(e,t){this.checkUpdate=e.checkUpdate!==void 0?e.checkUpdate:ie()?oe:null,this.readInstalledVersion=e.readInstalledVersion||ae,this.runningVersion=e.runningVersion||ne(),this.send=t}report({now:e=Date.now()}={}){let t=this.checkUpdate;return!t||this.pending?this.pending:e-this.checkedAt<Ht?null:(this.checkedAt=e,this.pending=Promise.resolve().then(()=>t()).then(r=>{if(!r?.ok||!r.latest)return;let n=this.runningVersion,i=this.readInstalledVersion()||n;this.send({type:"update_status",current:n,installed:i,latest:r.latest,updateAvailable:L(r.latest,n)>0,restartPending:L(i,n)>0,updateCommand:!0})}).catch(()=>{}).finally(()=>{this.pending=null}),this.pending)}};var Ft=["relay_password_required","host_auth_failed","invalid_host_credentials"],x=class{config;relayUrl;hostId;hostToken;relayPassword;socketPath;terminalPalette;sessions;font;agents;updates;ws=null;reconnectTimer=null;heartbeatTimer=null;keepaliveTimer=null;reconnectAttempts=0;clientCount=0;legacyHeartbeat=!1;authFailure=!1;stopping=!1;lockPath;lockFd=null;onFatal;constructor(e={}){let t=e.config||ee();this.config=t,this.relayUrl=e.relayUrl||(process.env.RELAY_URL?Z(process.env.RELAY_URL):Q(t)),this.hostId=e.hostId||process.env.RELAY_HOST_ID||`host-${te(9)}`,this.hostToken=e.hostToken||process.env.RELAY_HOST_TOKEN||"",this.relayPassword=e.relayPassword??process.env.RELAY_PASSWORD??"",this.socketPath=e.socketPath||pe(t.herdr.socketPath),this.terminalPalette=e.terminalPalette!==void 0?e.terminalPalette:be();let r=n=>m(this.ws,n);this.sessions=new F({...e,socketPath:this.socketPath,herdrArgs:e.herdrArgs||t.herdr.args,cwd:e.cwd||t.herdr.cwd,herdrLogPath:e.herdrLogPath||De.join(b(),"herdr-server.log")},{send:r,sendFrame:n=>{this.ws?.readyState===d.default.OPEN&&this.ws.send(n)},changed:()=>this.sendHeartbeat()}),this.font=new v(e,r),this.agents=new E({...e,socketPath:this.socketPath},r),this.updates=new O(e,r),this.lockPath=e.lockPath||process.env.HERDR_REMOTE_HOST_LOCK||De.join(b(),"host-connector.lock"),this.onFatal=e.onFatal||(n=>process.exit(n));try{I()}catch{}}acquireLock(){this.lockFd===null&&(this.lockFd=Me(this.lockPath,this.hostId))}releaseLock(){this.lockFd!==null&&(Ce(this.lockPath,this.lockFd),this.lockFd=null)}start(){if(!this.hostToken)throw new Error("RELAY_HOST_TOKEN is required");this.acquireLock(),this.stopping=!1,this.connect(),this.config.herdr?.autoStart&&this.sessions.startHerdr().catch(e=>{process.stderr.write(`herdr-remote host connector: could not start Herdr: ${e.message}
13
- `)})}stop(){this.stopping=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,m(this.ws,{type:"host_shutdown"}),this.disconnected(),Re(this.ws,"host_shutdown"),this.ws=null,this.releaseLock()}disconnected(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.stopKeepalive(),this.agents.stop(),this.clientCount=0,this.legacyHeartbeat=!1,this.sessions.stopAll()}connect(){if(this.stopping||this.ws?.readyState===d.default.OPEN||this.ws?.readyState===d.default.CONNECTING)return;this.stopKeepalive();let e;try{e=new d.default(this.relayUrl)}catch(t){this.scheduleReconnect(t);return}this.ws=e,e.isAlive=!0,e.on("open",()=>{try{e._socket?.setNoDelay(!0)}catch{}e.isAlive=!0,this.authFailure=!1,m(e,Oe({hostId:this.hostId,token:this.hostToken,password:this.relayPassword,version:this.updates.runningVersion,terminalPalette:this.terminalPalette,terminalFont:this.font.publicFont()}))}),e.on("pong",()=>{e.isAlive=!0}),e.on("message",(t,r)=>this.handleMessage(t,r)),e.on("close",(t,r)=>{if(this.ws!==e)return;if(this.ws=null,this.disconnected(),(r?r.toString():"")==="host_replaced"){process.stderr.write(`herdr-remote host connector: another instance took over this workstation; exiting
11
+ `),e&&this.sendError(e,"herdr_start_failed",n);return}let t=[...this.waitingForHerdr.values()];this.waitingForHerdr.clear();for(let r of t)this.spawn(r)}spawn(e){let t=u(e),r=typeof e.streamIndex=="number"?e.streamIndex:null,n=new this.Pty({command:this.herdrCommand,args:this.herdrArgs,cwd:this.cwd,socketPath:this.socketPath}),i={id:t,streamIndex:r,pty:n,cols:Number(e.cols)||g.DEFAULT_COLS,rows:Number(e.rows)||g.DEFAULT_ROWS,createdAt:new Date().toISOString(),startedAtMs:Date.now(),pendingOutput:[],flushImmediate:null,flushTimeout:null},o=()=>{if(i.flushImmediate&&(clearImmediate(i.flushImmediate),i.flushImmediate=null),i.flushTimeout&&(clearTimeout(i.flushTimeout),i.flushTimeout=null),i.pendingOutput.length===0)return;let a=Buffer.concat(i.pendingOutput);i.pendingOutput=[],this.link.sendFrame(i.streamIndex!==null?Y(0,i.streamIndex,a):G("output",t,a))};try{n.start({cols:i.cols,rows:i.rows,onData:a=>{let h=Buffer.isBuffer(a)?a:Buffer.from(a,"utf8");h.length!==0&&(i.pendingOutput.push(h),!i.flushImmediate&&!i.flushTimeout&&(process.platform==="win32"?i.flushTimeout=setTimeout(o,Ht):i.flushImmediate=setImmediate(o)))},onExit:({exitCode:a})=>{this.byStream.get(t)===i&&(this.forget(i),this.reportExit(i,a),this.link.changed())}})}catch(a){$(i),this.sendError(t,"pty_start_failed",a.message),n.kill();return}this.byStream.set(t,i),r!==null&&this.streamIndexToId.set(r,t),this.link.send({type:"session_ready",clientId:t}),this.link.changed()}reportExit(e,t){let r=e.id,n=Date.now()-e.startedAtMs,i=t!==0&&n<At;if(this.fastFailures=i?this.fastFailures+1:0,this.fastFailures<vt){this.link.send({type:"session_exit",clientId:r,code:t});return}let o=`"${this.herdrCommand}" exited immediately with code ${t} on ${this.fastFailures} attempts in a row. Check that it runs from a terminal, and see the host connector log for what it printed.`;process.stderr.write(`herdr-remote host connector: ${o}
12
+ `),this.sendError(r,"herdr_start_failed",o)}write(e,t){let r=e.streamIndex!==void 0?this.streamIndexToId.get(e.streamIndex):e.streamId;r&&this.byStream.get(r)?.pty.write(t)}resize(e){let t=u(e);if(!t)return;let r=this.waitingForHerdr.get(t)||this.probingStarts.get(t)?.message;r&&(Number.isInteger(e.cols)&&(r.cols=e.cols),Number.isInteger(e.rows)&&(r.rows=e.rows));let n=this.byStream.get(t);n&&(Number.isInteger(e.cols)&&(n.cols=g.clampDimension(e.cols,0)),Number.isInteger(e.rows)&&(n.rows=g.clampDimension(e.rows,0)),n.pty.resize(n.cols,n.rows))}stop(e){this.waitingForHerdr.delete(e),this.probingStarts.delete(e);let t=this.byStream.get(e);t&&(this.forget(t),t.pty.kill(),this.link.changed())}stopAll(){for(let e of this.byStream.values())$(e),e.pty.kill();this.byStream.clear(),this.streamIndexToId.clear(),this.waitingForHerdr.clear(),this.probingStarts.clear()}summaries(){return[...this.byStream.values()].map(e=>({id:e.id,pid:e.pty.terminal?.pid||null,command:e.pty.command,cols:e.cols,rows:e.rows,cwd:e.pty.cwd,createdAt:e.createdAt,activeClients:1}))}forget(e){this.byStream.delete(e.id),e.streamIndex!==null&&this.streamIndexToId.delete(e.streamIndex),$(e)}};function $(s){s.flushImmediate&&(clearImmediate(s.flushImmediate),s.flushImmediate=null),s.flushTimeout&&(clearTimeout(s.flushTimeout),s.flushTimeout=null),s.pendingOutput=[]}var Pt=6e4,O=class{checkUpdate;readInstalledVersion;runningVersion;send;checkedAt=0;pending=null;constructor(e,t){this.checkUpdate=e.checkUpdate!==void 0?e.checkUpdate:ae()?ce:null,this.readInstalledVersion=e.readInstalledVersion||he,this.runningVersion=e.runningVersion||oe(),this.send=t}report({now:e=Date.now()}={}){let t=this.checkUpdate;return!t||this.pending?this.pending:e-this.checkedAt<Pt?null:(this.checkedAt=e,this.pending=Promise.resolve().then(()=>t()).then(r=>{if(!r?.ok||!r.latest)return;let n=this.runningVersion,i=this.readInstalledVersion()||n;this.send({type:"update_status",current:n,installed:i,latest:r.latest,updateAvailable:L(r.latest,n)>0,restartPending:L(i,n)>0,updateCommand:!0})}).catch(()=>{}).finally(()=>{this.pending=null}),this.pending)}};var xt=["relay_password_required","host_auth_failed","invalid_host_credentials"],x=class{config;relayUrl;hostId;hostToken;relayPassword;socketPath;terminalPalette;sessions;font;agents;updates;ws=null;reconnectTimer=null;heartbeatTimer=null;keepaliveTimer=null;reconnectAttempts=0;clientCount=0;legacyHeartbeat=!1;authFailure=!1;stopping=!1;lockPath;lockFd=null;onFatal;constructor(e={}){let t=e.config||re();this.config=t,this.relayUrl=e.relayUrl||(process.env.RELAY_URL?te(process.env.RELAY_URL):ee(t)),this.hostId=e.hostId||process.env.RELAY_HOST_ID||`host-${se(9)}`,this.hostToken=e.hostToken||process.env.RELAY_HOST_TOKEN||"",this.relayPassword=e.relayPassword??process.env.RELAY_PASSWORD??"",this.socketPath=e.socketPath||ge(t.herdr.socketPath),this.terminalPalette=e.terminalPalette!==void 0?e.terminalPalette:Te();let r=n=>m(this.ws,n);this.sessions=new F({...e,socketPath:this.socketPath,herdrArgs:e.herdrArgs||t.herdr.args,cwd:e.cwd||t.herdr.cwd,herdrLogPath:e.herdrLogPath||Ve.join(w(),"herdr-server.log")},{send:r,sendFrame:n=>{this.ws?.readyState===d.default.OPEN&&this.ws.send(n)},changed:()=>this.sendHeartbeat()}),this.font=new v(e,r),this.agents=new E({...e,socketPath:this.socketPath},r),this.updates=new O(e,r),this.lockPath=e.lockPath||process.env.HERDR_REMOTE_HOST_LOCK||Ve.join(w(),"host-connector.lock"),this.onFatal=e.onFatal||(n=>process.exit(n));try{I()}catch{}}acquireLock(){this.lockFd===null&&(this.lockFd=Re(this.lockPath,this.hostId))}releaseLock(){this.lockFd!==null&&(De(this.lockPath,this.lockFd),this.lockFd=null)}start(){if(!this.hostToken)throw new Error("RELAY_HOST_TOKEN is required");this.acquireLock(),this.stopping=!1,this.connect(),this.config.herdr?.autoStart&&this.sessions.startHerdr().catch(e=>{process.stderr.write(`herdr-remote host connector: could not start Herdr: ${e.message}
13
+ `)})}stop(){this.stopping=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,m(this.ws,{type:"host_shutdown"}),this.disconnected(),$e(this.ws,"host_shutdown"),this.ws=null,this.releaseLock()}disconnected(){this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.stopKeepalive(),this.agents.stop(),this.clientCount=0,this.legacyHeartbeat=!1,this.sessions.stopAll()}connect(){if(this.stopping||this.ws?.readyState===d.default.OPEN||this.ws?.readyState===d.default.CONNECTING)return;this.stopKeepalive();let e;try{e=new d.default(this.relayUrl)}catch(t){this.scheduleReconnect(t);return}this.ws=e,e.isAlive=!0,e.on("open",()=>{try{e._socket?.setNoDelay(!0)}catch{}e.isAlive=!0,this.authFailure=!1,m(e,Me({hostId:this.hostId,token:this.hostToken,password:this.relayPassword,version:this.updates.runningVersion,terminalPalette:this.terminalPalette,terminalFont:this.font.publicFont()}))}),e.on("pong",()=>{e.isAlive=!0}),e.on("message",(t,r)=>this.handleMessage(t,r)),e.on("close",(t,r)=>{if(this.ws!==e)return;if(this.ws=null,this.disconnected(),(r?r.toString():"")==="host_replaced"){process.stderr.write(`herdr-remote host connector: another instance took over this workstation; exiting
14
14
  `),this.stop(),this.onFatal(12);return}if(this.authFailure){this.stopping=!0,process.stderr.write(`herdr-remote host connector: authentication failed; update relay credentials and restart the service
15
15
  `),this.releaseLock(),this.onFatal(13);return}this.scheduleReconnect()}),e.on("error",t=>{process.stderr.write(`herdr-remote host connector: ${t.message}
16
16
  `)})}scheduleReconnect(e=null){if(this.stopping||this.reconnectTimer)return;e&&process.stderr.write(`herdr-remote host connector: ${e.message}
17
- `);let t=Math.min(3e4,500*1.5**this.reconnectAttempts+Math.floor(Math.random()*250));this.reconnectAttempts+=1,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},t)}handleMessage(e,t=!1){if(t){this.handleFrame(e);return}let r;try{r=JSON.parse(typeof e=="string"?e:e.toString("utf8"))}catch{return}switch(r.type){case"error":if(r.clientId)return;this.authFailure=Ft.includes(r.code),process.stderr.write(`herdr-remote host connector: relay rejected the connection: ${r.message||r.code}
18
- `);return;case"host_ready":this.hostReady(r);return;case"client_count":this.setClientCount(r.clientCount);return;case"session_start":return this.startSession(r);case"herdr_start":return this.sessions.startHerdrFor(u(r));case"admin_tab_open":return Se(u(r),{socketPath:this.socketPath,language:this.config.ui?.language,send:n=>m(this.ws,n)});case"session_stop":{let n=u(r);n&&this.sessions.stop(n);return}case"resize":this.sessions.resize(r);return;case"paste_file":this.savePaste(u(r),r);return;case"host_font_chunk_request":this.font.sendChunk(u(r),r);return;case"host_font_subset_request":this.font.sendSubset(u(r),r);return;case"host_font_refresh":this.font.refresh();return;default:return}}handleFrame(e){let t;try{t=W(e)}catch(r){process.stderr.write(`herdr-remote host connector: invalid relay frame: ${r.message}
19
- `);return}t.type==="input"&&this.sessions.write(t.version===2?{streamIndex:t.streamIndex}:{streamId:t.streamId},t.payload)}hostReady(e){if(this.reconnectAttempts=0,this.startKeepalive(),Object.hasOwn(e,"clientCount")){this.legacyHeartbeat=!1,this.setClientCount(e.clientCount);return}this.legacyHeartbeat=!0,this.sendHeartbeat(!0),this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.config.cleanup.heartbeatIntervalMs)}startSession(e){if(u(e))return this.updates.report(),this.font.pickUp(),this.sessions.start(e)}savePaste(e,t){try{let r=Ie({mime:t.mime,dataBase64:t.dataBase64});m(this.ws,{type:"paste_file_ready",clientId:e,path:r})}catch(r){m(this.ws,{type:"error",clientId:e,code:"paste_file_write_failed",message:r.message||"Failed to save pasted file"})}}startKeepalive(){if(this.stopKeepalive(),!this.ws||this.stopping)return;this.ws.isAlive=!0;let e=this.config?.cleanup?.heartbeatIntervalMs||3e4;this.keepaliveTimer=setInterval(()=>this.tickKeepalive(),e)}stopKeepalive(){this.keepaliveTimer&&(clearInterval(this.keepaliveTimer),this.keepaliveTimer=null)}tickKeepalive(){let e=this.ws;if(!(!e||this.stopping)){if(e.readyState===d.default.CLOSING){U(e);return}if(e.readyState===d.default.OPEN){if(!e.isAlive){U(e);return}e.isAlive=!1;try{typeof e.ping=="function"&&e.ping()}catch{}this.clientCount<=0&&!this.legacyHeartbeat&&m(e,{type:"heartbeat",load:{},ptys:[]})}}}setClientCount(e){let t=Number.isInteger(e)?Math.max(0,e):0;if(t===this.clientCount&&(t===0||this.heartbeatTimer))return;let r=this.clientCount>0;this.clientCount=t,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,t>0?(this.sendHeartbeat(!0),this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.config.cleanup.heartbeatIntervalMs)):r&&this.sendHeartbeat(!0),t>0&&!this.stopping?this.agents.start():this.agents.stop()}sendHeartbeat(e=!1){if(!e&&this.clientCount<=0&&!this.legacyHeartbeat)return;let t=process.memoryUsage(),r=Pt.loadavg();m(this.ws,{type:"heartbeat",load:{load1m:r[0]||0,load5m:r[1]||0,load15m:r[2]||0,rssBytes:t.rss,heapUsedBytes:t.heapUsed},ptys:this.sessions.summaries()})}};var Ue=new x({onFatal:s=>process.exit(s)});try{Ue.start()}catch(s){let{code:e,message:t}=s;process.stderr.write(`herdr-remote host connector failed: ${t}
20
- `),process.exitCode=e==="HOST_ALREADY_RUNNING"?12:1}var $e=()=>{Ue.stop(),process.exit(0)};process.once("SIGINT",$e);process.once("SIGTERM",$e);
17
+ `);let t=Math.min(3e4,500*1.5**this.reconnectAttempts+Math.floor(Math.random()*250));this.reconnectAttempts+=1,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},t)}handleMessage(e,t=!1){if(t){this.handleFrame(e);return}let r;try{r=JSON.parse(typeof e=="string"?e:e.toString("utf8"))}catch{return}switch(r.type){case"error":if(r.clientId)return;this.authFailure=xt.includes(r.code),process.stderr.write(`herdr-remote host connector: relay rejected the connection: ${r.message||r.code}
18
+ `);return;case"host_ready":this.hostReady(r);return;case"client_count":this.setClientCount(r.clientCount);return;case"session_start":return this.startSession(r);case"herdr_start":return this.sessions.startHerdrFor(u(r));case"admin_tab_open":return Ie(u(r),{socketPath:this.socketPath,language:this.config.ui?.language,send:n=>m(this.ws,n)});case"session_stop":{let n=u(r);n&&this.sessions.stop(n);return}case"resize":this.sessions.resize(r);return;case"paste_file":this.savePaste(u(r),r);return;case"host_font_chunk_request":this.font.sendChunk(u(r),r);return;case"host_font_subset_request":this.font.sendSubset(u(r),r);return;case"host_font_refresh":this.font.refresh();return;default:return}}handleFrame(e){let t;try{t=W(e)}catch(r){process.stderr.write(`herdr-remote host connector: invalid relay frame: ${r.message}
19
+ `);return}t.type==="input"&&this.sessions.write(t.version===2?{streamIndex:t.streamIndex}:{streamId:t.streamId},t.payload)}hostReady(e){if(this.reconnectAttempts=0,this.startKeepalive(),Object.hasOwn(e,"clientCount")){this.legacyHeartbeat=!1,this.setClientCount(e.clientCount);return}this.legacyHeartbeat=!0,this.sendHeartbeat(!0),this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.config.cleanup.heartbeatIntervalMs)}startSession(e){if(u(e))return this.updates.report(),this.font.pickUp(),this.sessions.start(e)}savePaste(e,t){try{let r=He({mime:t.mime,dataBase64:t.dataBase64,name:t.name});m(this.ws,{type:"paste_file_ready",clientId:e,path:r})}catch(r){m(this.ws,{type:"error",clientId:e,code:"paste_file_write_failed",message:r.message||"Failed to save pasted file"})}}startKeepalive(){if(this.stopKeepalive(),!this.ws||this.stopping)return;this.ws.isAlive=!0;let e=this.config?.cleanup?.heartbeatIntervalMs||3e4;this.keepaliveTimer=setInterval(()=>this.tickKeepalive(),e)}stopKeepalive(){this.keepaliveTimer&&(clearInterval(this.keepaliveTimer),this.keepaliveTimer=null)}tickKeepalive(){let e=this.ws;if(!(!e||this.stopping)){if(e.readyState===d.default.CLOSING){U(e);return}if(e.readyState===d.default.OPEN){if(!e.isAlive){U(e);return}e.isAlive=!1;try{typeof e.ping=="function"&&e.ping()}catch{}this.clientCount<=0&&!this.legacyHeartbeat&&m(e,{type:"heartbeat",load:{},ptys:[]})}}}setClientCount(e){let t=Number.isInteger(e)?Math.max(0,e):0;if(t===this.clientCount&&(t===0||this.heartbeatTimer))return;let r=this.clientCount>0;this.clientCount=t,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,t>0?(this.sendHeartbeat(!0),this.heartbeatTimer=setInterval(()=>this.sendHeartbeat(),this.config.cleanup.heartbeatIntervalMs)):r&&this.sendHeartbeat(!0),t>0&&!this.stopping?this.agents.start():this.agents.stop()}sendHeartbeat(e=!1){if(!e&&this.clientCount<=0&&!this.legacyHeartbeat)return;let t=process.memoryUsage(),r=Ot.loadavg();m(this.ws,{type:"heartbeat",load:{load1m:r[0]||0,load5m:r[1]||0,load15m:r[2]||0,rssBytes:t.rss,heapUsedBytes:t.heapUsed},ptys:this.sessions.summaries()})}};var Be=new x({onFatal:s=>process.exit(s)});try{Be.start()}catch(s){let{code:e,message:t}=s;process.stderr.write(`herdr-remote host connector failed: ${t}
20
+ `),process.exitCode=e==="HOST_ALREADY_RUNNING"?12:1}var ze=()=>{Be.stop(),process.exit(0)};process.once("SIGINT",ze);process.once("SIGTERM",ze);
package/herdr-plugin.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  id = "herdr.remote.web"
2
2
  name = "Herdr Remote Web"
3
- version = "0.3.33"
3
+ version = "0.3.34"
4
4
  min_herdr_version = "0.9.3"
5
5
  description = "Browser access to Herdr workspaces via local or self-hosted relay"
6
6
  platforms = ["linux", "macos", "windows"]