@wendongfly/zihi 1.1.0 → 1.1.2
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.js +1 -1
- package/dist/lib/xterm/README.md +27 -14
- package/dist/lib/xterm/css/xterm.css +81 -5
- package/dist/lib/xterm/lib/xterm.js +1 -1
- package/dist/lib/xterm/lib/xterm.js.map +1 -1
- package/dist/lib/xterm/lib/xterm.mjs +53 -0
- package/dist/lib/xterm/lib/xterm.mjs.map +7 -0
- package/dist/lib/xterm/package.json +49 -38
- package/dist/lib/xterm/src/browser/AccessibilityManager.ts +185 -50
- package/dist/lib/xterm/src/browser/CoreBrowserTerminal.ts +1339 -0
- package/dist/lib/xterm/src/browser/Linkifier.ts +403 -0
- package/dist/lib/xterm/src/browser/LocalizableStrings.ts +15 -4
- package/dist/lib/xterm/src/browser/OscLinkProvider.ts +2 -1
- package/dist/lib/xterm/src/browser/RenderDebouncer.ts +6 -5
- package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +2 -2
- package/dist/lib/xterm/src/browser/Types.ts +226 -0
- package/dist/lib/xterm/src/browser/Viewport.ts +148 -357
- package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +17 -12
- package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +47 -52
- package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +5 -3
- package/dist/lib/xterm/src/browser/input/MoveToCell.ts +3 -1
- package/dist/lib/xterm/src/browser/public/Terminal.ts +39 -24
- package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +76 -40
- package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +47 -23
- package/dist/lib/xterm/src/browser/renderer/dom/WidthCache.ts +19 -9
- package/dist/lib/xterm/src/browser/renderer/shared/Constants.ts +0 -8
- package/dist/lib/xterm/src/browser/renderer/shared/RendererUtils.ts +38 -1
- package/dist/lib/xterm/src/browser/renderer/shared/SelectionRenderModel.ts +6 -4
- package/dist/lib/xterm/src/browser/renderer/shared/Types.ts +84 -0
- package/dist/lib/xterm/src/browser/selection/Types.ts +15 -0
- package/dist/lib/xterm/src/browser/services/CharSizeService.ts +57 -32
- package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +108 -4
- package/dist/lib/xterm/src/browser/services/LinkProviderService.ts +28 -0
- package/dist/lib/xterm/src/browser/services/RenderService.ts +132 -40
- package/dist/lib/xterm/src/browser/services/SelectionService.ts +19 -9
- package/dist/lib/xterm/src/browser/services/Services.ts +36 -16
- package/dist/lib/xterm/src/browser/services/ThemeService.ts +19 -58
- package/dist/lib/xterm/src/browser/shared/Constants.ts +8 -0
- package/dist/lib/xterm/src/common/CircularList.ts +5 -5
- package/dist/lib/xterm/src/common/Color.ts +34 -14
- package/dist/lib/xterm/src/common/CoreTerminal.ts +40 -41
- package/dist/lib/xterm/src/common/InputHandler.ts +177 -125
- package/dist/lib/xterm/src/common/Platform.ts +2 -1
- package/dist/lib/xterm/src/common/SortedList.ts +86 -10
- package/dist/lib/xterm/src/common/TaskQueue.ts +7 -7
- package/dist/lib/xterm/src/common/Types.ts +552 -0
- package/dist/lib/xterm/src/common/buffer/AttributeData.ts +15 -0
- package/dist/lib/xterm/src/common/buffer/Buffer.ts +15 -7
- package/dist/lib/xterm/src/common/buffer/BufferLine.ts +53 -22
- package/dist/lib/xterm/src/common/buffer/BufferRange.ts +1 -1
- package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +9 -6
- package/dist/lib/xterm/src/common/buffer/BufferSet.ts +5 -5
- package/dist/lib/xterm/src/common/buffer/Constants.ts +10 -2
- package/dist/lib/xterm/src/common/buffer/Marker.ts +4 -4
- package/dist/lib/xterm/src/common/buffer/Types.ts +52 -0
- package/dist/lib/xterm/src/common/input/Keyboard.ts +2 -27
- package/dist/lib/xterm/src/common/input/UnicodeV6.ts +18 -5
- package/dist/lib/xterm/src/common/input/WriteBuffer.ts +9 -8
- package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +13 -13
- package/dist/lib/xterm/src/common/parser/Types.ts +275 -0
- package/dist/lib/xterm/src/common/public/AddonManager.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferApiView.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +4 -4
- package/dist/lib/xterm/src/common/public/ParserApi.ts +1 -1
- package/dist/lib/xterm/src/common/public/UnicodeApi.ts +1 -1
- package/dist/lib/xterm/src/common/services/BufferService.ts +14 -11
- package/dist/lib/xterm/src/common/services/CoreMouseService.ts +53 -6
- package/dist/lib/xterm/src/common/services/CoreService.ts +13 -8
- package/dist/lib/xterm/src/common/services/DecorationService.ts +11 -11
- package/dist/lib/xterm/src/common/services/InstantiationService.ts +1 -1
- package/dist/lib/xterm/src/common/services/LogService.ts +2 -2
- package/dist/lib/xterm/src/common/services/OptionsService.ts +16 -5
- package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +1 -1
- package/dist/lib/xterm/src/common/services/Services.ts +73 -19
- package/dist/lib/xterm/src/common/services/UnicodeService.ts +30 -5
- package/dist/lib/xterm/src/vs/base/browser/browser.ts +141 -0
- package/dist/lib/xterm/src/vs/base/browser/canIUse.ts +49 -0
- package/dist/lib/xterm/src/vs/base/browser/dom.ts +2369 -0
- package/dist/lib/xterm/src/vs/base/browser/fastDomNode.ts +316 -0
- package/dist/lib/xterm/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
- package/dist/lib/xterm/src/vs/base/browser/iframe.ts +135 -0
- package/dist/lib/xterm/src/vs/base/browser/keyboardEvent.ts +213 -0
- package/dist/lib/xterm/src/vs/base/browser/mouseEvent.ts +229 -0
- package/dist/lib/xterm/src/vs/base/browser/touch.ts +372 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/widget.ts +57 -0
- package/dist/lib/xterm/src/vs/base/browser/window.ts +14 -0
- package/dist/lib/xterm/src/vs/base/common/arrays.ts +887 -0
- package/dist/lib/xterm/src/vs/base/common/arraysFind.ts +202 -0
- package/dist/lib/xterm/src/vs/base/common/assert.ts +71 -0
- package/dist/lib/xterm/src/vs/base/common/async.ts +1992 -0
- package/dist/lib/xterm/src/vs/base/common/cancellation.ts +148 -0
- package/dist/lib/xterm/src/vs/base/common/charCode.ts +450 -0
- package/dist/lib/xterm/src/vs/base/common/collections.ts +140 -0
- package/dist/lib/xterm/src/vs/base/common/decorators.ts +130 -0
- package/dist/lib/xterm/src/vs/base/common/equals.ts +146 -0
- package/dist/lib/xterm/src/vs/base/common/errors.ts +303 -0
- package/dist/lib/xterm/src/vs/base/common/event.ts +1778 -0
- package/dist/lib/xterm/src/vs/base/common/functional.ts +32 -0
- package/dist/lib/xterm/src/vs/base/common/hash.ts +316 -0
- package/dist/lib/xterm/src/vs/base/common/iterator.ts +159 -0
- package/dist/lib/xterm/src/vs/base/common/keyCodes.ts +526 -0
- package/dist/lib/xterm/src/vs/base/common/keybindings.ts +284 -0
- package/dist/lib/xterm/src/vs/base/common/lazy.ts +47 -0
- package/dist/lib/xterm/src/vs/base/common/lifecycle.ts +801 -0
- package/dist/lib/xterm/src/vs/base/common/linkedList.ts +142 -0
- package/dist/lib/xterm/src/vs/base/common/map.ts +202 -0
- package/dist/lib/xterm/src/vs/base/common/numbers.ts +98 -0
- package/dist/lib/xterm/src/vs/base/common/observable.ts +76 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/api.ts +31 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/autorun.ts +281 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/base.ts +489 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/debugName.ts +145 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/derived.ts +428 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/logging.ts +328 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/promise.ts +209 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/utils.ts +610 -0
- package/dist/lib/xterm/src/vs/base/common/platform.ts +281 -0
- package/dist/lib/xterm/src/vs/base/common/scrollable.ts +522 -0
- package/dist/lib/xterm/src/vs/base/common/sequence.ts +34 -0
- package/dist/lib/xterm/src/vs/base/common/stopwatch.ts +43 -0
- package/dist/lib/xterm/src/vs/base/common/strings.ts +557 -0
- package/dist/lib/xterm/src/vs/base/common/symbols.ts +9 -0
- package/dist/lib/xterm/src/vs/base/common/uint.ts +59 -0
- package/dist/lib/xterm/src/vs/patches/nls.ts +90 -0
- package/dist/lib/xterm/src/vs/typings/base-common.d.ts +20 -0
- package/dist/lib/xterm/src/vs/typings/require.d.ts +42 -0
- package/dist/lib/xterm/src/vs/typings/vscode-globals-nls.d.ts +36 -0
- package/dist/lib/xterm/src/vs/typings/vscode-globals-product.d.ts +33 -0
- package/dist/lib/xterm/typings/xterm.d.ts +156 -43
- package/dist/lib/xterm-fit/README.md +5 -5
- package/dist/lib/xterm-fit/lib/addon-fit.js +2 -0
- package/dist/lib/xterm-fit/lib/addon-fit.js.map +1 -0
- package/dist/lib/xterm-fit/lib/addon-fit.mjs +18 -0
- package/dist/lib/xterm-fit/lib/addon-fit.mjs.map +7 -0
- package/dist/lib/xterm-fit/package.json +9 -9
- package/dist/lib/xterm-fit/src/FitAddon.ts +7 -4
- package/dist/lib/xterm-fit/typings/addon-fit.d.ts +55 -0
- package/dist/lib/xterm-links/README.md +5 -5
- package/dist/lib/xterm-links/lib/addon-web-links.js +2 -0
- package/dist/lib/xterm-links/lib/addon-web-links.js.map +1 -0
- package/dist/lib/xterm-links/lib/addon-web-links.mjs +18 -0
- package/dist/lib/xterm-links/lib/addon-web-links.mjs.map +7 -0
- package/dist/lib/xterm-links/package.json +9 -9
- package/dist/lib/xterm-links/src/WebLinkProvider.ts +16 -15
- package/dist/lib/xterm-links/src/WebLinksAddon.ts +4 -3
- package/dist/lib/xterm-links/typings/addon-web-links.d.ts +57 -0
- package/package.json +5 -6
package/dist/index.js
CHANGED
|
@@ -465,7 +465,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
465
465
|
`).filter(Boolean).slice(-20);for(const x of h)try{const j=JSON.parse(x);if(j.type==="human"&&j.message?.content){const b=typeof j.message.content=="string"?j.message.content:j.message.content.find((w=>w.type==="text"))?.text||"";b&&this._history.push({type:"user",content:b,timestamp:j.timestamp})}else j.type==="assistant"&&j.message?.content?this._history.push({type:"assistant",message:j.message,timestamp:j.timestamp}):j.type==="result"&&this._history.push({type:"result",total_cost_usd:j.costUSD||j.total_cost_usd,timestamp:j.timestamp})}catch{}return}}catch(t){console.warn("[agent] \u52A0\u8F7D\u6062\u590D\u4F1A\u8BDD\u5386\u53F2\u5931\u8D25:",t.message)}}get isBusy(){return this._busy}addViewer(t,u){this._viewers.add(t),u&&this._viewerNames.set(t,u)}removeViewer(t){this._viewers.delete(t),this._viewerNames.delete(t)}get viewerCount(){return new Set(this._viewerNames.values()).size||this._viewers.size}takeControl(t,u){this.controlHolder=t,this.controlHolderName=u||null,this.lastInputTime=Date.now()}releaseControl(){this.controlHolder=null,this.controlHolderName=null,this.lastInputTime=null}isController(t){return this.controlHolder===t}toJSON(){return{id:this.id,title:this.title,cwd:this.cwd,createdAt:this.createdAt,mode:"agent",alive:this.alive,viewers:this.viewerCount,controlHolder:this.controlHolder,controlHolderName:this.controlHolderName,permissionMode:this.permissionMode,owner:this.owner,claudeSessionId:this.claudeSessionId,busy:this._busy,usage:this._usage}}}let _claudeSessionsCache=null,_claudeSessionsCacheTime=0;const CLAUDE_SESSIONS_CACHE_TTL=3e4;function listLocalClaudeSessions(r){const t=Date.now();if(_claudeSessionsCache&&t-_claudeSessionsCacheTime<CLAUDE_SESSIONS_CACHE_TTL){if(!r)return _claudeSessionsCache;const h=(0,external_path_.resolve)((0,external_path_.normalize)(r)).replace(/[\\/]+$/,"");return _claudeSessionsCache.filter((x=>(0,external_path_.resolve)((0,external_path_.normalize)(x.projectPath)).replace(/[\\/]+$/,"").startsWith(h)))}const u=[],d=r?(0,external_path_.resolve)((0,external_path_.normalize)(r)).replace(/[\\/]+$/,""):null;try{const h=(0,external_path_.join)((0,external_os_.homedir)(),".claude","projects");if(!(0,external_fs_.existsSync)(h))return u;for(const x of(0,external_fs_.readdirSync)(h,{withFileTypes:!0})){if(!x.isDirectory())continue;const j=(0,external_path_.join)(h,x.name);try{for(const b of(0,external_fs_.readdirSync)(j)){if(!b.endsWith(".jsonl"))continue;const w=b.replace(".jsonl",""),$=(0,external_path_.join)(j,b);try{const O=(0,external_fs_.readFileSync)($,"utf8").split(`
|
|
466
466
|
`).filter(Boolean);let I=null,U=null,z=0,N="";for(const L of O)try{const W=JSON.parse(L);if(I||(I=W),U=W,z++,!N&&W.type==="human"&&W.message?.content){const H=W.message.content;if(typeof H=="string")N=H.slice(0,120);else if(Array.isArray(H)){const V=H.find((J=>J.type==="text"));V&&(N=V.text?.slice(0,120)||"")}}}catch{}let B=x.name;if(process.platform==="win32"&&/^[A-Za-z]--/.test(B)?B=B[0]+":\\"+B.slice(3).replace(/-/g,"\\"):B.startsWith("-")&&(B=B.replace(/-/g,"/")),d&&!(0,external_path_.resolve)((0,external_path_.normalize)(B)).replace(/[\\/]+$/,"").startsWith(d))continue;u.push({sessionId:w,projectDir:x.name,projectPath:B,messageCount:z,summary:N,createdAt:I?.timestamp||null,updatedAt:U?.timestamp||null})}catch{}}}catch{}}}catch{}u.sort(((h,x)=>new Date(x.updatedAt||0).getTime()-new Date(h.updatedAt||0).getTime()));const p=u.slice(0,50);return _claudeSessionsCache=p,_claudeSessionsCacheTime=Date.now(),p.slice(0,20)}const CONFIG_DIR=(0,external_path_.join)((0,external_os_.homedir)(),".zihi"),SESSIONS_FILE=(0,external_path_.join)(CONFIG_DIR,"sessions.json");function loadSavedConfigs(){try{return JSON.parse((0,external_fs_.readFileSync)(SESSIONS_FILE,"utf8"))}catch{return[]}}function writeSavedConfigs(r){try{(0,external_fs_.mkdirSync)(CONFIG_DIR,{recursive:!0});const t=SESSIONS_FILE+".tmp";(0,external_fs_.writeFileSync)(t,JSON.stringify(r,null,2),{mode:384}),(0,external_fs_.renameSync)(t,SESSIONS_FILE)}catch(t){console.error("[sessions] \u6301\u4E45\u5316\u5199\u5165\u5931\u8D25:",t.message)}}class SessionManager{constructor(){this._agentSessions=new Map;for(const t of loadSavedConfigs())try{if(t.claudeSessionId){const u=(0,external_crypto_.randomUUID)(),d=new AgentSession(u,{...t,resumeSessionId:t.claudeSessionId});d.on("session-id",(()=>this._persist())),this._agentSessions.set(u,d),console.log(`[\u4F1A\u8BDD] \u6062\u590D Agent "${t.title}" (claude: ${t.claudeSessionId.slice(0,8)}...)`)}}catch(u){console.warn(`[\u4F1A\u8BDD] \u6062\u590D "${t.title}" \u5931\u8D25:`,u.message)}}createAgent(t={}){const u=(0,external_crypto_.randomUUID)(),d=new AgentSession(u,t);return this._agentSessions.set(u,d),d.on("session-id",(()=>this._persist())),this._persist(),d}get(t){return this._agentSessions.get(t)}list(t,u=!1){let d=[...this._agentSessions.values()].map((p=>p.toJSON()));return t&&!u&&(d=d.filter((p=>!p.owner||p.owner===t))),d}listSessions(){return[...this._agentSessions.values()]}kill(t){const u=this._agentSessions.get(t);u&&(u.kill(),this._agentSessions.delete(t),this._persist())}persist(){this._persist()}_persist(){const t=[...this._agentSessions.values()].filter((u=>u.alive)).map((u=>({mode:"agent",title:u.title,cwd:u.cwd,permissionMode:u.permissionMode||void 0,owner:u.owner||void 0,userDir:u.userDir||void 0,claudeSessionId:u.claudeSessionId||void 0})));writeSavedConfigs(t)}}const roles_CONFIG_DIR=(0,external_path_.join)((0,external_os_.homedir)(),".zihi"),ROLES_FILE=(0,external_path_.join)(roles_CONFIG_DIR,"roles.json"),USERS_FILE=(0,external_path_.join)(roles_CONFIG_DIR,"users.json"),ROLE_LEVELS={admin:3,operator:2,viewer:1};let rolesConfig=null;function loadRoles(){try{if((0,external_fs_.existsSync)(ROLES_FILE))return rolesConfig=JSON.parse((0,external_fs_.readFileSync)(ROLES_FILE,"utf8")),rolesConfig}catch(r){console.warn("[\u89D2\u8272] \u52A0\u8F7D roles.json \u5931\u8D25:",r.message)}return rolesConfig=null,null}function lookupPassword(r){if(!rolesConfig?.passwords)return null;const t=rolesConfig.passwords[r];return t?{name:t.name||"\u7528\u6237",role:t.role||"viewer"}:null}function hasPermission(r,t){return(ROLE_LEVELS[r]||0)>=(ROLE_LEVELS[t]||0)}function isMultiUserMode(){return rolesConfig!==null&&rolesConfig.passwords&&Object.keys(rolesConfig.passwords).length>0}function getDefaultRole(){return rolesConfig?.defaultRole||"admin"}let usersConfig=null;function loadUsers(){try{if((0,external_fs_.existsSync)(USERS_FILE))return usersConfig=JSON.parse((0,external_fs_.readFileSync)(USERS_FILE,"utf8")),usersConfig}catch(r){console.warn("[\u7528\u6237] \u52A0\u8F7D users.json \u5931\u8D25:",r.message)}return usersConfig=null,null}function hasUsers(){return usersConfig!==null&&usersConfig.users&&Object.keys(usersConfig.users).length>0}function isExclusiveMode(){return hasUsers()&&usersConfig.exclusive===!0}function setExclusiveMode(r){usersConfig||(usersConfig={users:{}}),usersConfig.exclusive=!!r,_writeUsers()}function lookupUser(r){if(!usersConfig?.users)return null;const t=usersConfig.users[r];return t?{name:t.name||"\u7528\u6237",dir:t.dir}:null}function listUsers(){return usersConfig?.users?Object.entries(usersConfig.users).map((([r,t])=>({password:r.slice(0,2)+"*".repeat(r.length-2),name:t.name,dir:t.dir}))):[]}function addUser(r,t,u){usersConfig||(usersConfig={users:{}}),usersConfig.users||(usersConfig.users={}),usersConfig.users[r]={name:t,dir:u},_writeUsers()}function removeUser(r){return!usersConfig?.users||!usersConfig.users[r]?!1:(delete usersConfig.users[r],_writeUsers(),!0)}function _writeUsers(){(0,external_fs_.mkdirSync)(roles_CONFIG_DIR,{recursive:!0}),(0,external_fs_.writeFileSync)(USERS_FILE,JSON.stringify(usersConfig,null,2),{mode:384})}const server_dirname=(0,external_path_.dirname)((0,external_url_.fileURLToPath)(import.meta.url));let PORT=parseInt(process.env.PORT,10)||12345;const HOST=process.env.HOST||"0.0.0.0",PORT_EXPLICIT=!!process.env.PORT,configDir=(0,external_path_.join)((0,external_os_.homedir)(),".zihi");(0,external_fs_.mkdirSync)(configDir,{recursive:!0});const pidFile=(0,external_path_.join)(configDir,"daemon.pid"),IS_DAEMON_CHILD=!!process.env.ZIHI_DAEMON;(function r(){if(!IS_DAEMON_CHILD){try{const t=parseInt((0,external_fs_.readFileSync)(pidFile,"utf8").trim(),10);if(t&&t!==process.pid){let u=!1;try{process.kill(t,0),u=!0}catch{}if(u){console.log(`[zihi] \u68C0\u6D4B\u5230\u5DF2\u8FD0\u884C\u7684\u5B9E\u4F8B (PID ${t})\uFF0C\u6B63\u5728\u505C\u6B62...`);try{process.platform==="win32"?(0,external_child_process_namespaceObject.execSync)(`taskkill /PID ${t} /F /T`,{stdio:"pipe",timeout:5e3}):process.kill(t,"SIGTERM")}catch(h){console.warn(`[zihi] \u505C\u6B62\u65E7\u8FDB\u7A0B\u5931\u8D25: ${h.message?.split(`
|
|
467
467
|
`)[0]||h}`)}const d=Date.now()+5e3;for(;Date.now()<d;){try{process.kill(t,0)}catch{break}const h=Date.now()+200;for(;Date.now()<h;);}let p=!1;try{process.kill(t,0),p=!0}catch{}p&&(console.error(`[zihi] \u65E0\u6CD5\u505C\u6B62\u65E7\u8FDB\u7A0B (PID ${t})\uFF0C\u8BF7\u624B\u52A8\u6267\u884C\uFF1A`),console.error(" zihi stop"),console.error(` \u6216: ${process.platform==="win32"?`taskkill /PID ${t} /F`:`kill -9 ${t}`}`),process.exit(1))}}}catch{}IS_DAEMON_CHILD||(0,external_fs_.writeFileSync)(pidFile,String(process.pid))}})();function cleanupPid(){try{parseInt((0,external_fs_.readFileSync)(pidFile,"utf8").trim(),10)===process.pid&&(0,external_fs_.unlinkSync)(pidFile)}catch{}}function gracefulShutdown(){try{if(typeof manager<"u"){try{manager.persist()}catch{}for(const r of manager.listSessions())try{r.kill()}catch{}}}catch{}cleanupPid()}process.on("exit",cleanupPid),process.on("SIGTERM",(()=>{gracefulShutdown(),process.exit(0)})),process.on("SIGINT",(()=>{gracefulShutdown(),process.exit(0)})),process.on("uncaughtException",(r=>{console.error("[zihi] \u672A\u6355\u83B7\u5F02\u5E38:",r.message),gracefulShutdown(),process.exit(1)})),process.on("unhandledRejection",(r=>{console.error("[zihi] \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD:",r)}));function readOrCreate(r,t){try{if((0,external_fs_.existsSync)(r))return(0,external_fs_.readFileSync)(r,"utf8").trim()}catch{}const u=t();return(0,external_fs_.writeFileSync)(r,u,{mode:384}),u}const TOKEN=readOrCreate((0,external_path_.join)(configDir,"token"),(()=>(0,external_crypto_.randomBytes)(16).toString("hex")));let PASSWORD=readOrCreate((0,external_path_.join)(configDir,"password"),(()=>String(Math.floor(1e3+Math.random()*9e3))));loadRoles(),loadUsers();let activeUser=null;const userSessions=new Map;userSessions.set(TOKEN,{role:"admin",name:"\u7BA1\u7406\u5458",permanent:!0});const SESSION_MAX_AGE=10080*60*1e3;setInterval((()=>{const r=Date.now();for(const[t,u]of userSessions)u.permanent||(!u.lastUsed||r-u.lastUsed>SESSION_MAX_AGE)&&userSessions.delete(t)}),3600*1e3);function getTailscaleIP(){try{return(0,external_child_process_namespaceObject.execSync)("tailscale ip -4",{timeout:3e3,stdio:"pipe"}).toString().trim().split(`
|
|
468
|
-
`)[0]}catch{}try{if(process.platform==="win32"){const t=(0,external_child_process_namespaceObject.execSync)("route print 0.0.0.0",{timeout:3e3,stdio:"pipe"}).toString().match(/0\.0\.0\.0\s+0\.0\.0\.0\s+\S+\s+(\d+\.\d+\.\d+\.\d+)/);if(t)return t[1]}else try{const t=(0,external_child_process_namespaceObject.execSync)("ip route get 1.1.1.1",{timeout:3e3,stdio:"pipe"}).toString().match(/src\s+(\d+\.\d+\.\d+\.\d+)/);if(t)return t[1]}catch{const r=(0,external_child_process_namespaceObject.execSync)("route -n get default 2>/dev/null || route -n 2>/dev/null",{timeout:3e3,stdio:"pipe"}).toString(),t=r.match(/interface:\s*(\S+)/i)||r.match(/0\.0\.0\.0\s+(\d+\.\d+\.\d+\.\d+)/);if(t){const u=(0,external_os_.networkInterfaces)()[t[1]];if(u){const d=u.find((p=>p.family==="IPv4"&&!p.internal));if(d)return d.address}if(/^\d+\.\d+\.\d+\.\d+$/.test(t[1]))return t[1]}}}catch{}for(const r of Object.values((0,external_os_.networkInterfaces)()))for(const t of r)if(t.family==="IPv4"&&!t.internal)return t.address;return"localhost"}function parseCookies(r=""){const t={};for(const u of r.split(";")){const d=u.indexOf("=");d>0&&(t[u.slice(0,d).trim()]=u.slice(d+1).trim())}return t}const SESSION_COOKIE="zihi_sid",COOKIE_OPTS="HttpOnly; SameSite=Lax; Path=/; Max-Age=31536000";function setSessionCookie(r,t){r.setHeader("Set-Cookie",`${SESSION_COOKIE}=${t||TOKEN}; ${COOKIE_OPTS}`)}function getSessionToken(r){return parseCookies(r)[SESSION_COOKIE]||null}function hasValidSession(r){const t=getSessionToken(r);if(t&&userSessions.has(t)){const u=userSessions.get(t);return u&&(u.lastUsed=Date.now()),!0}return!1}function getUserInfo(r){const t=getSessionToken(r);return t?userSessions.get(t):null}const MIME_MAP={".html":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/plain",".csv":"text/csv",".log":"text/plain",".sh":"text/plain",".py":"text/plain",".ts":"text/plain",".jsx":"text/plain",".tsx":"text/plain",".yml":"text/plain",".yaml":"text/plain",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".aac":"audio/aac",".wma":"audio/x-ms-wma",".mp4":"video/mp4",".webm":"video/webm",".mkv":"video/x-matroska",".avi":"video/x-msvideo",".mov":"video/quicktime",".flv":"video/x-flv",".pdf":"application/pdf",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".7z":"application/x-7z-compressed",".rar":"application/x-rar-compressed",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"};function getMime(r){return MIME_MAP[(0,external_path_.extname)(r).toLowerCase()]||"application/octet-stream"}function sanitizeError(r){return(r||"\u64CD\u4F5C\u5931\u8D25").replace(/[<>"'&]/g,(t=>({"<":"<",">":">",'"':""","'":"'","&":"&"})[t]))}function resolveUserFilePath(r,t){const u=getUserInfo(r.headers.cookie),d=r.query.sessionId||r.body?.sessionId,p=d?manager.get(d):null,x=(p?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(p.cwd)):null)||(u?.dir?(0,external_path_.resolve)((0,external_path_.normalize)(u.dir)):process.env.ZIHI_CWD||(0,external_os_.homedir)());let j=t?(0,external_path_.resolve)((0,external_path_.normalize)(x),(0,external_path_.normalize)(t)):x;if(process.platform==="win32"&&/^[A-Za-z]:$/.test(j)&&(j+="\\"),!j.startsWith(x))return{error:"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF1A\u8DEF\u5F84\u8D85\u51FA\u5141\u8BB8\u8303\u56F4",status:403};try{if(!(0,external_fs_.realpathSync)(j).startsWith(x))return{error:"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF1A\u7B26\u53F7\u94FE\u63A5\u6307\u5411\u5141\u8BB8\u8303\u56F4\u5916",status:403}}catch{}return{resolved:j,userRoot:x,info:u}}const app=express();app.set("trust proxy","loopback"),app.use(((r,t,u)=>{t.setHeader("Referrer-Policy","no-referrer"),t.setHeader("X-Content-Type-Options","nosniff"),u()}));const httpServer=(0,external_http_.createServer)(app),_corsAllowed=/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\]|10\.\d+\.\d+\.\d+|172\.(1[6-9]|2\d|3[01])\.\d+\.\d+|192\.168\.\d+\.\d+|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.\d+\.\d+)(:\d+)?$/,io=new Server({cors:{origin:(r,t)=>{if(!r||_corsAllowed.test(r))return t(null,!0);t(new Error("CORS \u4E0D\u5141\u8BB8\u6B64\u6765\u6E90"),!1)},credentials:!0},transports:["polling","websocket"],pingTimeout:6e4,pingInterval:25e3,upgradeTimeout:3e4,allowUpgrades:!0,maxHttpBufferSize:5e6});io.attach(httpServer);const manager=new SessionManager,uploadDir=(0,external_path_.join)(configDir,"uploads");(0,external_fs_.mkdirSync)(uploadDir,{recursive:!0});function checkAuth(r,t,u){const d=r.query.token;if(d&&userSessions.has(d)){const p=userSessions.get(d);if(p?.onetime){userSessions.delete(d);const x=(0,external_crypto_.randomBytes)(16).toString("hex");userSessions.set(x,{role:p.role,name:p.name,lastUsed:Date.now()}),setSessionCookie(t,x)}else setSessionCookie(t,d);const h=r.path+(Object.keys(r.query).filter((x=>x!=="token")).length?"?"+new URLSearchParams(Object.fromEntries(Object.entries(r.query).filter((([x])=>x!=="token")))):"");return t.redirect(h)}if(hasValidSession(r.headers.cookie)){if(isExclusiveMode()&&activeUser){const p=getSessionToken(r.headers.cookie);if(p!==TOKEN){const h=userSessions.get(p);if(!h||h.name!==activeUser.name)return t.setHeader("Set-Cookie",`${SESSION_COOKIE}=; HttpOnly; SameSite=Strict; Path=/; Max-Age=0`),t.redirect("/login")}}return u()}t.redirect("/login")}const server_require=(0,external_module_namespaceObject.createRequire)(import.meta.url);function pkgDirSafe(r){try{return(0,external_path_.dirname)(server_require.resolve(`${r}/package.json`))}catch{return null}}const libDir=(0,external_path_.join)(server_dirname,"lib"),staticOpts={maxAge:864e5};app.use("/lib/xterm",express.static(pkgDirSafe("xterm")||(0,external_path_.join)(libDir,"xterm"),staticOpts)),app.use("/lib/xterm-fit",express.static(pkgDirSafe("xterm-addon-fit")||(0,external_path_.join)(libDir,"xterm-fit"),staticOpts)),app.use("/lib/xterm-links",express.static(pkgDirSafe("xterm-addon-web-links")||(0,external_path_.join)(libDir,"xterm-links"),staticOpts));const _loginAttempts=new Map,LOGIN_MAX_ATTEMPTS=5,LOGIN_LOCKOUT_MS=300*1e3;function checkLoginRate(r){const t=Date.now(),u=_loginAttempts.get(r);return!u||t>u.resetAt?!0:u.count<LOGIN_MAX_ATTEMPTS}function recordLoginFailure(r){const t=Date.now(),u=_loginAttempts.get(r);!u||t>u.resetAt?_loginAttempts.set(r,{count:1,resetAt:t+LOGIN_LOCKOUT_MS}):u.count++}function clearLoginFailures(r){_loginAttempts.delete(r)}setInterval((()=>{const r=Date.now();for(const[t,u]of _loginAttempts)r>u.resetAt&&_loginAttempts.delete(t)}),600*1e3),app.get("/login",((r,t)=>{t.sendFile(__nccwpck_require__.ab+"login.html")})),app.post("/login",express.urlencoded({extended:!1}),((r,t)=>{const u=r.ip;if(!checkLoginRate(u))return t.redirect("/login?error=locked");loadRoles(),loadUsers();const d=r.body?.password,p=r.query.from,h=p&&p.startsWith("/")&&!p.startsWith("//")?p:"/";if(hasUsers()){const j=lookupUser(d);if(!j)return recordLoginFailure(u),t.redirect("/login?error=1");if(isExclusiveMode()&&activeUser&&activeUser.name!==j.name)return t.redirect("/login?error=occupied&user="+encodeURIComponent(activeUser.name));clearLoginFailures(u);const b=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(b,{role:"operator",name:j.name,dir:j.dir,lastUsed:Date.now()}),isExclusiveMode()&&(activeUser?activeUser.tokens.add(b):activeUser={name:j.name,dir:j.dir,tokens:new Set([b]),loginAt:Date.now()}),setSessionCookie(t,b),console.log(`[\u767B\u5F55] ${j.name} \u767B\u5F55\uFF08${isExclusiveMode()?"\u72EC\u5360":"\u5171\u4EAB"}\u6A21\u5F0F\uFF09`),t.redirect(h)}const x=lookupPassword(d);if(x){clearLoginFailures(u);const j=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(j,{role:x.role,name:x.name,lastUsed:Date.now()}),setSessionCookie(t,j),t.redirect(h)}if(d===PASSWORD){clearLoginFailures(u);const j=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(j,{role:"admin",name:"\u7BA1\u7406\u5458",lastUsed:Date.now()}),setSessionCookie(t,j),t.redirect(h)}recordLoginFailure(u),t.redirect("/login?error=1")})),app.post("/logout",((r,t)=>{const u=getSessionToken(r.headers.cookie);u&&(activeUser&&activeUser.tokens.has(u)&&(activeUser.tokens.delete(u),activeUser.tokens.size===0?(console.log(`[\u9000\u51FA] ${activeUser.name} \u5168\u90E8\u8BBE\u5907\u9000\u51FA\uFF0C\u91CA\u653E\u767B\u5F55\u72B6\u6001\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09`),activeUser=null):console.log(`[\u9000\u51FA] ${activeUser.name} \u4E00\u4E2A\u8BBE\u5907\u9000\u51FA\uFF08\u5269\u4F59 ${activeUser.tokens.size} \u4E2A\uFF09`)),userSessions.delete(u)),t.setHeader("Set-Cookie",`${SESSION_COOKIE}=; HttpOnly; SameSite=Strict; Path=/; Max-Age=0`),t.redirect("/login")})),app.get("/api/status",((r,t)=>{if(isExclusiveMode()&&activeUser)return t.json({occupied:!0,userName:activeUser.name,releasing:!!_exclusiveReleaseTimer});if(hasUsers()&&!isExclusiveMode()){const u=new Set;for(const[,d]of io.sockets.sockets){if(!d.data.userName||d.data.userName==="\u7BA1\u7406\u5458")continue;const p=d.handshake.headers.cookie;p&&!hasValidSession(p)||u.add(d.data.userName)}return t.json({occupied:!1,onlineUsers:[...u]})}t.json({occupied:!1})})),app.get("/admin",((r,t)=>t.sendFile(__nccwpck_require__.ab+"admin.html"))),app.get("/sw.js",((r,t)=>{t.setHeader("Service-Worker-Allowed","/"),t.sendFile(__nccwpck_require__.ab+"sw.js")})),app.get("/",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"index.html"))),app.get("/terminal/:id",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"chat.html"))),app.get("/files",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"files.html"))),app.use("/lib",express.static(__nccwpck_require__.ab+"lib",staticOpts)),app.get("/api/sessions",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json(manager.list(u?.name,u?.role==="admin"))})),app.get("/api/usage",checkAuth,((r,t)=>{try{const u=manager.listSessions().filter((p=>p.mode==="agent"&&p.alive)).map((p=>({id:p.id,title:p.title,owner:p.owner,usage:p._usage})));let d=null;for(const p of u)if(p.usage?.rateLimitInfo){d=p.usage.rateLimitInfo;break}t.json({rateLimit:d,activeSessions:u})}catch(u){t.status(500).json({error:u.message})}})),app.post("/api/sessions",checkAuth,express.json(),((r,t)=>{const u=getUserInfo(r.headers.cookie),d=manager.createAgent({...r.body,owner:u?.name,userDir:u?.dir});t.status(201).json(d.toJSON())})),app.delete("/api/sessions/:id",checkAuth,((r,t)=>{manager.kill(r.params.id),t.status(204).end()})),app.get("/api/claude-sessions",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json(listLocalClaudeSessions(u?.dir))})),app.get("/api/dirs",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);if(!u||u.role!=="admin")return t.status(403).json({error:"\u6CA1\u6709\u76EE\u5F55\u6D4F\u89C8\u6743\u9650"});const d=u.dir?(0,external_path_.resolve)((0,external_path_.normalize)(u.dir)):null,p=process.platform==="win32"?"\\":"/";let h=r.query.path||d||process.env.ZIHI_CWD||(0,external_os_.homedir)(),x=(0,external_path_.resolve)((0,external_path_.normalize)(h)).replace(/[/\\]+$/,"");process.platform==="win32"&&/^[A-Za-z]:$/.test(x)&&(x+="\\"),d&&!x.startsWith(d)&&(x=d);try{const j=(0,external_fs_.readdirSync)(x,{withFileTypes:!0}).filter(($=>$.isDirectory()&&!$.name.startsWith("."))).map(($=>({name:$.name,path:x.replace(/[/\\]+$/,"")+p+$.name}))).sort((($,O)=>$.name.localeCompare(O.name))),b=(0,external_path_.join)(x,".."),w=!d||(0,external_path_.resolve)((0,external_path_.normalize)(b)).startsWith(d);t.json({current:x,parent:w&&b!==x?b:null,dirs:j})}catch(j){t.status(400).json({error:sanitizeError(j.message)})}})),app.get("/api/me",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json({name:u?.name||"\u7528\u6237",exclusive:isExclusiveMode(),hasUsers:hasUsers(),dir:u?.dir||null})}));function getPkgVersion(){for(const r of["../package.json","./package.json","package.json"])try{const t=JSON.parse((0,external_fs_.readFileSync)((0,external_path_.join)(server_dirname,r),"utf8")).version;if(t&&t!=="0.0.0")return t}catch{}return"0.0.0"}const PKG_VERSION=getPkgVersion();let _latestVersion=null,_lastVersionCheck=0;const VERSION_CHECK_INTERVAL=600*1e3;async function checkLatestVersion(){const r=Date.now();if(_latestVersion&&r-_lastVersionCheck<VERSION_CHECK_INTERVAL)return _latestVersion;try{const t=await fetch("https://registry.npmjs.org/@wendongfly/zihi/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(8e3)});t.ok&&(_latestVersion=(await t.json()).version,_lastVersionCheck=r)}catch{}return _latestVersion}app.get("/api/version",(async(r,t)=>{const u=getPkgVersion(),d=await checkLatestVersion();t.json({current:u,latest:d||u,updateAvailable:d&&d!==u})})),app.post("/api/git/push",checkAuth,express.json(),(async(r,t)=>{const{sessionId:u,url:d,username:p,password:h,message:x,branch:j}=r.body||{};if(!u||!x)return t.status(400).json({ok:!1,error:"\u7F3A\u5C11\u53C2\u6570"});const b=manager.get(u);if(!b)return t.status(404).json({ok:!1,error:"\u4F1A\u8BDD\u4E0D\u5B58\u5728"});const w=b.cwd||process.cwd(),$=process.platform==="win32",O="git";function I(U,z={}){return new Promise(((N,B)=>{const L={...process.env,GIT_TERMINAL_PROMPT:"0"},W=(0,external_path_.join)(w,".gitconfig");(0,external_fs_.existsSync)(W)&&(L.GIT_CONFIG_GLOBAL=W);const H=(0,external_child_process_namespaceObject.spawn)(O,U,{cwd:w,env:L,timeout:6e4});let V="",J="";H.stdout.on("data",(G=>V+=G)),H.stderr.on("data",(G=>J+=G)),H.on("close",(G=>G===0?N(V.trim()):B(new Error(J.trim()||`exit ${G}`)))),H.on("error",B)}))}try{try{await I(["rev-parse","--git-dir"])}catch{await I(["init"])}if(d&&p&&h){const B=new URL(d);B.username=encodeURIComponent(p),B.password=encodeURIComponent(h);const L=B.toString(),W=(0,external_path_.join)(w,".git-credentials");(0,external_fs_.writeFileSync)(W,L+`
|
|
468
|
+
`)[0]}catch{}try{if(process.platform==="win32"){const t=(0,external_child_process_namespaceObject.execSync)("route print 0.0.0.0",{timeout:3e3,stdio:"pipe"}).toString().match(/0\.0\.0\.0\s+0\.0\.0\.0\s+\S+\s+(\d+\.\d+\.\d+\.\d+)/);if(t)return t[1]}else try{const t=(0,external_child_process_namespaceObject.execSync)("ip route get 1.1.1.1",{timeout:3e3,stdio:"pipe"}).toString().match(/src\s+(\d+\.\d+\.\d+\.\d+)/);if(t)return t[1]}catch{const r=(0,external_child_process_namespaceObject.execSync)("route -n get default 2>/dev/null || route -n 2>/dev/null",{timeout:3e3,stdio:"pipe"}).toString(),t=r.match(/interface:\s*(\S+)/i)||r.match(/0\.0\.0\.0\s+(\d+\.\d+\.\d+\.\d+)/);if(t){const u=(0,external_os_.networkInterfaces)()[t[1]];if(u){const d=u.find((p=>p.family==="IPv4"&&!p.internal));if(d)return d.address}if(/^\d+\.\d+\.\d+\.\d+$/.test(t[1]))return t[1]}}}catch{}for(const r of Object.values((0,external_os_.networkInterfaces)()))for(const t of r)if(t.family==="IPv4"&&!t.internal)return t.address;return"localhost"}function parseCookies(r=""){const t={};for(const u of r.split(";")){const d=u.indexOf("=");d>0&&(t[u.slice(0,d).trim()]=u.slice(d+1).trim())}return t}const SESSION_COOKIE="zihi_sid",COOKIE_OPTS="HttpOnly; SameSite=Lax; Path=/; Max-Age=31536000";function setSessionCookie(r,t){r.setHeader("Set-Cookie",`${SESSION_COOKIE}=${t||TOKEN}; ${COOKIE_OPTS}`)}function getSessionToken(r){return parseCookies(r)[SESSION_COOKIE]||null}function hasValidSession(r){const t=getSessionToken(r);if(t&&userSessions.has(t)){const u=userSessions.get(t);return u&&(u.lastUsed=Date.now()),!0}return!1}function getUserInfo(r){const t=getSessionToken(r);return t?userSessions.get(t):null}const MIME_MAP={".html":"text/html",".css":"text/css",".js":"text/javascript",".mjs":"text/javascript",".json":"application/json",".xml":"application/xml",".txt":"text/plain",".md":"text/plain",".csv":"text/csv",".log":"text/plain",".sh":"text/plain",".py":"text/plain",".ts":"text/plain",".jsx":"text/plain",".tsx":"text/plain",".yml":"text/plain",".yaml":"text/plain",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".flac":"audio/flac",".m4a":"audio/mp4",".aac":"audio/aac",".wma":"audio/x-ms-wma",".mp4":"video/mp4",".webm":"video/webm",".mkv":"video/x-matroska",".avi":"video/x-msvideo",".mov":"video/quicktime",".flv":"video/x-flv",".pdf":"application/pdf",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".7z":"application/x-7z-compressed",".rar":"application/x-rar-compressed",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"};function getMime(r){return MIME_MAP[(0,external_path_.extname)(r).toLowerCase()]||"application/octet-stream"}function sanitizeError(r){return(r||"\u64CD\u4F5C\u5931\u8D25").replace(/[<>"'&]/g,(t=>({"<":"<",">":">",'"':""","'":"'","&":"&"})[t]))}function resolveUserFilePath(r,t){const u=getUserInfo(r.headers.cookie),d=r.query.sessionId||r.body?.sessionId,p=d?manager.get(d):null,x=(p?.cwd?(0,external_path_.resolve)((0,external_path_.normalize)(p.cwd)):null)||(u?.dir?(0,external_path_.resolve)((0,external_path_.normalize)(u.dir)):process.env.ZIHI_CWD||(0,external_os_.homedir)());let j=t?(0,external_path_.resolve)((0,external_path_.normalize)(x),(0,external_path_.normalize)(t)):x;if(process.platform==="win32"&&/^[A-Za-z]:$/.test(j)&&(j+="\\"),!j.startsWith(x))return{error:"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF1A\u8DEF\u5F84\u8D85\u51FA\u5141\u8BB8\u8303\u56F4",status:403};try{if(!(0,external_fs_.realpathSync)(j).startsWith(x))return{error:"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF1A\u7B26\u53F7\u94FE\u63A5\u6307\u5411\u5141\u8BB8\u8303\u56F4\u5916",status:403}}catch{}return{resolved:j,userRoot:x,info:u}}const app=express();app.set("trust proxy","loopback"),app.use(((r,t,u)=>{t.setHeader("Referrer-Policy","no-referrer"),t.setHeader("X-Content-Type-Options","nosniff"),u()}));const httpServer=(0,external_http_.createServer)(app),_corsAllowed=/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\]|10\.\d+\.\d+\.\d+|172\.(1[6-9]|2\d|3[01])\.\d+\.\d+|192\.168\.\d+\.\d+|100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\.\d+\.\d+)(:\d+)?$/,io=new Server({cors:{origin:(r,t)=>{if(!r||_corsAllowed.test(r))return t(null,!0);t(new Error("CORS \u4E0D\u5141\u8BB8\u6B64\u6765\u6E90"),!1)},credentials:!0},transports:["polling","websocket"],pingTimeout:6e4,pingInterval:25e3,upgradeTimeout:3e4,allowUpgrades:!0,maxHttpBufferSize:5e6});io.attach(httpServer);const manager=new SessionManager,uploadDir=(0,external_path_.join)(configDir,"uploads");(0,external_fs_.mkdirSync)(uploadDir,{recursive:!0});function checkAuth(r,t,u){const d=r.query.token;if(d&&userSessions.has(d)){const p=userSessions.get(d);if(p?.onetime){userSessions.delete(d);const x=(0,external_crypto_.randomBytes)(16).toString("hex");userSessions.set(x,{role:p.role,name:p.name,lastUsed:Date.now()}),setSessionCookie(t,x)}else setSessionCookie(t,d);const h=r.path+(Object.keys(r.query).filter((x=>x!=="token")).length?"?"+new URLSearchParams(Object.fromEntries(Object.entries(r.query).filter((([x])=>x!=="token")))):"");return t.redirect(h)}if(hasValidSession(r.headers.cookie)){if(isExclusiveMode()&&activeUser){const p=getSessionToken(r.headers.cookie);if(p!==TOKEN){const h=userSessions.get(p);if(!h||h.name!==activeUser.name)return t.setHeader("Set-Cookie",`${SESSION_COOKIE}=; HttpOnly; SameSite=Strict; Path=/; Max-Age=0`),t.redirect("/login")}}return u()}t.redirect("/login")}const server_require=(0,external_module_namespaceObject.createRequire)(import.meta.url);function pkgDirSafe(r){try{return(0,external_path_.dirname)(server_require.resolve(`${r}/package.json`))}catch{return null}}const libDir=(0,external_path_.join)(server_dirname,"lib"),staticOpts={maxAge:864e5};app.use("/lib/xterm",express.static(pkgDirSafe("@xterm/xterm")||(0,external_path_.join)(libDir,"xterm"),staticOpts)),app.use("/lib/xterm-fit",express.static(pkgDirSafe("@xterm/addon-fit")||(0,external_path_.join)(libDir,"xterm-fit"),staticOpts)),app.use("/lib/xterm-links",express.static(pkgDirSafe("@xterm/addon-web-links")||(0,external_path_.join)(libDir,"xterm-links"),staticOpts));const _loginAttempts=new Map,LOGIN_MAX_ATTEMPTS=5,LOGIN_LOCKOUT_MS=300*1e3;function checkLoginRate(r){const t=Date.now(),u=_loginAttempts.get(r);return!u||t>u.resetAt?!0:u.count<LOGIN_MAX_ATTEMPTS}function recordLoginFailure(r){const t=Date.now(),u=_loginAttempts.get(r);!u||t>u.resetAt?_loginAttempts.set(r,{count:1,resetAt:t+LOGIN_LOCKOUT_MS}):u.count++}function clearLoginFailures(r){_loginAttempts.delete(r)}setInterval((()=>{const r=Date.now();for(const[t,u]of _loginAttempts)r>u.resetAt&&_loginAttempts.delete(t)}),600*1e3),app.get("/login",((r,t)=>{t.sendFile(__nccwpck_require__.ab+"login.html")})),app.post("/login",express.urlencoded({extended:!1}),((r,t)=>{const u=r.ip;if(!checkLoginRate(u))return t.redirect("/login?error=locked");loadRoles(),loadUsers();const d=r.body?.password,p=r.query.from,h=p&&p.startsWith("/")&&!p.startsWith("//")?p:"/";if(hasUsers()){const j=lookupUser(d);if(!j)return recordLoginFailure(u),t.redirect("/login?error=1");if(isExclusiveMode()&&activeUser&&activeUser.name!==j.name)return t.redirect("/login?error=occupied&user="+encodeURIComponent(activeUser.name));clearLoginFailures(u);const b=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(b,{role:"operator",name:j.name,dir:j.dir,lastUsed:Date.now()}),isExclusiveMode()&&(activeUser?activeUser.tokens.add(b):activeUser={name:j.name,dir:j.dir,tokens:new Set([b]),loginAt:Date.now()}),setSessionCookie(t,b),console.log(`[\u767B\u5F55] ${j.name} \u767B\u5F55\uFF08${isExclusiveMode()?"\u72EC\u5360":"\u5171\u4EAB"}\u6A21\u5F0F\uFF09`),t.redirect(h)}const x=lookupPassword(d);if(x){clearLoginFailures(u);const j=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(j,{role:x.role,name:x.name,lastUsed:Date.now()}),setSessionCookie(t,j),t.redirect(h)}if(d===PASSWORD){clearLoginFailures(u);const j=(0,external_crypto_.randomBytes)(16).toString("hex");return userSessions.set(j,{role:"admin",name:"\u7BA1\u7406\u5458",lastUsed:Date.now()}),setSessionCookie(t,j),t.redirect(h)}recordLoginFailure(u),t.redirect("/login?error=1")})),app.post("/logout",((r,t)=>{const u=getSessionToken(r.headers.cookie);u&&(activeUser&&activeUser.tokens.has(u)&&(activeUser.tokens.delete(u),activeUser.tokens.size===0?(console.log(`[\u9000\u51FA] ${activeUser.name} \u5168\u90E8\u8BBE\u5907\u9000\u51FA\uFF0C\u91CA\u653E\u767B\u5F55\u72B6\u6001\uFF08\u4F1A\u8BDD\u4FDD\u7559\uFF09`),activeUser=null):console.log(`[\u9000\u51FA] ${activeUser.name} \u4E00\u4E2A\u8BBE\u5907\u9000\u51FA\uFF08\u5269\u4F59 ${activeUser.tokens.size} \u4E2A\uFF09`)),userSessions.delete(u)),t.setHeader("Set-Cookie",`${SESSION_COOKIE}=; HttpOnly; SameSite=Strict; Path=/; Max-Age=0`),t.redirect("/login")})),app.get("/api/status",((r,t)=>{if(isExclusiveMode()&&activeUser)return t.json({occupied:!0,userName:activeUser.name,releasing:!!_exclusiveReleaseTimer});if(hasUsers()&&!isExclusiveMode()){const u=new Set;for(const[,d]of io.sockets.sockets){if(!d.data.userName||d.data.userName==="\u7BA1\u7406\u5458")continue;const p=d.handshake.headers.cookie;p&&!hasValidSession(p)||u.add(d.data.userName)}return t.json({occupied:!1,onlineUsers:[...u]})}t.json({occupied:!1})})),app.get("/admin",((r,t)=>t.sendFile(__nccwpck_require__.ab+"admin.html"))),app.get("/sw.js",((r,t)=>{t.setHeader("Service-Worker-Allowed","/"),t.sendFile(__nccwpck_require__.ab+"sw.js")})),app.get("/",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"index.html"))),app.get("/terminal/:id",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"chat.html"))),app.get("/files",checkAuth,((r,t)=>t.sendFile(__nccwpck_require__.ab+"files.html"))),app.use("/lib",express.static(__nccwpck_require__.ab+"lib",staticOpts)),app.get("/api/sessions",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json(manager.list(u?.name,u?.role==="admin"))})),app.get("/api/usage",checkAuth,((r,t)=>{try{const u=manager.listSessions().filter((p=>p.mode==="agent"&&p.alive)).map((p=>({id:p.id,title:p.title,owner:p.owner,usage:p._usage})));let d=null;for(const p of u)if(p.usage?.rateLimitInfo){d=p.usage.rateLimitInfo;break}t.json({rateLimit:d,activeSessions:u})}catch(u){t.status(500).json({error:u.message})}})),app.post("/api/sessions",checkAuth,express.json(),((r,t)=>{const u=getUserInfo(r.headers.cookie),d=manager.createAgent({...r.body,owner:u?.name,userDir:u?.dir});t.status(201).json(d.toJSON())})),app.delete("/api/sessions/:id",checkAuth,((r,t)=>{manager.kill(r.params.id),t.status(204).end()})),app.get("/api/claude-sessions",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json(listLocalClaudeSessions(u?.dir))})),app.get("/api/dirs",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);if(!u||u.role!=="admin")return t.status(403).json({error:"\u6CA1\u6709\u76EE\u5F55\u6D4F\u89C8\u6743\u9650"});const d=u.dir?(0,external_path_.resolve)((0,external_path_.normalize)(u.dir)):null,p=process.platform==="win32"?"\\":"/";let h=r.query.path||d||process.env.ZIHI_CWD||(0,external_os_.homedir)(),x=(0,external_path_.resolve)((0,external_path_.normalize)(h)).replace(/[/\\]+$/,"");process.platform==="win32"&&/^[A-Za-z]:$/.test(x)&&(x+="\\"),d&&!x.startsWith(d)&&(x=d);try{const j=(0,external_fs_.readdirSync)(x,{withFileTypes:!0}).filter(($=>$.isDirectory()&&!$.name.startsWith("."))).map(($=>({name:$.name,path:x.replace(/[/\\]+$/,"")+p+$.name}))).sort((($,O)=>$.name.localeCompare(O.name))),b=(0,external_path_.join)(x,".."),w=!d||(0,external_path_.resolve)((0,external_path_.normalize)(b)).startsWith(d);t.json({current:x,parent:w&&b!==x?b:null,dirs:j})}catch(j){t.status(400).json({error:sanitizeError(j.message)})}})),app.get("/api/me",checkAuth,((r,t)=>{const u=getUserInfo(r.headers.cookie);t.json({name:u?.name||"\u7528\u6237",exclusive:isExclusiveMode(),hasUsers:hasUsers(),dir:u?.dir||null})}));function getPkgVersion(){for(const r of["../package.json","./package.json","package.json"])try{const t=JSON.parse((0,external_fs_.readFileSync)((0,external_path_.join)(server_dirname,r),"utf8")).version;if(t&&t!=="0.0.0")return t}catch{}return"0.0.0"}const PKG_VERSION=getPkgVersion();let _latestVersion=null,_lastVersionCheck=0;const VERSION_CHECK_INTERVAL=600*1e3;async function checkLatestVersion(){const r=Date.now();if(_latestVersion&&r-_lastVersionCheck<VERSION_CHECK_INTERVAL)return _latestVersion;try{const t=await fetch("https://registry.npmjs.org/@wendongfly/zihi/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(8e3)});t.ok&&(_latestVersion=(await t.json()).version,_lastVersionCheck=r)}catch{}return _latestVersion}app.get("/api/version",(async(r,t)=>{const u=getPkgVersion(),d=await checkLatestVersion();t.json({current:u,latest:d||u,updateAvailable:d&&d!==u})})),app.post("/api/git/push",checkAuth,express.json(),(async(r,t)=>{const{sessionId:u,url:d,username:p,password:h,message:x,branch:j}=r.body||{};if(!u||!x)return t.status(400).json({ok:!1,error:"\u7F3A\u5C11\u53C2\u6570"});const b=manager.get(u);if(!b)return t.status(404).json({ok:!1,error:"\u4F1A\u8BDD\u4E0D\u5B58\u5728"});const w=b.cwd||process.cwd(),$=process.platform==="win32",O="git";function I(U,z={}){return new Promise(((N,B)=>{const L={...process.env,GIT_TERMINAL_PROMPT:"0"},W=(0,external_path_.join)(w,".gitconfig");(0,external_fs_.existsSync)(W)&&(L.GIT_CONFIG_GLOBAL=W);const H=(0,external_child_process_namespaceObject.spawn)(O,U,{cwd:w,env:L,timeout:6e4});let V="",J="";H.stdout.on("data",(G=>V+=G)),H.stderr.on("data",(G=>J+=G)),H.on("close",(G=>G===0?N(V.trim()):B(new Error(J.trim()||`exit ${G}`)))),H.on("error",B)}))}try{try{await I(["rev-parse","--git-dir"])}catch{await I(["init"])}if(d&&p&&h){const B=new URL(d);B.username=encodeURIComponent(p),B.password=encodeURIComponent(h);const L=B.toString(),W=(0,external_path_.join)(w,".git-credentials");(0,external_fs_.writeFileSync)(W,L+`
|
|
469
469
|
`,{mode:384});const H=(0,external_path_.join)(w,".gitconfig"),J=`[credential]
|
|
470
470
|
helper = store --file ${W.replace(/\\/g,"/")}
|
|
471
471
|
[user]
|
package/dist/lib/xterm/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# [](https://xtermjs.org)
|
|
1
|
+
# [](https://xtermjs.org)
|
|
2
2
|
|
|
3
3
|
Xterm.js is a front-end component written in TypeScript that lets applications bring fully-featured terminals to their users in the browser. It's used by popular projects such as VS Code, Hyper and Theia.
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ Xterm.js is a front-end component written in TypeScript that lets applications b
|
|
|
21
21
|
First, you need to install the module, we ship exclusively through [npm](https://www.npmjs.com/), so you need that installed and then add xterm.js as a dependency by running:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm install xterm
|
|
24
|
+
npm install @xterm/xterm
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to the head of your HTML page. Then create a `<div id="terminal"></div>` onto which xterm can attach itself. Finally, instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`.
|
|
@@ -30,8 +30,8 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t
|
|
|
30
30
|
<!doctype html>
|
|
31
31
|
<html>
|
|
32
32
|
<head>
|
|
33
|
-
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
|
|
34
|
-
<script src="node_modules/xterm/lib/xterm.js"></script>
|
|
33
|
+
<link rel="stylesheet" href="node_modules/@xterm/xterm/css/xterm.css" />
|
|
34
|
+
<script src="node_modules/@xterm/xterm/lib/xterm.js"></script>
|
|
35
35
|
</head>
|
|
36
36
|
<body>
|
|
37
37
|
<div id="terminal"></div>
|
|
@@ -49,7 +49,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t
|
|
|
49
49
|
The recommended way to load xterm.js is via the ES6 module syntax:
|
|
50
50
|
|
|
51
51
|
```javascript
|
|
52
|
-
import { Terminal } from 'xterm';
|
|
52
|
+
import { Terminal } from '@xterm/xterm';
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
### Addons
|
|
@@ -59,14 +59,14 @@ import { Terminal } from 'xterm';
|
|
|
59
59
|
Addons are separate modules that extend the `Terminal` by building on the [xterm.js API](https://github.com/xtermjs/xterm.js/blob/master/typings/xterm.d.ts). To use an addon, you first need to install it in your project:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
npm i -S xterm
|
|
62
|
+
npm i -S @xterm/addon-web-links
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Then import the addon, instantiate it and call `Terminal.loadAddon`:
|
|
66
66
|
|
|
67
67
|
```ts
|
|
68
|
-
import { Terminal } from 'xterm';
|
|
69
|
-
import { WebLinksAddon } from 'xterm
|
|
68
|
+
import { Terminal } from '@xterm/xterm';
|
|
69
|
+
import { WebLinksAddon } from '@xterm/addon-web-links';
|
|
70
70
|
|
|
71
71
|
const terminal = new Terminal();
|
|
72
72
|
// Load WebLinksAddon on terminal, this is all that's needed to get web links
|
|
@@ -76,10 +76,15 @@ terminal.loadAddon(new WebLinksAddon());
|
|
|
76
76
|
|
|
77
77
|
The xterm.js team maintains the following addons, but anyone can build them:
|
|
78
78
|
|
|
79
|
-
- [
|
|
80
|
-
- [
|
|
81
|
-
- [
|
|
82
|
-
- [
|
|
79
|
+
- [`@xterm/addon-attach`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-attach): Attaches to a server running a process via a websocket
|
|
80
|
+
- [`@xterm/addon-clipboard`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-clipboard): Access the browser's clipboard
|
|
81
|
+
- [`@xterm/addon-fit`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-fit): Fits the terminal to the containing element
|
|
82
|
+
- [`@xterm/addon-image`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-image): Adds image support
|
|
83
|
+
- [`@xterm/addon-search`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-search): Adds search functionality
|
|
84
|
+
- [`@xterm/addon-serialize`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-serialize): Serializes the terminal's buffer to a VT sequences or HTML
|
|
85
|
+
- [`@xterm/addon-unicode11`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-unicode11): Updates character widths to their unicode11 values
|
|
86
|
+
- [`@xterm/addon-web-links`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-web-links): Adds web link detection and interaction
|
|
87
|
+
- [`@xterm/addon-webgl`](https://github.com/xtermjs/xterm.js/tree/master/addons/addon-webgl): Renders xterm.js using a `canvas` element's webgl2 context
|
|
83
88
|
|
|
84
89
|
## Browser Support
|
|
85
90
|
|
|
@@ -108,7 +113,7 @@ All current and past releases are available on this repo's [Releases page](https
|
|
|
108
113
|
Our CI releases beta builds to npm for every change that goes into master. Install the latest beta build with:
|
|
109
114
|
|
|
110
115
|
```bash
|
|
111
|
-
npm install -S xterm@beta
|
|
116
|
+
npm install -S @xterm/xterm@beta
|
|
112
117
|
```
|
|
113
118
|
|
|
114
119
|
These should generally be stable, but some bugs may slip in. We recommend using the beta build primarily to test out new features and to verify bug fixes.
|
|
@@ -123,7 +128,6 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
|
|
123
128
|
- [**SourceLair**](https://www.sourcelair.com/): In-browser IDE that provides its users with fully-featured Linux terminals based on xterm.js.
|
|
124
129
|
- [**Microsoft Visual Studio Code**](http://code.visualstudio.com/): Modern, versatile, and powerful open source code editor that provides an integrated terminal based on xterm.js.
|
|
125
130
|
- [**ttyd**](https://github.com/tsl0922/ttyd): A command-line tool for sharing terminal over the web, with fully-featured terminal emulation based on xterm.js.
|
|
126
|
-
- [**Katacoda**](https://www.katacoda.com/): Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies.
|
|
127
131
|
- [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE.
|
|
128
132
|
- [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams.
|
|
129
133
|
- [**CoderPad**](https://coderpad.io): Online interviewing platform for programmers. Run code in many programming languages, with results displayed by xterm.js.
|
|
@@ -217,6 +221,15 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
|
|
217
221
|
- [**Cloudtutor.io**](https://cloudtutor.io): innovative online learning platform that offers users access to an interactive lab.
|
|
218
222
|
- [**Helix Editor Playground**](https://github.com/tomgroenwoldt/helix-editor-playground): Online playground for the terminal based helix editor.
|
|
219
223
|
- [**Coder**](https://github.com/coder/coder): Self-Hosted Remote Development Environments
|
|
224
|
+
- [**Wave Terminal**](https://waveterm.dev): An open-source, ai-native, terminal built for seamless workflows.
|
|
225
|
+
- [**eva**](https://github.com/info24/eva): Eva is a web application for SSH remote login, developed in Go.
|
|
226
|
+
- [**OpenSFTP**](https://opensftp.com): Super beautiful SSH and SFTP integrated workspace client.
|
|
227
|
+
- [**balena**](https://www.balena.io/): Balena is a full-stack solution for developing, deploying, updating, and troubleshooting IoT Edge devices. We use xterm.js to manage & debug devices on [balenaCloud](https://www.balena.io/cloud).
|
|
228
|
+
- [**Filet Cloud**](https://github.com/fuglaro/filet-cloud): The lean and powerful personal cloud ⛅.
|
|
229
|
+
- [**pyTermTk**](https://github.com/ceccopierangiolieugenio/pyTermTk): Python Terminal Toolkit - a Spiced Up Cross Compatible TUI Library 🌶️, use xterm.js for the [HTML5 exporter](https://ceccopierangiolieugenio.github.io/pyTermTk/sandbox/sandbox.html).
|
|
230
|
+
- [**ecmaOS**](https://ecmaos.sh): A kernel and suite of applications tying modern web technologies into a browser-based operating system.
|
|
231
|
+
- [**LabEx**](https://labex.io): Interactive learning platform with hands-on labs and xterm.js-based online terminals, focused on learn-by-doing approach.
|
|
232
|
+
- [**EmuDevz**](https://afska.github.io/emudevz): A free coding game where players learn how to build an emulator from scratch.
|
|
220
233
|
- [And much more...](https://github.com/xtermjs/xterm.js/network/dependents?package_id=UGFja2FnZS0xNjYzMjc4OQ%3D%3D)
|
|
221
234
|
|
|
222
235
|
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only.
|
|
@@ -112,10 +112,6 @@
|
|
|
112
112
|
top: 0;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
.xterm .xterm-scroll-area {
|
|
116
|
-
visibility: hidden;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
115
|
.xterm-char-measure-element {
|
|
120
116
|
display: inline-block;
|
|
121
117
|
visibility: hidden;
|
|
@@ -140,7 +136,7 @@
|
|
|
140
136
|
cursor: crosshair;
|
|
141
137
|
}
|
|
142
138
|
|
|
143
|
-
.xterm .xterm-accessibility,
|
|
139
|
+
.xterm .xterm-accessibility:not(.debug),
|
|
144
140
|
.xterm .xterm-message {
|
|
145
141
|
position: absolute;
|
|
146
142
|
left: 0;
|
|
@@ -152,6 +148,21 @@
|
|
|
152
148
|
pointer-events: none;
|
|
153
149
|
}
|
|
154
150
|
|
|
151
|
+
.xterm .xterm-accessibility-tree:not(.debug) *::selection {
|
|
152
|
+
color: transparent;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.xterm .xterm-accessibility-tree {
|
|
156
|
+
font-family: monospace;
|
|
157
|
+
user-select: text;
|
|
158
|
+
white-space: pre;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.xterm .xterm-accessibility-tree > div {
|
|
162
|
+
transform-origin: left;
|
|
163
|
+
width: fit-content;
|
|
164
|
+
}
|
|
165
|
+
|
|
155
166
|
.xterm .live-region {
|
|
156
167
|
position: absolute;
|
|
157
168
|
left: -9999px;
|
|
@@ -207,3 +218,68 @@
|
|
|
207
218
|
z-index: 2;
|
|
208
219
|
position: relative;
|
|
209
220
|
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
/* Derived from vs/base/browser/ui/scrollbar/media/scrollbar.css */
|
|
225
|
+
|
|
226
|
+
/* xterm.js customization: Override xterm's cursor style */
|
|
227
|
+
.xterm .xterm-scrollable-element > .scrollbar {
|
|
228
|
+
cursor: default;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Arrows */
|
|
232
|
+
.xterm .xterm-scrollable-element > .scrollbar > .scra {
|
|
233
|
+
cursor: pointer;
|
|
234
|
+
font-size: 11px !important;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.xterm .xterm-scrollable-element > .visible {
|
|
238
|
+
opacity: 1;
|
|
239
|
+
|
|
240
|
+
/* Background rule added for IE9 - to allow clicks on dom node */
|
|
241
|
+
background:rgba(0,0,0,0);
|
|
242
|
+
|
|
243
|
+
transition: opacity 100ms linear;
|
|
244
|
+
/* In front of peek view */
|
|
245
|
+
z-index: 11;
|
|
246
|
+
}
|
|
247
|
+
.xterm .xterm-scrollable-element > .invisible {
|
|
248
|
+
opacity: 0;
|
|
249
|
+
pointer-events: none;
|
|
250
|
+
}
|
|
251
|
+
.xterm .xterm-scrollable-element > .invisible.fade {
|
|
252
|
+
transition: opacity 800ms linear;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* Scrollable Content Inset Shadow */
|
|
256
|
+
.xterm .xterm-scrollable-element > .shadow {
|
|
257
|
+
position: absolute;
|
|
258
|
+
display: none;
|
|
259
|
+
}
|
|
260
|
+
.xterm .xterm-scrollable-element > .shadow.top {
|
|
261
|
+
display: block;
|
|
262
|
+
top: 0;
|
|
263
|
+
left: 3px;
|
|
264
|
+
height: 3px;
|
|
265
|
+
width: 100%;
|
|
266
|
+
box-shadow: var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset;
|
|
267
|
+
}
|
|
268
|
+
.xterm .xterm-scrollable-element > .shadow.left {
|
|
269
|
+
display: block;
|
|
270
|
+
top: 3px;
|
|
271
|
+
left: 0;
|
|
272
|
+
height: 100%;
|
|
273
|
+
width: 3px;
|
|
274
|
+
box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
|
|
275
|
+
}
|
|
276
|
+
.xterm .xterm-scrollable-element > .shadow.top-left-corner {
|
|
277
|
+
display: block;
|
|
278
|
+
top: 0;
|
|
279
|
+
left: 0;
|
|
280
|
+
height: 3px;
|
|
281
|
+
width: 3px;
|
|
282
|
+
}
|
|
283
|
+
.xterm .xterm-scrollable-element > .shadow.top.left {
|
|
284
|
+
box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset;
|
|
285
|
+
}
|