@wendongfly/myhi 1.3.67 → 1.3.68

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/index.min.js CHANGED
@@ -413,7 +413,7 @@ ${d}
413
413
  4. \u4FDD\u7559\u6240\u6709\u5177\u4F53\u7684\u6570\u5B57\u3001\u540D\u79F0\u3001\u89C4\u5219\u7B49\u5173\u952E\u4FE1\u606F
414
414
  5. \u5982\u6709\u6B67\u4E49\u8BF7\u5728\u672B\u5C3E\u7528"\u2753\u5F85\u786E\u8BA4"\u6807\u6CE8
415
415
 
416
- \u53EA\u8F93\u51FA\u6574\u7406\u540E\u7684\u9700\u6C42\u5185\u5BB9\uFF0C\u4E0D\u9700\u8981\u89E3\u91CA\u3002`;try{const t=await new Promise(((c,l)=>{let v="",s="";const i=process.platform==="win32"?(0,external_fs_.existsSync)((0,external_path_.join)((0,external_os_.homedir)(),"AppData","Roaming","npm","claude.cmd"))?(0,external_path_.join)((0,external_os_.homedir)(),"AppData","Roaming","npm","claude.cmd"):(0,external_path_.join)((0,external_os_.homedir)(),".claude","local","claude.cmd"):"claude",n=process.platform==="win32"?process.env.ComSpec||"cmd.exe":i,e=process.platform==="win32"?["/c",i,"-p",o]:["-p",o],r=(0,external_child_process_namespaceObject.spawn)(n,e,{env:{...process.env,NO_COLOR:"1"},timeout:9e4});r.stdout.on("data",(u=>{v+=u.toString()})),r.stderr.on("data",(u=>{s+=u.toString()})),r.on("close",(u=>{u!==0&&!v.trim()?l(new Error(s||`exit ${u}`)):c(v.trim())})),r.on("error",l)}));w.json({requirement:t})}catch(t){w.status(500).json({error:t.message})}})),app.get("/qr/:sessionId",checkAuth,(async(A,w)=>{const d=getTailscaleIP(),o=(0,external_crypto_.randomBytes)(16).toString("hex");userSessions.set(o,{role:"admin",name:"\u626B\u7801\u7528\u6237",onetime:!0,lastUsed:Date.now()});const c=`${httpsServer?"https":"http"}://${d}:${PORT}/terminal/${A.params.sessionId}?token=${o}`;try{const l=await lib.toString(c,{type:"svg"});w.setHeader("Content-Type","image/svg+xml"),w.send(l)}catch(l){w.status(500).send(l.message)}})),io.use(((A,w)=>{const d=A.handshake.headers.cookie;if(hasValidSession(d)){const t=getUserInfo(d);return A.data.role=t?.role||"admin",A.data.userName=t?.name||"\u7528\u6237",A.data.dir=t?.dir||null,w()}const o=A.handshake.auth?.password;if(o){loadUsers();const t=lookupUser(o);if(t)return A.data.role="operator",A.data.userName=t.name,A.data.dir=t.dir,w()}if((A.handshake.auth?.token||A.handshake.query?.token)===TOKEN)return A.data.role="admin",A.data.userName="\u7BA1\u7406\u5458",w();w(new Error("\u672A\u6388\u6743"))}));const EXCLUSIVE_RELEASE_DELAY=120*1e3;let _exclusiveReleaseTimer=null;function checkExclusiveRelease(){if(!isExclusiveMode()||!activeUser)return;let A=!1;for(const[,w]of io.sockets.sockets)if(w.data.userName===activeUser.name){A=!0;break}if(A){_exclusiveReleaseTimer&&(clearTimeout(_exclusiveReleaseTimer),_exclusiveReleaseTimer=null);return}_exclusiveReleaseTimer||(_exclusiveReleaseTimer=setTimeout((()=>{if(_exclusiveReleaseTimer=null,!!activeUser){for(const[,w]of io.sockets.sockets)if(w.data.userName===activeUser.name)return;console.log(`[\u72EC\u5360] ${activeUser.name} \u5DF2\u79BB\u7EBF\u8D85\u65F6\uFF0C\u91CA\u653E\u767B\u5F55\u72B6\u6001\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09`);for(const w of activeUser.tokens)userSessions.delete(w);activeUser=null}}),EXCLUSIVE_RELEASE_DELAY))}let _broadcastTimer=null;function broadcastSessions(){_broadcastTimer||(_broadcastTimer=setTimeout((()=>{_broadcastTimer=null;for(const[,A]of io.sockets.sockets)A.emit("sessions",manager.list(A.data.userName,A.data.role==="admin"))}),100))}io.on("connection",(A=>{const w=A.handshake.address?.replace("::ffff:","")||"?";console.log(`[\u8FDE\u63A5] ${A.data.userName}(${A.data.role}) \u4ECE ${w} \u63A5\u5165 id=${A.id}`),_exclusiveReleaseTimer&&activeUser&&A.data.userName===activeUser.name&&(clearTimeout(_exclusiveReleaseTimer),_exclusiveReleaseTimer=null);let d=null,o=null,t=null,c=null,l=null;function v(){d&&(d.isController(A.id)&&(d.releaseControl(),io.emit("control-changed",{sessionId:d.id,holder:null,holderName:null})),d.removeViewer(A.id),o&&d.off("data",o),t&&d.off("agent:message",t),c&&d.off("agent:busy",c),l&&d.off("agent:error",l),o=null,t=null,c=null,l=null)}A.on("join",(s=>{const i=manager.get(s);if(!i){A.emit("error",{message:`\u4F1A\u8BDD ${s} \u672A\u627E\u5230`});return}const n=d?.id===s;if(v(),d=i,d.addViewer(A.id,A.data.userName),i.mode==="agent"?(t=e=>A.emit("agent:message",e),d.on("agent:message",t),c=e=>A.emit("agent:busy",e),d.on("agent:busy",c),l=e=>A.emit("agent:error",e),d.on("agent:error",l)):(o=e=>A.emit("output",e),d.on("data",o),d.once("exit",(e=>{A.emit("session-exit",{code:e}),o&&d?.off("data",o)})),spawnLocalTerminal(s,i.title)),console.log(`[\u52A0\u5165] ${A.data.userName} \u52A0\u5165\u4F1A\u8BDD "${i.title}" (${s}) \u6A21\u5F0F=${i.mode||"pty"}${n?" [\u91CD\u65B0\u8BA2\u9605]":""}`),A.emit("joined",{...i.toJSON(),role:A.data.role}),!n){if(i.mode==="agent")i._history?.length&&A.emit("agent:history",i._history);else if(i._scrollback?.length){const e=i._scrollback;if(e.length<=4096)A.emit("output",e);else{let r=0;(function u(){r>=e.length||(A.emit("output",e.slice(r,r+4096)),r+=4096,setImmediate(u))})()}}}broadcastSessions()})),A.on("disconnect",(()=>{console.log(`[\u65AD\u5F00] ${A.data.userName} \u79BB\u5F00\u4F1A\u8BDD "${d?.title||"?"}" id=${A.id}`),v(),broadcastSessions(),checkExclusiveRelease(),manager.persist()})),A.on("agent:query",(async({prompt:s}={})=>{if(!d||d.mode!=="agent"){A.emit("agent:error",{message:"\u5F53\u524D\u4E0D\u662F Agent \u6A21\u5F0F\u4F1A\u8BDD"});return}if(!d.isController(A.id)){A.emit("control-denied",{reason:"\u4F60\u6CA1\u6709\u5F53\u524D\u4F1A\u8BDD\u7684\u63A7\u5236\u6743"});return}if(d.isBusy){A.emit("agent:error",{message:"\u6B63\u5728\u5904\u7406\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210"});return}try{await d.query(s)}catch(i){console.error("[agent:query] \u9519\u8BEF:",i.message);try{A.connected&&A.emit("agent:error",{message:i.message})}catch{}}})),A.on("agent:interrupt",(()=>{!d||d.mode!=="agent"||d.interrupt()})),A.on("create-agent",((s,i)=>{if(!hasPermission(A.data.role,"operator")){typeof i=="function"&&i({ok:!1,error:"\u6CA1\u6709\u521B\u5EFA\u4F1A\u8BDD\u7684\u6743\u9650"});return}if(A.data.dir){const e=(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)),r=s?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(s.cwd)):null;if(r&&r!==e&&!r.startsWith(e+external_path_.sep)){typeof i=="function"&&i({ok:!1,error:"\u4E0D\u80FD\u5728\u7ED1\u5B9A\u76EE\u5F55\u4E4B\u5916\u521B\u5EFA\u4F1A\u8BDD"});return}r||(s={...s,cwd:e})}const n=s?.cwd||process.env.MYHI_CWD||process.cwd();if(!(0,external_fs_.existsSync)(n))try{(0,external_fs_.mkdirSync)(n,{recursive:!0}),console.log(`[\u521B\u5EFA] \u81EA\u52A8\u521B\u5EFA\u76EE\u5F55: ${n}`)}catch(e){typeof i=="function"&&i({ok:!1,error:`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e.message}`});return}try{const e=manager.createAgent({...s,owner:A.data.userName,userDir:A.data.dir});console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u521B\u5EFA Agent \u4F1A\u8BDD "${e.title}" (${e.id})`),broadcastSessions(),typeof i=="function"&&i({ok:!0,session:e.toJSON()})}catch(e){typeof i=="function"&&i({ok:!1,error:e.message})}})),A.on("input",(s=>{if(!(s==null||!d)&&d.mode!=="agent"){if(!d.isController(A.id)){A.emit("control-denied",{reason:"\u4F60\u6CA1\u6709\u5F53\u524D\u4F1A\u8BDD\u7684\u63A7\u5236\u6743"});return}d.lastInputTime=Date.now(),d.write(s)}})),A.on("take-control",(({sessionId:s}={})=>{const i=s?manager.get(s):d;if(i){if(!hasPermission(A.data.role,"operator")){A.emit("control-denied",{reason:"\u4F60\u7684\u89D2\u8272\u6CA1\u6709\u63A7\u5236\u6743\u9650"});return}if(i.controlHolder&&i.controlHolder!==A.id){const n=i.controlHolderName===A.data.userName;if(A.data.role!=="admin"&&!n){A.emit("control-denied",{reason:"\u5176\u4ED6\u7528\u6237\u6B63\u5728\u63A7\u5236\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u91CA\u653E"});return}}i.takeControl(A.id,A.data.userName),console.log(`[\u63A7\u5236] ${A.data.userName} \u83B7\u53D6\u4F1A\u8BDD "${i.title}" \u7684\u63A7\u5236\u6743`),io.emit("control-changed",{sessionId:i.id,holder:A.id,holderName:A.data.userName})}})),A.on("release-control",(({sessionId:s}={})=>{const i=s?manager.get(s):d;!i||!i.isController(A.id)||(console.log(`[\u63A7\u5236] ${A.data.userName} \u91CA\u653E\u4F1A\u8BDD "${i.title}" \u7684\u63A7\u5236\u6743`),i.releaseControl(),io.emit("control-changed",{sessionId:i.id,holder:null,holderName:null}))})),A.on("set-mode",(({sessionId:s,mode:i}={})=>{const n=s?manager.get(s):d;n&&(n.mode==="agent"&&n.setPermissionMode?(n.setPermissionMode(i),console.log(`[\u6A21\u5F0F] ${A.data.userName} \u5207\u6362\u4F1A\u8BDD "${n.title}" \u4E3A ${i}`)):n.permissionMode=i,io.emit("mode-changed",{sessionId:n.id,mode:i}),manager.persist())})),A.on("rename",(({sessionId:s,title:i}={})=>{const n=s?manager.get(s):d;!n||!i||(n.title=i,io.emit("session-renamed",{sessionId:n.id,title:i}),broadcastSessions(),manager.persist())})),A.on("resize",(({cols:s,rows:i})=>d?.resize(s,i))),A.on("list",(()=>A.emit("sessions",manager.list(A.data.userName,A.data.role==="admin")))),A.on("dirs",((s,i)=>{if(typeof i!="function")return;const n=A.data.dir?(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)):null,e=process.platform==="win32"?"\\":"/";let r=(s||n||process.env.MYHI_CWD||(0,external_os_.homedir)()).replace(/[/\\]+$/,"")||(0,external_os_.homedir)();process.platform==="win32"&&/^[A-Za-z]:$/.test(r)&&(r+="\\");const u=(0,external_path_.resolve)((0,external_path_.normalize)(r));n&&u!==n&&!u.startsWith(n+e)&&(r=n);try{const p=(0,external_fs_.readdirSync)(r,{withFileTypes:!0}).filter((m=>m.isDirectory()&&m.name!==".git")).map((m=>({name:m.name,path:r.replace(/[/\\]+$/,"")+e+m.name}))).sort(((m,b)=>m.name.localeCompare(b.name))),a=(0,external_path_.join)(r,".."),g=(0,external_path_.resolve)((0,external_path_.normalize)(a)),h=!n||g===n||g.startsWith(n+e);i({ok:!0,current:r,parent:h&&a!==r?a:null,dirs:p})}catch(p){i({ok:!1,error:p.message})}})),A.on("create",((s,i)=>{if(!hasPermission(A.data.role,"operator")){typeof i=="function"&&i({ok:!1,error:"\u6CA1\u6709\u521B\u5EFA\u4F1A\u8BDD\u7684\u6743\u9650"});return}if(A.data.dir){const e=(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)),r=s?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(s.cwd)):null;if(r&&r!==e&&!r.startsWith(e+external_path_.sep)){typeof i=="function"&&i({ok:!1,error:"\u4E0D\u80FD\u5728\u7ED1\u5B9A\u76EE\u5F55\u4E4B\u5916\u521B\u5EFA\u4F1A\u8BDD"});return}r||(s={...s,cwd:e})}const n=s?.cwd||process.env.MYHI_CWD||process.cwd();if(!(0,external_fs_.existsSync)(n))try{(0,external_fs_.mkdirSync)(n,{recursive:!0}),console.log(`[\u521B\u5EFA] \u81EA\u52A8\u521B\u5EFA\u76EE\u5F55: ${n}`)}catch(e){typeof i=="function"&&i({ok:!1,error:`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e.message}`});return}try{const e=manager.create({...s,owner:A.data.userName,userDir:A.data.dir});console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u521B\u5EFA PTY \u4F1A\u8BDD "${e.title}" (${e.id})`),broadcastSessions(),typeof i=="function"&&i({ok:!0,session:e.toJSON()})}catch(e){console.error("[\u521B\u5EFA] PTY \u542F\u52A8\u5931\u8D25:",e.message),typeof i=="function"&&i({ok:!1,error:e.message})}})),A.on("kill",(s=>{if(!hasPermission(A.data.role,"operator")){A.emit("error",{message:"\u6CA1\u6709\u5220\u9664\u4F1A\u8BDD\u7684\u6743\u9650"});return}console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u5220\u9664\u4F1A\u8BDD ${s}`),manager.kill(s),_autoSpawned.delete(s),broadcastSessions()})),A.on("kick-user",(({socketId:s,sessionId:i}={},n)=>{if(!hasPermission(A.data.role,"admin")){typeof n=="function"&&n({ok:!1,error:"\u6CA1\u6709\u8E22\u51FA\u7528\u6237\u7684\u6743\u9650"});return}const e=io.sockets.sockets.get(s);if(!e){typeof n=="function"&&n({ok:!1,error:"\u76EE\u6807\u7528\u6237\u4E0D\u5728\u7EBF"});return}const r=e.data.userName||"\u672A\u77E5";console.log(`[\u8E22\u51FA] ${A.data.userName} \u8E22\u51FA\u4E86\u7528\u6237 ${r} (${s})`),e.emit("kicked",{reason:`\u4F60\u5DF2\u88AB\u7BA1\u7406\u5458 ${A.data.userName} \u8E22\u51FA`}),e.disconnect(!0),typeof n=="function"&&n({ok:!0,name:r})})),A.on("list-viewers",(({sessionId:s}={},i)=>{if(typeof i!="function")return;const n=s?manager.get(s):d;if(!n){i({ok:!1,error:"\u4F1A\u8BDD\u4E0D\u5B58\u5728"});return}const e=[];for(const r of n._viewers){const u=io.sockets.sockets.get(r);u&&e.push({socketId:r,userName:u.data.userName||"\u672A\u77E5",role:u.data.role||"viewer",isController:n.controlHolder===r})}i({ok:!0,viewers:e})}))}));const CONTROL_TIMEOUT=300*1e3;setInterval((()=>{for(const A of manager.listSessions()){A.controlHolder&&(!io.sockets.sockets.get(A.controlHolder)||A.lastInputTime&&Date.now()-A.lastInputTime>CONTROL_TIMEOUT)&&(A.releaseControl(),io.emit("control-changed",{sessionId:A.id,holder:null,holderName:null}));for(const w of A._viewers)io.sockets.sockets.has(w)||A.removeViewer(w)}}),60*1e3);function showStartupInfo(){PORT=(httpsServer||httpServer).address()?.port||PORT;const w=getTailscaleIP(),o=`${httpsServer?"https":"http"}://${w}:${PORT}`;console.log(`
416
+ \u53EA\u8F93\u51FA\u6574\u7406\u540E\u7684\u9700\u6C42\u5185\u5BB9\uFF0C\u4E0D\u9700\u8981\u89E3\u91CA\u3002\u5FC5\u987B\u7528\u4E2D\u6587\u8F93\u51FA\u3002`;try{const t=await new Promise(((c,l)=>{let v="",s="";const i=process.platform==="win32"?(0,external_fs_.existsSync)((0,external_path_.join)((0,external_os_.homedir)(),"AppData","Roaming","npm","claude.cmd"))?(0,external_path_.join)((0,external_os_.homedir)(),"AppData","Roaming","npm","claude.cmd"):(0,external_path_.join)((0,external_os_.homedir)(),".claude","local","claude.cmd"):"claude",n=process.platform==="win32"?process.env.ComSpec||"cmd.exe":i,e=process.platform==="win32"?["/c",i,"-p",o]:["-p",o],r=(0,external_child_process_namespaceObject.spawn)(n,e,{env:{...process.env,NO_COLOR:"1"},timeout:9e4});r.stdout.on("data",(u=>{v+=u.toString()})),r.stderr.on("data",(u=>{s+=u.toString()})),r.on("close",(u=>{u!==0&&!v.trim()?l(new Error(s||`exit ${u}`)):c(v.trim())})),r.on("error",l)}));w.json({requirement:t})}catch(t){w.status(500).json({error:t.message})}})),app.get("/qr/:sessionId",checkAuth,(async(A,w)=>{const d=getTailscaleIP(),o=(0,external_crypto_.randomBytes)(16).toString("hex");userSessions.set(o,{role:"admin",name:"\u626B\u7801\u7528\u6237",onetime:!0,lastUsed:Date.now()});const c=`${httpsServer?"https":"http"}://${d}:${PORT}/terminal/${A.params.sessionId}?token=${o}`;try{const l=await lib.toString(c,{type:"svg"});w.setHeader("Content-Type","image/svg+xml"),w.send(l)}catch(l){w.status(500).send(l.message)}})),io.use(((A,w)=>{const d=A.handshake.headers.cookie;if(hasValidSession(d)){const t=getUserInfo(d);return A.data.role=t?.role||"admin",A.data.userName=t?.name||"\u7528\u6237",A.data.dir=t?.dir||null,w()}const o=A.handshake.auth?.password;if(o){loadUsers();const t=lookupUser(o);if(t)return A.data.role="operator",A.data.userName=t.name,A.data.dir=t.dir,w()}if((A.handshake.auth?.token||A.handshake.query?.token)===TOKEN)return A.data.role="admin",A.data.userName="\u7BA1\u7406\u5458",w();w(new Error("\u672A\u6388\u6743"))}));const EXCLUSIVE_RELEASE_DELAY=120*1e3;let _exclusiveReleaseTimer=null;function checkExclusiveRelease(){if(!isExclusiveMode()||!activeUser)return;let A=!1;for(const[,w]of io.sockets.sockets)if(w.data.userName===activeUser.name){A=!0;break}if(A){_exclusiveReleaseTimer&&(clearTimeout(_exclusiveReleaseTimer),_exclusiveReleaseTimer=null);return}_exclusiveReleaseTimer||(_exclusiveReleaseTimer=setTimeout((()=>{if(_exclusiveReleaseTimer=null,!!activeUser){for(const[,w]of io.sockets.sockets)if(w.data.userName===activeUser.name)return;console.log(`[\u72EC\u5360] ${activeUser.name} \u5DF2\u79BB\u7EBF\u8D85\u65F6\uFF0C\u91CA\u653E\u767B\u5F55\u72B6\u6001\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09`);for(const w of activeUser.tokens)userSessions.delete(w);activeUser=null}}),EXCLUSIVE_RELEASE_DELAY))}let _broadcastTimer=null;function broadcastSessions(){_broadcastTimer||(_broadcastTimer=setTimeout((()=>{_broadcastTimer=null;for(const[,A]of io.sockets.sockets)A.emit("sessions",manager.list(A.data.userName,A.data.role==="admin"))}),100))}io.on("connection",(A=>{const w=A.handshake.address?.replace("::ffff:","")||"?";console.log(`[\u8FDE\u63A5] ${A.data.userName}(${A.data.role}) \u4ECE ${w} \u63A5\u5165 id=${A.id}`),_exclusiveReleaseTimer&&activeUser&&A.data.userName===activeUser.name&&(clearTimeout(_exclusiveReleaseTimer),_exclusiveReleaseTimer=null);let d=null,o=null,t=null,c=null,l=null;function v(){d&&(d.isController(A.id)&&(d.releaseControl(),io.emit("control-changed",{sessionId:d.id,holder:null,holderName:null})),d.removeViewer(A.id),o&&d.off("data",o),t&&d.off("agent:message",t),c&&d.off("agent:busy",c),l&&d.off("agent:error",l),o=null,t=null,c=null,l=null)}A.on("join",(s=>{const i=manager.get(s);if(!i){A.emit("error",{message:`\u4F1A\u8BDD ${s} \u672A\u627E\u5230`});return}const n=d?.id===s;if(v(),d=i,d.addViewer(A.id,A.data.userName),i.mode==="agent"?(t=e=>A.emit("agent:message",e),d.on("agent:message",t),c=e=>A.emit("agent:busy",e),d.on("agent:busy",c),l=e=>A.emit("agent:error",e),d.on("agent:error",l)):(o=e=>A.emit("output",e),d.on("data",o),d.once("exit",(e=>{A.emit("session-exit",{code:e}),o&&d?.off("data",o)})),spawnLocalTerminal(s,i.title)),console.log(`[\u52A0\u5165] ${A.data.userName} \u52A0\u5165\u4F1A\u8BDD "${i.title}" (${s}) \u6A21\u5F0F=${i.mode||"pty"}${n?" [\u91CD\u65B0\u8BA2\u9605]":""}`),A.emit("joined",{...i.toJSON(),role:A.data.role}),!n){if(i.mode==="agent")i._history?.length&&A.emit("agent:history",i._history);else if(i._scrollback?.length){const e=i._scrollback;if(e.length<=4096)A.emit("output",e);else{let r=0;(function u(){r>=e.length||(A.emit("output",e.slice(r,r+4096)),r+=4096,setImmediate(u))})()}}}broadcastSessions()})),A.on("disconnect",(()=>{console.log(`[\u65AD\u5F00] ${A.data.userName} \u79BB\u5F00\u4F1A\u8BDD "${d?.title||"?"}" id=${A.id}`),v(),broadcastSessions(),checkExclusiveRelease(),manager.persist()})),A.on("agent:query",(async({prompt:s}={})=>{if(!d||d.mode!=="agent"){A.emit("agent:error",{message:"\u5F53\u524D\u4E0D\u662F Agent \u6A21\u5F0F\u4F1A\u8BDD"});return}if(!d.isController(A.id)){A.emit("control-denied",{reason:"\u4F60\u6CA1\u6709\u5F53\u524D\u4F1A\u8BDD\u7684\u63A7\u5236\u6743"});return}if(d.isBusy){A.emit("agent:error",{message:"\u6B63\u5728\u5904\u7406\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210"});return}try{await d.query(s)}catch(i){console.error("[agent:query] \u9519\u8BEF:",i.message);try{A.connected&&A.emit("agent:error",{message:i.message})}catch{}}})),A.on("agent:interrupt",(()=>{!d||d.mode!=="agent"||d.interrupt()})),A.on("create-agent",((s,i)=>{if(!hasPermission(A.data.role,"operator")){typeof i=="function"&&i({ok:!1,error:"\u6CA1\u6709\u521B\u5EFA\u4F1A\u8BDD\u7684\u6743\u9650"});return}if(A.data.dir){const e=(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)),r=s?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(s.cwd)):null;if(r&&r!==e&&!r.startsWith(e+external_path_.sep)){typeof i=="function"&&i({ok:!1,error:"\u4E0D\u80FD\u5728\u7ED1\u5B9A\u76EE\u5F55\u4E4B\u5916\u521B\u5EFA\u4F1A\u8BDD"});return}r||(s={...s,cwd:e})}const n=s?.cwd||process.env.MYHI_CWD||process.cwd();if(!(0,external_fs_.existsSync)(n))try{(0,external_fs_.mkdirSync)(n,{recursive:!0}),console.log(`[\u521B\u5EFA] \u81EA\u52A8\u521B\u5EFA\u76EE\u5F55: ${n}`)}catch(e){typeof i=="function"&&i({ok:!1,error:`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e.message}`});return}try{const e=manager.createAgent({...s,owner:A.data.userName,userDir:A.data.dir});console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u521B\u5EFA Agent \u4F1A\u8BDD "${e.title}" (${e.id})`),broadcastSessions(),typeof i=="function"&&i({ok:!0,session:e.toJSON()})}catch(e){typeof i=="function"&&i({ok:!1,error:e.message})}})),A.on("input",(s=>{if(!(s==null||!d)&&d.mode!=="agent"){if(!d.isController(A.id)){A.emit("control-denied",{reason:"\u4F60\u6CA1\u6709\u5F53\u524D\u4F1A\u8BDD\u7684\u63A7\u5236\u6743"});return}d.lastInputTime=Date.now(),d.write(s)}})),A.on("take-control",(({sessionId:s}={})=>{const i=s?manager.get(s):d;if(i){if(!hasPermission(A.data.role,"operator")){A.emit("control-denied",{reason:"\u4F60\u7684\u89D2\u8272\u6CA1\u6709\u63A7\u5236\u6743\u9650"});return}if(i.controlHolder&&i.controlHolder!==A.id){const n=i.controlHolderName===A.data.userName;if(A.data.role!=="admin"&&!n){A.emit("control-denied",{reason:"\u5176\u4ED6\u7528\u6237\u6B63\u5728\u63A7\u5236\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u91CA\u653E"});return}}i.takeControl(A.id,A.data.userName),console.log(`[\u63A7\u5236] ${A.data.userName} \u83B7\u53D6\u4F1A\u8BDD "${i.title}" \u7684\u63A7\u5236\u6743`),io.emit("control-changed",{sessionId:i.id,holder:A.id,holderName:A.data.userName})}})),A.on("release-control",(({sessionId:s}={})=>{const i=s?manager.get(s):d;!i||!i.isController(A.id)||(console.log(`[\u63A7\u5236] ${A.data.userName} \u91CA\u653E\u4F1A\u8BDD "${i.title}" \u7684\u63A7\u5236\u6743`),i.releaseControl(),io.emit("control-changed",{sessionId:i.id,holder:null,holderName:null}))})),A.on("set-mode",(({sessionId:s,mode:i}={})=>{const n=s?manager.get(s):d;n&&(n.mode==="agent"&&n.setPermissionMode?(n.setPermissionMode(i),console.log(`[\u6A21\u5F0F] ${A.data.userName} \u5207\u6362\u4F1A\u8BDD "${n.title}" \u4E3A ${i}`)):n.permissionMode=i,io.emit("mode-changed",{sessionId:n.id,mode:i}),manager.persist())})),A.on("rename",(({sessionId:s,title:i}={})=>{const n=s?manager.get(s):d;!n||!i||(n.title=i,io.emit("session-renamed",{sessionId:n.id,title:i}),broadcastSessions(),manager.persist())})),A.on("resize",(({cols:s,rows:i})=>d?.resize(s,i))),A.on("list",(()=>A.emit("sessions",manager.list(A.data.userName,A.data.role==="admin")))),A.on("dirs",((s,i)=>{if(typeof i!="function")return;const n=A.data.dir?(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)):null,e=process.platform==="win32"?"\\":"/";let r=(s||n||process.env.MYHI_CWD||(0,external_os_.homedir)()).replace(/[/\\]+$/,"")||(0,external_os_.homedir)();process.platform==="win32"&&/^[A-Za-z]:$/.test(r)&&(r+="\\");const u=(0,external_path_.resolve)((0,external_path_.normalize)(r));n&&u!==n&&!u.startsWith(n+e)&&(r=n);try{const p=(0,external_fs_.readdirSync)(r,{withFileTypes:!0}).filter((m=>m.isDirectory()&&m.name!==".git")).map((m=>({name:m.name,path:r.replace(/[/\\]+$/,"")+e+m.name}))).sort(((m,b)=>m.name.localeCompare(b.name))),a=(0,external_path_.join)(r,".."),g=(0,external_path_.resolve)((0,external_path_.normalize)(a)),h=!n||g===n||g.startsWith(n+e);i({ok:!0,current:r,parent:h&&a!==r?a:null,dirs:p})}catch(p){i({ok:!1,error:p.message})}})),A.on("create",((s,i)=>{if(!hasPermission(A.data.role,"operator")){typeof i=="function"&&i({ok:!1,error:"\u6CA1\u6709\u521B\u5EFA\u4F1A\u8BDD\u7684\u6743\u9650"});return}if(A.data.dir){const e=(0,external_path_.resolve)((0,external_path_.normalize)(A.data.dir)),r=s?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(s.cwd)):null;if(r&&r!==e&&!r.startsWith(e+external_path_.sep)){typeof i=="function"&&i({ok:!1,error:"\u4E0D\u80FD\u5728\u7ED1\u5B9A\u76EE\u5F55\u4E4B\u5916\u521B\u5EFA\u4F1A\u8BDD"});return}r||(s={...s,cwd:e})}const n=s?.cwd||process.env.MYHI_CWD||process.cwd();if(!(0,external_fs_.existsSync)(n))try{(0,external_fs_.mkdirSync)(n,{recursive:!0}),console.log(`[\u521B\u5EFA] \u81EA\u52A8\u521B\u5EFA\u76EE\u5F55: ${n}`)}catch(e){typeof i=="function"&&i({ok:!1,error:`\u521B\u5EFA\u76EE\u5F55\u5931\u8D25: ${e.message}`});return}try{const e=manager.create({...s,owner:A.data.userName,userDir:A.data.dir});console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u521B\u5EFA PTY \u4F1A\u8BDD "${e.title}" (${e.id})`),broadcastSessions(),typeof i=="function"&&i({ok:!0,session:e.toJSON()})}catch(e){console.error("[\u521B\u5EFA] PTY \u542F\u52A8\u5931\u8D25:",e.message),typeof i=="function"&&i({ok:!1,error:e.message})}})),A.on("kill",(s=>{if(!hasPermission(A.data.role,"operator")){A.emit("error",{message:"\u6CA1\u6709\u5220\u9664\u4F1A\u8BDD\u7684\u6743\u9650"});return}console.log(`[\u4F1A\u8BDD] ${A.data.userName} \u5220\u9664\u4F1A\u8BDD ${s}`),manager.kill(s),_autoSpawned.delete(s),broadcastSessions()})),A.on("kick-user",(({socketId:s,sessionId:i}={},n)=>{if(!hasPermission(A.data.role,"admin")){typeof n=="function"&&n({ok:!1,error:"\u6CA1\u6709\u8E22\u51FA\u7528\u6237\u7684\u6743\u9650"});return}const e=io.sockets.sockets.get(s);if(!e){typeof n=="function"&&n({ok:!1,error:"\u76EE\u6807\u7528\u6237\u4E0D\u5728\u7EBF"});return}const r=e.data.userName||"\u672A\u77E5";console.log(`[\u8E22\u51FA] ${A.data.userName} \u8E22\u51FA\u4E86\u7528\u6237 ${r} (${s})`),e.emit("kicked",{reason:`\u4F60\u5DF2\u88AB\u7BA1\u7406\u5458 ${A.data.userName} \u8E22\u51FA`}),e.disconnect(!0),typeof n=="function"&&n({ok:!0,name:r})})),A.on("list-viewers",(({sessionId:s}={},i)=>{if(typeof i!="function")return;const n=s?manager.get(s):d;if(!n){i({ok:!1,error:"\u4F1A\u8BDD\u4E0D\u5B58\u5728"});return}const e=[];for(const r of n._viewers){const u=io.sockets.sockets.get(r);u&&e.push({socketId:r,userName:u.data.userName||"\u672A\u77E5",role:u.data.role||"viewer",isController:n.controlHolder===r})}i({ok:!0,viewers:e})}))}));const CONTROL_TIMEOUT=300*1e3;setInterval((()=>{for(const A of manager.listSessions()){A.controlHolder&&(!io.sockets.sockets.get(A.controlHolder)||A.lastInputTime&&Date.now()-A.lastInputTime>CONTROL_TIMEOUT)&&(A.releaseControl(),io.emit("control-changed",{sessionId:A.id,holder:null,holderName:null}));for(const w of A._viewers)io.sockets.sockets.has(w)||A.removeViewer(w)}}),60*1e3);function showStartupInfo(){PORT=(httpsServer||httpServer).address()?.port||PORT;const w=getTailscaleIP(),o=`${httpsServer?"https":"http"}://${w}:${PORT}`;console.log(`
417
417
  \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`),console.log(" myhi \u2014 \u57FA\u4E8E Tailscale \u7684 Web \u7EC8\u7AEF"),console.log("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),console.log(`
418
418
  \u5730\u5740: ${o}`),httpsServer&&console.log(` HTTP\u91CD\u5B9A\u5411: http://${w}:${PORT+1} \u2192 HTTPS`),console.log(` \u5BC6\u7801: ${PASSWORD} (\u7F16\u8F91 ~/.myhi/password \u53EF\u4FEE\u6539)`),console.log(`
419
419
  \u626B\u63CF\u4E8C\u7EF4\u7801\u5728\u624B\u673A\u4E0A\u6253\u5F00:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wendongfly/myhi",
3
- "version": "1.3.67",
3
+ "version": "1.3.68",
4
4
  "description": "Web-based terminal sharing with chat UI — control your terminal from phone via LAN/Tailscale",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",