tabby-bianbu-mcp 0.3.0 → 0.3.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/README.md CHANGED
@@ -4,8 +4,9 @@ A Tabby plugin that adds polished Bianbu Cloud remote tabs backed by your MCP en
4
4
 
5
5
  What it provides:
6
6
  - a dedicated `Bianbu MCP` settings page inside Tabby
7
- - a `Bianbu Cloud Shell` tab that behaves like a remote shell window
8
- - a `Bianbu Cloud Files` tab that behaves like a file-manager / SFTP-style window
7
+ - `Bianbu Cloud Shell` and `Bianbu Cloud Files` entries integrated into Tabby's tab/profile flow
8
+ - a terminal-based shell experience backed by MCP `run_command`
9
+ - an explorer-like file manager backed by MCP file tools
9
10
  - connection fields for MCP URL, `X-API-KEY`, pacing, retries, and notes
10
11
  - quick actions and copyable config snippets
11
12
 
package/dist/index.js CHANGED
@@ -41,7 +41,7 @@ module.exports = (req['default'] || req).apply(req, [])
41
41
 
42
42
  var pug = __webpack_require__(/*! !../node_modules/pug-runtime/index.js */ "./node_modules/pug-runtime/index.js");
43
43
 
44
- function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv style=\"padding: 16px; display:flex; flex-direction:column; gap:16px; height:100%\"\u003E\u003Cdiv class=\"card\" style=\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08)\"\u003E\u003Ch3 style=\"margin-top:0\"\u003EBianbu Cloud Files\u003C\u002Fh3\u003E\u003Cp style=\"opacity:.8; margin-bottom:0\"\u003EFile-manager-like remote access over MCP. This behaves like an SFTP panel, but it is backed by MCP file tools instead of the native SFTP protocol.\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"card\" style=\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08)\"\u003E\u003Cdiv class=\"row\" style=\"display:grid; grid-template-columns: 1fr auto auto; gap:12px; align-items:end\"\u003E\u003Cdiv class=\"field\"\u003E\u003Clabel style=\"display:block; margin-bottom:6px\"\u003ECurrent path\u003C\u002Flabel\u003E\u003Cinput class=\"form-control\" type=\"text\" [(ngModel)]=\"currentPath\" [disabled]=\"busy\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"field\"\u003E\u003Clabel style=\"display:block; margin-bottom:6px\"\u003ERoot\u003C\u002Flabel\u003E\u003Cinput type=\"checkbox\" [(ngModel)]=\"asRoot\" [disabled]=\"busy\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"field\" style=\"display:flex; gap:8px\"\u003E\u003Cbutton class=\"btn btn-primary\" type=\"button\" (click)=\"refresh()\" [disabled]=\"busy\"\u003ERefresh\u003C\u002Fbutton\u003E\u003Clabel class=\"btn btn-secondary\" style=\"margin:0\"\u003EUpload\u003Cinput type=\"file\" style=\"display:none\" (change)=\"uploadFile($event)\" [disabled]=\"busy\"\u003E\u003C\u002Flabel\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"margin-top:12px; opacity:.75\"\u003E{{ status }}\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"row\" style=\"display:grid; grid-template-columns: 420px 1fr; gap:16px; flex:1; min-height:0\"\u003E\u003Cdiv class=\"card\" style=\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08); overflow:auto\"\u003E\u003Cdiv style=\"display:grid; grid-template-columns: 1fr 1fr auto; gap:8px; margin-bottom:12px\"\u003E\u003Cinput class=\"form-control\" type=\"text\" [(ngModel)]=\"newDirectoryName\" placeholder=\"new-directory\" [disabled]=\"busy\"\u003E\u003Cinput class=\"form-control\" type=\"text\" [(ngModel)]=\"newFileName\" placeholder=\"new-file.txt\" [disabled]=\"busy\"\u003E\u003Cdiv style=\"display:flex; gap:8px\"\u003E\u003Cbutton class=\"btn btn-secondary\" type=\"button\" (click)=\"createDirectory()\" [disabled]=\"busy || !newDirectoryName.trim()\"\u003EMkdir\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-secondary\" type=\"button\" (click)=\"createFile()\" [disabled]=\"busy || !newFileName.trim()\"\u003ENew file\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Ctable style=\"width:100%; border-collapse:collapse\"\u003E\u003Cthead\u003E\u003Ctr style=\"text-align:left; opacity:.7\"\u003E\u003Cth style=\"padding:8px\"\u003EName\u003C\u002Fth\u003E\u003Cth style=\"padding:8px\"\u003EType\u003C\u002Fth\u003E\u003Cth style=\"padding:8px\"\u003ESize\u003C\u002Fth\u003E\u003Cth style=\"padding:8px\"\u003E\u003C\u002Fth\u003E\u003C\u002Ftr\u003E\u003C\u002Fthead\u003E\u003Ctbody\u003E\u003Ctr *ngFor=\"let item of items\" style=\"border-top:1px solid rgba(255,255,255,0.08)\"\u003E\u003Ctd style=\"padding:8px; cursor:pointer\" (click)=\"openItem(item)\"\u003E{{ item.path.split('\u002F').pop() || item.path }}\u003C\u002Ftd\u003E\u003Ctd style=\"padding:8px\"\u003E{{ item.is_dir ? 'dir' : 'file' }}\u003C\u002Ftd\u003E\u003Ctd style=\"padding:8px\"\u003E{{ item.size }}\u003C\u002Ftd\u003E\u003Ctd style=\"padding:8px; text-align:right\"\u003E\u003Cbutton class=\"btn btn-sm btn-outline-danger\" type=\"button\" (click)=\"deleteItem(item)\" [disabled]=\"busy\"\u003EDelete\u003C\u002Fbutton\u003E\u003C\u002Ftd\u003E\u003C\u002Ftr\u003E\u003C\u002Ftbody\u003E\u003C\u002Ftable\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"card\" style=\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08); display:flex; flex-direction:column; min-height:0\"\u003E\u003Cdiv style=\"display:flex; justify-content:space-between; gap:12px; align-items:center; margin-bottom:12px\"\u003E\u003Cdiv\u003E\u003Ch4 style=\"margin:0\"\u003EFile preview\u003C\u002Fh4\u003E\u003Cdiv style=\"opacity:.7; font-size:.9em\"\u003E{{ selectedPath || 'No file selected' }}\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"display:flex; gap:8px\"\u003E\u003Cbutton class=\"btn btn-secondary\" type=\"button\" (click)=\"downloadSelected()\" [disabled]=\"busy || !selectedPath\"\u003EDownload\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-primary\" type=\"button\" (click)=\"saveSelected()\" [disabled]=\"busy || !selectedPath\"\u003ESave\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Ctextarea class=\"form-control\" style=\"flex:1; min-height:320px\" [(ngModel)]=\"selectedContent\" [disabled]=\"busy || !selectedPath\" placeholder=\"Select a text file to view or edit\"\u003E\u003C\u002Ftextarea\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
44
+ function template(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_html = pug_html + "\u003Cdiv style=\"height:100%; display:flex; flex-direction:column; background:#111827; color:#e5e7eb\"\u003E\u003Cdiv class=\"topbar\" style=\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; flex-direction:column; gap:10px; background:#0f172a\"\u003E\u003Cdiv class=\"toolbar\" style=\"display:flex; gap:8px; align-items:center; flex-wrap:wrap\"\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"goBack()\" [disabled]=\"busy || historyIndex <= 0\" title=\"Back (Alt+Left)\" style=\"min-width:34px; font-weight:700\"\u003E←\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"goForward()\" [disabled]=\"busy || historyIndex >= history.length - 1\" title=\"Forward (Alt+Right)\" style=\"min-width:34px; font-weight:700\"\u003E→\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"goUp()\" [disabled]=\"busy || currentPath === "." || currentPath === "\u002F"\" title=\"Up (Alt+Up \u002F Backspace)\" style=\"min-width:34px; font-weight:700\"\u003E↑\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"refresh()\" [disabled]=\"busy\" title=\"Refresh (F5)\" style=\"min-width:34px; font-weight:700\"\u003E⟳\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"openCreateDirectoryPrompt()\" [disabled]=\"busy\"\u003ENew folder\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"openCreateFilePrompt()\" [disabled]=\"busy\"\u003ENew file\u003C\u002Fbutton\u003E\u003Clabel class=\"btn btn-sm btn-secondary\" style=\"margin:0\"\u003EUpload\u003Cinput type=\"file\" style=\"display:none\" (change)=\"uploadFile($event)\" [disabled]=\"busy\"\u003E\u003C\u002Flabel\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"downloadSelected()\" [disabled]=\"busy || !selectedPath\"\u003EDownload\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"transfersVisible = !transfersVisible\"\u003ETransfers\u003C\u002Fbutton\u003E\u003Clabel style=\"display:flex; align-items:center; gap:6px; margin-left:auto; background:#1e293b; padding:6px 10px; border-radius:8px\"\u003E\u003Cinput type=\"checkbox\" [(ngModel)]=\"asRoot\" (ngModelChange)=\"refresh()\"\u003E\u003Cspan\u003Eas_root\u003C\u002Fspan\u003E\u003C\u002Flabel\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"address\" style=\"display:flex; gap:8px; align-items:center\"\u003E\u003Cdiv style=\"display:flex; gap:4px; align-items:center; flex-wrap:wrap; padding:10px 12px; border-radius:10px; background:#1e293b; border:1px solid #334155; flex:1\"\u003E\u003Cbutton class=\"btn btn-link\" type=\"button\" *ngFor=\"let crumb of breadcrumbs; let i=index\" (click)=\"navigateBreadcrumb(i)\" style=\"padding:0 4px; min-height:auto; color:#f8fafc; text-decoration:none; font-weight:600\"\u003E{{ crumb }}\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003Cinput class=\"form-control\" id=\"bianbu-path-input\" type=\"text\" style=\"max-width:420px; background:#0b1220; color:#f8fafc; border:1px solid #334155\" [(ngModel)]=\"pathInput\" (keyup.enter)=\"navigateToInput()\" title=\"Ctrl+L to focus path\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"searchrow\" style=\"display:flex; gap:8px; align-items:center\"\u003E\u003Cinput class=\"form-control\" type=\"text\" style=\"background:#0b1220; color:#f8fafc; border:1px solid #334155\" [(ngModel)]=\"searchText\" (ngModelChange)=\"applyFilter()\" placeholder=\"Filter current directory…\"\u003E\u003Cdiv style=\"color:#cbd5e1; white-space:nowrap\"\u003E{{ status }}\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"main\" style=\"display:grid; grid-template-columns: minmax(460px, 48%) 1fr; gap:0; flex:1; min-height:0\"\u003E\u003Cdiv class=\"pane left\" style=\"display:flex; flex-direction:column; min-height:0; border-right:1px solid #334155; position:relative; background:#0b1220\" [style.outline]=\"dragActive ? "2px dashed #4ade80" : "none"\" (dragover)=\"onDragOver($event)\" (dragleave)=\"onDragLeave()\" (drop)=\"onDrop($event)\"\u003E\u003Cdiv *ngIf=\"dragActive\" style=\"position:absolute; inset:12px; border-radius:12px; background:rgba(74,222,128,0.12); display:flex; align-items:center; justify-content:center; z-index:10; pointer-events:none; color:#d1fae5; font-size:18px; font-weight:700\"\u003EDrop file to upload\u003C\u002Fdiv\u003E\u003Cdiv style=\"overflow:auto; flex:1\"\u003E\u003Ctable style=\"width:100%; border-collapse:collapse; table-layout:fixed\"\u003E\u003Cthead style=\"position:sticky; top:0; z-index:2; background:#0f172a\"\u003E\u003Ctr style=\"text-align:left; color:#cbd5e1; border-bottom:1px solid #334155\"\u003E\u003Cth style=\"padding:10px 12px; width:58%\"\u003EName\u003C\u002Fth\u003E\u003Cth style=\"padding:10px 12px; width:16%\"\u003EType\u003C\u002Fth\u003E\u003Cth style=\"padding:10px 12px; width:26%\"\u003ESize\u003C\u002Fth\u003E\u003C\u002Ftr\u003E\u003C\u002Fthead\u003E\u003Ctbody\u003E\u003Ctr *ngFor=\"let item of filteredItems; let i=index\" [style.background]=\"i === selectedIndex ? "#1d4ed8" : "transparent"\" [style.color]=\"i === selectedIndex ? "#ffffff" : "#e5e7eb"\" style=\"border-bottom:1px solid #1e293b; cursor:default\" (click)=\"selectItem(item)\" (dblclick)=\"openItem(item)\" (contextmenu)=\"showContextMenu($event, item)\"\u003E\u003Ctd style=\"padding:10px 12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-weight:600\"\u003E{{ baseName(item.path) }}\u003C\u002Ftd\u003E\u003Ctd style=\"padding:10px 12px\"\u003E{{ item.is_dir ? 'dir' : 'file' }}\u003C\u002Ftd\u003E\u003Ctd style=\"padding:10px 12px\"\u003E{{ item.size }}\u003C\u002Ftd\u003E\u003C\u002Ftr\u003E\u003C\u002Ftbody\u003E\u003C\u002Ftable\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"pane right\" style=\"display:flex; flex-direction:column; min-height:0; background:#111827\"\u003E\u003Cdiv class=\"previewHeader\" style=\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; justify-content:space-between; gap:12px; align-items:center; background:#0f172a\"\u003E\u003Cdiv\u003E\u003Ch4 style=\"margin:0; color:#f8fafc\"\u003EPreview \u002F Editor\u003C\u002Fh4\u003E\u003Cdiv style=\"color:#94a3b8; font-size:.9em\"\u003E{{ selectedPath || 'Select a file from the left pane' }}\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"display:flex; gap:8px\"\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"downloadSelected()\" [disabled]=\"busy || !selectedPath\"\u003EDownload\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"saveSelected()\" [disabled]=\"busy || !selectedPath || !selectedIsText\"\u003ESave\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"flex:1; min-height:0; display:flex\"\u003E\u003Ctextarea class=\"form-control\" *ngIf=\"selectedPath && selectedIsText\" style=\"flex:1; min-height:0; border:none; border-radius:0; background:#111827; color:#f8fafc; padding:14px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace\" [(ngModel)]=\"selectedContent\" [disabled]=\"busy\" placeholder=\"Open a text file to preview or edit it\"\u003E\u003C\u002Ftextarea\u003E\u003Cdiv *ngIf=\"selectedPath && !selectedIsText\" style=\"flex:1; display:flex; align-items:center; justify-content:center; text-align:center; color:#cbd5e1; padding:24px\"\u003E\u003Cdiv\u003E\u003Cdiv style=\"font-size:20px; font-weight:700; margin-bottom:10px\"\u003EThis file type is not previewed inline\u003C\u002Fdiv\u003E\u003Cdiv style=\"margin-bottom:16px; color:#94a3b8\"\u003EDownload the file to inspect it locally.\u003C\u002Fdiv\u003E\u003Cbutton class=\"btn btn-primary\" type=\"button\" (click)=\"downloadSelected()\"\u003EDownload file\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv *ngIf=\"!selectedPath\" style=\"flex:1; display:flex; align-items:center; justify-content:center; text-align:center; color:#94a3b8\"\u003ESelect a file from the left pane to preview or edit it.\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"contextMenu\" *ngIf=\"contextMenuVisible && contextItem\" [style.left.px]=\"contextMenuX\" [style.top.px]=\"contextMenuY\" style=\"position:fixed; z-index:1000; min-width:180px; background:#0f172a; border:1px solid #334155; border-radius:10px; box-shadow:0 12px 30px rgba(0,0,0,.45); padding:6px\"\u003E\u003Cbutton class=\"btn btn-link\" type=\"button\" style=\"display:block; width:100%; text-align:left; color:#f8fafc; text-decoration:none; padding:8px 10px\" (click)=\"openItem(contextItem); hideContextMenu()\"\u003EOpen\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-link\" type=\"button\" style=\"display:block; width:100%; text-align:left; color:#f8fafc; text-decoration:none; padding:8px 10px\" (click)=\"openRenamePrompt(contextItem); hideContextMenu()\"\u003ERename\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-link\" type=\"button\" style=\"display:block; width:100%; text-align:left; color:#fca5a5; text-decoration:none; padding:8px 10px\" (click)=\"deleteItem(contextItem); hideContextMenu()\"\u003EDelete\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"promptOverlay\" *ngIf=\"promptVisible\" style=\"position:fixed; inset:0; background:rgba(2,6,23,.65); z-index:1100; display:flex; align-items:center; justify-content:center\"\u003E\u003Cdiv class=\"promptCard\" style=\"width:420px; background:#0f172a; border:1px solid #334155; border-radius:14px; padding:18px; box-shadow:0 20px 50px rgba(0,0,0,.45)\"\u003E\u003Ch3 style=\"margin-top:0; color:#f8fafc\"\u003E{{ promptTitle }}\u003C\u002Fh3\u003E\u003Cinput class=\"form-control\" type=\"text\" style=\"background:#0b1220; color:#f8fafc; border:1px solid #334155\" [(ngModel)]=\"promptValue\" [placeholder]=\"promptPlaceholder\" (keyup.enter)=\"confirmPrompt()\" (keyup.escape)=\"closePrompt()\"\u003E\u003Cdiv style=\"display:flex; justify-content:flex-end; gap:10px; margin-top:16px\"\u003E\u003Cbutton class=\"btn btn-secondary\" type=\"button\" (click)=\"closePrompt()\"\u003ECancel\u003C\u002Fbutton\u003E\u003Cbutton class=\"btn btn-primary\" type=\"button\" (click)=\"confirmPrompt()\"\u003EConfirm\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"transferOverlay\" *ngIf=\"transfersVisible\" style=\"position:fixed; right:16px; bottom:16px; width:360px; max-height:50vh; overflow:auto; z-index:900; background:#0f172a; border:1px solid #334155; border-radius:14px; box-shadow:0 20px 50px rgba(0,0,0,.45)\"\u003E\u003Cdiv style=\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; justify-content:space-between; align-items:center\"\u003E\u003Cb style=\"color:#f8fafc\"\u003ETransfers\u003C\u002Fb\u003E\u003Cbutton class=\"btn btn-sm btn-secondary\" type=\"button\" (click)=\"transfersVisible = false\"\u003EHide\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003Cdiv *ngIf=\"!transfers.length\" style=\"padding:14px; color:#94a3b8\"\u003ENo uploads or downloads yet.\u003C\u002Fdiv\u003E\u003Cdiv *ngFor=\"let transfer of transfers\" style=\"padding:12px 14px; border-bottom:1px solid #1e293b\"\u003E\u003Cdiv style=\"display:flex; justify-content:space-between; gap:12px; margin-bottom:6px\"\u003E\u003Cdiv style=\"color:#f8fafc; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis\"\u003E{{ transfer.name }}\u003C\u002Fdiv\u003E\u003Cdiv style=\"color:#94a3b8; font-size:.9em\"\u003E{{ transfer.direction }}\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"color:#94a3b8; font-size:.9em; margin-bottom:8px\"\u003E{{ transfer.status }} • {{ transferRate(transfer) }}\u003C\u002Fdiv\u003E\u003Cdiv style=\"height:8px; border-radius:999px; background:#1e293b; overflow:hidden; margin-bottom:8px\"\u003E\u003Cdiv *ngIf=\"transferPercent(transfer) !== null\" [style.width.%]=\"transferPercent(transfer)\" style=\"height:100%; background:#3b82f6\"\u003E\u003C\u002Fdiv\u003E\u003Cdiv *ngIf=\"transferPercent(transfer) === null && transfer.status === "running"\" style=\"height:100%; width:45%; background:linear-gradient(90deg,#334155,#60a5fa,#334155)\"\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003Cdiv style=\"display:flex; justify-content:space-between; align-items:center\"\u003E\u003Cdiv style=\"color:#cbd5e1; font-size:.9em\"\u003E{{ transfer.bytesDone }} \u002F {{ transfer.bytesTotal || 'unknown' }} bytes\u003C\u002Fdiv\u003E\u003Cbutton class=\"btn btn-sm btn-outline-danger\" type=\"button\" *ngIf=\"transfer.status === "running"\" (click)=\"cancelTransfer(transfer)\"\u003ECancel\u003C\u002Fbutton\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E";;return pug_html;};
45
45
  module.exports = template;
46
46
 
47
47
  /***/ },
@@ -448,28 +448,146 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
448
448
  this.mcp = mcp;
449
449
  this.notifications = notifications;
450
450
  this.currentPath = '.';
451
+ this.pathInput = '.';
451
452
  this.asRoot = false;
452
453
  this.busy = false;
453
454
  this.items = [];
455
+ this.filteredItems = [];
454
456
  this.selectedPath = '';
455
457
  this.selectedContent = '';
456
- this.newDirectoryName = '';
457
- this.newFileName = '';
458
+ this.selectedIsText = false;
458
459
  this.status = 'Ready';
460
+ this.dragActive = false;
461
+ this.searchText = '';
462
+ this.history = ['.'];
463
+ this.historyIndex = 0;
464
+ this.selectedIndex = -1;
465
+ this.contextMenuVisible = false;
466
+ this.contextMenuX = 0;
467
+ this.contextMenuY = 0;
468
+ this.contextItem = null;
469
+ this.promptVisible = false;
470
+ this.promptTitle = '';
471
+ this.promptPlaceholder = '';
472
+ this.promptValue = '';
473
+ this.promptAction = null;
474
+ this.promptTarget = null;
475
+ this.transfersVisible = true;
476
+ this.transfers = [];
477
+ this.transferSeq = 1;
459
478
  this.setTitle('Bianbu Cloud Files');
460
479
  this.icon = 'folder-open';
461
480
  }
462
481
  ngOnInit() {
463
482
  this.refresh().catch(() => null);
464
483
  }
