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 +3 -2
- package/dist/index.js +421 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
-
|
|
8
|
-
- a
|
|
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.
|
|
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.
|
|
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.
|
|
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 = `
|
|
685
|
+
this.status = `Opening ${item.path}`;
|
|
686
|
+
this.selectedPath = item.path;
|
|
687
|
+
this.selectedIsText = this.isTextLike(item.path);
|
|
493
688
|
try {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
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
|
-
|
|
528
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
603
|
-
|
|
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.
|
|
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
|
-
|
|
624
|
-
|
|
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,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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=\\\"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<domain>\\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, ''') + '\\'';\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 = '"'; break;\n case 38: escape = '&'; break;\n case 60: escape = '<'; break;\n case 62: escape = '>'; 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 <= 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;};\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<domain>\\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, ''') + '\\'';\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 = '"'; break;\n case 38: escape = '&'; break;\n case 60: escape = '<'; break;\n case 62: escape = '>'; 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":""}
|