9remote 0.1.37 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +3 -3
- package/dist/ptyDaemon.cjs +5 -5
- package/dist/server.cjs +59 -41
- package/index.js +20 -0
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -61,7 +61,7 @@ ${N6.default.cursorShow}`)}releaseCursor(){this.extraLinesUnderPrompt>0&&Pf(this
|
|
|
61
61
|
`:`
|
|
62
62
|
`)+t,i=n+1,n=r.indexOf(`
|
|
63
63
|
`,i)}while(n!==-1);return o+=r.slice(i),o}var{stdout:by,stderr:my}=hy,ex=Symbol("GENERATOR"),ei=Symbol("STYLER"),co=Symbol("IS_EMPTY"),yy=["ansi","ansi","ansi256","ansi16m"],ri=Object.create(null),iR=(r,e={})=>{if(e.level&&!(Number.isInteger(e.level)&&e.level>=0&&e.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let t=by?by.level:0;r.level=e.level===void 0?t:e.level};var oR=r=>{let e=(...t)=>t.join(" ");return iR(e,r),Object.setPrototypeOf(e,lo.prototype),e};function lo(r){return oR(r)}Object.setPrototypeOf(lo.prototype,Function.prototype);for(let[r,e]of Object.entries(Ze))ri[r]={get(){let t=Js(this,tx(e.open,e.close,this[ei]),this[co]);return Object.defineProperty(this,r,{value:t}),t}};ri.visible={get(){let r=Js(this,this[ei],!0);return Object.defineProperty(this,"visible",{value:r}),r}};var rx=(r,e,t,...n)=>r==="rgb"?e==="ansi16m"?Ze[t].ansi16m(...n):e==="ansi256"?Ze[t].ansi256(Ze.rgbToAnsi256(...n)):Ze[t].ansi(Ze.rgbToAnsi(...n)):r==="hex"?rx("rgb",e,t,...Ze.hexToRgb(...n)):Ze[t][r](...n),aR=["rgb","hex","ansi256"];for(let r of aR){ri[r]={get(){let{level:t}=this;return function(...n){let i=tx(rx(r,yy[t],"color",...n),Ze.color.close,this[ei]);return Js(this,i,this[co])}}};let e="bg"+r[0].toUpperCase()+r.slice(1);ri[e]={get(){let{level:t}=this;return function(...n){let i=tx(rx(r,yy[t],"bgColor",...n),Ze.bgColor.close,this[ei]);return Js(this,i,this[co])}}}}var uR=Object.defineProperties(()=>{},{...ri,level:{enumerable:!0,get(){return this[ex].level},set(r){this[ex].level=r}}}),tx=(r,e,t)=>{let n,i;return t===void 0?(n=r,i=e):(n=t.openAll+r,i=e+t.closeAll),{open:r,close:e,openAll:n,closeAll:i,parent:t}},Js=(r,e,t)=>{let n=(...i)=>sR(n,i.length===1?""+i[0]:i.join(" "));return Object.setPrototypeOf(n,uR),n[ex]=r,n[ei]=e,n[co]=t,n},sR=(r,e)=>{if(r.level<=0||!e)return r[co]?"":e;let t=r[ei];if(t===void 0)return e;let{openAll:n,closeAll:i}=t;if(e.includes("\x1B"))for(;t!==void 0;)e=py(e,t.close,t.open),t=t.parent;let o=e.indexOf(`
|
|
64
|
-
`);return o!==-1&&(e=vy(e,i,n,o)),n+e+i};Object.defineProperties(lo.prototype,ri);var cR=lo(),m$=lo({level:my?my.level:0});var q=cR;var f_=O(Vy(),1),go=require("child_process"),Wt=O(require("path"),1),d_=require("url"),lc=O(require("fs"),1);var Ky=O($y(),1),cx=O(require("crypto"),1),{machineIdSync:mR}=Ky.default;async function rc(r=null){let e=r||process.env.MACHINE_ID_SALT||"9remote-salt";try{let t=mR();return cx.default.createHash("sha256").update(t+e).digest("hex").substring(0,16)}catch(t){return console.error("Error getting machine ID:",t),cx.default.randomUUID().replace(/-/g,"").substring(0,16)}}var Gy=O(require("crypto"),1),yR=process.env.API_KEY_SECRET||"9remote-api-key-secret";function _R(){let r="abcdefghijklmnopqrstuvwxyz0123456789",e="";for(let t=0;t<6;t++)e+=r.charAt(Math.floor(Math.random()*r.length));return e}function gR(r,e){return Gy.default.createHmac("sha256",yR).update(r+e).digest("hex").slice(0,8)}function xo(r){let e=_R(),t=gR(r,e);return{key:`sk-${r}-${e}-${t}`,keyId:e}}var rr=O(require("fs"),1),nc=O(require("path"),1),Hy=O(require("os"),1),tc=nc.default.join(Hy.default.homedir(),".9remote"),ho=nc.default.join(tc,"state.json"),lx=nc.default.join(tc,"keys.json");function ic(){rr.default.existsSync(tc)||rr.default.mkdirSync(tc,{recursive:!0})}function Yy(){try{return ic(),rr.default.existsSync(ho)?JSON.parse(rr.default.readFileSync(ho,"utf8")):null}catch{return null}}function zy(r){try{ic(),rr.default.writeFileSync(ho,JSON.stringify(r,null,2))}catch(e){console.error("Error saving state:",e)}}function Qy(){try{rr.default.existsSync(ho)&&rr.default.unlinkSync(ho)}catch{}}function oc(){try{return ic(),rr.default.existsSync(lx)?JSON.parse(rr.default.readFileSync(lx,"utf8")):{machineId:null,key:null,name:"Default",createdAt:null}}catch{return{machineId:null,key:null,name:"Default",createdAt:null}}}function po(r,e,t="Default"){try{ic();let n={machineId:r,key:e,name:t,createdAt:new Date().toISOString()};return rr.default.writeFileSync(lx,JSON.stringify(n,null,2)),n}catch(n){return console.error("Error saving key:",n),null}}async function fx(r,e){try{let t=await fetch(`${e}/api/temp-key/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r,expiryMinutes:30})});if(!t.ok){let n=await t.json();throw new Error(n.error||"Failed to create temp key")}return await t.json()}catch(t){return console.error("Error creating temp key:",t),null}}var Nt=require("fs"),Jy=require("url"),Xy=require("child_process"),vo=O(require("path"),1),dx=O(require("os"),1),DR=vo.default.dirname((0,Jy.fileURLToPath)(__importMetaUrl)),Pe="9remote",wR=`https://registry.npmjs.org/${Pe}/latest`,ER=3e3,SR=8e3;function OR(){return"0.1.
|
|
64
|
+
`);return o!==-1&&(e=vy(e,i,n,o)),n+e+i};Object.defineProperties(lo.prototype,ri);var cR=lo(),m$=lo({level:my?my.level:0});var q=cR;var f_=O(Vy(),1),go=require("child_process"),Wt=O(require("path"),1),d_=require("url"),lc=O(require("fs"),1);var Ky=O($y(),1),cx=O(require("crypto"),1),{machineIdSync:mR}=Ky.default;async function rc(r=null){let e=r||process.env.MACHINE_ID_SALT||"9remote-salt";try{let t=mR();return cx.default.createHash("sha256").update(t+e).digest("hex").substring(0,16)}catch(t){return console.error("Error getting machine ID:",t),cx.default.randomUUID().replace(/-/g,"").substring(0,16)}}var Gy=O(require("crypto"),1),yR=process.env.API_KEY_SECRET||"9remote-api-key-secret";function _R(){let r="abcdefghijklmnopqrstuvwxyz0123456789",e="";for(let t=0;t<6;t++)e+=r.charAt(Math.floor(Math.random()*r.length));return e}function gR(r,e){return Gy.default.createHmac("sha256",yR).update(r+e).digest("hex").slice(0,8)}function xo(r){let e=_R(),t=gR(r,e);return{key:`sk-${r}-${e}-${t}`,keyId:e}}var rr=O(require("fs"),1),nc=O(require("path"),1),Hy=O(require("os"),1),tc=nc.default.join(Hy.default.homedir(),".9remote"),ho=nc.default.join(tc,"state.json"),lx=nc.default.join(tc,"keys.json");function ic(){rr.default.existsSync(tc)||rr.default.mkdirSync(tc,{recursive:!0})}function Yy(){try{return ic(),rr.default.existsSync(ho)?JSON.parse(rr.default.readFileSync(ho,"utf8")):null}catch{return null}}function zy(r){try{ic(),rr.default.writeFileSync(ho,JSON.stringify(r,null,2))}catch(e){console.error("Error saving state:",e)}}function Qy(){try{rr.default.existsSync(ho)&&rr.default.unlinkSync(ho)}catch{}}function oc(){try{return ic(),rr.default.existsSync(lx)?JSON.parse(rr.default.readFileSync(lx,"utf8")):{machineId:null,key:null,name:"Default",createdAt:null}}catch{return{machineId:null,key:null,name:"Default",createdAt:null}}}function po(r,e,t="Default"){try{ic();let n={machineId:r,key:e,name:t,createdAt:new Date().toISOString()};return rr.default.writeFileSync(lx,JSON.stringify(n,null,2)),n}catch(n){return console.error("Error saving key:",n),null}}async function fx(r,e){try{let t=await fetch(`${e}/api/temp-key/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r,expiryMinutes:30})});if(!t.ok){let n=await t.json();throw new Error(n.error||"Failed to create temp key")}return await t.json()}catch(t){return console.error("Error creating temp key:",t),null}}var Nt=require("fs"),Jy=require("url"),Xy=require("child_process"),vo=O(require("path"),1),dx=O(require("os"),1),DR=vo.default.dirname((0,Jy.fileURLToPath)(__importMetaUrl)),Pe="9remote",wR=`https://registry.npmjs.org/${Pe}/latest`,ER=3e3,SR=8e3;function OR(){return"0.1.39"}function FR(r,e){let t=r.split(".").map(Number),n=e.split(".").map(Number);for(let i=0;i<3;i++){if(n[i]>t[i])return!0;if(n[i]<t[i])return!1}return!1}function CR(){return process.env.CODESPACES==="true"||process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN?"GitHub Codespaces":(0,Nt.existsSync)("/.dockerenv")?"Docker":null}async function Zy(r=!1){if(r)return!1;let e=OR();if(!e)return!1;let t=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],n=0,i=null,o=u=>{process.stdout.isTTY&&(process.stdout.write(`\r${t[0]} ${u}`),i=setInterval(()=>{process.stdout.write(`\r${t[n++%t.length]} ${u}`)},80))},a=()=>{i&&(clearInterval(i),i=null),process.stdout.isTTY&&process.stdout.write("\r\x1B[K")};return new Promise(u=>{let s=!1,c=x=>{s||(s=!0,a(),u(x))},l=setTimeout(()=>c(!1),SR);o("Checking for updates..."),fetch(wR,{signal:AbortSignal.timeout(ER)}).then(x=>x.json()).then(x=>{if(s)return;clearTimeout(l);let h=x.version;if(!h||!FR(e,h)){c(!1);return}a(),console.log(q.green(`\u2705 New version available: ${e} \u2192 ${h}`));let v=CR();if(v){console.log(q.yellow(` \u26A0\uFE0F ${v} detected - manual update required`)),console.log(q.gray(` Run: npm install -g ${Pe}@latest
|
|
65
65
|
`)),c(!1);return}console.log(q.yellow(`\u{1F504} Auto-updating...
|
|
66
66
|
`));let b=process.argv.slice(2).filter(A=>A!=="--skip-update").join(" "),m=process.platform,y,_;if(m==="win32"){let A=`@echo off
|
|
67
67
|
echo \u{1F4E5} Downloading update...
|
|
@@ -108,7 +108,7 @@ else
|
|
|
108
108
|
${Pe} ${b} --skip-update
|
|
109
109
|
fi
|
|
110
110
|
`;y=vo.default.join(dx.default.tmpdir(),`${Pe}-update.sh`),(0,Nt.writeFileSync)(y,A,{mode:493}),_=["sh",[y]]}(0,Xy.spawn)(_[0],_[1],{detached:!0,stdio:"inherit"}).unref(),process.exit(0)}).catch(()=>{clearTimeout(l),c(!1)})})}var pe=O(require("fs"),1),_o=O(require("path"),1),n_=O(require("https"),1),Ut=O(require("os"),1),cc=require("child_process"),yo=null,ac=null,sc=null,bo=_o.default.join(Ut.default.homedir(),".9remote","bin"),e_="cloudflared",hx=Ut.default.platform()==="win32",AR=hx?`${e_}.exe`:e_,ti=_o.default.join(bo,AR),uc=_o.default.join(Ut.default.homedir(),".9remote","cloudflared.pid"),mo=!1,xx=5,r_=6e4,ni=[],ii=null,qR="https://github.com/cloudflare/cloudflared/releases/latest/download",PR={darwin:{x64:"cloudflared-darwin-amd64.tgz",arm64:"cloudflared-darwin-amd64.tgz"},win32:{x64:"cloudflared-windows-amd64.exe"},linux:{x64:"cloudflared-linux-amd64",arm64:"cloudflared-linux-arm64"}};function TR(){let r=Ut.default.platform(),e=Ut.default.arch(),t=PR[r];if(!t)throw new Error(`Unsupported platform: ${r}`);let n=t[e];if(!n)throw new Error(`Unsupported architecture: ${e} for platform ${r}`);return`${qR}/${n}`}async function i_(r,e){return new Promise((t,n)=>{let i=pe.default.createWriteStream(e);n_.default.get(r,o=>{if([301,302].includes(o.statusCode)){i.close(),pe.default.unlinkSync(e),i_(o.headers.location,e).then(t).catch(n);return}if(o.statusCode!==200){i.close(),pe.default.unlinkSync(e),n(new Error(`Download failed with status ${o.statusCode}`));return}o.pipe(i),i.on("finish",()=>{i.close(()=>t(e))}),i.on("error",a=>{i.close(),pe.default.unlinkSync(e),n(a)})}).on("error",o=>{i.close(),pe.default.existsSync(e)&&pe.default.unlinkSync(e),n(o)})})}async function px(){if(pe.default.existsSync(bo)||pe.default.mkdirSync(bo,{recursive:!0}),pe.default.existsSync(ti))return hx||pe.default.chmodSync(ti,"755"),ti;console.log("\u{1F4E5} Downloading tunnel binary...");let r=TR(),e=r.endsWith(".tgz"),t=e?_o.default.join(bo,"cloudflared.tgz"):ti;try{return await i_(r,t),e&&(console.log("\u2705 Extracting..."),(0,cc.execSync)(`tar -xzf "${t}" -C "${bo}"`,{stdio:"pipe"}),pe.default.unlinkSync(t)),hx||pe.default.chmodSync(ti,"755"),console.log("\u2705 cloudflared ready"),ti}catch(n){throw console.error("\u274C Failed to download cloudflared:",n.message),n}}var BR=["INF Starting tunnel","INF Version","GOOS:","Settings:","Autoupdate frequency","Generated Connector","Initial protocol","ICMP proxy","Created ICMP","Starting metrics server","curve preferences","Updated to new configuration"];async function o_(r,e=null){let t=await px();e&&(ii=e),sc=r;let n=(0,cc.spawn)(t,["tunnel","run","--token",r],{detached:!1,stdio:["ignore","pipe","pipe"]});return mo=!1,console.log(`\u2705 Cloudflared spawned with PID: ${n.pid}`),await new Promise((i,o)=>{let a=0,u=!1,s=setTimeout(()=>{u||(u=!0,i(n))},9e4),c=l=>{let x=l.toString().trim();if(!BR.some(h=>x.includes(h))&&!mo&&x.includes("Registered tunnel connection")){a++,a<=4&&(process.stdout.write(`\r \u2714 Connection ${a}/4 established`),a===4&&(process.stdout.write(`
|
|
111
|
-
`),u||(u=!0,clearTimeout(s),i(n))));return}};n.stdout.on("data",c),n.stderr.on("data",c),n.on("error",l=>{u||(u=!0,clearTimeout(s),o(l))}),n.on("exit",l=>{u||(u=!0,clearTimeout(s),o(new Error(`cloudflared exited with code ${l}`)))})}),n.on("error",i=>{console.error("\u274C cloudflared error:",i)}),n.on("exit",(i,o)=>{if(console.log(`\u26A0\uFE0F Cloudflared process exited (code: ${i}, signal: ${o}, intentional: ${mo})`),mo)console.log("\u2139\uFE0F Cloudflared exit ignored (intentional shutdown)");else if(console.log("\u26A0\uFE0F Cloudflared unexpected exit detected - will restart"),ii){let a=Date.now();ni.push(a),ni=ni.filter(u=>u>a-r_),ni.length<=xx?(console.log(`\u{1F504} Restarting tunnel... (attempt ${ni.length}/${xx})`),setTimeout(()=>{console.log("\u{1F504} Executing tunnel restart..."),ii(r)},2e3)):console.log(`\u274C Too many tunnel restarts (${xx} in ${r_/1e3}s). Giving up.`)}else console.log("\u26A0\uFE0F No restart callback registered")}),pe.default.writeFileSync(uc,n.pid.toString()),jR(),n}function vx(){try{if(pe.default.existsSync(uc)){mo=!0;let r=parseInt(pe.default.readFileSync(uc,"utf8"));process.kill(r),pe.default.unlinkSync(uc),console.log("\u2705 Cloudflared killed")}}catch{}}function a_(){ni=[],ii=null,sc=null,MR()}function t_(){let r=Ut.default.networkInterfaces(),e=[];for(let[t,n]of Object.entries(r))if(n)for(let i of n)!i.internal&&i.family==="IPv4"&&e.push(`${t}:${i.address}`);return e.sort().join("|")}function jR(){yo||(ac=t_(),yo=setInterval(()=>{let r=t_();r!==ac&&(console.log("\u{1F504} Network change detected - restarting tunnel..."),ac=r,vx(),ii&&sc&&setTimeout(()=>{console.log("\u{1F504} Restarting tunnel after network change..."),ii(sc)},2e3))},5e3))}function MR(){yo&&(clearInterval(yo),yo=null),ac=null}var RR=process.argv.includes("--skip-update"),yx=Wt.default.dirname((0,d_.fileURLToPath)(__importMetaUrl)),IR=Wt.default.resolve(yx,".."),kR=Wt.default.join(yx,"server.cjs"),u_=Wt.default.join(IR,"server/index.js"),ft="https://9remote.cc",mx=2208,s_="abcdefghijklmnpqrstuvwxyz23456789",bx=10,c_=6e4,H=q.rgb(230,138,110),LR=q.rgb(200,120,95);function NR(){return"0.1.
|
|
111
|
+
`),u||(u=!0,clearTimeout(s),i(n))));return}};n.stdout.on("data",c),n.stderr.on("data",c),n.on("error",l=>{u||(u=!0,clearTimeout(s),o(l))}),n.on("exit",l=>{u||(u=!0,clearTimeout(s),o(new Error(`cloudflared exited with code ${l}`)))})}),n.on("error",i=>{console.error("\u274C cloudflared error:",i)}),n.on("exit",(i,o)=>{if(console.log(`\u26A0\uFE0F Cloudflared process exited (code: ${i}, signal: ${o}, intentional: ${mo})`),mo)console.log("\u2139\uFE0F Cloudflared exit ignored (intentional shutdown)");else if(console.log("\u26A0\uFE0F Cloudflared unexpected exit detected - will restart"),ii){let a=Date.now();ni.push(a),ni=ni.filter(u=>u>a-r_),ni.length<=xx?(console.log(`\u{1F504} Restarting tunnel... (attempt ${ni.length}/${xx})`),setTimeout(()=>{console.log("\u{1F504} Executing tunnel restart..."),ii(r)},2e3)):console.log(`\u274C Too many tunnel restarts (${xx} in ${r_/1e3}s). Giving up.`)}else console.log("\u26A0\uFE0F No restart callback registered")}),pe.default.writeFileSync(uc,n.pid.toString()),jR(),n}function vx(){try{if(pe.default.existsSync(uc)){mo=!0;let r=parseInt(pe.default.readFileSync(uc,"utf8"));process.kill(r),pe.default.unlinkSync(uc),console.log("\u2705 Cloudflared killed")}}catch{}}function a_(){ni=[],ii=null,sc=null,MR()}function t_(){let r=Ut.default.networkInterfaces(),e=[];for(let[t,n]of Object.entries(r))if(n)for(let i of n)!i.internal&&i.family==="IPv4"&&e.push(`${t}:${i.address}`);return e.sort().join("|")}function jR(){yo||(ac=t_(),yo=setInterval(()=>{let r=t_();r!==ac&&(console.log("\u{1F504} Network change detected - restarting tunnel..."),ac=r,vx(),ii&&sc&&setTimeout(()=>{console.log("\u{1F504} Restarting tunnel after network change..."),ii(sc)},2e3))},5e3))}function MR(){yo&&(clearInterval(yo),yo=null),ac=null}var RR=process.argv.includes("--skip-update"),yx=Wt.default.dirname((0,d_.fileURLToPath)(__importMetaUrl)),IR=Wt.default.resolve(yx,".."),kR=Wt.default.join(yx,"server.cjs"),u_=Wt.default.join(IR,"server/index.js"),ft="https://9remote.cc",mx=2208,s_="abcdefghijklmnpqrstuvwxyz23456789",bx=10,c_=6e4,H=q.rgb(230,138,110),LR=q.rgb(200,120,95);function NR(){return"0.1.39"}function x_(){let r=NR(),e=Math.min(44,process.stdout.columns||44);console.log(""),console.log(H("\u2554"+"\u2550".repeat(e-2)+"\u2557")),console.log(H("\u2551")+" ".repeat(e-2)+H("\u2551"));let t=`\u{1F680} 9Remote v${r}`,n=Math.floor((e-2-t.length)/2);console.log(H("\u2551")+" ".repeat(n)+H.bold(t)+" ".repeat(e-2-n-t.length)+H("\u2551"));let i="Remote terminal access from anywhere",o=Math.floor((e-2-i.length)/2);console.log(H("\u2551")+" ".repeat(o)+q.gray(i)+" ".repeat(e-2-o-i.length)+H("\u2551")),console.log(H("\u2551")+" ".repeat(e-2)+H("\u2551")),console.log(H("\u255A"+"\u2550".repeat(e-2)+"\u255D")),console.log("")}function UR(){let r="";for(let e=0;e<6;e++)r+=s_.charAt(Math.floor(Math.random()*s_.length));return r}function h_(r,e="\u{1F4F1} Scan QR to connect:"){console.log(H(`
|
|
112
112
|
${e}`)),f_.default.generate(r,{small:!0,type:"terminal",margin:0},t=>{let n=t.trim().split(`
|
|
113
113
|
`);console.log(n.join(`
|
|
114
114
|
`))})}async function p_(r,e){let t=await fx(r,ft);if(!t){console.log(q.red("\u274C Failed to create temp key"));return}let n=`${ft}/login?k=${t.tempKey}`,i=Math.min(44,process.stdout.columns||55);h_(n),console.log(q.gray(`
|
|
@@ -117,7 +117,7 @@ QR will expire in 30 minutes (one-time use)
|
|
|
117
117
|
\u{1F4A5} Server crashed (code: ${c}, signal: ${l})`));let x=Date.now();for(t.push(x);t.length>0&&t[0]<x-c_;)t.shift();t.length>bx&&(console.log(q.red(`\u274C Too many restarts (${bx} in ${c_/1e3}s). Giving up.`)),process.exit(1)),console.log(q.yellow(`\u{1F504} Restarting server... (attempt ${t.length}/${bx})`)),console.log(LR("\u26A0\uFE0F [DEBUG] NOTE: Tunnel connection may be stale - will restart tunnel")),e&&(console.log(q.yellow("\u2705 Restarting tunnel connection...")),e()),setTimeout(()=>{a()},1e3)}}),n.on("error",c=>{console.log(q.red(`\u274C Server error: ${c.message}`))}),r&&r(n)};return a(),{getProcess:()=>n,shutdown:()=>{i=!0,n&&n.kill()}}}var l_=!1;function v_(r,e,t){l_||(l_=!0,process.on("SIGINT",async()=>{console.log(q.yellow(`
|
|
118
118
|
|
|
119
119
|
\u{1F6D1} Stopping server...`)),r.shutdown(),e.kill(),a_(),Qy(),console.log(q.green("\u2705 Server stopped")),process.exit(0)}))}async function $R(r){let e=await fetch(`${ft}/api/tunnel/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r})});if(!e.ok){let n=await e.json();throw new Error(n.error||"Failed to create tunnel")}return await e.json()}async function b_(r){console.log(H(`
|
|
120
|
-
\u{1F680} Starting server...`));try{vx(),await new Promise(
|
|
120
|
+
\u{1F680} Starting server...`));try{vx(),await new Promise(x=>setTimeout(x,1e3))}catch{}let t=Yy()?.shortId||UR();try{let x=await fetch(`${ft}/api/session/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:r,shortId:t})});if(!x.ok){let v=await x.text();return console.log(q.red(`\u274C Failed to create session: ${x.status} ${x.statusText}`)),console.log(q.yellow(`Response: ${v.substring(0,200)}`)),null}let h=await x.json()}catch(x){return console.log(q.red(`\u274C Failed to create session: ${x.message}`)),null}let n=VR(null,async()=>{if(!u)return;let x=6e4,h=1e3,v=Math.floor(x/h),p=!1;for(let b=0;b<v;b++){try{let m=await fetch(`http://localhost:${mx}/api/health`,{method:"GET",timeout:2e3});if(m.ok&&(await m.json()).status==="ok"){p=!0,console.log(q.green(`\u2705 Server ready after ${b+1}s`));break}}catch{}b%5,await new Promise(m=>setTimeout(m,h))}if(!p){console.log(q.red("\u274C Server not ready after 60s - skipping tunnel reconnect"));return}try{process.kill(u.pid,"SIGHUP"),console.log(q.green("\u2705 SIGHUP sent - cloudflared should reconnect"))}catch{try{u.kill(),await new Promise(m=>setTimeout(m,1e3)),u=await s(o),console.log(q.green("\u2705 Tunnel restarted"))}catch(m){console.log(q.red(`\u274C Failed to restart tunnel: ${m.message}`))}}});await new Promise(x=>setTimeout(x,2e3)),console.log(H("\u2705 Creating tunnel..."));try{await px()}catch(x){return console.log(q.red(`\u274C Failed to install cloudflared: ${x.message}`)),n.shutdown(),null}let i;try{i=await $R(r),console.log(H(`\u2705 Tunnel ID: ${i.tunnelId}`))}catch(x){return console.log(q.red(`\u274C Failed to create tunnel: ${x.message}`)),n.shutdown(),null}let{token:o,hostname:a}=i;console.log(H("\u2705 Starting tunnel..."));let u,s=async x=>{try{return u=await o_(x,s),u}catch(h){return console.log(q.red(`\u274C Failed to start cloudflared: ${h.message}`)),null}};if(u=await s(o),!u)return n.shutdown(),null;let c=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],l=!1;for(let x=0;x<15;x++){try{if((await fetch(`${a}/api/health`,{signal:AbortSignal.timeout(3e3)})).ok){l=!0;break}}catch{}process.stdout.write(`\r Verifying tunnel ${c[x%c.length]} (${x*2}s)`),await new Promise(h=>setTimeout(h,2e3))}return process.stdout.write("\r"+" ".repeat(40)+"\r"),l?(console.log(H(`\u2705 Tunnel URL: ${a}`)),console.log(H("\u2705 Connection established")),zy({apiKey:r,shortId:t,tunnelUrl:a,serverPid:n.getProcess()?.pid,tunnelPid:u.pid}),{serverManager:n,tunnelProcess:u,tunnelUrl:a}):(console.log(q.red("\u274C Tunnel not reachable from outside")),n.shutdown(),u.kill(),null)}async function _x(){console.clear(),x_();let{action:r}=await Zn.prompt([{type:"list",name:"action",message:"Select action:",choices:[{name:"\u{1F680} Start Server",value:"start"},{name:"\u{1F511} Manage Key",value:"key"},{name:"\u274C Exit",value:"exit"}]}]);switch(r){case"start":await KR();break;case"key":await GR();break;case"exit":console.log(q.gray("Goodbye!")),process.exit(0)}}async function KR(){let r=await rc(),e=oc();if(!e.key){console.log(q.yellow(`
|
|
121
121
|
\u26A0\uFE0F No key found. Creating default key...`));let{key:a}=xo(r);e=po(r,a,"Default"),console.log(q.green("\u2705 Default key created!"))}let t=await b_(e.key);if(!t){await _x();return}let{serverManager:n,tunnelProcess:i,tunnelUrl:o}=t;await p_(e.key,o),v_(n,i,e.key),await new Promise(()=>{})}async function GR(){let r=await rc(),e=oc();if(!e.key){console.log(q.yellow(`
|
|
122
122
|
\u26A0\uFE0F No key found. Creating default key...`));let{key:n}=xo(r);e=po(r,n,"Default"),console.log(q.green("\u2705 Default key created!"))}console.log(H(`
|
|
123
123
|
\u{1F511} Manage Key`)),console.log(q.gray("\u2501".repeat(30))),console.log(q.white(`Key: ${e.key}`)),console.log(q.gray(`Created: ${e.createdAt}
|
package/dist/ptyDaemon.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const __importMetaUrl = require('url').pathToFileURL(__filename).href;
|
|
3
|
-
var
|
|
4
|
-
`;try{
|
|
3
|
+
var T=Object.create;var k=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var x=(e,s,n,r)=>{if(s&&typeof s=="object"||typeof s=="function")for(let t of _(s))!P.call(e,t)&&t!==n&&k(e,t,{get:()=>s[t],enumerable:!(r=A(s,t))||r.enumerable});return e};var h=(e,s,n)=>(n=e!=null?T(q(e)):{},x(s||!e||!e.__esModule?k(n,"default",{value:e,enumerable:!0}):n,e));var M=h(require("net"),1),c=h(require("fs"),1),b=h(require("path"),1),D=h(require("os"),1),v=h(require("node-pty"),1),I=b.default.join(D.default.homedir(),".9remote"),g=process.platform==="win32"?"\\\\.\\pipe\\9remote-pty":b.default.join(I,"pty-daemon.sock"),o=new Map,O=new Set,N=50*1024,L=5*1024*1024,R=b.default.join(I,"daemon.log");function F(){try{if(c.default.existsSync(R)&&c.default.statSync(R).size>L){let n=c.default.readFileSync(R,"utf8").slice(-1024*1024);c.default.writeFileSync(R,n)}}catch{}}function l(e,s=null){F();let r=`[${new Date().toISOString()}] ERROR: ${e}`;s&&(r+=` - ${s.message||s}`),r+=`
|
|
4
|
+
`;try{c.default.appendFileSync(R,r)}catch{}console.error(r.trim())}function C(){return process.platform==="win32"?process.env.COMSPEC||"cmd.exe":process.env.SHELL||"/bin/bash"}function $(){return process.env.CODESPACES==="true"?process.env.CODESPACE_VSCODE_FOLDER||"/workspaces":process.env.HOME||process.env.USERPROFILE||D.default.homedir()}function z(){let e={...process.env,TERM:"xterm-256color",COLORTERM:"truecolor",LANG:process.env.LANG||"en_US.UTF-8"},s=C(),n=s.includes("zsh"),r=s.includes("bash");if(n){e.ZDOTDIR=e.ZDOTDIR||e.HOME;let t=`
|
|
5
5
|
precmd() {
|
|
6
6
|
print -Pn "\\e]7;file://%m\${PWD}\\e\\\\"
|
|
7
7
|
}
|
|
8
8
|
`;e._9REMOTE_PRECMD=t}else if(r){let t=e.PROMPT_COMMAND||"";e.PROMPT_COMMAND=`printf "\\e]7;file://%s\\a" "\${HOSTNAME}\${PWD}"${t?`; ${t}`:""}`}return e}function w(e){let s=JSON.stringify(e)+`
|
|
9
|
-
`;for(let
|
|
10
|
-
`)}catch{}}function j(e,s,
|
|
11
|
-
`);
|
|
9
|
+
`;for(let n of O)try{n.write(s)}catch{}}function a(e,s){try{e.write(JSON.stringify(s)+`
|
|
10
|
+
`)}catch{}}function j(e,s,n=80,r=24){if(o.has(e))return{success:!1,error:"Session already exists"};let t=C(),d=process.platform==="win32"?[]:["-l"],f=$();try{let i=z();i.NINE_REMOTE_SESSION_ID=e;let m=v.default.spawn(t,d,{name:"xterm-256color",cols:n,rows:r,cwd:f,env:i,useConpty:process.platform==="win32"}),u={pty:m,buffer:[],name:s||`Terminal ${o.size+1}`,createdAt:Date.now(),cwd:f};return m.onData(S=>{u.buffer.push(S);let E=u.buffer.reduce((p,y)=>p+y.length,0);for(;E>N&&u.buffer.length>1;)u.buffer.shift(),E=u.buffer.reduce((p,y)=>p+y.length,0);w({type:"output",sessionId:e,data:Buffer.from(S).toString("base64")})}),m.onExit(()=>{o.delete(e),w({type:"sessionClosed",sessionId:e})}),o.set(e,u),{success:!0,sessionId:e,cwd:f}}catch(i){return l("Failed to create session",i),{success:!1,error:i.message}}}function G(e,s){let{type:n,sessionId:r,...t}=s;switch(n){case"ping":a(e,{type:"pong"});break;case"listSessions":let d=Array.from(o.entries()).map(([p,y])=>({id:p,name:y.name,createdAt:y.createdAt}));a(e,{type:"sessionList",sessions:d,requestId:t.requestId});break;case"createSession":let f=j(t.sessionId||`session-${Date.now()}`,t.name,t.cols,t.rows);a(e,{type:"createResult",...f,requestId:t.requestId});break;case"joinSession":let i=o.get(r);if(!i){a(e,{type:"joinResult",success:!1,error:"Session not found",requestId:t.requestId});return}if(i.buffer.length>0){let p=i.buffer.join("");a(e,{type:"output",sessionId:r,data:Buffer.from(p).toString("base64")})}a(e,{type:"joinResult",success:!0,name:i.name,cwd:i.cwd,requestId:t.requestId});break;case"input":let m=o.get(r);m?.pty&&m.pty.write(t.data);break;case"resize":let u=o.get(r);if(u?.pty)try{u.pty.resize(t.cols,t.rows)}catch{}break;case"deleteSession":let S=o.get(r);S?(S.pty&&S.pty.kill(),o.delete(r),w({type:"sessionClosed",sessionId:r}),a(e,{type:"deleteResult",success:!0,requestId:t.requestId})):a(e,{type:"deleteResult",success:!1,error:"Session not found",requestId:t.requestId});break;case"renameSession":let E=o.get(r);E?(E.name=t.name,w({type:"sessionRenamed",sessionId:r,name:t.name}),a(e,{type:"renameResult",success:!0,requestId:t.requestId})):a(e,{type:"renameResult",success:!1,error:"Session not found",requestId:t.requestId});break;default:l(`Unknown message type: ${n}`)}}function H(){if(!c.default.existsSync(I))try{c.default.mkdirSync(I,{recursive:!0})}catch(s){l("Failed to create socket directory",s),process.exit(1)}if(process.platform!=="win32"&&c.default.existsSync(g))try{c.default.unlinkSync(g)}catch(s){l("Failed to remove stale socket",s),process.exit(1)}let e=M.default.createServer(s=>{O.add(s);let n="";s.on("data",r=>{n+=r.toString();let t=n.split(`
|
|
11
|
+
`);n=t.pop()||"";for(let d of t)if(d.trim())try{let f=JSON.parse(d);G(s,f)}catch{l("Invalid message",d)}}),s.on("close",()=>{O.delete(s)}),s.on("error",r=>{l("Client error",r),O.delete(s)})});e.on("error",s=>{l("Server error",s),s.code==="EADDRINUSE"&&l("Socket already in use, exiting"),process.exit(1)}),e.listen(g),process.on("SIGTERM",()=>{for(let[,s]of o)s.pty&&s.pty.kill();e.close(),process.platform!=="win32"&&c.default.existsSync(g)&&c.default.unlinkSync(g),process.exit(0)}),process.on("SIGINT",()=>{process.emit("SIGTERM")})}H();
|