484
+ get breadcrumbs() {
485
+ if (!this.currentPath || this.currentPath === '.') {
486
+ return ['.'];
487
+ }
488
+ const normalized = this.currentPath.replace(/\\/g, '/');
489
+ if (normalized === '/') {
490
+ return ['/'];
491
+ }
492
+ const parts = normalized.split('/').filter(Boolean);
493
+ return normalized.startsWith('/') ? ['/'].concat(parts) : parts;
494
+ }
495
+ get selectedItem() {
496
+ var _a;
497
+ return (_a = this.filteredItems[this.selectedIndex]) !== null && _a !== void 0 ? _a : null;
498
+ }
499
+ onDocumentClick() {
500
+ this.hideContextMenu();
501
+ }
502
+ onKeyDown(event) {
503
+ var _a;
504
+ const target = event.target;
505
+ const tag = (_a = target === null || target === void 0 ? void 0 : target.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase();
506
+ const editing = ['input', 'textarea'].includes(tag || '') || this.promptVisible;
507
+ if (event.key === 'F5') {
508
+ event.preventDefault();
509
+ void this.refresh();
510
+ return;
511
+ }
512
+ if (event.altKey && event.key === 'ArrowUp') {
513
+ event.preventDefault();
514
+ this.goUp();
515
+ return;
516
+ }
517
+ if (event.altKey && event.key === 'ArrowLeft') {
518
+ event.preventDefault();
519
+ this.goBack();
520
+ return;
521
+ }
522
+ if (event.altKey && event.key === 'ArrowRight') {
523
+ event.preventDefault();
524
+ this.goForward();
525
+ return;
526
+ }
527
+ if (event.ctrlKey && event.key.toLowerCase() === 'l') {
528
+ event.preventDefault();
529
+ const el = document.getElementById('bianbu-path-input');
530
+ el === null || el === void 0 ? void 0 : el.focus();
531
+ el === null || el === void 0 ? void 0 : el.select();
532
+ return;
533
+ }
534
+ if (event.ctrlKey && event.key.toLowerCase() === 'n') {
535
+ event.preventDefault();
536
+ this.openCreateFilePrompt();
537
+ return;
538
+ }
539
+ if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === 'n') {
540
+ event.preventDefault();
541
+ this.openCreateDirectoryPrompt();
542
+ return;
543
+ }
544
+ if (editing) {
545
+ return;
546
+ }
547
+ if (event.key === 'Backspace') {
548
+ event.preventDefault();
549
+ this.goUp();
550
+ return;
551
+ }
552
+ if (event.key === 'Delete' && this.selectedItem) {
553
+ event.preventDefault();
554
+ void this.deleteItem(this.selectedItem);
555
+ return;
556
+ }
557
+ if (event.key === 'F2' && this.selectedItem) {
558
+ event.preventDefault();
559
+ this.openRenamePrompt(this.selectedItem);
560
+ return;
561
+ }
562
+ if (event.key === 'Enter' && this.selectedItem) {
563
+ event.preventDefault();
564
+ void this.openItem(this.selectedItem);
565
+ return;
566
+ }
567
+ if (event.key === 'ArrowDown') {
568
+ event.preventDefault();
569
+ this.moveSelection(1);
570
+ return;
571
+ }
572
+ if (event.key === 'ArrowUp') {
573
+ event.preventDefault();
574
+ this.moveSelection(-1);
575
+ return;
576
+ }
577
+ }
465
578
  async refresh() {
466
579
  this.busy = true;
467
580
  this.status = 'Loading directory…';
468
- this.setProgress(0.3);
581
+ this.pathInput = this.currentPath;
582
+ this.setProgress(0.25);
469
583
  try {
470
584
  const result = await this.mcp.listDirectory(this.currentPath || '.', this.asRoot);
471
585
  this.items = result.items || [];
586
+ this.applyFilter();
472
587
  this.status = `Loaded ${this.items.length} item(s)`;
588
+ if (this.filteredItems.length && this.selectedIndex < 0) {
589
+ this.selectedIndex = 0;
590
+ }
473
591
  }
474
592
  catch (error) {
475
593
  this.notifications.error('Failed to list directory', String((error === null || error === void 0 ? void 0 : error.message) || error));
@@ -480,32 +598,115 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
480
598
  this.setProgress(null);
481
599
  }
482
600
  }
601
+ applyFilter() {
602
+ const q = this.searchText.trim().toLowerCase();
603
+ this.filteredItems = this.items.filter(item => {
604
+ const name = this.baseName(item.path).toLowerCase();
605
+ return !q || name.includes(q) || item.path.toLowerCase().includes(q);
606
+ });
607
+ if (this.selectedIndex >= this.filteredItems.length) {
608
+ this.selectedIndex = this.filteredItems.length - 1;
609
+ }
610
+ }
611
+ navigateToInput() {
612
+ this.navigate(this.pathInput || '.');
613
+ }
614
+ navigate(path, pushHistory = true) {
615
+ this.currentPath = path || '.';
616
+ this.pathInput = this.currentPath;
617
+ if (pushHistory) {
618
+ this.history = this.history.slice(0, this.historyIndex + 1);
619
+ this.history.push(this.currentPath);
620
+ this.historyIndex = this.history.length - 1;
621
+ }
622
+ this.clearPreview();
623
+ this.selectedIndex = -1;
624
+ void this.refresh();
625
+ }
626
+ navigateBreadcrumb(index) {
627
+ if (this.currentPath === '.' && index === 0) {
628
+ this.navigate('.', true);
629
+ return;
630
+ }
631
+ const crumbs = this.breadcrumbs;
632
+ if (crumbs[0] === '/') {
633
+ if (index === 0) {
634
+ this.navigate('/', true);
635
+ return;
636
+ }
637
+ this.navigate('/' + crumbs.slice(1, index + 1).join('/'), true);
638
+ return;
639
+ }
640
+ this.navigate(crumbs.slice(0, index + 1).join('/'), true);
641
+ }
642
+ goBack() {
643
+ if (this.historyIndex <= 0) {
644
+ return;
645
+ }
646
+ this.historyIndex -= 1;
647
+ this.navigate(this.history[this.historyIndex], false);
648
+ }
649
+ goForward() {
650
+ if (this.historyIndex >= this.history.length - 1) {
651
+ return;
652
+ }
653
+ this.historyIndex += 1;
654
+ this.navigate(this.history[this.historyIndex], false);
655
+ }
656
+ goUp() {
657
+ if (this.currentPath === '.' || this.currentPath === '/') {
658
+ return;
659
+ }
660
+ const normalized = this.currentPath.replace(/\\/g, '/');
661
+ const parent = normalized.split('/').slice(0, -1).join('/') || (normalized.startsWith('/') ? '/' : '.');
662
+ this.navigate(parent, true);
663
+ }
664
+ moveSelection(delta) {
665
+ if (!this.filteredItems.length) {
666
+ this.selectedIndex = -1;
667
+ return;
668
+ }
669
+ if (this.selectedIndex < 0) {
670
+ this.selectedIndex = 0;
671
+ return;
672
+ }
673
+ this.selectedIndex = Math.max(0, Math.min(this.filteredItems.length - 1, this.selectedIndex + delta));
674
+ }
675
+ selectItem(item) {
676
+ this.selectedIndex = this.filteredItems.indexOf(item);
677
+ }
483
678
  async openItem(item) {
679
+ this.selectItem(item);
484
680
  if (item.is_dir) {
485
- this.currentPath = item.path;
486
- this.selectedPath = '';
487
- this.selectedContent = '';
488
- await this.refresh();
681
+ this.navigate(item.path, true);
489
682
  return;
490
683
  }
491
684
  this.busy = true;
492
- this.status = `Reading ${item.path}`;
685
+ this.status = `Opening ${item.path}`;
686
+ this.selectedPath = item.path;
687
+ this.selectedIsText = this.isTextLike(item.path);
493
688
  try {
494
- const result = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot);
495
- this.selectedPath = item.path;
496
- this.selectedContent = result.content || '';
497
- this.status = `Opened ${item.path}`;
689
+ if (this.selectedIsText) {
690
+ const result = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot);
691
+ this.selectedContent = result.content || '';
692
+ this.status = `Opened ${item.path}`;
693
+ }
694
+ else {
695
+ this.selectedContent = '';
696
+ this.status = `Binary / non-text file selected: ${item.path}`;
697
+ }
498
698
  }
499
699
  catch (error) {
500
700
  this.notifications.error('Failed to open file', String((error === null || error === void 0 ? void 0 : error.message) || error));
501
701
  this.status = String((error === null || error === void 0 ? void 0 : error.message) || error);
702
+ this.selectedContent = '';
502
703
  }
503
704
  finally {
504
705
  this.busy = false;
505
706
  }
506
707
  }
507
708
  async saveSelected() {
508
- if (!this.selectedPath) {
709
+ if (!this.selectedPath || !this.selectedIsText) {
509
710
  return;
510
711
  }
511
712
  this.busy = true;
@@ -524,15 +725,62 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
524
725
  this.busy = false;
525
726
  }
526
727
  }
527
- async createDirectory() {
528
- if (!this.newDirectoryName.trim()) {
728
+ openCreateDirectoryPrompt() {
729
+ this.promptVisible = true;
730
+ this.promptTitle = 'Create new folder';
731
+ this.promptPlaceholder = 'Folder name';
732
+ this.promptValue = '';
733
+ this.promptAction = 'mkdir';
734
+ this.promptTarget = null;
735
+ }
736
+ openCreateFilePrompt() {
737
+ this.promptVisible = true;
738
+ this.promptTitle = 'Create new file';
739
+ this.promptPlaceholder = 'File name';
740
+ this.promptValue = '';
741
+ this.promptAction = 'newfile';
742
+ this.promptTarget = null;
743
+ }
744
+ openRenamePrompt(item) {
745
+ this.promptVisible = true;
746
+ this.promptTitle = 'Rename';
747
+ this.promptPlaceholder = 'New name';
748
+ this.promptValue = this.baseName(item.path);
749
+ this.promptAction = 'rename';
750
+ this.promptTarget = item;
751
+ }
752
+ closePrompt() {
753
+ this.promptVisible = false;
754
+ this.promptAction = null;
755
+ this.promptTarget = null;
756
+ this.promptValue = '';
757
+ }
758
+ async confirmPrompt() {
759
+ const value = this.promptValue.trim();
760
+ if (!value || !this.promptAction) {
761
+ this.closePrompt();
762
+ return;
763
+ }
764
+ if (this.promptAction === 'mkdir') {
765
+ await this.createDirectory(value);
766
+ this.closePrompt();
767
+ return;
768
+ }
769
+ if (this.promptAction === 'newfile') {
770
+ await this.createFile(value);
771
+ this.closePrompt();
529
772
  return;
530
773
  }
531
- const path = this.joinPath(this.currentPath, this.newDirectoryName.trim());
774
+ if (this.promptAction === 'rename' && this.promptTarget) {
775
+ await this.renameItem(this.promptTarget, value);
776
+ this.closePrompt();
777
+ }
778
+ }
779
+ async createDirectory(name) {
780
+ const path = this.joinPath(this.currentPath, name);
532
781
  this.busy = true;
533
782
  try {
534
783
  await this.mcp.makeDirectory(path, this.asRoot);
535
- this.newDirectoryName = '';
536
784
  await this.refresh();
537
785
  this.notifications.notice('Directory created');
538
786
  }
@@ -544,15 +792,11 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
544
792
  this.busy = false;
545
793
  }
546
794
  }
547
- async createFile() {
548
- if (!this.newFileName.trim()) {
549
- return;
550
- }
551
- const path = this.joinPath(this.currentPath, this.newFileName.trim());
795
+ async createFile(name) {
796
+ const path = this.joinPath(this.currentPath, name);
552
797
  this.busy = true;
553
798
  try {
554
799
  await this.mcp.writeTextFile(path, '', this.asRoot);
555
- this.newFileName = '';
556
800
  await this.refresh();
557
801
  this.notifications.notice('File created');
558
802
  }
@@ -564,13 +808,32 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
564
808
  this.busy = false;
565
809
  }
566
810
  }
811
+ async renameItem(item, name) {
812
+ const parent = item.path.split('/').slice(0, -1).join('/') || '.';
813
+ const newPath = this.joinPath(parent, name);
814
+ try {
815
+ if (item.is_dir) {
816
+ await this.mcp.makeDirectory(newPath, this.asRoot);
817
+ }
818
+ else {
819
+ const content = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot);
820
+ await this.mcp.writeTextFile(newPath, content.content || '', this.asRoot);
821
+ }
822
+ await this.mcp.deletePath(item.path, !!item.is_dir, this.asRoot);
823
+ this.notifications.notice('Path renamed');
824
+ await this.refresh();
825
+ }
826
+ catch (error) {
827
+ this.notifications.error('Rename failed', String((error === null || error === void 0 ? void 0 : error.message) || error));
828
+ this.status = String((error === null || error === void 0 ? void 0 : error.message) || error);
829
+ }
830
+ }
567
831
  async deleteItem(item) {
568
832
  this.busy = true;
569
833
  try {
570
834
  await this.mcp.deletePath(item.path, !!item.is_dir, this.asRoot);
571
835
  if (this.selectedPath === item.path) {
572
- this.selectedPath = '';
573
- this.selectedContent = '';
836
+ this.clearPreview();
574
837
  }
575
838
  await this.refresh();
576
839
  this.notifications.notice('Path deleted');
@@ -583,6 +846,19 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
583
846
  this.busy = false;
584
847
  }
585
848
  }
849
+ showContextMenu(event, item) {
850
+ event.preventDefault();
851
+ event.stopPropagation();
852
+ this.selectItem(item);
853
+ this.contextItem = item;
854
+ this.contextMenuVisible = true;
855
+ this.contextMenuX = event.clientX;
856
+ this.contextMenuY = event.clientY;
857
+ }
858
+ hideContextMenu() {
859
+ this.contextMenuVisible = false;
860
+ this.contextItem = null;
861
+ }
586
862
  async uploadFile(event) {
587
863
  var _a;
588
864
  const input = event.target;
@@ -590,40 +866,131 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
590
866
  if (!file) {
591
867
  return;
592
868
  }
869
+ await this.uploadDroppedFile(file);
870
+ input.value = '';
871
+ }
872
+ createTransfer(name, direction, total, controller) {
873
+ const transfer = {
874
+ id: this.transferSeq++,
875
+ name,
876
+ direction,
877
+ status: 'running',
878
+ bytesDone: 0,
879
+ bytesTotal: total,
880
+ startedAt: Date.now(),
881
+ controller,
882
+ };
883
+ this.transfers.unshift(transfer);
884
+ return transfer;
885
+ }
886
+ cancelTransfer(transfer) {
887
+ var _a;
888
+ if (transfer.status !== 'running') {
889
+ return;
890
+ }
891
+ (_a = transfer.controller) === null || _a === void 0 ? void 0 : _a.abort();
892
+ transfer.status = 'cancelled';
893
+ transfer.finishedAt = Date.now();
894
+ }
895
+ transferPercent(transfer) {
896
+ if (!transfer.bytesTotal) {
897
+ return null;
898
+ }
899
+ return Math.max(0, Math.min(100, Math.round((transfer.bytesDone / transfer.bytesTotal) * 100)));
900
+ }
901
+ transferRate(transfer) {
902
+ const end = transfer.finishedAt || Date.now();
903
+ const seconds = Math.max(1, (end - transfer.startedAt) / 1000);
904
+ const bytes = transfer.bytesDone || 0;
905
+ return `${Math.round(bytes / seconds / 1024)} KB/s`;
906
+ }
907
+ async uploadDroppedFile(file) {
908
+ const controller = new AbortController();
909
+ const transfer = this.createTransfer(file.name, 'upload', file.size, controller);
593
910
  this.busy = true;
594
911
  try {
595
912
  const base64 = await this.readFileAsBase64(file);
913
+ transfer.bytesDone = Math.floor(file.size * 0.3);
596
914
  const path = this.joinPath(this.currentPath, file.name);
597
- await this.mcp.uploadBinaryFile(path, base64, this.asRoot);
915
+ await this.mcp.uploadBinaryFile(path, base64, this.asRoot, controller.signal);
916
+ transfer.bytesDone = file.size;
917
+ transfer.status = 'done';
918
+ transfer.finishedAt = Date.now();
598
919
  this.notifications.notice('File uploaded');
599
920
  await this.refresh();
600
921
  }
601
922
  catch (error) {
602
- this.notifications.error('Upload failed', String((error === null || error === void 0 ? void 0 : error.message) || error));
603
- this.status = String((error === null || error === void 0 ? void 0 : error.message) || error);
923
+ if (transfer.status !== 'cancelled') {
924
+ transfer.status = 'error';
925
+ transfer.error = String((error === null || error === void 0 ? void 0 : error.message) || error);
926
+ transfer.finishedAt = Date.now();
927
+ this.notifications.error('Upload failed', transfer.error);
928
+ this.status = transfer.error;
929
+ }
604
930
  }
605
931
  finally {
606
932
  this.busy = false;
607
- input.value = '';
608
933
  }
609
934
  }
935
+ onDragOver(event) {
936
+ event.preventDefault();
937
+ this.dragActive = true;
938
+ }
939
+ onDragLeave() {
940
+ this.dragActive = false;
941
+ }
942
+ async onDrop(event) {
943
+ var _a, _b;
944
+ event.preventDefault();
945
+ this.dragActive = false;
946
+ const file = (_b = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0];
947
+ if (!file) {
948
+ return;
949
+ }
950
+ await this.uploadDroppedFile(file);
951
+ }
610
952
  async downloadSelected() {
611
953
  if (!this.selectedPath) {
612
954
  return;
613
955
  }
956
+ const controller = new AbortController();
957
+ const transfer = this.createTransfer(this.baseName(this.selectedPath), 'download', null, controller);
614
958
  try {
615
- const result = await this.mcp.downloadBinaryFile(this.selectedPath, this.asRoot);
959
+ const result = await this.mcp.downloadBinaryFile(this.selectedPath, this.asRoot, controller.signal);
960
+ const raw = atob(result.content_base64);
961
+ transfer.bytesTotal = raw.length;
962
+ transfer.bytesDone = raw.length;
963
+ transfer.status = 'done';
964
+ transfer.finishedAt = Date.now();
616
965
  const a = document.createElement('a');
617
966
  a.href = `data:application/octet-stream;base64,${result.content_base64}`;
618
- a.download = this.selectedPath.split('/').pop() || 'download.bin';
967
+ a.download = this.baseName(this.selectedPath) || 'download.bin';
619
968
  a.click();
620
969
  this.notifications.notice('Download started');
621
970
  }
622
971
  catch (error) {
623
- this.notifications.error('Download failed', String((error === null || error === void 0 ? void 0 : error.message) || error));
624
- this.status = String((error === null || error === void 0 ? void 0 : error.message) || error);
972
+ if (transfer.status !== 'cancelled') {
973
+ transfer.status = 'error';
974
+ transfer.error = String((error === null || error === void 0 ? void 0 : error.message) || error);
975
+ transfer.finishedAt = Date.now();
976
+ this.notifications.error('Download failed', transfer.error);
977
+ this.status = transfer.error;
978
+ }
625
979
  }
626
980
  }
981
+ clearPreview() {
982
+ this.selectedPath = '';
983
+ this.selectedContent = '';
984
+ this.selectedIsText = false;
985
+ }
986
+ baseName(path) {
987
+ return path.split('/').pop() || path;
988
+ }
989
+ isTextLike(path) {
990
+ const name = path.toLowerCase();
991
+ const exts = ['.txt', '.md', '.json', '.yaml', '.yml', '.xml', '.ini', '.cfg', '.conf', '.log', '.sh', '.py', '.js', '.ts', '.tsx', '.jsx', '.html', '.css', '.scss', '.c', '.cpp', '.h', '.hpp', '.java', '.go', '.rs', '.sql'];
992
+ return exts.some(ext => name.endsWith(ext));
993
+ }
627
994
  joinPath(base, child) {
628
995
  if (!base || base === '.') {
629
996
  return child;
@@ -645,6 +1012,18 @@ let BianbuCloudFilesTabComponent = class BianbuCloudFilesTabComponent extends ta
645
1012
  });
646
1013
  }
647
1014
  };
1015
+ __decorate([
1016
+ (0, core_1.HostListener)('document:click'),
1017
+ __metadata("design:type", Function),
1018
+ __metadata("design:paramtypes", []),
1019
+ __metadata("design:returntype", void 0)
1020
+ ], BianbuCloudFilesTabComponent.prototype, "onDocumentClick", null);
1021
+ __decorate([
1022
+ (0, core_1.HostListener)('document:keydown', ['$event']),
1023
+ __metadata("design:type", Function),
1024
+ __metadata("design:paramtypes", [KeyboardEvent]),
1025
+ __metadata("design:returntype", void 0)
1026
+ ], BianbuCloudFilesTabComponent.prototype, "onKeyDown", null);
648
1027
  BianbuCloudFilesTabComponent = __decorate([
649
1028
  (0, core_1.Component)({
650
1029
  template: __webpack_require__(/*! ./filesTab.component.pug */ "./src/filesTab.component.pug"),
@@ -786,7 +1165,7 @@ let BianbuMcpService = class BianbuMcpService {
786
1165
  this.nextAllowedAt = Date.now() + ((_a = this.settings.minIntervalMs) !== null && _a !== void 0 ? _a : 1000);
787
1166
  return fetch(input, init);
788
1167
  }
789
- async request(payload) {
1168
+ async request(payload, signal) {
790
1169
  var _a, _b, _c, _d, _e, _f, _g;
791
1170
  const settings = this.settings;
792
1171
  const maxRetries = Number((_a = settings.maxRetries) !== null && _a !== void 0 ? _a : 2);
@@ -805,6 +1184,7 @@ let BianbuMcpService = class BianbuMcpService {
805
1184
  'X-API-KEY': settings.apiKey,
806
1185
  },
807
1186
  body: JSON.stringify(payload),
1187
+ signal,
808
1188
  });
809
1189
  const text = await response.text();
810
1190
  lastBody = text;
@@ -852,7 +1232,7 @@ let BianbuMcpService = class BianbuMcpService {
852
1232
  }
853
1233
  return { error: { message: text || 'Invalid MCP response' } };
854
1234
  }
855
- async callTool(name, args) {
1235
+ async callTool(name, args, signal) {
856
1236
  return this.request({
857
1237
  jsonrpc: '2.0',
858
1238
  id: `${name}-${Date.now()}`,
@@ -861,7 +1241,7 @@ let BianbuMcpService = class BianbuMcpService {
861
1241
  name,
862
1242
  arguments: args,
863
1243
  },
864
- });
1244
+ }, signal);
865
1245
  }
866
1246
  async health() {
867
1247
  return this.callTool('health', {});
@@ -908,20 +1288,20 @@ let BianbuMcpService = class BianbuMcpService {
908
1288
  as_root: asRoot,
909
1289
  });
910
1290
  }
911
- async uploadBinaryFile(path, base64, asRoot) {
1291
+ async uploadBinaryFile(path, base64, asRoot, signal) {
912
1292
  return this.callTool('upload_binary_file', {
913
1293
  path,
914
1294
  content_base64: base64,
915
1295
  overwrite: true,
916
1296
  as_root: asRoot,
917
- });
1297
+ }, signal);
918
1298
  }
919
- async downloadBinaryFile(path, asRoot) {
1299
+ async downloadBinaryFile(path, asRoot, signal) {
920
1300
  return this.callTool('download_binary_file', {
921
1301
  path,
922
1302
  max_bytes: 64 * 1024 * 1024,
923
1303
  as_root: asRoot,
924
- });
1304
+ }, signal);
925
1305
  }
926
1306
  };
927
1307
  BianbuMcpService = __decorate([
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","mappings":"AAAA;AACA;AACA,4JAA4J,MAAM,wBAAwB,aAAa;AACvM;AACA;AACA;AACA,iLAAiL,MAAM,wBAAwB,aAAa;AAC5N;AACA;AACA,CAAC;AACD,O;;;;;;;;;ACVA,UAAU,mBAAO,CAAC,0IAA0J;AAC5K,uD;;;;;;;;;;ACDA,UAAU,mBAAO,CAAC,gJAA6J;AAC/K,uD;;;;;;;;;;ACDA,UAAU,mBAAO,CAAC,kFAAuC;;AAEzD,2BAA2B,kCAAkC,aAAa,wDAAwD,cAAc,uBAAuB,UAAU,kEAAkE,oBAAoB,mCAAmC,sJAAsJ,gQAAgQ,oBAAoB,mCAAmC,6FAA6F,sCAAsC,UAAU,yFAAyF,yPAAyP,uMAAuM,waAAwa,sBAAsB,SAAS,wFAAwF,kCAAkC,UAAU,QAAQ,mEAAmE,oBAAoB,mCAAmC,yCAAyC,qDAAqD,qCAAqC,SAAS,sUAAsU,oaAAoa,mFAAmF,ybAAyb,oDAAoD,+CAA+C,2DAA2D,+BAA+B,2DAA2D,YAAY,kDAAkD,2UAA2U,oBAAoB,mCAAmC,yCAAyC,cAAc,uBAAuB,oDAAoD,+BAA+B,UAAU,oBAAoB,wIAAwI,yBAAyB,qCAAqC,0EAA0E,yaAAya,4OAA4O;AACxwK,0B;;;;;;;;;;ACHA,UAAU,mBAAO,CAAC,kFAAuC;;AAEzD,2BAA2B,kCAAkC,aAAa,wDAAwD,cAAc,uBAAuB,+DAA+D,oBAAoB,4EAA4E,oHAAoH,4NAA4N,oBAAoB,oCAAoC,sJAAsJ,UAAU,uXAAuX,oBAAoB,oCAAoC,2KAA2K,kCAAkC,UAAU,utDAAutD,oBAAoB,oCAAoC,sKAAsK,0BAA0B,aAAa,yFAAyF,oBAAoB,oCAAoC,kOAAkO,UAAU,6WAA6W;AAC1rI,0B;;;;;;;;;;;ACHa;;AAEb;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY,QAAQ;AACpB;AACA;;AAEA,aAAa;AACb;AACA;AACA;AACA,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,iDAAiD,aAAa;AAC9D;AACA,iDAAiD,aAAa;AAC9D;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,iBAAiB;AAC5B,YAAY;AACZ;AACA,eAAe;AACf;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,YAAY;AACZ;;AAEA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY;AACZ;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY;AACZ;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,iBAAiB;AAC9D;AACA,+BAA+B,GAAG;AAClC,8BAA8B,GAAG;AACjC,6BAA6B,GAAG;AAChC,6BAA6B,GAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;;AAEA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kDAA0B;AAC3C,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AC7PA,yEAA0C;AAC1C,yEAAkF;AAClF,4GAAmE;AACnE,4GAAmE;AAEnE,cAAc;AAEP,IAAM,0BAA0B,GAAhC,MAAM,0BAA2B,SAAQ,4BAAe;IAC7D,YACU,GAAe;QAEvB,KAAK,EAAE;QAFC,QAAG,GAAH,GAAG,CAAY;IAGzB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO;YACL;gBACE,EAAE,EAAE,oBAAoB;gBACxB,KAAK,EAAE,yBAAyB;gBAChC,QAAQ,EAAE,mCAAmC;gBAC7C,SAAS,EAAE,CAAC,4BAAe,CAAC,SAAS,CAAC;gBACtC,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,iDAA4B,EAAE,CAAC;gBAC7D,CAAC;aACF;YACD;gBACE,EAAE,EAAE,oBAAoB;gBACxB,KAAK,EAAE,yBAAyB;gBAChC,QAAQ,EAAE,kCAAkC;gBAC5C,SAAS,EAAE,CAAC,4BAAe,CAAC,SAAS,CAAC;gBACtC,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,iDAA4B,EAAE,CAAC;gBAC7D,CAAC;aACF;SACF;IACH,CAAC;CACF;AA7BY,0BAA0B;IADtC,qBAAU,GAAE;qCAGI,uBAAU;GAFd,0BAA0B,CA6BtC;AA7BY,gEAA0B;;;;;;;;;;;;;;;ACPvC,yEAA2C;AAE3C,cAAc;AACd,MAAa,uBAAwB,SAAQ,2BAAc;IAA3D;;QACE,aAAQ,GAAG;YACT,SAAS,EAAE;gBACT,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,EAAE;gBACP,MAAM,EAAE,EAAE;gBACV,aAAa,EAAE,IAAI;gBACnB,UAAU,EAAE,CAAC;gBACb,WAAW,EAAE,IAAI;gBACjB,KAAK,EAAE,EAAE;aACV;SACF;IACH,CAAC;CAAA;AAbD,0DAaC;;;;;;;;;;;;;;;;;;;;;;;;AChBD,yEAAmD;AACnD,yEAAmE;AACnE,uFAAgD;AAEhD,cAAc;AAIP,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,6BAAgB;IAWhE,YACE,QAAkB,EACV,GAAqB,EACrB,aAAmC;QAE3C,KAAK,CAAC,QAAQ,CAAC;QAHP,QAAG,GAAH,GAAG,CAAkB;QACrB,kBAAa,GAAb,aAAa,CAAsB;QAb7C,gBAAW,GAAG,GAAG;QACjB,WAAM,GAAG,KAAK;QACd,SAAI,GAAG,KAAK;QACZ,UAAK,GAAU,EAAE;QACjB,iBAAY,GAAG,EAAE;QACjB,oBAAe,GAAG,EAAE;QACpB,qBAAgB,GAAG,EAAE;QACrB,gBAAW,GAAG,EAAE;QAChB,WAAM,GAAG,OAAO;QAQd,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,aAAa;IAC3B,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,CAAC,MAAM,GAAG,oBAAoB;QAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;QACrB,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YACjF,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE;YAC/B,IAAI,CAAC,MAAM,GAAG,UAAU,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU;SACpD;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,0BAA0B,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YACrF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;YACjB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;SACvB;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAE,IAAS;QACvB,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI;YAC5B,IAAI,CAAC,YAAY,GAAG,EAAE;YACtB,IAAI,CAAC,eAAe,GAAG,EAAE;YACzB,MAAM,IAAI,CAAC,OAAO,EAAE;YACpB,OAAM;SACP;QAED,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,CAAC,MAAM,GAAG,WAAW,IAAI,CAAC,IAAI,EAAE;QACpC,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAC9E,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI;YAC7B,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE;YAC3C,IAAI,CAAC,MAAM,GAAG,UAAU,IAAI,CAAC,IAAI,EAAE;SACpC;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAChF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;SAClB;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,OAAM;SACP;QACD,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,CAAC,MAAM,GAAG,UAAU,IAAI,CAAC,YAAY,EAAE;QAC3C,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC;YAClF,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC;YACvC,IAAI,CAAC,MAAM,GAAG,SAAS,IAAI,CAAC,YAAY,EAAE;YAC1C,MAAM,IAAI,CAAC,OAAO,EAAE;SACrB;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAChF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;SAClB;IACH,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE;YACjC,OAAM;SACP;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QAC1E,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAC/C,IAAI,CAAC,gBAAgB,GAAG,EAAE;YAC1B,MAAM,IAAI,CAAC,OAAO,EAAE;YACpB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,mBAAmB,CAAC;SAC/C;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,4BAA4B,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YACvF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;SAClB;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE;YAC5B,OAAM;SACP;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACrE,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC;YACnD,IAAI,CAAC,WAAW,GAAG,EAAE;YACrB,MAAM,IAAI,CAAC,OAAO,EAAE;YACpB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC;SAC1C;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAClF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;SAClB;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAE,IAAS;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI;YACF,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;YAChE,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,IAAI,EAAE;gBACnC,IAAI,CAAC,YAAY,GAAG,EAAE;gBACtB,IAAI,CAAC,eAAe,GAAG,EAAE;aAC1B;YACD,MAAM,IAAI,CAAC,OAAO,EAAE;YACpB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC;SAC1C;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAClF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;SAClB;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAE,KAAY;;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,MAA0B;QAC9C,MAAM,IAAI,GAAG,WAAK,CAAC,KAAK,0CAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE;YACT,OAAM;SACP;QACD,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC;YACvD,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;YAC1D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,eAAe,CAAC;YAC1C,MAAM,IAAI,CAAC,OAAO,EAAE;SACrB;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAC1E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;gBAAS;YACR,IAAI,CAAC,IAAI,GAAG,KAAK;YACjB,KAAK,CAAC,KAAK,GAAG,EAAE;SACjB;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,OAAM;SACP;QACD,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC;YAChF,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC;YACrC,CAAC,CAAC,IAAI,GAAG,wCAAwC,MAAM,CAAC,cAAc,EAAE;YACxE,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,cAAc;YACjE,CAAC,CAAC,KAAK,EAAE;YACT,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC;SAC9C;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC;SAC9C;IACH,CAAC;IAEO,QAAQ,CAAE,IAAY,EAAE,KAAa;QAC3C,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE;YACzB,OAAO,KAAK;SACb;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACtB,OAAO,GAAG,IAAI,GAAG,KAAK,EAAE;SACzB;QACD,OAAO,GAAG,IAAI,IAAI,KAAK,EAAE;IAC3B,CAAC;IAEO,gBAAgB,CAAE,IAAU;QAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE;YAC/B,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;gBACnB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACnC,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAC3C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC;CACF;AAzMY,4BAA4B;IAHxC,oBAAS,EAAC;QACT,QAAQ,EAAE,mBAAO,CAAC,8DAA0B,CAAC;KAC9C,CAAC;qCAaY,eAAQ;QACL,8BAAgB;QACN,iCAAoB;GAdlC,4BAA4B,CAyMxC;AAzMY,oEAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACRzC,yEAAwC;AACxC,+EAA8C;AAC9C,4EAA4C;AAC5C,uFAA8F;AAC9F,qFAAoD;AAEpD,gGAA0D;AAC1D,+GAAoE;AACpE,qHAAoE;AACpE,8EAAuD;AACvD,uFAAgD;AAChD,4GAAmE;AACnE,4GAAmE;AACnE,mGAA8D;AA0B/C,IAAM,eAAe,GAArB,MAAM,eAAe;CAAI;AAAnB,eAAe;IAxBnC,mBAAQ,EAAC;QACR,OAAO,EAAE;YACP,qBAAY;YACZ,mBAAW;YACX,oBAAe;SAChB;QACD,SAAS,EAAE;YACT,8BAAgB;YAChB,EAAE,OAAO,EAAE,2BAAc,EAAE,QAAQ,EAAE,wCAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;YAC3E,EAAE,OAAO,EAAE,oCAAmB,EAAE,QAAQ,EAAE,kDAA4B,EAAE,KAAK,EAAE,IAAI,EAAE;YACrF,EAAE,OAAO,EAAE,4BAAe,EAAE,QAAQ,EAAE,qCAA0B,EAAE,KAAK,EAAE,IAAI,EAAE;YAC/E,EAAE,OAAO,EAAE,4BAAe,EAAE,QAAQ,EAAE,4CAA0B,EAAE,KAAK,EAAE,IAAI,EAAE;SAChF;QACD,YAAY,EAAE;YACZ,kDAA0B;YAC1B,iDAA4B;YAC5B,iDAA4B;SAC7B;QACD,eAAe,EAAE;YACf,kDAA0B;YAC1B,iDAA4B;YAC5B,iDAA4B;SAC7B;KACF,CAAC;GACmB,eAAe,CAAI;qBAAnB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;ACvCpC,yEAA0C;AAC1C,yEAA0C;AAQnC,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAG3B,YACU,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;QAHvB,kBAAa,GAAG,CAAC;IAIrB,CAAC;IAEL,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;IACpC,CAAC;IAEO,KAAK,CAAE,EAAU;QACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC;IAEO,iBAAiB,CAAE,MAAc;QACvC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,UAAU,CAAE,KAAwB,EAAE,IAAkB;;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3D,IAAI,MAAM,GAAG,CAAC,EAAE;YACd,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;SACzB;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,UAAI,CAAC,QAAQ,CAAC,aAAa,mCAAI,IAAI,CAAC;QACvE,OAAO,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;IAC3B,CAAC;IAEO,KAAK,CAAC,OAAO,CAAE,OAAY;;QACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,cAAQ,CAAC,UAAU,mCAAI,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,MAAM,CAAC,cAAQ,CAAC,WAAW,mCAAI,IAAI,CAAC;QACxD,IAAI,QAAQ,GAAG,EAAE;QACjB,IAAI,UAAU,GAAG,CAAC;QAClB,IAAI,SAAS,GAAQ,IAAI;QAEzB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE;YACtD,IAAI;gBACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE;oBACnD,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,MAAM,EAAE,qCAAqC;wBAC7C,sBAAsB,EAAE,YAAY;wBACpC,WAAW,EAAE,QAAQ,CAAC,MAAM;qBAC7B;oBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;iBAC9B,CAAC;gBACF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;gBAClC,QAAQ,GAAG,IAAI;gBACf,UAAU,GAAG,QAAQ,CAAC,MAAM;gBAE5B,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;oBAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBACnC,IAAI,MAAM,CAAC,KAAK,EAAE;wBAChB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,WAAW,CAAC;qBACrD;oBACD,IAAI,aAAM,CAAC,MAAM,0CAAE,OAAO,MAAI,wBAAM,CAAC,MAAM,0CAAE,OAAO,0CAAG,CAAC,CAAC,0CAAE,IAAI,GAAE;wBAC/D,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;qBAC/C;oBACD,IAAI,aAAM,CAAC,MAAM,0CAAE,iBAAiB,MAAK,SAAS,EAAE;wBAClD,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB;qBACvC;oBACD,OAAO,MAAM,CAAC,MAAM;iBACrB;aACF;YAAC,OAAO,KAAK,EAAE;gBACd,SAAS,GAAG,KAAK;gBACjB,IAAI,OAAO,KAAK,UAAU,EAAE;oBAC1B,MAAK;iBACN;aACF;YAED,IAAI,OAAO,GAAG,UAAU,EAAE;gBACxB,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;aAC9C;SACF;QAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,kCAAkC,UAAU,KAAK,QAAQ,EAAE,CAAC;IAC3F,CAAC;IAEO,SAAS,CAAE,IAAY;QAC7B,IAAI;YACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;SACxB;QAAC,MAAM;YACN,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC;YACpD,IAAI,QAAQ,EAAE;gBACZ,IAAI;oBACF,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;iBAC/B;gBAAC,MAAM;oBACN,SAAS;iBACV;aACF;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,sBAAsB,EAAE,EAAE;IAC/D,CAAC;IAED,KAAK,CAAC,QAAQ,CAAE,IAAY,EAAE,IAAS;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YAC3B,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE;gBACN,IAAI;gBACJ,SAAS,EAAE,IAAI;aAChB;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,UAAU,CAAE,OAAe,EAAE,GAAW,EAAE,cAAsB,EAAE,MAAe;QACrF,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;YAClC,OAAO;YACP,GAAG;YACH,eAAe,EAAE,cAAc;YAC/B,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,IAAY,EAAE,MAAe;QAChD,OAAO,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,YAAY,CAAE,IAAY,EAAE,QAAgB,EAAE,MAAe;QACjE,OAAO,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACrC,IAAI;YACJ,SAAS,EAAE,QAAQ;YACnB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,IAAY,EAAE,OAAe,EAAE,MAAe;QACjE,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE;YACtC,IAAI;YACJ,OAAO;YACP,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAE,IAAY,EAAE,MAAe;QAChD,OAAO,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACrC,IAAI;YACJ,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAE,IAAY,EAAE,SAAkB,EAAE,MAAe;QACjE,OAAO,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE;YAClC,IAAI;YACJ,SAAS;YACT,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAE,IAAY,EAAE,MAAc,EAAE,MAAe;QACnE,OAAO,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE;YACzC,IAAI;YACJ,cAAc,EAAE,MAAM;YACtB,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAE,IAAY,EAAE,MAAe;QACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,sBAAsB,EAAE;YAC3C,IAAI;YACJ,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;YAC3B,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;CACF;AAhLY,gBAAgB;IAD5B,qBAAU,GAAE;qCAKO,0BAAa;GAJpB,gBAAgB,CAgL5B;AAhLY,4CAAgB;;;;;;;;;;;;;;;ACT7B,yEAAyF;AACzF,4GAAmE;AACnE,4GAAmE;AAQnE,cAAc;AACd,MAAa,0BAA2B,SAAQ,4BAAmC;IAAnF;;QACE,OAAE,GAAG,cAAc;QACnB,SAAI,GAAG,cAAc;QACrB,mBAAc,GAAG,EAAE;IA8DrB,CAAC;IA5DC,KAAK,CAAC,kBAAkB;QACtB,OAAO;YACL;gBACE,EAAE,EAAE,oBAAoB;gBACxB,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,cAAc;gBACrB,mBAAmB,EAAE,KAAK;gBAC1B,oBAAoB,EAAE,MAAM;gBAC5B,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;iBACd;aACF;YACD;gBACE,EAAE,EAAE,oBAAoB;gBACxB,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,cAAc;gBACrB,mBAAmB,EAAE,IAAI;gBACzB,oBAAoB,EAAE,MAAM;gBAC5B,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,IAAI;gBACf,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE;oBACP,IAAI,EAAE,OAAO;iBACd;aACF;SACF;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAE,OAA2B;QACpD,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE;YACpC,OAAO;gBACL,IAAI,EAAE,iDAA4B;gBAClC,MAAM,EAAE,EAAE,OAAO,EAAE;aACpB;SACF;QACD,OAAO;YACL,IAAI,EAAE,iDAA4B;YAClC,MAAM,EAAE,EAAE,OAAO,EAAE;SACpB;IACH,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI;IACb,CAAC;IAED,cAAc,CAAE,OAAY;;QAC1B,IAAI,cAAO,CAAC,OAAO,0CAAE,IAAI,MAAK,OAAO,EAAE;YACrC,OAAO,oDAAoD;SAC5D;QACD,OAAO,uDAAuD;IAChE,CAAC;CACF;AAjED,gEAiEC;;;;;;;;;;;;;;;;;;;;;;;;AC5ED,yEAAyC;AACzC,yEAAsD;AACtD,4GAAmE;AACnE,4GAAmE;AAEnE,cAAc;AAIP,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IACrC,YACS,MAAqB,EACpB,GAAe;QADhB,WAAM,GAAN,MAAM,CAAe;QACpB,QAAG,GAAH,GAAG,CAAY;IACrB,CAAC;IAEL,IAAI,UAAU;QACZ,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;QACrC,OAAO,IAAI,CAAC,SAAS,CAAC;YACpB,UAAU,EAAE;gBACV,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE;oBACpB,IAAI,EAAE,MAAM;oBACZ,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,qCAAqC;oBACnD,OAAO,EAAE;wBACP,WAAW,EAAE,CAAC,CAAC,MAAM,IAAI,gBAAgB;qBAC1C;iBACF;aACF;SACF,EAAE,IAAI,EAAE,CAAC,CAAC;IACb,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;IACpB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,iDAA4B,EAAE,CAAC;IAC7D,CAAC;IAED,SAAS;QACP,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,iDAA4B,EAAE,CAAC;IAC7D,CAAC;CACF;AAhCY,0BAA0B;IAHtC,oBAAS,EAAC;QACT,QAAQ,EAAE,mBAAO,CAAC,oEAA6B,CAAC;KACjD,CAAC;qCAGiB,0BAAa;QACf,uBAAU;GAHd,0BAA0B,CAgCtC;AAhCY,gEAA0B;;;;;;;;;;;;;;;;;;;;;ACTvC,yEAA0C;AAC1C,qFAAoD;AACpD,qHAAoE;AAEpE,cAAc;AAEP,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,oCAAmB;IAA9D;;QACL,OAAE,GAAG,YAAY;QACjB,SAAI,GAAG,MAAM;QACb,UAAK,GAAG,YAAY;IAKtB,CAAC;IAHC,gBAAgB;QACd,OAAO,kDAA0B;IACnC,CAAC;CACF;AARY,4BAA4B;IADxC,qBAAU,GAAE;GACA,4BAA4B,CAQxC;AARY,oEAA4B;;;;;;;;;;;;;;;ACNzC,qFAA4C;AAI5C,MAAa,kBAAmB,SAAQ,4BAAW;IAMjD,YACE,MAAc,EACN,GAAqB;QAE7B,KAAK,CAAC,MAAM,CAAC;QAFL,QAAG,GAAH,GAAG,CAAkB;QAPvB,QAAG,GAAG,GAAG;QACT,gBAAW,GAAG,EAAE;QAChB,YAAO,GAAG,KAAK;QACf,WAAM,GAAG,KAAK;IAOtB,CAAC;IAED,KAAK,CAAC,KAAK,CAAE,OAAY;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI;QAChB,IAAI,CAAC,GAAG,GAAG,QAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG,KAAI,GAAG;QAC9B,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,QAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM;QAC/B,IAAI,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACxD,IAAI,CAAC,UAAU,EAAE;IACnB,CAAC;IAED,MAAM,CAAE,QAAgB,EAAE,KAAa;QACrC,0CAA0C;IAC5C,CAAC;IAED,KAAK,CAAE,IAAY;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnC,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE;YACrB,KAAK,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;SACzB;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK;IACtB,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,OAAO,GAAG,KAAK;IACtB,CAAC;IAED,wBAAwB;QACtB,OAAO,IAAI;IACb,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,OAAO,IAAI,CAAC,GAAG;IACjB,CAAC;IAEO,KAAK,CAAC,UAAU,CAAE,EAAU;QAClC,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,EAAE,KAAK,QAAQ,EAAE;gBACnB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;aACxB;YACD,OAAM;SACP;QAED,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW;YAChC,IAAI,CAAC,WAAW,GAAG,EAAE;YACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACrB,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE;gBAClB,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;aAC5B;YACD,IAAI,CAAC,UAAU,EAAE;YACjB,OAAM;SACP;QAED,IAAI,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI,EAAE;YAClC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;gBAC3B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;aACvB;YACD,OAAM;SACP;QAED,IAAI,EAAE,KAAK,QAAQ,EAAE;YACnB,IAAI,CAAC,WAAW,GAAG,EAAE;YACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvB,IAAI,CAAC,UAAU,EAAE;YACjB,OAAM;SACP;QAED,IAAI,EAAE,IAAI,GAAG,EAAE;YACb,IAAI,CAAC,WAAW,IAAI,EAAE;YACtB,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;SAClB;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAE,OAAe;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI;QACnB,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC;YAC7E,IAAI,MAAM,CAAC,MAAM,EAAE;gBACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;aAC7C;YACD,IAAI,MAAM,CAAC,MAAM,EAAE;gBACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;aAC7C;YACD,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBAC5C,IAAI,CAAC,QAAQ,CAAC,4BAA4B,MAAM,CAAC,SAAS,MAAM,CAAC;aAClE;YACD,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YAClE,IAAI,WAAW,EAAE;gBACf,IAAI,CAAC,GAAG,GAAG,WAAW;aACvB;SACF;QAAC,OAAO,KAAU,EAAE;YACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,KAAI,KAAK,CAAC,CAAC,CAAC;SAC/D;gBAAS;YACR,IAAI,CAAC,OAAO,GAAG,KAAK;SACrB;IACH,CAAC;IAEO,oBAAoB,CAAE,MAAc;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACtE,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;gBAC5B,OAAO,KAAK,CAAC,CAAC,CAAC;aAChB;SACF;QACD,OAAO,IAAI;IACb,CAAC;IAEO,UAAU;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;QACtC,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,GAAG,IAAI,MAAM,GAAG,CAAC;IACjD,CAAC;IAEO,QAAQ,CAAE,IAAY;QAC5B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAEO,SAAS,CAAE,IAAY;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7E,CAAC;CACF;AAtID,gDAsIC;;;;;;;;;;;;;;;;;;;;;;;;AC1ID,yEAA0D;AAC1D,qFAAsE;AACtE,yEAAiD;AACjD,uFAAgD;AAChD,0FAAmD;AAGnD,cAAc;AAMP,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,yCAA6B;IAK7E,YACE,QAAkB,EACV,GAAqB,EACnB,kBAAwC;QAElD,KAAK,CAAC,QAAQ,CAAC;QAHP,QAAG,GAAH,GAAG,CAAkB;QACnB,uBAAkB,GAAlB,kBAAkB,CAAsB;QAN3C,WAAM,GAAG,KAAK;QACd,QAAG,GAAG,GAAG;QAQhB,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,UAAU;QACtB,IAAI,CAAC,aAAa,GAAG,IAAI;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI;YAC7B,EAAE,EAAE,oBAAoB;YACxB,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,oBAAoB;YAC1B,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;YAC1B,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,SAAS;YAChB,mBAAmB,EAAE,KAAK;YAC1B,oBAAoB,EAAE,MAAM;YAC5B,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,KAAK;SAClB;IACH,CAAC;IAES,KAAK,CAAC,eAAe;QAC7B,MAAM,OAAO,GAAG,IAAI,iCAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,OAAsB,EAAE,IAAI,CAAC;QAC7C,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3D,OAAO,CAAC,wBAAwB,EAAE;QAClC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,0BAA0B,CAAC;QAC1D,KAAK,CAAC,eAAe,EAAE;IACzB,CAAC;CACF;AArCC;IAAC,gBAAK,GAAE;;6DAA4B;AACpC;IAAC,gBAAK,GAAE;;4DAAe;AACvB;IAAC,gBAAK,GAAE;;yDAAU;AAHP,4BAA4B;IALxC,oBAAS,EAAC;QACT,QAAQ,EAAE,yCAAwB,CAAC,QAAQ;QAC3C,MAAM,EAAE,yCAAwB,CAAC,MAAM;QACvC,UAAU,EAAE,yCAAwB,CAAC,UAAU;KAChD,CAAC;qCAOY,eAAQ;QACL,8BAAgB;QACC,iCAAoB;GARzC,4BAA4B,CAsCxC;AAtCY,oEAA4B;;;;;;;;;;;;ACbzC,6D;;;;;;;;;;;ACAA,2D;;;;;;;;;;;ACAA,4D;;;;;;;;;;;ACAA,4DAA4D,8CAA8C,6BAA6B;;AAEvI,gD;;;;;;;;;;;ACFA,wD;;;;;;;;;;;ACAA,4D;;;;;;;;;;;ACAA,4D;;;;;;UCAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;UACA;;;;UE5BA;UACA;UACA;UACA","sources":["webpack-tabby-bianbu-mcp:///webpack/universalModuleDefinition","webpack://tabby-bianbu-mcp/./src/filesTab.component.pug?1f87","webpack://tabby-bianbu-mcp/./src/settingsTab.component.pug?a198","webpack-tabby-bianbu-mcp:///./src/filesTab.component.pug","webpack-tabby-bianbu-mcp:///./src/settingsTab.component.pug","webpack-tabby-bianbu-mcp:///./node_modules/pug-runtime/index.js","webpack-tabby-bianbu-mcp:///./src/commands.ts","webpack-tabby-bianbu-mcp:///./src/configProvider.ts","webpack-tabby-bianbu-mcp:///./src/filesTab.component.ts","webpack-tabby-bianbu-mcp:///./src/index.ts","webpack-tabby-bianbu-mcp:///./src/mcp.service.ts","webpack-tabby-bianbu-mcp:///./src/profileProvider.ts","webpack-tabby-bianbu-mcp:///./src/settingsTab.component.ts","webpack-tabby-bianbu-mcp:///./src/settingsTabProvider.ts","webpack-tabby-bianbu-mcp:///./src/shellSession.ts","webpack-tabby-bianbu-mcp:///./src/shellTab.component.ts","webpack-tabby-bianbu-mcp:///external umd \"@angular/common\"","webpack-tabby-bianbu-mcp:///external umd \"@angular/core\"","webpack-tabby-bianbu-mcp:///external umd \"@angular/forms\"","webpack-tabby-bianbu-mcp:///external umd \"fs\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-core\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-settings\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-terminal\"","webpack-tabby-bianbu-mcp:///webpack/bootstrap","webpack-tabby-bianbu-mcp:///webpack/before-startup","webpack-tabby-bianbu-mcp:///webpack/startup","webpack-tabby-bianbu-mcp:///webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"fs\"); } catch(e) {} }()), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/core\", \"@angular/forms\", \"fs\", \"tabby-core\", \"tabby-settings\", \"tabby-terminal\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"fs\"); } catch(e) {} }()), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\")) : factory(root[\"@angular/common\"], root[\"@angular/core\"], root[\"@angular/forms\"], root[\"fs\"], root[\"tabby-core\"], root[\"tabby-settings\"], root[\"tabby-terminal\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(global, (__WEBPACK_EXTERNAL_MODULE__angular_common__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_settings__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__) => {\nreturn ","var req = require(\"!!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\node_modules\\\\pug-loader\\\\index.js!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\src\\\\filesTab.component.pug\");\nmodule.exports = (req['default'] || req).apply(req, [])","var req = require(\"!!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\node_modules\\\\pug-loader\\\\index.js!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\src\\\\settingsTab.component.pug\");\nmodule.exports = (req['default'] || req).apply(req, [])","var pug = require(\"!../node_modules/pug-runtime/index.js\");\n\nfunction template(locals) {var pug_html = \"\", pug_mixins = {}, pug_interp;pug_html = pug_html + \"\\u003Cdiv style=\\\"padding: 16px; display:flex; flex-direction:column; gap:16px; height:100%\\\"\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EBianbu Cloud Files\\u003C\\u002Fh3\\u003E\\u003Cp style=\\\"opacity:.8; margin-bottom:0\\\"\\u003EFile-manager-like remote access over MCP. This behaves like an SFTP panel, but it is backed by MCP file tools instead of the native SFTP protocol.\\u003C\\u002Fp\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Cdiv class=\\\"row\\\" style=\\\"display:grid; grid-template-columns: 1fr auto auto; gap:12px; align-items:end\\\"\\u003E\\u003Cdiv class=\\\"field\\\"\\u003E\\u003Clabel style=\\\"display:block; margin-bottom:6px\\\"\\u003ECurrent path\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"currentPath\\\" [disabled]=\\\"busy\\\"\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"field\\\"\\u003E\\u003Clabel style=\\\"display:block; margin-bottom:6px\\\"\\u003ERoot\\u003C\\u002Flabel\\u003E\\u003Cinput type=\\\"checkbox\\\" [(ngModel)]=\\\"asRoot\\\" [disabled]=\\\"busy\\\"\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"field\\\" style=\\\"display:flex; gap:8px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"refresh()\\\" [disabled]=\\\"busy\\\"\\u003ERefresh\\u003C\\u002Fbutton\\u003E\\u003Clabel class=\\\"btn btn-secondary\\\" style=\\\"margin:0\\\"\\u003EUpload\\u003Cinput type=\\\"file\\\" style=\\\"display:none\\\" (change)=\\\"uploadFile($event)\\\" [disabled]=\\\"busy\\\"\\u003E\\u003C\\u002Flabel\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"margin-top:12px; opacity:.75\\\"\\u003E{{ status }}\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"row\\\" style=\\\"display:grid; grid-template-columns: 420px 1fr; gap:16px; flex:1; min-height:0\\\"\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08); overflow:auto\\\"\\u003E\\u003Cdiv style=\\\"display:grid; grid-template-columns: 1fr 1fr auto; gap:8px; margin-bottom:12px\\\"\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"newDirectoryName\\\" placeholder=\\\"new-directory\\\" [disabled]=\\\"busy\\\"\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"newFileName\\\" placeholder=\\\"new-file.txt\\\" [disabled]=\\\"busy\\\"\\u003E\\u003Cdiv style=\\\"display:flex; gap:8px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"createDirectory()\\\" [disabled]=\\\"busy || !newDirectoryName.trim()\\\"\\u003EMkdir\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"createFile()\\\" [disabled]=\\\"busy || !newFileName.trim()\\\"\\u003ENew file\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Ctable style=\\\"width:100%; border-collapse:collapse\\\"\\u003E\\u003Cthead\\u003E\\u003Ctr style=\\\"text-align:left; opacity:.7\\\"\\u003E\\u003Cth style=\\\"padding:8px\\\"\\u003EName\\u003C\\u002Fth\\u003E\\u003Cth style=\\\"padding:8px\\\"\\u003EType\\u003C\\u002Fth\\u003E\\u003Cth style=\\\"padding:8px\\\"\\u003ESize\\u003C\\u002Fth\\u003E\\u003Cth style=\\\"padding:8px\\\"\\u003E\\u003C\\u002Fth\\u003E\\u003C\\u002Ftr\\u003E\\u003C\\u002Fthead\\u003E\\u003Ctbody\\u003E\\u003Ctr *ngFor=\\\"let item of items\\\" style=\\\"border-top:1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ctd style=\\\"padding:8px; cursor:pointer\\\" (click)=\\\"openItem(item)\\\"\\u003E{{ item.path.split('\\u002F').pop() || item.path }}\\u003C\\u002Ftd\\u003E\\u003Ctd style=\\\"padding:8px\\\"\\u003E{{ item.is_dir ? 'dir' : 'file' }}\\u003C\\u002Ftd\\u003E\\u003Ctd style=\\\"padding:8px\\\"\\u003E{{ item.size }}\\u003C\\u002Ftd\\u003E\\u003Ctd style=\\\"padding:8px; text-align:right\\\"\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-outline-danger\\\" type=\\\"button\\\" (click)=\\\"deleteItem(item)\\\" [disabled]=\\\"busy\\\"\\u003EDelete\\u003C\\u002Fbutton\\u003E\\u003C\\u002Ftd\\u003E\\u003C\\u002Ftr\\u003E\\u003C\\u002Ftbody\\u003E\\u003C\\u002Ftable\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.08); display:flex; flex-direction:column; min-height:0\\\"\\u003E\\u003Cdiv style=\\\"display:flex; justify-content:space-between; gap:12px; align-items:center; margin-bottom:12px\\\"\\u003E\\u003Cdiv\\u003E\\u003Ch4 style=\\\"margin:0\\\"\\u003EFile preview\\u003C\\u002Fh4\\u003E\\u003Cdiv style=\\\"opacity:.7; font-size:.9em\\\"\\u003E{{ selectedPath || 'No file selected' }}\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"display:flex; gap:8px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"downloadSelected()\\\" [disabled]=\\\"busy || !selectedPath\\\"\\u003EDownload\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"saveSelected()\\\" [disabled]=\\\"busy || !selectedPath\\\"\\u003ESave\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Ctextarea class=\\\"form-control\\\" style=\\\"flex:1; min-height:320px\\\" [(ngModel)]=\\\"selectedContent\\\" [disabled]=\\\"busy || !selectedPath\\\" placeholder=\\\"Select a text file to view or edit\\\"\\u003E\\u003C\\u002Ftextarea\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\";;return pug_html;};\nmodule.exports = template;","var pug = require(\"!../node_modules/pug-runtime/index.js\");\n\nfunction template(locals) {var pug_html = \"\", pug_mixins = {}, pug_interp;pug_html = pug_html + \"\\u003Cdiv style=\\\"padding: 20px; display:flex; flex-direction:column; gap:16px\\\"\\u003E\\u003Cdiv class=\\\"hero\\\" style=\\\"padding:18px; border-radius:12px; background:linear-gradient(135deg, rgba(25,53,103,.9), rgba(17,94,89,.85)); color:white\\\"\\u003E\\u003Ch2 style=\\\"margin:0 0 8px 0\\\"\\u003EBianbu MCP\\u003C\\u002Fh2\\u003E\\u003Cp style=\\\"margin:0; opacity:.92\\\"\\u003EConfigure your Bianbu Cloud MCP endpoint and open a shell-like tab or a file-manager-like tab directly from Tabby.\\u003C\\u002Fp\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EQuick actions\\u003C\\u002Fh3\\u003E\\u003Cdiv style=\\\"display:flex; gap:12px; flex-wrap:wrap\\\"\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"openShell()\\\"\\u003EOpen Bianbu Cloud Shell\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"openFiles()\\\"\\u003EOpen Bianbu Cloud Files\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EConnection settings\\u003C\\u002Fh3\\u003E\\u003Cdiv class=\\\"grid\\\" style=\\\"display:grid; grid-template-columns: 160px 1fr; gap:12px; align-items:center\\\"\\u003E\\u003Clabel\\u003EEnable integration\\u003C\\u002Flabel\\u003E\\u003Cinput type=\\\"checkbox\\\" [(ngModel)]=\\\"config.store.bianbuMcp.enabled\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003EProfile name\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"config.store.bianbuMcp.name\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"bianbu\\\"\\u003E\\u003Clabel\\u003EMCP URL\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"config.store.bianbuMcp.url\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"https:\\u002F\\u002Fyour-domain.example.com\\u002Fmcp\\\"\\u003E\\u003Clabel\\u003EX-API-KEY\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"password\\\" [(ngModel)]=\\\"config.store.bianbuMcp.apiKey\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"your-x-api-key\\\"\\u003E\\u003Clabel\\u003EInterval (ms)\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.minIntervalMs\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003EMax retries\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.maxRetries\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003ERetry base (ms)\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.retryBaseMs\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003ENotes\\u003C\\u002Flabel\\u003E\\u003Ctextarea class=\\\"form-control\\\" rows=\\\"3\\\" [(ngModel)]=\\\"config.store.bianbuMcp.notes\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"Optional notes\\\"\\u003E\\u003C\\u002Ftextarea\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003ECopyable MCP snippet\\u003C\\u002Fh3\\u003E\\u003Cpre style=\\\"white-space: pre-wrap; margin-bottom:0\\\"\\u003E{{ sampleJson }}\\u003C\\u002Fpre\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EReminder\\u003C\\u002Fh3\\u003E\\u003Cul style=\\\"margin-bottom:0\\\"\\u003E\\u003Cli\\u003EMCP URL is typically \\u003Ccode\\u003Ehttps:\\u002F\\u002F&lt;domain&gt;\\u002Fmcp\\u003C\\u002Fcode\\u003E\\u003C\\u002Fli\\u003E\\u003Cli\\u003E\\u003Ccode\\u003EX-API-KEY\\u003C\\u002Fcode\\u003E is copied from the Bianbu Cloud API Key page\\u003C\\u002Fli\\u003E\\u003Cli\\u003EShell and Files tabs are UI views backed by MCP calls, not native SSH\\u002FSFTP transport\\u003C\\u002Fli\\u003E\\u003C\\u002Ful\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\";;return pug_html;};\nmodule.exports = template;","'use strict';\n\nvar pug_has_own_property = Object.prototype.hasOwnProperty;\n\n/**\n * Merge two attribute objects giving precedence\n * to values in object `b`. Classes are special-cased\n * allowing for arrays and merging/joining appropriately\n * resulting in a string.\n *\n * @param {Object} a\n * @param {Object} b\n * @return {Object} a\n * @api private\n */\n\nexports.merge = pug_merge;\nfunction pug_merge(a, b) {\n if (arguments.length === 1) {\n var attrs = a[0];\n for (var i = 1; i < a.length; i++) {\n attrs = pug_merge(attrs, a[i]);\n }\n return attrs;\n }\n\n for (var key in b) {\n if (key === 'class') {\n var valA = a[key] || [];\n a[key] = (Array.isArray(valA) ? valA : [valA]).concat(b[key] || []);\n } else if (key === 'style') {\n var valA = pug_style(a[key]);\n valA = valA && valA[valA.length - 1] !== ';' ? valA + ';' : valA;\n var valB = pug_style(b[key]);\n valB = valB && valB[valB.length - 1] !== ';' ? valB + ';' : valB;\n a[key] = valA + valB;\n } else {\n a[key] = b[key];\n }\n }\n\n return a;\n};\n\n/**\n * Process array, object, or string as a string of classes delimited by a space.\n *\n * If `val` is an array, all members of it and its subarrays are counted as\n * classes. If `escaping` is an array, then whether or not the item in `val` is\n * escaped depends on the corresponding item in `escaping`. If `escaping` is\n * not an array, no escaping is done.\n *\n * If `val` is an object, all the keys whose value is truthy are counted as\n * classes. No escaping is done.\n *\n * If `val` is a string, it is counted as a class. No escaping is done.\n *\n * @param {(Array.<string>|Object.<string, boolean>|string)} val\n * @param {?Array.<string>} escaping\n * @return {String}\n */\nexports.classes = pug_classes;\nfunction pug_classes_array(val, escaping) {\n var classString = '', className, padding = '', escapeEnabled = Array.isArray(escaping);\n for (var i = 0; i < val.length; i++) {\n className = pug_classes(val[i]);\n if (!className) continue;\n escapeEnabled && escaping[i] && (className = pug_escape(className));\n classString = classString + padding + className;\n padding = ' ';\n }\n return classString;\n}\nfunction pug_classes_object(val) {\n var classString = '', padding = '';\n for (var key in val) {\n if (key && val[key] && pug_has_own_property.call(val, key)) {\n classString = classString + padding + key;\n padding = ' ';\n }\n }\n return classString;\n}\nfunction pug_classes(val, escaping) {\n if (Array.isArray(val)) {\n return pug_classes_array(val, escaping);\n } else if (val && typeof val === 'object') {\n return pug_classes_object(val);\n } else {\n return val || '';\n }\n}\n\n/**\n * Convert object or string to a string of CSS styles delimited by a semicolon.\n *\n * @param {(Object.<string, string>|string)} val\n * @return {String}\n */\n\nexports.style = pug_style;\nfunction pug_style(val) {\n if (!val) return '';\n if (typeof val === 'object') {\n var out = '';\n for (var style in val) {\n /* istanbul ignore else */\n if (pug_has_own_property.call(val, style)) {\n out = out + style + ':' + val[style] + ';';\n }\n }\n return out;\n } else {\n return val + '';\n }\n};\n\n/**\n * Render the given attribute.\n *\n * @param {String} key\n * @param {String} val\n * @param {Boolean} escaped\n * @param {Boolean} terse\n * @return {String}\n */\nexports.attr = pug_attr;\nfunction pug_attr(key, val, escaped, terse) {\n if (val === false || val == null || !val && (key === 'class' || key === 'style')) {\n return '';\n }\n if (val === true) {\n return ' ' + (terse ? key : key + '=\"' + key + '\"');\n }\n var type = typeof val;\n if ((type === 'object' || type === 'function') && typeof val.toJSON === 'function') {\n val = val.toJSON();\n }\n if (typeof val !== 'string') {\n val = JSON.stringify(val);\n if (!escaped && val.indexOf('\"') !== -1) {\n return ' ' + key + '=\\'' + val.replace(/'/g, '&#39;') + '\\'';\n }\n }\n if (escaped) val = pug_escape(val);\n return ' ' + key + '=\"' + val + '\"';\n};\n\n/**\n * Render the given attributes object.\n *\n * @param {Object} obj\n * @param {Object} terse whether to use HTML5 terse boolean attributes\n * @return {String}\n */\nexports.attrs = pug_attrs;\nfunction pug_attrs(obj, terse){\n var attrs = '';\n\n for (var key in obj) {\n if (pug_has_own_property.call(obj, key)) {\n var val = obj[key];\n\n if ('class' === key) {\n val = pug_classes(val);\n attrs = pug_attr(key, val, false, terse) + attrs;\n continue;\n }\n if ('style' === key) {\n val = pug_style(val);\n }\n attrs += pug_attr(key, val, false, terse);\n }\n }\n\n return attrs;\n};\n\n/**\n * Escape the given string of `html`.\n *\n * @param {String} html\n * @return {String}\n * @api private\n */\n\nvar pug_match_html = /[\"&<>]/;\nexports.escape = pug_escape;\nfunction pug_escape(_html){\n var html = '' + _html;\n var regexResult = pug_match_html.exec(html);\n if (!regexResult) return _html;\n\n var result = '';\n var i, lastIndex, escape;\n for (i = regexResult.index, lastIndex = 0; i < html.length; i++) {\n switch (html.charCodeAt(i)) {\n case 34: escape = '&quot;'; break;\n case 38: escape = '&amp;'; break;\n case 60: escape = '&lt;'; break;\n case 62: escape = '&gt;'; break;\n default: continue;\n }\n if (lastIndex !== i) result += html.substring(lastIndex, i);\n lastIndex = i + 1;\n result += escape;\n }\n if (lastIndex !== i) return result + html.substring(lastIndex, i);\n else return result;\n};\n\n/**\n * Re-throw the given `err` in context to the\n * the pug in `filename` at the given `lineno`.\n *\n * @param {Error} err\n * @param {String} filename\n * @param {String} lineno\n * @param {String} str original source\n * @api private\n */\n\nexports.rethrow = pug_rethrow;\nfunction pug_rethrow(err, filename, lineno, str){\n if (!(err instanceof Error)) throw err;\n if ((typeof window != 'undefined' || !filename) && !str) {\n err.message += ' on line ' + lineno;\n throw err;\n }\n try {\n str = str || require('fs').readFileSync(filename, 'utf8')\n } catch (ex) {\n pug_rethrow(err, null, lineno)\n }\n var context = 3\n , lines = str.split('\\n')\n , start = Math.max(lineno - context, 0)\n , end = Math.min(lines.length, lineno + context);\n\n // Error context\n var context = lines.slice(start, end).map(function(line, i){\n var curr = i + start + 1;\n return (curr == lineno ? ' > ' : ' ')\n + curr\n + '| '\n + line;\n }).join('\\n');\n\n // Alter exception message\n err.path = filename;\n err.message = (filename || 'Pug') + ':' + lineno\n + '\\n' + context + '\\n\\n' + err.message;\n throw err;\n};\n","import { Injectable } from '@angular/core'\r\nimport { AppService, Command, CommandLocation, CommandProvider } from 'tabby-core'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\n\r\n/** @hidden */\r\n@Injectable()\r\nexport class BianbuCloudCommandProvider extends CommandProvider {\r\n constructor (\r\n private app: AppService,\r\n ) {\r\n super()\r\n }\r\n\r\n async provide (): Promise<Command[]> {\r\n return [\r\n {\r\n id: 'bianbu-cloud-shell',\r\n label: 'Open Bianbu Cloud Shell',\r\n sublabel: 'Remote shell over MCP run_command',\r\n locations: [CommandLocation.StartPage],\r\n run: async () => {\r\n this.app.openNewTab({ type: BianbuCloudShellTabComponent })\r\n },\r\n },\r\n {\r\n id: 'bianbu-cloud-files',\r\n label: 'Open Bianbu Cloud Files',\r\n sublabel: 'File manager over MCP file tools',\r\n locations: [CommandLocation.StartPage],\r\n run: async () => {\r\n this.app.openNewTab({ type: BianbuCloudFilesTabComponent })\r\n },\r\n },\r\n ]\r\n }\r\n}\r\n","import { ConfigProvider } from 'tabby-core'\r\n\r\n/** @hidden */\r\nexport class BianbuMcpConfigProvider extends ConfigProvider {\r\n defaults = {\r\n bianbuMcp: {\r\n enabled: true,\r\n name: 'bianbu',\r\n url: '',\r\n apiKey: '',\r\n minIntervalMs: 1000,\r\n maxRetries: 2,\r\n retryBaseMs: 1000,\r\n notes: '',\r\n },\r\n }\r\n}\r\n","import { Component, Injector } from '@angular/core'\r\nimport { BaseTabComponent, NotificationsService } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\n\r\n/** @hidden */\r\n@Component({\r\n template: require('./filesTab.component.pug'),\r\n})\r\nexport class BianbuCloudFilesTabComponent extends BaseTabComponent {\r\n currentPath = '.'\r\n asRoot = false\r\n busy = false\r\n items: any[] = []\r\n selectedPath = ''\r\n selectedContent = ''\r\n newDirectoryName = ''\r\n newFileName = ''\r\n status = 'Ready'\r\n\r\n constructor (\r\n injector: Injector,\r\n private mcp: BianbuMcpService,\r\n private notifications: NotificationsService,\r\n ) {\r\n super(injector)\r\n this.setTitle('Bianbu Cloud Files')\r\n this.icon = 'folder-open'\r\n }\r\n\r\n ngOnInit (): void {\r\n this.refresh().catch(() => null)\r\n }\r\n\r\n async refresh (): Promise<void> {\r\n this.busy = true\r\n this.status = 'Loading directory…'\r\n this.setProgress(0.3)\r\n try {\r\n const result = await this.mcp.listDirectory(this.currentPath || '.', this.asRoot)\r\n this.items = result.items || []\r\n this.status = `Loaded ${this.items.length} item(s)`\r\n } catch (error: any) {\r\n this.notifications.error('Failed to list directory', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n this.setProgress(null)\r\n }\r\n }\r\n\r\n async openItem (item: any): Promise<void> {\r\n if (item.is_dir) {\r\n this.currentPath = item.path\r\n this.selectedPath = ''\r\n this.selectedContent = ''\r\n await this.refresh()\r\n return\r\n }\r\n\r\n this.busy = true\r\n this.status = `Reading ${item.path}`\r\n try {\r\n const result = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot)\r\n this.selectedPath = item.path\r\n this.selectedContent = result.content || ''\r\n this.status = `Opened ${item.path}`\r\n } catch (error: any) {\r\n this.notifications.error('Failed to open file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async saveSelected (): Promise<void> {\r\n if (!this.selectedPath) {\r\n return\r\n }\r\n this.busy = true\r\n this.status = `Saving ${this.selectedPath}`\r\n try {\r\n await this.mcp.writeTextFile(this.selectedPath, this.selectedContent, this.asRoot)\r\n this.notifications.notice('File saved')\r\n this.status = `Saved ${this.selectedPath}`\r\n await this.refresh()\r\n } catch (error: any) {\r\n this.notifications.error('Failed to save file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async createDirectory (): Promise<void> {\r\n if (!this.newDirectoryName.trim()) {\r\n return\r\n }\r\n const path = this.joinPath(this.currentPath, this.newDirectoryName.trim())\r\n this.busy = true\r\n try {\r\n await this.mcp.makeDirectory(path, this.asRoot)\r\n this.newDirectoryName = ''\r\n await this.refresh()\r\n this.notifications.notice('Directory created')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to create directory', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async createFile (): Promise<void> {\r\n if (!this.newFileName.trim()) {\r\n return\r\n }\r\n const path = this.joinPath(this.currentPath, this.newFileName.trim())\r\n this.busy = true\r\n try {\r\n await this.mcp.writeTextFile(path, '', this.asRoot)\r\n this.newFileName = ''\r\n await this.refresh()\r\n this.notifications.notice('File created')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to create file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async deleteItem (item: any): Promise<void> {\r\n this.busy = true\r\n try {\r\n await this.mcp.deletePath(item.path, !!item.is_dir, this.asRoot)\r\n if (this.selectedPath === item.path) {\r\n this.selectedPath = ''\r\n this.selectedContent = ''\r\n }\r\n await this.refresh()\r\n this.notifications.notice('Path deleted')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to delete path', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async uploadFile (event: Event): Promise<void> {\r\n const input = event.target as HTMLInputElement\r\n const file = input.files?.[0]\r\n if (!file) {\r\n return\r\n }\r\n this.busy = true\r\n try {\r\n const base64 = await this.readFileAsBase64(file)\r\n const path = this.joinPath(this.currentPath, file.name)\r\n await this.mcp.uploadBinaryFile(path, base64, this.asRoot)\r\n this.notifications.notice('File uploaded')\r\n await this.refresh()\r\n } catch (error: any) {\r\n this.notifications.error('Upload failed', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n input.value = ''\r\n }\r\n }\r\n\r\n async downloadSelected (): Promise<void> {\r\n if (!this.selectedPath) {\r\n return\r\n }\r\n try {\r\n const result = await this.mcp.downloadBinaryFile(this.selectedPath, this.asRoot)\r\n const a = document.createElement('a')\r\n a.href = `data:application/octet-stream;base64,${result.content_base64}`\r\n a.download = this.selectedPath.split('/').pop() || 'download.bin'\r\n a.click()\r\n this.notifications.notice('Download started')\r\n } catch (error: any) {\r\n this.notifications.error('Download failed', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n }\r\n }\r\n\r\n private joinPath (base: string, child: string): string {\r\n if (!base || base === '.') {\r\n return child\r\n }\r\n if (base.endsWith('/')) {\r\n return `${base}${child}`\r\n }\r\n return `${base}/${child}`\r\n }\r\n\r\n private readFileAsBase64 (file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader()\r\n reader.onload = () => {\r\n const text = String(reader.result || '')\r\n resolve(text.split(',')[1] || '')\r\n }\r\n reader.onerror = () => reject(reader.error)\r\n reader.readAsDataURL(file)\r\n })\r\n }\r\n}\r\n","import { NgModule } from '@angular/core'\r\nimport { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport TabbyCoreModule, { CommandProvider, ConfigProvider, ProfileProvider } from 'tabby-core'\r\nimport { SettingsTabProvider } from 'tabby-settings'\r\n\r\nimport { BianbuMcpConfigProvider } from './configProvider'\r\nimport { BianbuMcpSettingsTabProvider } from './settingsTabProvider'\r\nimport { BianbuMcpSettingsComponent } from './settingsTab.component'\r\nimport { BianbuCloudCommandProvider } from './commands'\r\nimport { BianbuMcpService } from './mcp.service'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\nimport { BianbuCloudProfileProvider } from './profileProvider'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n TabbyCoreModule,\r\n ],\r\n providers: [\r\n BianbuMcpService,\r\n { provide: ConfigProvider, useClass: BianbuMcpConfigProvider, multi: true },\r\n { provide: SettingsTabProvider, useClass: BianbuMcpSettingsTabProvider, multi: true },\r\n { provide: CommandProvider, useClass: BianbuCloudCommandProvider, multi: true },\r\n { provide: ProfileProvider, useClass: BianbuCloudProfileProvider, multi: true },\r\n ],\r\n declarations: [\r\n BianbuMcpSettingsComponent,\r\n BianbuCloudShellTabComponent,\r\n BianbuCloudFilesTabComponent,\r\n ],\r\n entryComponents: [\r\n BianbuMcpSettingsComponent,\r\n BianbuCloudShellTabComponent,\r\n BianbuCloudFilesTabComponent,\r\n ],\r\n})\r\nexport default class BianbuMcpModule { }\r\n","import { Injectable } from '@angular/core'\r\nimport { ConfigService } from 'tabby-core'\r\n\r\ninterface JsonRpcResponse {\r\n result?: any\r\n error?: { code?: number, message?: string }\r\n}\r\n\r\n@Injectable()\r\nexport class BianbuMcpService {\r\n private nextAllowedAt = 0\r\n\r\n constructor (\r\n private config: ConfigService,\r\n ) { }\r\n\r\n get settings (): any {\r\n return this.config.store.bianbuMcp\r\n }\r\n\r\n private sleep (ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n }\r\n\r\n private shouldRetryStatus (status: number): boolean {\r\n return [429, 502, 503, 504].includes(status)\r\n }\r\n\r\n private async pacedFetch (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\r\n const waitMs = Math.max(0, this.nextAllowedAt - Date.now())\r\n if (waitMs > 0) {\r\n await this.sleep(waitMs)\r\n }\r\n this.nextAllowedAt = Date.now() + (this.settings.minIntervalMs ?? 1000)\r\n return fetch(input, init)\r\n }\r\n\r\n private async request (payload: any): Promise<any> {\r\n const settings = this.settings\r\n const maxRetries = Number(settings.maxRetries ?? 2)\r\n const retryBaseMs = Number(settings.retryBaseMs ?? 1000)\r\n let lastBody = ''\r\n let lastStatus = 0\r\n let lastError: any = null\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n const response = await this.pacedFetch(settings.url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n Accept: 'application/json, text/event-stream',\r\n 'MCP-Protocol-Version': '2025-11-25',\r\n 'X-API-KEY': settings.apiKey,\r\n },\r\n body: JSON.stringify(payload),\r\n })\r\n const text = await response.text()\r\n lastBody = text\r\n lastStatus = response.status\r\n\r\n if (!this.shouldRetryStatus(response.status)) {\r\n const parsed = this.parseBody(text)\r\n if (parsed.error) {\r\n throw new Error(parsed.error.message || 'MCP error')\r\n }\r\n if (parsed.result?.isError && parsed.result?.content?.[0]?.text) {\r\n throw new Error(parsed.result.content[0].text)\r\n }\r\n if (parsed.result?.structuredContent !== undefined) {\r\n return parsed.result.structuredContent\r\n }\r\n return parsed.result\r\n }\r\n } catch (error) {\r\n lastError = error\r\n if (attempt === maxRetries) {\r\n break\r\n }\r\n }\r\n\r\n if (attempt < maxRetries) {\r\n await this.sleep(retryBaseMs * (attempt + 1))\r\n }\r\n }\r\n\r\n throw lastError || new Error(`MCP request failed with status ${lastStatus}: ${lastBody}`)\r\n }\r\n\r\n private parseBody (text: string): JsonRpcResponse {\r\n try {\r\n return JSON.parse(text)\r\n } catch {\r\n const sseMatch = text.match(/data:\\s*(\\{[\\s\\S]*\\})/)\r\n if (sseMatch) {\r\n try {\r\n return JSON.parse(sseMatch[1])\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n }\r\n return { error: { message: text || 'Invalid MCP response' } }\r\n }\r\n\r\n async callTool (name: string, args: any): Promise<any> {\r\n return this.request({\r\n jsonrpc: '2.0',\r\n id: `${name}-${Date.now()}`,\r\n method: 'tools/call',\r\n params: {\r\n name,\r\n arguments: args,\r\n },\r\n })\r\n }\r\n\r\n async health (): Promise<any> {\r\n return this.callTool('health', {})\r\n }\r\n\r\n async runCommand (command: string, cwd: string, timeoutSeconds: number, asRoot: boolean): Promise<any> {\r\n return this.callTool('run_command', {\r\n command,\r\n cwd,\r\n timeout_seconds: timeoutSeconds,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async listDirectory (path: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('list_directory', { path, as_root: asRoot })\r\n }\r\n\r\n async readTextFile (path: string, maxBytes: number, asRoot: boolean): Promise<any> {\r\n return this.callTool('read_text_file', {\r\n path,\r\n max_bytes: maxBytes,\r\n encoding: 'utf-8',\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async writeTextFile (path: string, content: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('write_text_file', {\r\n path,\r\n content,\r\n overwrite: true,\r\n encoding: 'utf-8',\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async makeDirectory (path: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('make_directory', {\r\n path,\r\n parents: true,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async deletePath (path: string, recursive: boolean, asRoot: boolean): Promise<any> {\r\n return this.callTool('delete_path', {\r\n path,\r\n recursive,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async uploadBinaryFile (path: string, base64: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('upload_binary_file', {\r\n path,\r\n content_base64: base64,\r\n overwrite: true,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async downloadBinaryFile (path: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('download_binary_file', {\r\n path,\r\n max_bytes: 64 * 1024 * 1024,\r\n as_root: asRoot,\r\n })\r\n }\r\n}\r\n","import { ProfileProvider, Profile, NewTabParameters, BaseTabComponent } from 'tabby-core'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\n\r\nexport interface BianbuCloudProfile extends Profile {\r\n options: {\r\n kind: 'shell' | 'files'\r\n }\r\n}\r\n\r\n/** @hidden */\r\nexport class BianbuCloudProfileProvider extends ProfileProvider<BianbuCloudProfile> {\r\n id = 'bianbu-cloud'\r\n name = 'Bianbu Cloud'\r\n configDefaults = {}\r\n\r\n async getBuiltinProfiles (): Promise<any[]> {\r\n return [\r\n {\r\n id: 'bianbu-cloud-shell',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Shell',\r\n icon: 'terminal',\r\n color: '#2b6cb0',\r\n group: 'Bianbu Cloud',\r\n disableDynamicTitle: false,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 0,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n options: {\r\n kind: 'shell',\r\n },\r\n },\r\n {\r\n id: 'bianbu-cloud-files',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Files',\r\n icon: 'folder-open',\r\n color: '#0f766e',\r\n group: 'Bianbu Cloud',\r\n disableDynamicTitle: true,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 1,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n options: {\r\n kind: 'files',\r\n },\r\n },\r\n ]\r\n }\r\n\r\n async getNewTabParameters (profile: BianbuCloudProfile): Promise<NewTabParameters<BaseTabComponent>> {\r\n if (profile.options.kind === 'files') {\r\n return {\r\n type: BianbuCloudFilesTabComponent,\r\n inputs: { profile },\r\n }\r\n }\r\n return {\r\n type: BianbuCloudShellTabComponent,\r\n inputs: { profile },\r\n }\r\n }\r\n\r\n getSuggestedName (): string | null {\r\n return null\r\n }\r\n\r\n getDescription (profile: any): string {\r\n if (profile.options?.kind === 'files') {\r\n return 'Explorer-like file access backed by MCP file tools'\r\n }\r\n return 'Terminal-like shell session backed by MCP run_command'\r\n }\r\n}\r\n","import { Component } from '@angular/core'\r\nimport { AppService, ConfigService } from 'tabby-core'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\n\r\n/** @hidden */\r\n@Component({\r\n template: require('./settingsTab.component.pug'),\r\n})\r\nexport class BianbuMcpSettingsComponent {\r\n constructor (\r\n public config: ConfigService,\r\n private app: AppService,\r\n ) { }\r\n\r\n get sampleJson (): string {\r\n const s = this.config.store.bianbuMcp\r\n return JSON.stringify({\r\n mcpServers: {\r\n [s.name || 'bianbu']: {\r\n type: 'http',\r\n url: s.url || 'https://your-domain.example.com/mcp',\r\n headers: {\r\n 'X-API-KEY': s.apiKey || 'your-x-api-key',\r\n },\r\n },\r\n },\r\n }, null, 2)\r\n }\r\n\r\n save (): void {\r\n this.config.save()\r\n }\r\n\r\n openShell (): void {\r\n this.app.openNewTab({ type: BianbuCloudShellTabComponent })\r\n }\r\n\r\n openFiles (): void {\r\n this.app.openNewTab({ type: BianbuCloudFilesTabComponent })\r\n }\r\n}\r\n","import { Injectable } from '@angular/core'\r\nimport { SettingsTabProvider } from 'tabby-settings'\r\nimport { BianbuMcpSettingsComponent } from './settingsTab.component'\r\n\r\n/** @hidden */\r\n@Injectable()\r\nexport class BianbuMcpSettingsTabProvider extends SettingsTabProvider {\r\n id = 'bianbu-mcp'\r\n icon = 'plug'\r\n title = 'Bianbu MCP'\r\n\r\n getComponentType (): any {\r\n return BianbuMcpSettingsComponent\r\n }\r\n}\r\n","import { BaseSession } from 'tabby-terminal'\r\nimport { Logger } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\n\r\nexport class BianbuShellSession extends BaseSession {\r\n private cwd = '.'\r\n private currentLine = ''\r\n private running = false\r\n private asRoot = false\r\n\r\n constructor (\r\n logger: Logger,\r\n private mcp: BianbuMcpService,\r\n ) {\r\n super(logger)\r\n }\r\n\r\n async start (options: any): Promise<void> {\r\n this.open = true\r\n this.cwd = options?.cwd || '.'\r\n this.asRoot = !!options?.asRoot\r\n this.emitText('Connected to Bianbu Cloud MCP shell\\r\\n')\r\n this.emitPrompt()\r\n }\r\n\r\n resize (_columns: number, _rows: number): void {\r\n // no-op for stateless MCP shell emulation\r\n }\r\n\r\n write (data: Buffer): void {\r\n const text = data.toString('utf-8')\r\n for (const ch of text) {\r\n void this.handleChar(ch)\r\n }\r\n }\r\n\r\n kill (): void {\r\n this.running = false\r\n }\r\n\r\n async gracefullyKillProcess (): Promise<void> {\r\n this.running = false\r\n }\r\n\r\n supportsWorkingDirectory (): boolean {\r\n return true\r\n }\r\n\r\n async getWorkingDirectory (): Promise<string | null> {\r\n return this.cwd\r\n }\r\n\r\n private async handleChar (ch: string): Promise<void> {\r\n if (this.running) {\r\n if (ch === '\\u0003') {\r\n this.emitText('^C\\r\\n')\r\n }\r\n return\r\n }\r\n\r\n if (ch === '\\r' || ch === '\\n') {\r\n const command = this.currentLine\r\n this.currentLine = ''\r\n this.emitText('\\r\\n')\r\n if (command.trim()) {\r\n await this.execute(command)\r\n }\r\n this.emitPrompt()\r\n return\r\n }\r\n\r\n if (ch === '\\u007f' || ch === '\\b') {\r\n if (this.currentLine.length) {\r\n this.currentLine = this.currentLine.slice(0, -1)\r\n this.emitText('\\b \\b')\r\n }\r\n return\r\n }\r\n\r\n if (ch === '\\u0003') {\r\n this.currentLine = ''\r\n this.emitText('^C\\r\\n')\r\n this.emitPrompt()\r\n return\r\n }\r\n\r\n if (ch >= ' ') {\r\n this.currentLine += ch\r\n this.emitText(ch)\r\n }\r\n }\r\n\r\n private async execute (command: string): Promise<void> {\r\n this.running = true\r\n try {\r\n const result = await this.mcp.runCommand(command, this.cwd, 120, this.asRoot)\r\n if (result.stdout) {\r\n this.emitText(this.normalize(result.stdout))\r\n }\r\n if (result.stderr) {\r\n this.emitText(this.normalize(result.stderr))\r\n }\r\n if (result.exit_code !== 0 && !result.stderr) {\r\n this.emitText(`command exited with code ${result.exit_code}\\r\\n`)\r\n }\r\n const detectedCwd = this.extractLastDirectory(result.stdout || '')\r\n if (detectedCwd) {\r\n this.cwd = detectedCwd\r\n }\r\n } catch (error: any) {\r\n this.emitText(this.normalize(String(error?.message || error)))\r\n } finally {\r\n this.running = false\r\n }\r\n }\r\n\r\n private extractLastDirectory (stdout: string): string | null {\r\n const lines = stdout.split(/\\r?\\n/).map(x => x.trim()).filter(Boolean)\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n if (lines[i].startsWith('/')) {\r\n return lines[i]\r\n }\r\n }\r\n return null\r\n }\r\n\r\n private emitPrompt (): void {\r\n const marker = this.asRoot ? '#' : '$'\r\n this.emitText(`[bianbu ${this.cwd}]${marker} `)\r\n }\r\n\r\n private emitText (text: string): void {\r\n this.emitOutput(Buffer.from(text, 'utf-8'))\r\n }\r\n\r\n private normalize (text: string): string {\r\n return text.replace(/\\r?\\n/g, '\\r\\n') + (text.endsWith('\\n') ? '' : '\\r\\n')\r\n }\r\n}\r\n","import { Component, Injector, Input } from '@angular/core'\r\nimport { BaseSession, BaseTerminalTabComponent } from 'tabby-terminal'\r\nimport { NotificationsService } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\nimport { BianbuShellSession } from './shellSession'\r\nimport { BianbuCloudProfile } from './profileProvider'\r\n\r\n/** @hidden */\r\n@Component({\r\n template: BaseTerminalTabComponent.template,\r\n styles: BaseTerminalTabComponent.styles,\r\n animations: BaseTerminalTabComponent.animations,\r\n})\r\nexport class BianbuCloudShellTabComponent extends BaseTerminalTabComponent<any> {\r\n @Input() profile: BianbuCloudProfile\r\n @Input() asRoot = false\r\n @Input() cwd = '.'\r\n\r\n constructor (\r\n injector: Injector,\r\n private mcp: BianbuMcpService,\r\n protected localNotifications: NotificationsService,\r\n ) {\r\n super(injector)\r\n this.setTitle('Bianbu Cloud Shell')\r\n this.icon = 'terminal'\r\n this.enableToolbar = true\r\n this.profile = this.profile || {\r\n id: 'bianbu-cloud-shell',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Shell',\r\n group: 'Bianbu Cloud',\r\n options: { kind: 'shell' },\r\n icon: 'terminal',\r\n color: '#2b6cb0',\r\n disableDynamicTitle: false,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 0,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n }\r\n }\r\n\r\n protected async onFrontendReady (): Promise<void> {\r\n const session = new BianbuShellSession(this.logger, this.mcp)\r\n this.setSession(session as BaseSession, true)\r\n await session.start({ cwd: this.cwd, asRoot: this.asRoot })\r\n session.releaseInitialDataBuffer()\r\n this.localNotifications.notice('Bianbu Cloud shell ready')\r\n super.onFrontendReady()\r\n }\r\n}\r\n","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","if(typeof __WEBPACK_EXTERNAL_MODULE_fs__ === 'undefined') { var e = new Error(\"Cannot find module 'fs'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_settings__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tif (!(moduleId in __webpack_modules__)) {\n\t\tdelete __webpack_module_cache__[moduleId];\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/index.ts\");\n",""],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"index.js","mappings":"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D;AACA,iDAAiD,aAAa;AAC9D;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,iBAAiB;AAC5B,YAAY;AACZ;AACA,eAAe;AACf;AACA;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,YAAY;AACZ;;AAEA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,YAAY;AACZ;AACA,aAAa;AACb;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY;AACZ;AACA;;AAEA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA,6CAA6C,iBAAiB;AAC9D;AACA,+BAA+B,GAAG;AAClC,8BAA8B,GAAG;AACjC,6BAA6B,GAAG;AAChC,6BAA6B,GAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,QAAQ;A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","sources":["webpack-tabby-bianbu-mcp:///webpack/universalModuleDefinition","webpack://tabby-bianbu-mcp/./src/filesTab.component.pug?1f87","webpack://tabby-bianbu-mcp/./src/settingsTab.component.pug?a198","webpack-tabby-bianbu-mcp:///./src/filesTab.component.pug","webpack-tabby-bianbu-mcp:///./src/settingsTab.component.pug","webpack-tabby-bianbu-mcp:///./node_modules/pug-runtime/index.js","webpack-tabby-bianbu-mcp:///./src/commands.ts","webpack-tabby-bianbu-mcp:///./src/configProvider.ts","webpack-tabby-bianbu-mcp:///./src/filesTab.component.ts","webpack-tabby-bianbu-mcp:///./src/index.ts","webpack-tabby-bianbu-mcp:///./src/mcp.service.ts","webpack-tabby-bianbu-mcp:///./src/profileProvider.ts","webpack-tabby-bianbu-mcp:///./src/settingsTab.component.ts","webpack-tabby-bianbu-mcp:///./src/settingsTabProvider.ts","webpack-tabby-bianbu-mcp:///./src/shellSession.ts","webpack-tabby-bianbu-mcp:///./src/shellTab.component.ts","webpack-tabby-bianbu-mcp:///external umd \"@angular/common\"","webpack-tabby-bianbu-mcp:///external umd \"@angular/core\"","webpack-tabby-bianbu-mcp:///external umd \"@angular/forms\"","webpack-tabby-bianbu-mcp:///external umd \"fs\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-core\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-settings\"","webpack-tabby-bianbu-mcp:///external umd \"tabby-terminal\"","webpack-tabby-bianbu-mcp:///webpack/bootstrap","webpack-tabby-bianbu-mcp:///webpack/before-startup","webpack-tabby-bianbu-mcp:///webpack/startup","webpack-tabby-bianbu-mcp:///webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"fs\"); } catch(e) {} }()), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/core\", \"@angular/forms\", \"fs\", \"tabby-core\", \"tabby-settings\", \"tabby-terminal\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/core\"), require(\"@angular/forms\"), (function webpackLoadOptionalExternalModule() { try { return require(\"fs\"); } catch(e) {} }()), require(\"tabby-core\"), require(\"tabby-settings\"), require(\"tabby-terminal\")) : factory(root[\"@angular/common\"], root[\"@angular/core\"], root[\"@angular/forms\"], root[\"fs\"], root[\"tabby-core\"], root[\"tabby-settings\"], root[\"tabby-terminal\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(global, (__WEBPACK_EXTERNAL_MODULE__angular_common__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_settings__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__) => {\nreturn ","var req = require(\"!!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\node_modules\\\\pug-loader\\\\index.js!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\src\\\\filesTab.component.pug\");\nmodule.exports = (req['default'] || req).apply(req, [])","var req = require(\"!!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\node_modules\\\\pug-loader\\\\index.js!C:\\\\Users\\\\Administrator\\\\tabby-bianbu-mcp\\\\src\\\\settingsTab.component.pug\");\nmodule.exports = (req['default'] || req).apply(req, [])","var pug = require(\"!../node_modules/pug-runtime/index.js\");\n\nfunction template(locals) {var pug_html = \"\", pug_mixins = {}, pug_interp;pug_html = pug_html + \"\\u003Cdiv style=\\\"height:100%; display:flex; flex-direction:column; background:#111827; color:#e5e7eb\\\"\\u003E\\u003Cdiv class=\\\"topbar\\\" style=\\\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; flex-direction:column; gap:10px; background:#0f172a\\\"\\u003E\\u003Cdiv class=\\\"toolbar\\\" style=\\\"display:flex; gap:8px; align-items:center; flex-wrap:wrap\\\"\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"goBack()\\\" [disabled]=\\\"busy || historyIndex &lt;= 0\\\" title=\\\"Back (Alt+Left)\\\" style=\\\"min-width:34px; font-weight:700\\\"\\u003E←\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"goForward()\\\" [disabled]=\\\"busy || historyIndex &gt;= history.length - 1\\\" title=\\\"Forward (Alt+Right)\\\" style=\\\"min-width:34px; font-weight:700\\\"\\u003E→\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"goUp()\\\" [disabled]=\\\"busy || currentPath === &quot;.&quot; || currentPath === &quot;\\u002F&quot;\\\" title=\\\"Up (Alt+Up \\u002F Backspace)\\\" style=\\\"min-width:34px; font-weight:700\\\"\\u003E↑\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"refresh()\\\" [disabled]=\\\"busy\\\" title=\\\"Refresh (F5)\\\" style=\\\"min-width:34px; font-weight:700\\\"\\u003E⟳\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"openCreateDirectoryPrompt()\\\" [disabled]=\\\"busy\\\"\\u003ENew folder\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"openCreateFilePrompt()\\\" [disabled]=\\\"busy\\\"\\u003ENew file\\u003C\\u002Fbutton\\u003E\\u003Clabel class=\\\"btn btn-sm btn-secondary\\\" style=\\\"margin:0\\\"\\u003EUpload\\u003Cinput type=\\\"file\\\" style=\\\"display:none\\\" (change)=\\\"uploadFile($event)\\\" [disabled]=\\\"busy\\\"\\u003E\\u003C\\u002Flabel\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"downloadSelected()\\\" [disabled]=\\\"busy || !selectedPath\\\"\\u003EDownload\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"transfersVisible = !transfersVisible\\\"\\u003ETransfers\\u003C\\u002Fbutton\\u003E\\u003Clabel style=\\\"display:flex; align-items:center; gap:6px; margin-left:auto; background:#1e293b; padding:6px 10px; border-radius:8px\\\"\\u003E\\u003Cinput type=\\\"checkbox\\\" [(ngModel)]=\\\"asRoot\\\" (ngModelChange)=\\\"refresh()\\\"\\u003E\\u003Cspan\\u003Eas_root\\u003C\\u002Fspan\\u003E\\u003C\\u002Flabel\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"address\\\" style=\\\"display:flex; gap:8px; align-items:center\\\"\\u003E\\u003Cdiv style=\\\"display:flex; gap:4px; align-items:center; flex-wrap:wrap; padding:10px 12px; border-radius:10px; background:#1e293b; border:1px solid #334155; flex:1\\\"\\u003E\\u003Cbutton class=\\\"btn btn-link\\\" type=\\\"button\\\" *ngFor=\\\"let crumb of breadcrumbs; let i=index\\\" (click)=\\\"navigateBreadcrumb(i)\\\" style=\\\"padding:0 4px; min-height:auto; color:#f8fafc; text-decoration:none; font-weight:600\\\"\\u003E{{ crumb }}\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cinput class=\\\"form-control\\\" id=\\\"bianbu-path-input\\\" type=\\\"text\\\" style=\\\"max-width:420px; background:#0b1220; color:#f8fafc; border:1px solid #334155\\\" [(ngModel)]=\\\"pathInput\\\" (keyup.enter)=\\\"navigateToInput()\\\" title=\\\"Ctrl+L to focus path\\\"\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"searchrow\\\" style=\\\"display:flex; gap:8px; align-items:center\\\"\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" style=\\\"background:#0b1220; color:#f8fafc; border:1px solid #334155\\\" [(ngModel)]=\\\"searchText\\\" (ngModelChange)=\\\"applyFilter()\\\" placeholder=\\\"Filter current directory…\\\"\\u003E\\u003Cdiv style=\\\"color:#cbd5e1; white-space:nowrap\\\"\\u003E{{ status }}\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"main\\\" style=\\\"display:grid; grid-template-columns: minmax(460px, 48%) 1fr; gap:0; flex:1; min-height:0\\\"\\u003E\\u003Cdiv class=\\\"pane left\\\" style=\\\"display:flex; flex-direction:column; min-height:0; border-right:1px solid #334155; position:relative; background:#0b1220\\\" [style.outline]=\\\"dragActive ? &quot;2px dashed #4ade80&quot; : &quot;none&quot;\\\" (dragover)=\\\"onDragOver($event)\\\" (dragleave)=\\\"onDragLeave()\\\" (drop)=\\\"onDrop($event)\\\"\\u003E\\u003Cdiv *ngIf=\\\"dragActive\\\" style=\\\"position:absolute; inset:12px; border-radius:12px; background:rgba(74,222,128,0.12); display:flex; align-items:center; justify-content:center; z-index:10; pointer-events:none; color:#d1fae5; font-size:18px; font-weight:700\\\"\\u003EDrop file to upload\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"overflow:auto; flex:1\\\"\\u003E\\u003Ctable style=\\\"width:100%; border-collapse:collapse; table-layout:fixed\\\"\\u003E\\u003Cthead style=\\\"position:sticky; top:0; z-index:2; background:#0f172a\\\"\\u003E\\u003Ctr style=\\\"text-align:left; color:#cbd5e1; border-bottom:1px solid #334155\\\"\\u003E\\u003Cth style=\\\"padding:10px 12px; width:58%\\\"\\u003EName\\u003C\\u002Fth\\u003E\\u003Cth style=\\\"padding:10px 12px; width:16%\\\"\\u003EType\\u003C\\u002Fth\\u003E\\u003Cth style=\\\"padding:10px 12px; width:26%\\\"\\u003ESize\\u003C\\u002Fth\\u003E\\u003C\\u002Ftr\\u003E\\u003C\\u002Fthead\\u003E\\u003Ctbody\\u003E\\u003Ctr *ngFor=\\\"let item of filteredItems; let i=index\\\" [style.background]=\\\"i === selectedIndex ? &quot;#1d4ed8&quot; : &quot;transparent&quot;\\\" [style.color]=\\\"i === selectedIndex ? &quot;#ffffff&quot; : &quot;#e5e7eb&quot;\\\" style=\\\"border-bottom:1px solid #1e293b; cursor:default\\\" (click)=\\\"selectItem(item)\\\" (dblclick)=\\\"openItem(item)\\\" (contextmenu)=\\\"showContextMenu($event, item)\\\"\\u003E\\u003Ctd style=\\\"padding:10px 12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-weight:600\\\"\\u003E{{ baseName(item.path) }}\\u003C\\u002Ftd\\u003E\\u003Ctd style=\\\"padding:10px 12px\\\"\\u003E{{ item.is_dir ? 'dir' : 'file' }}\\u003C\\u002Ftd\\u003E\\u003Ctd style=\\\"padding:10px 12px\\\"\\u003E{{ item.size }}\\u003C\\u002Ftd\\u003E\\u003C\\u002Ftr\\u003E\\u003C\\u002Ftbody\\u003E\\u003C\\u002Ftable\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"pane right\\\" style=\\\"display:flex; flex-direction:column; min-height:0; background:#111827\\\"\\u003E\\u003Cdiv class=\\\"previewHeader\\\" style=\\\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; justify-content:space-between; gap:12px; align-items:center; background:#0f172a\\\"\\u003E\\u003Cdiv\\u003E\\u003Ch4 style=\\\"margin:0; color:#f8fafc\\\"\\u003EPreview \\u002F Editor\\u003C\\u002Fh4\\u003E\\u003Cdiv style=\\\"color:#94a3b8; font-size:.9em\\\"\\u003E{{ selectedPath || 'Select a file from the left pane' }}\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"display:flex; gap:8px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"downloadSelected()\\\" [disabled]=\\\"busy || !selectedPath\\\"\\u003EDownload\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-primary\\\" type=\\\"button\\\" (click)=\\\"saveSelected()\\\" [disabled]=\\\"busy || !selectedPath || !selectedIsText\\\"\\u003ESave\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"flex:1; min-height:0; display:flex\\\"\\u003E\\u003Ctextarea class=\\\"form-control\\\" *ngIf=\\\"selectedPath &amp;&amp; selectedIsText\\\" style=\\\"flex:1; min-height:0; border:none; border-radius:0; background:#111827; color:#f8fafc; padding:14px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace\\\" [(ngModel)]=\\\"selectedContent\\\" [disabled]=\\\"busy\\\" placeholder=\\\"Open a text file to preview or edit it\\\"\\u003E\\u003C\\u002Ftextarea\\u003E\\u003Cdiv *ngIf=\\\"selectedPath &amp;&amp; !selectedIsText\\\" style=\\\"flex:1; display:flex; align-items:center; justify-content:center; text-align:center; color:#cbd5e1; padding:24px\\\"\\u003E\\u003Cdiv\\u003E\\u003Cdiv style=\\\"font-size:20px; font-weight:700; margin-bottom:10px\\\"\\u003EThis file type is not previewed inline\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"margin-bottom:16px; color:#94a3b8\\\"\\u003EDownload the file to inspect it locally.\\u003C\\u002Fdiv\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"downloadSelected()\\\"\\u003EDownload file\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv *ngIf=\\\"!selectedPath\\\" style=\\\"flex:1; display:flex; align-items:center; justify-content:center; text-align:center; color:#94a3b8\\\"\\u003ESelect a file from the left pane to preview or edit it.\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"contextMenu\\\" *ngIf=\\\"contextMenuVisible &amp;&amp; contextItem\\\" [style.left.px]=\\\"contextMenuX\\\" [style.top.px]=\\\"contextMenuY\\\" style=\\\"position:fixed; z-index:1000; min-width:180px; background:#0f172a; border:1px solid #334155; border-radius:10px; box-shadow:0 12px 30px rgba(0,0,0,.45); padding:6px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-link\\\" type=\\\"button\\\" style=\\\"display:block; width:100%; text-align:left; color:#f8fafc; text-decoration:none; padding:8px 10px\\\" (click)=\\\"openItem(contextItem); hideContextMenu()\\\"\\u003EOpen\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-link\\\" type=\\\"button\\\" style=\\\"display:block; width:100%; text-align:left; color:#f8fafc; text-decoration:none; padding:8px 10px\\\" (click)=\\\"openRenamePrompt(contextItem); hideContextMenu()\\\"\\u003ERename\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-link\\\" type=\\\"button\\\" style=\\\"display:block; width:100%; text-align:left; color:#fca5a5; text-decoration:none; padding:8px 10px\\\" (click)=\\\"deleteItem(contextItem); hideContextMenu()\\\"\\u003EDelete\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"promptOverlay\\\" *ngIf=\\\"promptVisible\\\" style=\\\"position:fixed; inset:0; background:rgba(2,6,23,.65); z-index:1100; display:flex; align-items:center; justify-content:center\\\"\\u003E\\u003Cdiv class=\\\"promptCard\\\" style=\\\"width:420px; background:#0f172a; border:1px solid #334155; border-radius:14px; padding:18px; box-shadow:0 20px 50px rgba(0,0,0,.45)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0; color:#f8fafc\\\"\\u003E{{ promptTitle }}\\u003C\\u002Fh3\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" style=\\\"background:#0b1220; color:#f8fafc; border:1px solid #334155\\\" [(ngModel)]=\\\"promptValue\\\" [placeholder]=\\\"promptPlaceholder\\\" (keyup.enter)=\\\"confirmPrompt()\\\" (keyup.escape)=\\\"closePrompt()\\\"\\u003E\\u003Cdiv style=\\\"display:flex; justify-content:flex-end; gap:10px; margin-top:16px\\\"\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"closePrompt()\\\"\\u003ECancel\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"confirmPrompt()\\\"\\u003EConfirm\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"transferOverlay\\\" *ngIf=\\\"transfersVisible\\\" style=\\\"position:fixed; right:16px; bottom:16px; width:360px; max-height:50vh; overflow:auto; z-index:900; background:#0f172a; border:1px solid #334155; border-radius:14px; box-shadow:0 20px 50px rgba(0,0,0,.45)\\\"\\u003E\\u003Cdiv style=\\\"padding:12px 14px; border-bottom:1px solid #334155; display:flex; justify-content:space-between; align-items:center\\\"\\u003E\\u003Cb style=\\\"color:#f8fafc\\\"\\u003ETransfers\\u003C\\u002Fb\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-secondary\\\" type=\\\"button\\\" (click)=\\\"transfersVisible = false\\\"\\u003EHide\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv *ngIf=\\\"!transfers.length\\\" style=\\\"padding:14px; color:#94a3b8\\\"\\u003ENo uploads or downloads yet.\\u003C\\u002Fdiv\\u003E\\u003Cdiv *ngFor=\\\"let transfer of transfers\\\" style=\\\"padding:12px 14px; border-bottom:1px solid #1e293b\\\"\\u003E\\u003Cdiv style=\\\"display:flex; justify-content:space-between; gap:12px; margin-bottom:6px\\\"\\u003E\\u003Cdiv style=\\\"color:#f8fafc; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis\\\"\\u003E{{ transfer.name }}\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"color:#94a3b8; font-size:.9em\\\"\\u003E{{ transfer.direction }}\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"color:#94a3b8; font-size:.9em; margin-bottom:8px\\\"\\u003E{{ transfer.status }} • {{ transferRate(transfer) }}\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"height:8px; border-radius:999px; background:#1e293b; overflow:hidden; margin-bottom:8px\\\"\\u003E\\u003Cdiv *ngIf=\\\"transferPercent(transfer) !== null\\\" [style.width.%]=\\\"transferPercent(transfer)\\\" style=\\\"height:100%; background:#3b82f6\\\"\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv *ngIf=\\\"transferPercent(transfer) === null &amp;&amp; transfer.status === &quot;running&quot;\\\" style=\\\"height:100%; width:45%; background:linear-gradient(90deg,#334155,#60a5fa,#334155)\\\"\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv style=\\\"display:flex; justify-content:space-between; align-items:center\\\"\\u003E\\u003Cdiv style=\\\"color:#cbd5e1; font-size:.9em\\\"\\u003E{{ transfer.bytesDone }} \\u002F {{ transfer.bytesTotal || 'unknown' }} bytes\\u003C\\u002Fdiv\\u003E\\u003Cbutton class=\\\"btn btn-sm btn-outline-danger\\\" type=\\\"button\\\" *ngIf=\\\"transfer.status === &quot;running&quot;\\\" (click)=\\\"cancelTransfer(transfer)\\\"\\u003ECancel\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\";;return pug_html;};\nmodule.exports = template;","var pug = require(\"!../node_modules/pug-runtime/index.js\");\n\nfunction template(locals) {var pug_html = \"\", pug_mixins = {}, pug_interp;pug_html = pug_html + \"\\u003Cdiv style=\\\"padding: 20px; display:flex; flex-direction:column; gap:16px\\\"\\u003E\\u003Cdiv class=\\\"hero\\\" style=\\\"padding:18px; border-radius:12px; background:linear-gradient(135deg, rgba(25,53,103,.9), rgba(17,94,89,.85)); color:white\\\"\\u003E\\u003Ch2 style=\\\"margin:0 0 8px 0\\\"\\u003EBianbu MCP\\u003C\\u002Fh2\\u003E\\u003Cp style=\\\"margin:0; opacity:.92\\\"\\u003EConfigure your Bianbu Cloud MCP endpoint and open a shell-like tab or a file-manager-like tab directly from Tabby.\\u003C\\u002Fp\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EQuick actions\\u003C\\u002Fh3\\u003E\\u003Cdiv style=\\\"display:flex; gap:12px; flex-wrap:wrap\\\"\\u003E\\u003Cbutton class=\\\"btn btn-primary\\\" type=\\\"button\\\" (click)=\\\"openShell()\\\"\\u003EOpen Bianbu Cloud Shell\\u003C\\u002Fbutton\\u003E\\u003Cbutton class=\\\"btn btn-secondary\\\" type=\\\"button\\\" (click)=\\\"openFiles()\\\"\\u003EOpen Bianbu Cloud Files\\u003C\\u002Fbutton\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EConnection settings\\u003C\\u002Fh3\\u003E\\u003Cdiv class=\\\"grid\\\" style=\\\"display:grid; grid-template-columns: 160px 1fr; gap:12px; align-items:center\\\"\\u003E\\u003Clabel\\u003EEnable integration\\u003C\\u002Flabel\\u003E\\u003Cinput type=\\\"checkbox\\\" [(ngModel)]=\\\"config.store.bianbuMcp.enabled\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003EProfile name\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"config.store.bianbuMcp.name\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"bianbu\\\"\\u003E\\u003Clabel\\u003EMCP URL\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"text\\\" [(ngModel)]=\\\"config.store.bianbuMcp.url\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"https:\\u002F\\u002Fyour-domain.example.com\\u002Fmcp\\\"\\u003E\\u003Clabel\\u003EX-API-KEY\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"password\\\" [(ngModel)]=\\\"config.store.bianbuMcp.apiKey\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"your-x-api-key\\\"\\u003E\\u003Clabel\\u003EInterval (ms)\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.minIntervalMs\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003EMax retries\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.maxRetries\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003ERetry base (ms)\\u003C\\u002Flabel\\u003E\\u003Cinput class=\\\"form-control\\\" type=\\\"number\\\" min=\\\"0\\\" [(ngModel)]=\\\"config.store.bianbuMcp.retryBaseMs\\\" (ngModelChange)=\\\"save()\\\"\\u003E\\u003Clabel\\u003ENotes\\u003C\\u002Flabel\\u003E\\u003Ctextarea class=\\\"form-control\\\" rows=\\\"3\\\" [(ngModel)]=\\\"config.store.bianbuMcp.notes\\\" (ngModelChange)=\\\"save()\\\" placeholder=\\\"Optional notes\\\"\\u003E\\u003C\\u002Ftextarea\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003ECopyable MCP snippet\\u003C\\u002Fh3\\u003E\\u003Cpre style=\\\"white-space: pre-wrap; margin-bottom:0\\\"\\u003E{{ sampleJson }}\\u003C\\u002Fpre\\u003E\\u003C\\u002Fdiv\\u003E\\u003Cdiv class=\\\"card\\\" style=\\\"padding:16px; border-radius:10px; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08)\\\"\\u003E\\u003Ch3 style=\\\"margin-top:0\\\"\\u003EReminder\\u003C\\u002Fh3\\u003E\\u003Cul style=\\\"margin-bottom:0\\\"\\u003E\\u003Cli\\u003EMCP URL is typically \\u003Ccode\\u003Ehttps:\\u002F\\u002F&lt;domain&gt;\\u002Fmcp\\u003C\\u002Fcode\\u003E\\u003C\\u002Fli\\u003E\\u003Cli\\u003E\\u003Ccode\\u003EX-API-KEY\\u003C\\u002Fcode\\u003E is copied from the Bianbu Cloud API Key page\\u003C\\u002Fli\\u003E\\u003Cli\\u003EShell and Files tabs are UI views backed by MCP calls, not native SSH\\u002FSFTP transport\\u003C\\u002Fli\\u003E\\u003C\\u002Ful\\u003E\\u003C\\u002Fdiv\\u003E\\u003C\\u002Fdiv\\u003E\";;return pug_html;};\nmodule.exports = template;","'use strict';\n\nvar pug_has_own_property = Object.prototype.hasOwnProperty;\n\n/**\n * Merge two attribute objects giving precedence\n * to values in object `b`. Classes are special-cased\n * allowing for arrays and merging/joining appropriately\n * resulting in a string.\n *\n * @param {Object} a\n * @param {Object} b\n * @return {Object} a\n * @api private\n */\n\nexports.merge = pug_merge;\nfunction pug_merge(a, b) {\n if (arguments.length === 1) {\n var attrs = a[0];\n for (var i = 1; i < a.length; i++) {\n attrs = pug_merge(attrs, a[i]);\n }\n return attrs;\n }\n\n for (var key in b) {\n if (key === 'class') {\n var valA = a[key] || [];\n a[key] = (Array.isArray(valA) ? valA : [valA]).concat(b[key] || []);\n } else if (key === 'style') {\n var valA = pug_style(a[key]);\n valA = valA && valA[valA.length - 1] !== ';' ? valA + ';' : valA;\n var valB = pug_style(b[key]);\n valB = valB && valB[valB.length - 1] !== ';' ? valB + ';' : valB;\n a[key] = valA + valB;\n } else {\n a[key] = b[key];\n }\n }\n\n return a;\n};\n\n/**\n * Process array, object, or string as a string of classes delimited by a space.\n *\n * If `val` is an array, all members of it and its subarrays are counted as\n * classes. If `escaping` is an array, then whether or not the item in `val` is\n * escaped depends on the corresponding item in `escaping`. If `escaping` is\n * not an array, no escaping is done.\n *\n * If `val` is an object, all the keys whose value is truthy are counted as\n * classes. No escaping is done.\n *\n * If `val` is a string, it is counted as a class. No escaping is done.\n *\n * @param {(Array.<string>|Object.<string, boolean>|string)} val\n * @param {?Array.<string>} escaping\n * @return {String}\n */\nexports.classes = pug_classes;\nfunction pug_classes_array(val, escaping) {\n var classString = '', className, padding = '', escapeEnabled = Array.isArray(escaping);\n for (var i = 0; i < val.length; i++) {\n className = pug_classes(val[i]);\n if (!className) continue;\n escapeEnabled && escaping[i] && (className = pug_escape(className));\n classString = classString + padding + className;\n padding = ' ';\n }\n return classString;\n}\nfunction pug_classes_object(val) {\n var classString = '', padding = '';\n for (var key in val) {\n if (key && val[key] && pug_has_own_property.call(val, key)) {\n classString = classString + padding + key;\n padding = ' ';\n }\n }\n return classString;\n}\nfunction pug_classes(val, escaping) {\n if (Array.isArray(val)) {\n return pug_classes_array(val, escaping);\n } else if (val && typeof val === 'object') {\n return pug_classes_object(val);\n } else {\n return val || '';\n }\n}\n\n/**\n * Convert object or string to a string of CSS styles delimited by a semicolon.\n *\n * @param {(Object.<string, string>|string)} val\n * @return {String}\n */\n\nexports.style = pug_style;\nfunction pug_style(val) {\n if (!val) return '';\n if (typeof val === 'object') {\n var out = '';\n for (var style in val) {\n /* istanbul ignore else */\n if (pug_has_own_property.call(val, style)) {\n out = out + style + ':' + val[style] + ';';\n }\n }\n return out;\n } else {\n return val + '';\n }\n};\n\n/**\n * Render the given attribute.\n *\n * @param {String} key\n * @param {String} val\n * @param {Boolean} escaped\n * @param {Boolean} terse\n * @return {String}\n */\nexports.attr = pug_attr;\nfunction pug_attr(key, val, escaped, terse) {\n if (val === false || val == null || !val && (key === 'class' || key === 'style')) {\n return '';\n }\n if (val === true) {\n return ' ' + (terse ? key : key + '=\"' + key + '\"');\n }\n var type = typeof val;\n if ((type === 'object' || type === 'function') && typeof val.toJSON === 'function') {\n val = val.toJSON();\n }\n if (typeof val !== 'string') {\n val = JSON.stringify(val);\n if (!escaped && val.indexOf('\"') !== -1) {\n return ' ' + key + '=\\'' + val.replace(/'/g, '&#39;') + '\\'';\n }\n }\n if (escaped) val = pug_escape(val);\n return ' ' + key + '=\"' + val + '\"';\n};\n\n/**\n * Render the given attributes object.\n *\n * @param {Object} obj\n * @param {Object} terse whether to use HTML5 terse boolean attributes\n * @return {String}\n */\nexports.attrs = pug_attrs;\nfunction pug_attrs(obj, terse){\n var attrs = '';\n\n for (var key in obj) {\n if (pug_has_own_property.call(obj, key)) {\n var val = obj[key];\n\n if ('class' === key) {\n val = pug_classes(val);\n attrs = pug_attr(key, val, false, terse) + attrs;\n continue;\n }\n if ('style' === key) {\n val = pug_style(val);\n }\n attrs += pug_attr(key, val, false, terse);\n }\n }\n\n return attrs;\n};\n\n/**\n * Escape the given string of `html`.\n *\n * @param {String} html\n * @return {String}\n * @api private\n */\n\nvar pug_match_html = /[\"&<>]/;\nexports.escape = pug_escape;\nfunction pug_escape(_html){\n var html = '' + _html;\n var regexResult = pug_match_html.exec(html);\n if (!regexResult) return _html;\n\n var result = '';\n var i, lastIndex, escape;\n for (i = regexResult.index, lastIndex = 0; i < html.length; i++) {\n switch (html.charCodeAt(i)) {\n case 34: escape = '&quot;'; break;\n case 38: escape = '&amp;'; break;\n case 60: escape = '&lt;'; break;\n case 62: escape = '&gt;'; break;\n default: continue;\n }\n if (lastIndex !== i) result += html.substring(lastIndex, i);\n lastIndex = i + 1;\n result += escape;\n }\n if (lastIndex !== i) return result + html.substring(lastIndex, i);\n else return result;\n};\n\n/**\n * Re-throw the given `err` in context to the\n * the pug in `filename` at the given `lineno`.\n *\n * @param {Error} err\n * @param {String} filename\n * @param {String} lineno\n * @param {String} str original source\n * @api private\n */\n\nexports.rethrow = pug_rethrow;\nfunction pug_rethrow(err, filename, lineno, str){\n if (!(err instanceof Error)) throw err;\n if ((typeof window != 'undefined' || !filename) && !str) {\n err.message += ' on line ' + lineno;\n throw err;\n }\n try {\n str = str || require('fs').readFileSync(filename, 'utf8')\n } catch (ex) {\n pug_rethrow(err, null, lineno)\n }\n var context = 3\n , lines = str.split('\\n')\n , start = Math.max(lineno - context, 0)\n , end = Math.min(lines.length, lineno + context);\n\n // Error context\n var context = lines.slice(start, end).map(function(line, i){\n var curr = i + start + 1;\n return (curr == lineno ? ' > ' : ' ')\n + curr\n + '| '\n + line;\n }).join('\\n');\n\n // Alter exception message\n err.path = filename;\n err.message = (filename || 'Pug') + ':' + lineno\n + '\\n' + context + '\\n\\n' + err.message;\n throw err;\n};\n","import { Injectable } from '@angular/core'\r\nimport { AppService, Command, CommandLocation, CommandProvider } from 'tabby-core'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\n\r\n/** @hidden */\r\n@Injectable()\r\nexport class BianbuCloudCommandProvider extends CommandProvider {\r\n constructor (\r\n private app: AppService,\r\n ) {\r\n super()\r\n }\r\n\r\n async provide (): Promise<Command[]> {\r\n return [\r\n {\r\n id: 'bianbu-cloud-shell',\r\n label: 'Open Bianbu Cloud Shell',\r\n sublabel: 'Remote shell over MCP run_command',\r\n locations: [CommandLocation.StartPage],\r\n run: async () => {\r\n this.app.openNewTab({ type: BianbuCloudShellTabComponent })\r\n },\r\n },\r\n {\r\n id: 'bianbu-cloud-files',\r\n label: 'Open Bianbu Cloud Files',\r\n sublabel: 'File manager over MCP file tools',\r\n locations: [CommandLocation.StartPage],\r\n run: async () => {\r\n this.app.openNewTab({ type: BianbuCloudFilesTabComponent })\r\n },\r\n },\r\n ]\r\n }\r\n}\r\n","import { ConfigProvider } from 'tabby-core'\r\n\r\n/** @hidden */\r\nexport class BianbuMcpConfigProvider extends ConfigProvider {\r\n defaults = {\r\n bianbuMcp: {\r\n enabled: true,\r\n name: 'bianbu',\r\n url: '',\r\n apiKey: '',\r\n minIntervalMs: 1000,\r\n maxRetries: 2,\r\n retryBaseMs: 1000,\r\n notes: '',\r\n },\r\n }\r\n}\r\n","import { Component, Injector, HostListener } from '@angular/core'\r\nimport { BaseTabComponent, NotificationsService } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\n\r\ninterface TransferItem {\r\n id: number\r\n name: string\r\n direction: 'upload' | 'download'\r\n status: 'running' | 'done' | 'error' | 'cancelled'\r\n bytesDone: number\r\n bytesTotal: number | null\r\n startedAt: number\r\n finishedAt?: number\r\n error?: string\r\n controller?: AbortController\r\n}\r\n\r\n/** @hidden */\r\n@Component({\r\n template: require('./filesTab.component.pug'),\r\n})\r\nexport class BianbuCloudFilesTabComponent extends BaseTabComponent {\r\n currentPath = '.'\r\n pathInput = '.'\r\n asRoot = false\r\n busy = false\r\n items: any[] = []\r\n filteredItems: any[] = []\r\n selectedPath = ''\r\n selectedContent = ''\r\n selectedIsText = false\r\n status = 'Ready'\r\n dragActive = false\r\n searchText = ''\r\n history: string[] = ['.']\r\n historyIndex = 0\r\n selectedIndex = -1\r\n\r\n contextMenuVisible = false\r\n contextMenuX = 0\r\n contextMenuY = 0\r\n contextItem: any = null\r\n\r\n promptVisible = false\r\n promptTitle = ''\r\n promptPlaceholder = ''\r\n promptValue = ''\r\n promptAction: null | 'mkdir' | 'newfile' | 'rename' = null\r\n promptTarget: any = null\r\n\r\n transfersVisible = true\r\n transfers: TransferItem[] = []\r\n private transferSeq = 1\r\n\r\n constructor (\r\n injector: Injector,\r\n private mcp: BianbuMcpService,\r\n private notifications: NotificationsService,\r\n ) {\r\n super(injector)\r\n this.setTitle('Bianbu Cloud Files')\r\n this.icon = 'folder-open'\r\n }\r\n\r\n ngOnInit (): void {\r\n this.refresh().catch(() => null)\r\n }\r\n\r\n get breadcrumbs (): string[] {\r\n if (!this.currentPath || this.currentPath === '.') {\r\n return ['.']\r\n }\r\n const normalized = this.currentPath.replace(/\\\\/g, '/')\r\n if (normalized === '/') {\r\n return ['/']\r\n }\r\n const parts = normalized.split('/').filter(Boolean)\r\n return normalized.startsWith('/') ? ['/'].concat(parts) : parts\r\n }\r\n\r\n get selectedItem (): any | null {\r\n return this.filteredItems[this.selectedIndex] ?? null\r\n }\r\n\r\n @HostListener('document:click')\r\n onDocumentClick (): void {\r\n this.hideContextMenu()\r\n }\r\n\r\n @HostListener('document:keydown', ['$event'])\r\n onKeyDown (event: KeyboardEvent): void {\r\n const target = event.target as HTMLElement | null\r\n const tag = target?.tagName?.toLowerCase()\r\n const editing = ['input', 'textarea'].includes(tag || '') || this.promptVisible\r\n\r\n if (event.key === 'F5') {\r\n event.preventDefault()\r\n void this.refresh()\r\n return\r\n }\r\n if (event.altKey && event.key === 'ArrowUp') {\r\n event.preventDefault()\r\n this.goUp()\r\n return\r\n }\r\n if (event.altKey && event.key === 'ArrowLeft') {\r\n event.preventDefault()\r\n this.goBack()\r\n return\r\n }\r\n if (event.altKey && event.key === 'ArrowRight') {\r\n event.preventDefault()\r\n this.goForward()\r\n return\r\n }\r\n if (event.ctrlKey && event.key.toLowerCase() === 'l') {\r\n event.preventDefault()\r\n const el = document.getElementById('bianbu-path-input') as HTMLInputElement | null\r\n el?.focus()\r\n el?.select()\r\n return\r\n }\r\n if (event.ctrlKey && event.key.toLowerCase() === 'n') {\r\n event.preventDefault()\r\n this.openCreateFilePrompt()\r\n return\r\n }\r\n if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === 'n') {\r\n event.preventDefault()\r\n this.openCreateDirectoryPrompt()\r\n return\r\n }\r\n if (editing) {\r\n return\r\n }\r\n if (event.key === 'Backspace') {\r\n event.preventDefault()\r\n this.goUp()\r\n return\r\n }\r\n if (event.key === 'Delete' && this.selectedItem) {\r\n event.preventDefault()\r\n void this.deleteItem(this.selectedItem)\r\n return\r\n }\r\n if (event.key === 'F2' && this.selectedItem) {\r\n event.preventDefault()\r\n this.openRenamePrompt(this.selectedItem)\r\n return\r\n }\r\n if (event.key === 'Enter' && this.selectedItem) {\r\n event.preventDefault()\r\n void this.openItem(this.selectedItem)\r\n return\r\n }\r\n if (event.key === 'ArrowDown') {\r\n event.preventDefault()\r\n this.moveSelection(1)\r\n return\r\n }\r\n if (event.key === 'ArrowUp') {\r\n event.preventDefault()\r\n this.moveSelection(-1)\r\n return\r\n }\r\n }\r\n\r\n async refresh (): Promise<void> {\r\n this.busy = true\r\n this.status = 'Loading directory…'\r\n this.pathInput = this.currentPath\r\n this.setProgress(0.25)\r\n try {\r\n const result = await this.mcp.listDirectory(this.currentPath || '.', this.asRoot)\r\n this.items = result.items || []\r\n this.applyFilter()\r\n this.status = `Loaded ${this.items.length} item(s)`\r\n if (this.filteredItems.length && this.selectedIndex < 0) {\r\n this.selectedIndex = 0\r\n }\r\n } catch (error: any) {\r\n this.notifications.error('Failed to list directory', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n this.setProgress(null)\r\n }\r\n }\r\n\r\n applyFilter (): void {\r\n const q = this.searchText.trim().toLowerCase()\r\n this.filteredItems = this.items.filter(item => {\r\n const name = this.baseName(item.path).toLowerCase()\r\n return !q || name.includes(q) || item.path.toLowerCase().includes(q)\r\n })\r\n if (this.selectedIndex >= this.filteredItems.length) {\r\n this.selectedIndex = this.filteredItems.length - 1\r\n }\r\n }\r\n\r\n navigateToInput (): void {\r\n this.navigate(this.pathInput || '.')\r\n }\r\n\r\n navigate (path: string, pushHistory = true): void {\r\n this.currentPath = path || '.'\r\n this.pathInput = this.currentPath\r\n if (pushHistory) {\r\n this.history = this.history.slice(0, this.historyIndex + 1)\r\n this.history.push(this.currentPath)\r\n this.historyIndex = this.history.length - 1\r\n }\r\n this.clearPreview()\r\n this.selectedIndex = -1\r\n void this.refresh()\r\n }\r\n\r\n navigateBreadcrumb (index: number): void {\r\n if (this.currentPath === '.' && index === 0) {\r\n this.navigate('.', true)\r\n return\r\n }\r\n const crumbs = this.breadcrumbs\r\n if (crumbs[0] === '/') {\r\n if (index === 0) {\r\n this.navigate('/', true)\r\n return\r\n }\r\n this.navigate('/' + crumbs.slice(1, index + 1).join('/'), true)\r\n return\r\n }\r\n this.navigate(crumbs.slice(0, index + 1).join('/'), true)\r\n }\r\n\r\n goBack (): void {\r\n if (this.historyIndex <= 0) {\r\n return\r\n }\r\n this.historyIndex -= 1\r\n this.navigate(this.history[this.historyIndex], false)\r\n }\r\n\r\n goForward (): void {\r\n if (this.historyIndex >= this.history.length - 1) {\r\n return\r\n }\r\n this.historyIndex += 1\r\n this.navigate(this.history[this.historyIndex], false)\r\n }\r\n\r\n goUp (): void {\r\n if (this.currentPath === '.' || this.currentPath === '/') {\r\n return\r\n }\r\n const normalized = this.currentPath.replace(/\\\\/g, '/')\r\n const parent = normalized.split('/').slice(0, -1).join('/') || (normalized.startsWith('/') ? '/' : '.')\r\n this.navigate(parent, true)\r\n }\r\n\r\n moveSelection (delta: number): void {\r\n if (!this.filteredItems.length) {\r\n this.selectedIndex = -1\r\n return\r\n }\r\n if (this.selectedIndex < 0) {\r\n this.selectedIndex = 0\r\n return\r\n }\r\n this.selectedIndex = Math.max(0, Math.min(this.filteredItems.length - 1, this.selectedIndex + delta))\r\n }\r\n\r\n selectItem (item: any): void {\r\n this.selectedIndex = this.filteredItems.indexOf(item)\r\n }\r\n\r\n async openItem (item: any): Promise<void> {\r\n this.selectItem(item)\r\n if (item.is_dir) {\r\n this.navigate(item.path, true)\r\n return\r\n }\r\n\r\n this.busy = true\r\n this.status = `Opening ${item.path}`\r\n this.selectedPath = item.path\r\n this.selectedIsText = this.isTextLike(item.path)\r\n try {\r\n if (this.selectedIsText) {\r\n const result = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot)\r\n this.selectedContent = result.content || ''\r\n this.status = `Opened ${item.path}`\r\n } else {\r\n this.selectedContent = ''\r\n this.status = `Binary / non-text file selected: ${item.path}`\r\n }\r\n } catch (error: any) {\r\n this.notifications.error('Failed to open file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n this.selectedContent = ''\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async saveSelected (): Promise<void> {\r\n if (!this.selectedPath || !this.selectedIsText) {\r\n return\r\n }\r\n this.busy = true\r\n this.status = `Saving ${this.selectedPath}`\r\n try {\r\n await this.mcp.writeTextFile(this.selectedPath, this.selectedContent, this.asRoot)\r\n this.notifications.notice('File saved')\r\n this.status = `Saved ${this.selectedPath}`\r\n await this.refresh()\r\n } catch (error: any) {\r\n this.notifications.error('Failed to save file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n openCreateDirectoryPrompt (): void {\r\n this.promptVisible = true\r\n this.promptTitle = 'Create new folder'\r\n this.promptPlaceholder = 'Folder name'\r\n this.promptValue = ''\r\n this.promptAction = 'mkdir'\r\n this.promptTarget = null\r\n }\r\n\r\n openCreateFilePrompt (): void {\r\n this.promptVisible = true\r\n this.promptTitle = 'Create new file'\r\n this.promptPlaceholder = 'File name'\r\n this.promptValue = ''\r\n this.promptAction = 'newfile'\r\n this.promptTarget = null\r\n }\r\n\r\n openRenamePrompt (item: any): void {\r\n this.promptVisible = true\r\n this.promptTitle = 'Rename'\r\n this.promptPlaceholder = 'New name'\r\n this.promptValue = this.baseName(item.path)\r\n this.promptAction = 'rename'\r\n this.promptTarget = item\r\n }\r\n\r\n closePrompt (): void {\r\n this.promptVisible = false\r\n this.promptAction = null\r\n this.promptTarget = null\r\n this.promptValue = ''\r\n }\r\n\r\n async confirmPrompt (): Promise<void> {\r\n const value = this.promptValue.trim()\r\n if (!value || !this.promptAction) {\r\n this.closePrompt()\r\n return\r\n }\r\n\r\n if (this.promptAction === 'mkdir') {\r\n await this.createDirectory(value)\r\n this.closePrompt()\r\n return\r\n }\r\n if (this.promptAction === 'newfile') {\r\n await this.createFile(value)\r\n this.closePrompt()\r\n return\r\n }\r\n if (this.promptAction === 'rename' && this.promptTarget) {\r\n await this.renameItem(this.promptTarget, value)\r\n this.closePrompt()\r\n }\r\n }\r\n\r\n async createDirectory (name: string): Promise<void> {\r\n const path = this.joinPath(this.currentPath, name)\r\n this.busy = true\r\n try {\r\n await this.mcp.makeDirectory(path, this.asRoot)\r\n await this.refresh()\r\n this.notifications.notice('Directory created')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to create directory', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async createFile (name: string): Promise<void> {\r\n const path = this.joinPath(this.currentPath, name)\r\n this.busy = true\r\n try {\r\n await this.mcp.writeTextFile(path, '', this.asRoot)\r\n await this.refresh()\r\n this.notifications.notice('File created')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to create file', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n async renameItem (item: any, name: string): Promise<void> {\r\n const parent = item.path.split('/').slice(0, -1).join('/') || '.'\r\n const newPath = this.joinPath(parent, name)\r\n try {\r\n if (item.is_dir) {\r\n await this.mcp.makeDirectory(newPath, this.asRoot)\r\n } else {\r\n const content = await this.mcp.readTextFile(item.path, 512 * 1024, this.asRoot)\r\n await this.mcp.writeTextFile(newPath, content.content || '', this.asRoot)\r\n }\r\n await this.mcp.deletePath(item.path, !!item.is_dir, this.asRoot)\r\n this.notifications.notice('Path renamed')\r\n await this.refresh()\r\n } catch (error: any) {\r\n this.notifications.error('Rename failed', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n }\r\n }\r\n\r\n async deleteItem (item: any): Promise<void> {\r\n this.busy = true\r\n try {\r\n await this.mcp.deletePath(item.path, !!item.is_dir, this.asRoot)\r\n if (this.selectedPath === item.path) {\r\n this.clearPreview()\r\n }\r\n await this.refresh()\r\n this.notifications.notice('Path deleted')\r\n } catch (error: any) {\r\n this.notifications.error('Failed to delete path', String(error?.message || error))\r\n this.status = String(error?.message || error)\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n showContextMenu (event: MouseEvent, item: any): void {\r\n event.preventDefault()\r\n event.stopPropagation()\r\n this.selectItem(item)\r\n this.contextItem = item\r\n this.contextMenuVisible = true\r\n this.contextMenuX = event.clientX\r\n this.contextMenuY = event.clientY\r\n }\r\n\r\n hideContextMenu (): void {\r\n this.contextMenuVisible = false\r\n this.contextItem = null\r\n }\r\n\r\n async uploadFile (event: Event): Promise<void> {\r\n const input = event.target as HTMLInputElement\r\n const file = input.files?.[0]\r\n if (!file) {\r\n return\r\n }\r\n await this.uploadDroppedFile(file)\r\n input.value = ''\r\n }\r\n\r\n private createTransfer (name: string, direction: 'upload' | 'download', total: number | null, controller: AbortController): TransferItem {\r\n const transfer: TransferItem = {\r\n id: this.transferSeq++,\r\n name,\r\n direction,\r\n status: 'running',\r\n bytesDone: 0,\r\n bytesTotal: total,\r\n startedAt: Date.now(),\r\n controller,\r\n }\r\n this.transfers.unshift(transfer)\r\n return transfer\r\n }\r\n\r\n cancelTransfer (transfer: TransferItem): void {\r\n if (transfer.status !== 'running') {\r\n return\r\n }\r\n transfer.controller?.abort()\r\n transfer.status = 'cancelled'\r\n transfer.finishedAt = Date.now()\r\n }\r\n\r\n transferPercent (transfer: TransferItem): number | null {\r\n if (!transfer.bytesTotal) {\r\n return null\r\n }\r\n return Math.max(0, Math.min(100, Math.round((transfer.bytesDone / transfer.bytesTotal) * 100)))\r\n }\r\n\r\n transferRate (transfer: TransferItem): string {\r\n const end = transfer.finishedAt || Date.now()\r\n const seconds = Math.max(1, (end - transfer.startedAt) / 1000)\r\n const bytes = transfer.bytesDone || 0\r\n return `${Math.round(bytes / seconds / 1024)} KB/s`\r\n }\r\n\r\n async uploadDroppedFile (file: File): Promise<void> {\r\n const controller = new AbortController()\r\n const transfer = this.createTransfer(file.name, 'upload', file.size, controller)\r\n this.busy = true\r\n try {\r\n const base64 = await this.readFileAsBase64(file)\r\n transfer.bytesDone = Math.floor(file.size * 0.3)\r\n const path = this.joinPath(this.currentPath, file.name)\r\n await this.mcp.uploadBinaryFile(path, base64, this.asRoot, controller.signal)\r\n transfer.bytesDone = file.size\r\n transfer.status = 'done'\r\n transfer.finishedAt = Date.now()\r\n this.notifications.notice('File uploaded')\r\n await this.refresh()\r\n } catch (error: any) {\r\n if (transfer.status !== 'cancelled') {\r\n transfer.status = 'error'\r\n transfer.error = String(error?.message || error)\r\n transfer.finishedAt = Date.now()\r\n this.notifications.error('Upload failed', transfer.error)\r\n this.status = transfer.error\r\n }\r\n } finally {\r\n this.busy = false\r\n }\r\n }\r\n\r\n onDragOver (event: DragEvent): void {\r\n event.preventDefault()\r\n this.dragActive = true\r\n }\r\n\r\n onDragLeave (): void {\r\n this.dragActive = false\r\n }\r\n\r\n async onDrop (event: DragEvent): Promise<void> {\r\n event.preventDefault()\r\n this.dragActive = false\r\n const file = event.dataTransfer?.files?.[0]\r\n if (!file) {\r\n return\r\n }\r\n await this.uploadDroppedFile(file)\r\n }\r\n\r\n async downloadSelected (): Promise<void> {\r\n if (!this.selectedPath) {\r\n return\r\n }\r\n const controller = new AbortController()\r\n const transfer = this.createTransfer(this.baseName(this.selectedPath), 'download', null, controller)\r\n try {\r\n const result = await this.mcp.downloadBinaryFile(this.selectedPath, this.asRoot, controller.signal)\r\n const raw = atob(result.content_base64)\r\n transfer.bytesTotal = raw.length\r\n transfer.bytesDone = raw.length\r\n transfer.status = 'done'\r\n transfer.finishedAt = Date.now()\r\n const a = document.createElement('a')\r\n a.href = `data:application/octet-stream;base64,${result.content_base64}`\r\n a.download = this.baseName(this.selectedPath) || 'download.bin'\r\n a.click()\r\n this.notifications.notice('Download started')\r\n } catch (error: any) {\r\n if (transfer.status !== 'cancelled') {\r\n transfer.status = 'error'\r\n transfer.error = String(error?.message || error)\r\n transfer.finishedAt = Date.now()\r\n this.notifications.error('Download failed', transfer.error)\r\n this.status = transfer.error\r\n }\r\n }\r\n }\r\n\r\n private clearPreview (): void {\r\n this.selectedPath = ''\r\n this.selectedContent = ''\r\n this.selectedIsText = false\r\n }\r\n\r\n private baseName (path: string): string {\r\n return path.split('/').pop() || path\r\n }\r\n\r\n private isTextLike (path: string): boolean {\r\n const name = path.toLowerCase()\r\n const exts = ['.txt', '.md', '.json', '.yaml', '.yml', '.xml', '.ini', '.cfg', '.conf', '.log', '.sh', '.py', '.js', '.ts', '.tsx', '.jsx', '.html', '.css', '.scss', '.c', '.cpp', '.h', '.hpp', '.java', '.go', '.rs', '.sql']\r\n return exts.some(ext => name.endsWith(ext))\r\n }\r\n\r\n private joinPath (base: string, child: string): string {\r\n if (!base || base === '.') {\r\n return child\r\n }\r\n if (base.endsWith('/')) {\r\n return `${base}${child}`\r\n }\r\n return `${base}/${child}`\r\n }\r\n\r\n private readFileAsBase64 (file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader()\r\n reader.onload = () => {\r\n const text = String(reader.result || '')\r\n resolve(text.split(',')[1] || '')\r\n }\r\n reader.onerror = () => reject(reader.error)\r\n reader.readAsDataURL(file)\r\n })\r\n }\r\n}\r\n","import { NgModule } from '@angular/core'\r\nimport { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport TabbyCoreModule, { CommandProvider, ConfigProvider, ProfileProvider } from 'tabby-core'\r\nimport { SettingsTabProvider } from 'tabby-settings'\r\n\r\nimport { BianbuMcpConfigProvider } from './configProvider'\r\nimport { BianbuMcpSettingsTabProvider } from './settingsTabProvider'\r\nimport { BianbuMcpSettingsComponent } from './settingsTab.component'\r\nimport { BianbuCloudCommandProvider } from './commands'\r\nimport { BianbuMcpService } from './mcp.service'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\nimport { BianbuCloudProfileProvider } from './profileProvider'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n TabbyCoreModule,\r\n ],\r\n providers: [\r\n BianbuMcpService,\r\n { provide: ConfigProvider, useClass: BianbuMcpConfigProvider, multi: true },\r\n { provide: SettingsTabProvider, useClass: BianbuMcpSettingsTabProvider, multi: true },\r\n { provide: CommandProvider, useClass: BianbuCloudCommandProvider, multi: true },\r\n { provide: ProfileProvider, useClass: BianbuCloudProfileProvider, multi: true },\r\n ],\r\n declarations: [\r\n BianbuMcpSettingsComponent,\r\n BianbuCloudShellTabComponent,\r\n BianbuCloudFilesTabComponent,\r\n ],\r\n entryComponents: [\r\n BianbuMcpSettingsComponent,\r\n BianbuCloudShellTabComponent,\r\n BianbuCloudFilesTabComponent,\r\n ],\r\n})\r\nexport default class BianbuMcpModule { }\r\n","import { Injectable } from '@angular/core'\r\nimport { ConfigService } from 'tabby-core'\r\n\r\ninterface JsonRpcResponse {\r\n result?: any\r\n error?: { code?: number, message?: string }\r\n}\r\n\r\n@Injectable()\r\nexport class BianbuMcpService {\r\n private nextAllowedAt = 0\r\n\r\n constructor (\r\n private config: ConfigService,\r\n ) { }\r\n\r\n get settings (): any {\r\n return this.config.store.bianbuMcp\r\n }\r\n\r\n private sleep (ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n }\r\n\r\n private shouldRetryStatus (status: number): boolean {\r\n return [429, 502, 503, 504].includes(status)\r\n }\r\n\r\n private async pacedFetch (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {\r\n const waitMs = Math.max(0, this.nextAllowedAt - Date.now())\r\n if (waitMs > 0) {\r\n await this.sleep(waitMs)\r\n }\r\n this.nextAllowedAt = Date.now() + (this.settings.minIntervalMs ?? 1000)\r\n return fetch(input, init)\r\n }\r\n\r\n private async request (payload: any, signal?: AbortSignal): Promise<any> {\r\n const settings = this.settings\r\n const maxRetries = Number(settings.maxRetries ?? 2)\r\n const retryBaseMs = Number(settings.retryBaseMs ?? 1000)\r\n let lastBody = ''\r\n let lastStatus = 0\r\n let lastError: any = null\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n const response = await this.pacedFetch(settings.url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n Accept: 'application/json, text/event-stream',\r\n 'MCP-Protocol-Version': '2025-11-25',\r\n 'X-API-KEY': settings.apiKey,\r\n },\r\n body: JSON.stringify(payload),\r\n signal,\r\n })\r\n const text = await response.text()\r\n lastBody = text\r\n lastStatus = response.status\r\n\r\n if (!this.shouldRetryStatus(response.status)) {\r\n const parsed = this.parseBody(text)\r\n if (parsed.error) {\r\n throw new Error(parsed.error.message || 'MCP error')\r\n }\r\n if (parsed.result?.isError && parsed.result?.content?.[0]?.text) {\r\n throw new Error(parsed.result.content[0].text)\r\n }\r\n if (parsed.result?.structuredContent !== undefined) {\r\n return parsed.result.structuredContent\r\n }\r\n return parsed.result\r\n }\r\n } catch (error) {\r\n lastError = error\r\n if (attempt === maxRetries) {\r\n break\r\n }\r\n }\r\n\r\n if (attempt < maxRetries) {\r\n await this.sleep(retryBaseMs * (attempt + 1))\r\n }\r\n }\r\n\r\n throw lastError || new Error(`MCP request failed with status ${lastStatus}: ${lastBody}`)\r\n }\r\n\r\n private parseBody (text: string): JsonRpcResponse {\r\n try {\r\n return JSON.parse(text)\r\n } catch {\r\n const sseMatch = text.match(/data:\\s*(\\{[\\s\\S]*\\})/)\r\n if (sseMatch) {\r\n try {\r\n return JSON.parse(sseMatch[1])\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n }\r\n return { error: { message: text || 'Invalid MCP response' } }\r\n }\r\n\r\n async callTool (name: string, args: any, signal?: AbortSignal): Promise<any> {\r\n return this.request({\r\n jsonrpc: '2.0',\r\n id: `${name}-${Date.now()}`,\r\n method: 'tools/call',\r\n params: {\r\n name,\r\n arguments: args,\r\n },\r\n }, signal)\r\n }\r\n\r\n async health (): Promise<any> {\r\n return this.callTool('health', {})\r\n }\r\n\r\n async runCommand (command: string, cwd: string, timeoutSeconds: number, asRoot: boolean): Promise<any> {\r\n return this.callTool('run_command', {\r\n command,\r\n cwd,\r\n timeout_seconds: timeoutSeconds,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async listDirectory (path: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('list_directory', { path, as_root: asRoot })\r\n }\r\n\r\n async readTextFile (path: string, maxBytes: number, asRoot: boolean): Promise<any> {\r\n return this.callTool('read_text_file', {\r\n path,\r\n max_bytes: maxBytes,\r\n encoding: 'utf-8',\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async writeTextFile (path: string, content: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('write_text_file', {\r\n path,\r\n content,\r\n overwrite: true,\r\n encoding: 'utf-8',\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async makeDirectory (path: string, asRoot: boolean): Promise<any> {\r\n return this.callTool('make_directory', {\r\n path,\r\n parents: true,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async deletePath (path: string, recursive: boolean, asRoot: boolean): Promise<any> {\r\n return this.callTool('delete_path', {\r\n path,\r\n recursive,\r\n as_root: asRoot,\r\n })\r\n }\r\n\r\n async uploadBinaryFile (path: string, base64: string, asRoot: boolean, signal?: AbortSignal): Promise<any> {\r\n return this.callTool('upload_binary_file', {\r\n path,\r\n content_base64: base64,\r\n overwrite: true,\r\n as_root: asRoot,\r\n }, signal)\r\n }\r\n\r\n async downloadBinaryFile (path: string, asRoot: boolean, signal?: AbortSignal): Promise<any> {\r\n return this.callTool('download_binary_file', {\r\n path,\r\n max_bytes: 64 * 1024 * 1024,\r\n as_root: asRoot,\r\n }, signal)\r\n }\r\n}\r\n","import { ProfileProvider, Profile, NewTabParameters, BaseTabComponent } from 'tabby-core'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\n\r\nexport interface BianbuCloudProfile extends Profile {\r\n options: {\r\n kind: 'shell' | 'files'\r\n }\r\n}\r\n\r\n/** @hidden */\r\nexport class BianbuCloudProfileProvider extends ProfileProvider<BianbuCloudProfile> {\r\n id = 'bianbu-cloud'\r\n name = 'Bianbu Cloud'\r\n configDefaults = {}\r\n\r\n async getBuiltinProfiles (): Promise<any[]> {\r\n return [\r\n {\r\n id: 'bianbu-cloud-shell',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Shell',\r\n icon: 'terminal',\r\n color: '#2b6cb0',\r\n group: 'Bianbu Cloud',\r\n disableDynamicTitle: false,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 0,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n options: {\r\n kind: 'shell',\r\n },\r\n },\r\n {\r\n id: 'bianbu-cloud-files',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Files',\r\n icon: 'folder-open',\r\n color: '#0f766e',\r\n group: 'Bianbu Cloud',\r\n disableDynamicTitle: true,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 1,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n options: {\r\n kind: 'files',\r\n },\r\n },\r\n ]\r\n }\r\n\r\n async getNewTabParameters (profile: BianbuCloudProfile): Promise<NewTabParameters<BaseTabComponent>> {\r\n if (profile.options.kind === 'files') {\r\n return {\r\n type: BianbuCloudFilesTabComponent,\r\n inputs: { profile },\r\n }\r\n }\r\n return {\r\n type: BianbuCloudShellTabComponent,\r\n inputs: { profile },\r\n }\r\n }\r\n\r\n getSuggestedName (): string | null {\r\n return null\r\n }\r\n\r\n getDescription (profile: any): string {\r\n if (profile.options?.kind === 'files') {\r\n return 'Explorer-like file access backed by MCP file tools'\r\n }\r\n return 'Terminal-like shell session backed by MCP run_command'\r\n }\r\n}\r\n","import { Component } from '@angular/core'\r\nimport { AppService, ConfigService } from 'tabby-core'\r\nimport { BianbuCloudFilesTabComponent } from './filesTab.component'\r\nimport { BianbuCloudShellTabComponent } from './shellTab.component'\r\n\r\n/** @hidden */\r\n@Component({\r\n template: require('./settingsTab.component.pug'),\r\n})\r\nexport class BianbuMcpSettingsComponent {\r\n constructor (\r\n public config: ConfigService,\r\n private app: AppService,\r\n ) { }\r\n\r\n get sampleJson (): string {\r\n const s = this.config.store.bianbuMcp\r\n return JSON.stringify({\r\n mcpServers: {\r\n [s.name || 'bianbu']: {\r\n type: 'http',\r\n url: s.url || 'https://your-domain.example.com/mcp',\r\n headers: {\r\n 'X-API-KEY': s.apiKey || 'your-x-api-key',\r\n },\r\n },\r\n },\r\n }, null, 2)\r\n }\r\n\r\n save (): void {\r\n this.config.save()\r\n }\r\n\r\n openShell (): void {\r\n this.app.openNewTab({ type: BianbuCloudShellTabComponent })\r\n }\r\n\r\n openFiles (): void {\r\n this.app.openNewTab({ type: BianbuCloudFilesTabComponent })\r\n }\r\n}\r\n","import { Injectable } from '@angular/core'\r\nimport { SettingsTabProvider } from 'tabby-settings'\r\nimport { BianbuMcpSettingsComponent } from './settingsTab.component'\r\n\r\n/** @hidden */\r\n@Injectable()\r\nexport class BianbuMcpSettingsTabProvider extends SettingsTabProvider {\r\n id = 'bianbu-mcp'\r\n icon = 'plug'\r\n title = 'Bianbu MCP'\r\n\r\n getComponentType (): any {\r\n return BianbuMcpSettingsComponent\r\n }\r\n}\r\n","import { BaseSession } from 'tabby-terminal'\r\nimport { Logger } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\n\r\nexport class BianbuShellSession extends BaseSession {\r\n private cwd = '.'\r\n private currentLine = ''\r\n private running = false\r\n private asRoot = false\r\n\r\n constructor (\r\n logger: Logger,\r\n private mcp: BianbuMcpService,\r\n ) {\r\n super(logger)\r\n }\r\n\r\n async start (options: any): Promise<void> {\r\n this.open = true\r\n this.cwd = options?.cwd || '.'\r\n this.asRoot = !!options?.asRoot\r\n this.emitText('Connected to Bianbu Cloud MCP shell\\r\\n')\r\n this.emitPrompt()\r\n }\r\n\r\n resize (_columns: number, _rows: number): void {\r\n // no-op for stateless MCP shell emulation\r\n }\r\n\r\n write (data: Buffer): void {\r\n const text = data.toString('utf-8')\r\n for (const ch of text) {\r\n void this.handleChar(ch)\r\n }\r\n }\r\n\r\n kill (): void {\r\n this.running = false\r\n }\r\n\r\n async gracefullyKillProcess (): Promise<void> {\r\n this.running = false\r\n }\r\n\r\n supportsWorkingDirectory (): boolean {\r\n return true\r\n }\r\n\r\n async getWorkingDirectory (): Promise<string | null> {\r\n return this.cwd\r\n }\r\n\r\n private async handleChar (ch: string): Promise<void> {\r\n if (this.running) {\r\n if (ch === '\\u0003') {\r\n this.emitText('^C\\r\\n')\r\n }\r\n return\r\n }\r\n\r\n if (ch === '\\r' || ch === '\\n') {\r\n const command = this.currentLine\r\n this.currentLine = ''\r\n this.emitText('\\r\\n')\r\n if (command.trim()) {\r\n await this.execute(command)\r\n }\r\n this.emitPrompt()\r\n return\r\n }\r\n\r\n if (ch === '\\u007f' || ch === '\\b') {\r\n if (this.currentLine.length) {\r\n this.currentLine = this.currentLine.slice(0, -1)\r\n this.emitText('\\b \\b')\r\n }\r\n return\r\n }\r\n\r\n if (ch === '\\u0003') {\r\n this.currentLine = ''\r\n this.emitText('^C\\r\\n')\r\n this.emitPrompt()\r\n return\r\n }\r\n\r\n if (ch >= ' ') {\r\n this.currentLine += ch\r\n this.emitText(ch)\r\n }\r\n }\r\n\r\n private async execute (command: string): Promise<void> {\r\n this.running = true\r\n try {\r\n const result = await this.mcp.runCommand(command, this.cwd, 120, this.asRoot)\r\n if (result.stdout) {\r\n this.emitText(this.normalize(result.stdout))\r\n }\r\n if (result.stderr) {\r\n this.emitText(this.normalize(result.stderr))\r\n }\r\n if (result.exit_code !== 0 && !result.stderr) {\r\n this.emitText(`command exited with code ${result.exit_code}\\r\\n`)\r\n }\r\n const detectedCwd = this.extractLastDirectory(result.stdout || '')\r\n if (detectedCwd) {\r\n this.cwd = detectedCwd\r\n }\r\n } catch (error: any) {\r\n this.emitText(this.normalize(String(error?.message || error)))\r\n } finally {\r\n this.running = false\r\n }\r\n }\r\n\r\n private extractLastDirectory (stdout: string): string | null {\r\n const lines = stdout.split(/\\r?\\n/).map(x => x.trim()).filter(Boolean)\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n if (lines[i].startsWith('/')) {\r\n return lines[i]\r\n }\r\n }\r\n return null\r\n }\r\n\r\n private emitPrompt (): void {\r\n const marker = this.asRoot ? '#' : '$'\r\n this.emitText(`[bianbu ${this.cwd}]${marker} `)\r\n }\r\n\r\n private emitText (text: string): void {\r\n this.emitOutput(Buffer.from(text, 'utf-8'))\r\n }\r\n\r\n private normalize (text: string): string {\r\n return text.replace(/\\r?\\n/g, '\\r\\n') + (text.endsWith('\\n') ? '' : '\\r\\n')\r\n }\r\n}\r\n","import { Component, Injector, Input } from '@angular/core'\r\nimport { BaseSession, BaseTerminalTabComponent } from 'tabby-terminal'\r\nimport { NotificationsService } from 'tabby-core'\r\nimport { BianbuMcpService } from './mcp.service'\r\nimport { BianbuShellSession } from './shellSession'\r\nimport { BianbuCloudProfile } from './profileProvider'\r\n\r\n/** @hidden */\r\n@Component({\r\n template: BaseTerminalTabComponent.template,\r\n styles: BaseTerminalTabComponent.styles,\r\n animations: BaseTerminalTabComponent.animations,\r\n})\r\nexport class BianbuCloudShellTabComponent extends BaseTerminalTabComponent<any> {\r\n @Input() profile: BianbuCloudProfile\r\n @Input() asRoot = false\r\n @Input() cwd = '.'\r\n\r\n constructor (\r\n injector: Injector,\r\n private mcp: BianbuMcpService,\r\n protected localNotifications: NotificationsService,\r\n ) {\r\n super(injector)\r\n this.setTitle('Bianbu Cloud Shell')\r\n this.icon = 'terminal'\r\n this.enableToolbar = true\r\n this.profile = this.profile || {\r\n id: 'bianbu-cloud-shell',\r\n type: 'bianbu-cloud',\r\n name: 'Bianbu Cloud Shell',\r\n group: 'Bianbu Cloud',\r\n options: { kind: 'shell' },\r\n icon: 'terminal',\r\n color: '#2b6cb0',\r\n disableDynamicTitle: false,\r\n behaviorOnSessionEnd: 'keep',\r\n weight: 0,\r\n isBuiltin: true,\r\n isTemplate: false,\r\n }\r\n }\r\n\r\n protected async onFrontendReady (): Promise<void> {\r\n const session = new BianbuShellSession(this.logger, this.mcp)\r\n this.setSession(session as BaseSession, true)\r\n await session.start({ cwd: this.cwd, asRoot: this.asRoot })\r\n session.releaseInitialDataBuffer()\r\n this.localNotifications.notice('Bianbu Cloud shell ready')\r\n super.onFrontendReady()\r\n }\r\n}\r\n","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","if(typeof __WEBPACK_EXTERNAL_MODULE_fs__ === 'undefined') { var e = new Error(\"Cannot find module 'fs'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_settings__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_terminal__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\tif (!(moduleId in __webpack_modules__)) {\n\t\tdelete __webpack_module_cache__[moduleId];\n\t\tvar e = new Error(\"Cannot find module '\" + moduleId + \"'\");\n\t\te.code = 'MODULE_NOT_FOUND';\n\t\tthrow e;\n\t}\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/index.ts\");\n",""],"names":[],"sourceRoot":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tabby-bianbu-mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Tabby plugin for Bianbu Cloud shell-like and file-manager-like tabs over MCP",
5
5
  "author": "niver2002",
6
6
  "license": "MIT",