tabby-sftp-ui 0.2.2 → 0.2.3
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 +4 -0
- package/dist/index.js +203 -18
- package/dist/index.js.map +1 -1
- package/dist/sftp-manager-tab.component.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,6 +128,10 @@ Then restart Tabby.
|
|
|
128
128
|
|
|
129
129
|
- See [`CHANGELOG.md`](CHANGELOG.md)
|
|
130
130
|
|
|
131
|
+
- **0.2.3**
|
|
132
|
+
- Fix: Remote folders drag-and-drop (Remote → Local) works again.
|
|
133
|
+
- Feature: Replace confirmation is now symmetric (both Local → Remote and Remote → Local).
|
|
134
|
+
- UI: Added “Go up” row to the Local pane.
|
|
131
135
|
- **0.2.2**
|
|
132
136
|
- Integrate Tabby’s native `startUploadFromDragEvent` for more reliable OS drag-and-drop (files & folders).
|
|
133
137
|
- Refine Delete key handling so it works normally inside input dialogs while still triggering delete in lists.
|
package/dist/index.js
CHANGED
|
@@ -309,6 +309,9 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
309
309
|
this.deleteConfirmText = '';
|
|
310
310
|
this.pendingLocalDelete = [];
|
|
311
311
|
this.pendingRemoteDelete = [];
|
|
312
|
+
this.replaceConfirmVisible = false;
|
|
313
|
+
this.replaceConfirmText = '';
|
|
314
|
+
this.replaceConfirmResolve = null;
|
|
312
315
|
this.inputDialogVisible = false;
|
|
313
316
|
this.inputDialogTitle = '';
|
|
314
317
|
this.inputDialogPlaceholder = '';
|
|
@@ -609,17 +612,11 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
609
612
|
const movePayload = sources.map(x => x.fullPath);
|
|
610
613
|
ev.dataTransfer?.setData('application/x-tabby-sftp-ui-remote-move', JSON.stringify(movePayload));
|
|
611
614
|
// Existing cross-device drag (remote -> local) only for files
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
size: item.size,
|
|
618
|
-
mode: item.mode,
|
|
619
|
-
};
|
|
620
|
-
ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload));
|
|
621
|
-
ev.dataTransfer?.setData('text/plain', item.fullPath);
|
|
622
|
-
}
|
|
615
|
+
const payload = item.isDirectory
|
|
616
|
+
? { kind: 'remote-dir', remotePath: item.fullPath, name: item.name }
|
|
617
|
+
: { kind: 'remote-file', remotePath: item.fullPath, name: item.name, size: item.size, mode: item.mode };
|
|
618
|
+
ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload));
|
|
619
|
+
ev.dataTransfer?.setData('text/plain', item.fullPath);
|
|
623
620
|
ev.dataTransfer?.setDragImage?.(ev.target ?? document.body, 0, 0);
|
|
624
621
|
}
|
|
625
622
|
async onDropOnRemote(ev) {
|
|
@@ -636,6 +633,16 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
636
633
|
if (osPaths.length) {
|
|
637
634
|
try {
|
|
638
635
|
for (const p of osPaths) {
|
|
636
|
+
const baseName = path__WEBPACK_IMPORTED_MODULE_0__.basename(p);
|
|
637
|
+
const existing = this.remoteEntries.find(e => e.name === baseName);
|
|
638
|
+
if (existing) {
|
|
639
|
+
const ok = await this.showReplaceConfirm(`Replace existing "${baseName}" on remote?`);
|
|
640
|
+
if (!ok) {
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
const remoteTarget = path__WEBPACK_IMPORTED_MODULE_0__.posix.join(this.remotePath, baseName);
|
|
644
|
+
await this.deleteRemotePathRecursive(remoteTarget);
|
|
645
|
+
}
|
|
639
646
|
await this.uploadLocalPathToRemote(this.remotePath, p);
|
|
640
647
|
}
|
|
641
648
|
await this.refreshRemote();
|
|
@@ -673,6 +680,14 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
673
680
|
}
|
|
674
681
|
try {
|
|
675
682
|
const targetRemotePath = path__WEBPACK_IMPORTED_MODULE_0__.posix.join(this.remotePath, payload.name);
|
|
683
|
+
const existsOnRemote = this.remoteEntries.some(e => e.name === payload.name);
|
|
684
|
+
if (existsOnRemote) {
|
|
685
|
+
const ok = await this.showReplaceConfirm(`Replace existing "${payload.name}" on remote?`);
|
|
686
|
+
if (!ok) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
await this.deleteRemotePathRecursive(targetRemotePath);
|
|
690
|
+
}
|
|
676
691
|
const upload = new _local_transfers__WEBPACK_IMPORTED_MODULE_7__.LocalPathFileUpload(payload.fullPath);
|
|
677
692
|
this.trackTransfer(upload, 'upload', targetRemotePath, payload.fullPath);
|
|
678
693
|
await this.sftpSession.upload(targetRemotePath, upload);
|
|
@@ -685,11 +700,73 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
685
700
|
async onDropOnLocal(ev) {
|
|
686
701
|
ev.preventDefault();
|
|
687
702
|
this.localDropActive = false;
|
|
703
|
+
// 1) Tabby's internal drag (remote -> local download)
|
|
704
|
+
const rawInternal = ev.dataTransfer?.getData('application/x-tabby-sftp-ui');
|
|
705
|
+
if (rawInternal) {
|
|
706
|
+
let payload;
|
|
707
|
+
try {
|
|
708
|
+
payload = JSON.parse(rawInternal);
|
|
709
|
+
}
|
|
710
|
+
catch {
|
|
711
|
+
payload = null;
|
|
712
|
+
}
|
|
713
|
+
if (payload && payload.kind === 'remote-file') {
|
|
714
|
+
try {
|
|
715
|
+
const targetLocalPath = path__WEBPACK_IMPORTED_MODULE_0__.join(this.localPath, payload.name);
|
|
716
|
+
if (!this.sftpSession) {
|
|
717
|
+
throw new Error('Not connected');
|
|
718
|
+
}
|
|
719
|
+
if (fs__WEBPACK_IMPORTED_MODULE_3__.existsSync(targetLocalPath)) {
|
|
720
|
+
const ok = await this.showReplaceConfirm(`Replace existing "${payload.name}"?`);
|
|
721
|
+
if (!ok) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
const dl = new _local_transfers__WEBPACK_IMPORTED_MODULE_7__.LocalPathFileDownload(targetLocalPath, payload.mode, payload.size);
|
|
726
|
+
this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath);
|
|
727
|
+
await this.sftpSession.download(payload.remotePath, dl);
|
|
728
|
+
await this.refreshLocal();
|
|
729
|
+
}
|
|
730
|
+
catch (e) {
|
|
731
|
+
console.error('[SFTP-UI] Download failed', e);
|
|
732
|
+
}
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (payload && payload.kind === 'remote-dir') {
|
|
736
|
+
try {
|
|
737
|
+
if (!this.sftpSession) {
|
|
738
|
+
throw new Error('Not connected');
|
|
739
|
+
}
|
|
740
|
+
const targetLocalPath = path__WEBPACK_IMPORTED_MODULE_0__.join(this.localPath, payload.name);
|
|
741
|
+
if (fs__WEBPACK_IMPORTED_MODULE_3__.existsSync(targetLocalPath)) {
|
|
742
|
+
const ok = await this.showReplaceConfirm(`Replace existing folder "${payload.name}"?`);
|
|
743
|
+
if (!ok) {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
await this.deleteLocalPathRecursive(targetLocalPath);
|
|
747
|
+
}
|
|
748
|
+
await this.downloadRemoteDirectoryRecursive(payload.remotePath, targetLocalPath);
|
|
749
|
+
await this.refreshLocal();
|
|
750
|
+
}
|
|
751
|
+
catch (e) {
|
|
752
|
+
console.error('[SFTP-UI] Download directory failed', e);
|
|
753
|
+
}
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
688
757
|
// Drag & drop from OS file manager into the local pane (copy into current local folder)
|
|
689
758
|
const osPaths = this.getDroppedOsPaths(ev);
|
|
690
759
|
if (osPaths.length) {
|
|
691
760
|
try {
|
|
692
761
|
for (const p of osPaths) {
|
|
762
|
+
const baseName = path__WEBPACK_IMPORTED_MODULE_0__.basename(p);
|
|
763
|
+
const destPath = path__WEBPACK_IMPORTED_MODULE_0__.join(this.localPath, baseName);
|
|
764
|
+
if (fs__WEBPACK_IMPORTED_MODULE_3__.existsSync(destPath)) {
|
|
765
|
+
const ok = await this.showReplaceConfirm(`Replace existing "${baseName}"?`);
|
|
766
|
+
if (!ok) {
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
693
770
|
await this.copyLocalPathIntoLocalDir(this.localPath, p);
|
|
694
771
|
}
|
|
695
772
|
await this.refreshLocal();
|
|
@@ -722,17 +799,41 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
722
799
|
catch {
|
|
723
800
|
return;
|
|
724
801
|
}
|
|
725
|
-
if (payload.kind !== 'remote-file') {
|
|
802
|
+
if (payload.kind !== 'remote-file' && payload.kind !== 'remote-dir') {
|
|
726
803
|
return;
|
|
727
804
|
}
|
|
728
805
|
try {
|
|
729
|
-
|
|
806
|
+
if (payload.kind === 'remote-file') {
|
|
807
|
+
const targetLocalPath = path__WEBPACK_IMPORTED_MODULE_0__.join(this.localPath, payload.name);
|
|
808
|
+
if (!this.sftpSession) {
|
|
809
|
+
throw new Error('Not connected');
|
|
810
|
+
}
|
|
811
|
+
if (fs__WEBPACK_IMPORTED_MODULE_3__.existsSync(targetLocalPath)) {
|
|
812
|
+
const ok = await this.showReplaceConfirm(`Replace existing "${payload.name}"?`);
|
|
813
|
+
if (!ok) {
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
await this.deleteLocalPathRecursive(targetLocalPath);
|
|
817
|
+
}
|
|
818
|
+
const dl = new _local_transfers__WEBPACK_IMPORTED_MODULE_7__.LocalPathFileDownload(targetLocalPath, payload.mode, payload.size);
|
|
819
|
+
this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath);
|
|
820
|
+
await this.sftpSession.download(payload.remotePath, dl);
|
|
821
|
+
await this.refreshLocal();
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
// remote-dir -> local-dir (recursive download)
|
|
730
825
|
if (!this.sftpSession) {
|
|
731
826
|
throw new Error('Not connected');
|
|
732
827
|
}
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
828
|
+
const targetLocalPath = path__WEBPACK_IMPORTED_MODULE_0__.join(this.localPath, payload.name);
|
|
829
|
+
if (fs__WEBPACK_IMPORTED_MODULE_3__.existsSync(targetLocalPath)) {
|
|
830
|
+
const ok = await this.showReplaceConfirm(`Replace existing folder "${payload.name}"?`);
|
|
831
|
+
if (!ok) {
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
await this.deleteLocalPathRecursive(targetLocalPath);
|
|
835
|
+
}
|
|
836
|
+
await this.downloadRemoteDirectoryRecursive(payload.remotePath, targetLocalPath);
|
|
736
837
|
await this.refreshLocal();
|
|
737
838
|
}
|
|
738
839
|
catch (e) {
|
|
@@ -837,11 +938,39 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
837
938
|
}
|
|
838
939
|
}
|
|
839
940
|
}
|
|
941
|
+
async downloadRemoteDirectoryRecursive(remoteDir, localDir) {
|
|
942
|
+
if (!this.sftpSession) {
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
await fs_promises__WEBPACK_IMPORTED_MODULE_2__.mkdir(localDir, { recursive: true });
|
|
946
|
+
const entries = await this.sftpSession.readdir(remoteDir).catch(() => null);
|
|
947
|
+
if (!entries) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
for (const e of entries) {
|
|
951
|
+
const targetLocal = path__WEBPACK_IMPORTED_MODULE_0__.join(localDir, e.name);
|
|
952
|
+
if (e.isDirectory) {
|
|
953
|
+
await this.downloadRemoteDirectoryRecursive(e.fullPath, targetLocal);
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
const dl = new _local_transfers__WEBPACK_IMPORTED_MODULE_7__.LocalPathFileDownload(targetLocal, e.mode, e.size);
|
|
957
|
+
this.trackTransfer(dl, 'download', e.fullPath, targetLocal);
|
|
958
|
+
await this.sftpSession.download(e.fullPath, dl);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
840
962
|
getDroppedOsPaths(ev) {
|
|
841
963
|
const dt = ev.dataTransfer;
|
|
842
964
|
if (!dt) {
|
|
843
965
|
return [];
|
|
844
966
|
}
|
|
967
|
+
const isWin = os__WEBPACK_IMPORTED_MODULE_1__.platform() === 'win32';
|
|
968
|
+
const isLocalPath = (p) => {
|
|
969
|
+
if (isWin) {
|
|
970
|
+
return /^[A-Za-z]:\\/.test(p) || p.startsWith('\\\\');
|
|
971
|
+
}
|
|
972
|
+
return p.startsWith('/');
|
|
973
|
+
};
|
|
845
974
|
// 1) Electron-style File.path
|
|
846
975
|
const filePaths = Array.from(dt.files ?? [])
|
|
847
976
|
.map(f => f.path)
|
|
@@ -866,7 +995,7 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
866
995
|
}
|
|
867
996
|
return x;
|
|
868
997
|
})
|
|
869
|
-
.filter(x => x && (x
|
|
998
|
+
.filter(x => x && isLocalPath(x));
|
|
870
999
|
if (uris.length) {
|
|
871
1000
|
return uris;
|
|
872
1001
|
}
|
|
@@ -885,7 +1014,7 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
885
1014
|
}
|
|
886
1015
|
return x;
|
|
887
1016
|
})
|
|
888
|
-
.filter(x => x
|
|
1017
|
+
.filter(x => x && isLocalPath(x));
|
|
889
1018
|
return textPaths;
|
|
890
1019
|
}
|
|
891
1020
|
getFilteredLocalEntries() {
|
|
@@ -1800,6 +1929,11 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
1800
1929
|
this.cancelDelete();
|
|
1801
1930
|
return;
|
|
1802
1931
|
}
|
|
1932
|
+
if (this.replaceConfirmVisible) {
|
|
1933
|
+
event.preventDefault();
|
|
1934
|
+
this.cancelReplace();
|
|
1935
|
+
return;
|
|
1936
|
+
}
|
|
1803
1937
|
}
|
|
1804
1938
|
if (event.key === 'Delete' || event.key === 'Backspace') {
|
|
1805
1939
|
// Don't intercept Delete/Backspace while typing in inputs
|
|
@@ -1881,6 +2015,37 @@ let SftpManagerTabComponent = class SftpManagerTabComponent extends tabby_core__
|
|
|
1881
2015
|
this.pendingLocalDelete = [];
|
|
1882
2016
|
this.pendingRemoteDelete = [];
|
|
1883
2017
|
}
|
|
2018
|
+
async showReplaceConfirm(text) {
|
|
2019
|
+
if (this.replaceConfirmVisible) {
|
|
2020
|
+
// Prevent stacking multiple confirmations; choose the latest replacement intent.
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
this.replaceConfirmText = text;
|
|
2024
|
+
this.replaceConfirmVisible = true;
|
|
2025
|
+
return new Promise(resolve => {
|
|
2026
|
+
this.replaceConfirmResolve = resolve;
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
async confirmReplace() {
|
|
2030
|
+
if (!this.replaceConfirmVisible) {
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
this.replaceConfirmVisible = false;
|
|
2034
|
+
const resolve = this.replaceConfirmResolve;
|
|
2035
|
+
this.replaceConfirmResolve = null;
|
|
2036
|
+
this.replaceConfirmText = '';
|
|
2037
|
+
resolve?.(true);
|
|
2038
|
+
}
|
|
2039
|
+
cancelReplace() {
|
|
2040
|
+
if (!this.replaceConfirmVisible) {
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
this.replaceConfirmVisible = false;
|
|
2044
|
+
const resolve = this.replaceConfirmResolve;
|
|
2045
|
+
this.replaceConfirmResolve = null;
|
|
2046
|
+
this.replaceConfirmText = '';
|
|
2047
|
+
resolve?.(false);
|
|
2048
|
+
}
|
|
1884
2049
|
async deleteLocalEntry(entry) {
|
|
1885
2050
|
await this.deleteLocalPathRecursive(entry.fullPath);
|
|
1886
2051
|
}
|
|
@@ -2188,6 +2353,16 @@ SftpManagerTabComponent = __decorate([
|
|
|
2188
2353
|
<span class="size sortable" (click)="setLocalSort('size')">Size</span>
|
|
2189
2354
|
<span class="date sortable" (click)="setLocalSort('modified')">Modified</span>
|
|
2190
2355
|
</div>
|
|
2356
|
+
<div
|
|
2357
|
+
class="entry"
|
|
2358
|
+
*ngIf="canLocalUp()"
|
|
2359
|
+
(dblclick)="localUp()"
|
|
2360
|
+
>
|
|
2361
|
+
<span class="icon">⬆</span>
|
|
2362
|
+
<span class="name">Go up</span>
|
|
2363
|
+
<span class="size"></span>
|
|
2364
|
+
<span class="date"></span>
|
|
2365
|
+
</div>
|
|
2191
2366
|
<div
|
|
2192
2367
|
class="entry"
|
|
2193
2368
|
*ngFor="let e of getFilteredLocalEntries()"
|
|
@@ -2366,6 +2541,16 @@ SftpManagerTabComponent = __decorate([
|
|
|
2366
2541
|
</div>
|
|
2367
2542
|
</div>
|
|
2368
2543
|
|
|
2544
|
+
<div class="delete-overlay" *ngIf="replaceConfirmVisible">
|
|
2545
|
+
<div class="delete-dialog">
|
|
2546
|
+
<div class="delete-text">{{ replaceConfirmText }}</div>
|
|
2547
|
+
<div class="delete-buttons">
|
|
2548
|
+
<button class="danger" (click)="confirmReplace()">Replace</button>
|
|
2549
|
+
<button (click)="cancelReplace()">Cancel</button>
|
|
2550
|
+
</div>
|
|
2551
|
+
</div>
|
|
2552
|
+
</div>
|
|
2553
|
+
|
|
2369
2554
|
<div class="delete-overlay" *ngIf="inputDialogVisible">
|
|
2370
2555
|
<div class="delete-dialog" (click)="$event.stopPropagation()">
|
|
2371
2556
|
<div class="delete-text">{{ inputDialogTitle }}</div>
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","mappings":"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","sources":["webpack-tabby-sftp-ui:///webpack/universalModuleDefinition","webpack-tabby-sftp-ui:///./src/local-transfers.ts","webpack-tabby-sftp-ui:///./src/sftp-context-menu.ts","webpack-tabby-sftp-ui:///./src/sftp-hotkey.ts","webpack-tabby-sftp-ui:///./src/sftp-manager-tab.component.ts","webpack-tabby-sftp-ui:///./src/sftp-terminal-decorator.ts","webpack-tabby-sftp-ui:///./src/sftp-ui.service.ts","webpack-tabby-sftp-ui:///./src/sftp.service.ts","webpack-tabby-sftp-ui:///external node-commonjs \"crypto\"","webpack-tabby-sftp-ui:///external node-commonjs \"fs/promises\"","webpack-tabby-sftp-ui:///external node-commonjs \"os\"","webpack-tabby-sftp-ui:///external umd \"@angular/common\"","webpack-tabby-sftp-ui:///external umd \"@angular/core\"","webpack-tabby-sftp-ui:///external umd \"@angular/forms\"","webpack-tabby-sftp-ui:///external umd \"fs\"","webpack-tabby-sftp-ui:///external umd \"path\"","webpack-tabby-sftp-ui:///external umd \"tabby-core\"","webpack-tabby-sftp-ui:///external umd \"tabby-terminal\"","webpack-tabby-sftp-ui:///webpack/bootstrap","webpack-tabby-sftp-ui:///webpack/runtime/compat get default export","webpack-tabby-sftp-ui:///webpack/runtime/define property getters","webpack-tabby-sftp-ui:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-sftp-ui:///webpack/runtime/make namespace object","webpack-tabby-sftp-ui:///./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/forms\", \"@angular/core\", \"tabby-core\", \"tabby-terminal\", \"path\", \"fs\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\")) : factory(root[\"@angular/common\"], root[\"@angular/forms\"], root[\"@angular/core\"], root[\"tabby-core\"], root[\"tabby-terminal\"], root[\"path\"], root[\"fs\"]);\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_forms__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_fs__) => {\nreturn ","import * as fs from 'fs'\r\nimport * as path from 'path'\r\n\r\nimport { FileDownload, FileUpload } from 'tabby-core'\r\n\r\nexport class LocalPathFileUpload extends FileUpload {\r\n private fd: number | null = null\r\n private position = 0\r\n\r\n constructor (private filePath: string) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.filePath)\r\n }\r\n\r\n getMode (): number {\r\n return 0o644\r\n }\r\n\r\n getSize (): number {\r\n try {\r\n return fs.statSync(this.filePath).size\r\n } catch {\r\n return 0\r\n }\r\n }\r\n\r\n async read (): Promise<Buffer> {\r\n if (this.isCancelled()) {\r\n return Buffer.alloc(0)\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.filePath, 'r')\r\n }\r\n const buf = Buffer.allocUnsafe(256 * 1024)\r\n const bytesRead = fs.readSync(this.fd, buf, 0, buf.length, this.position)\r\n if (!bytesRead) {\r\n return Buffer.alloc(0)\r\n }\r\n this.position += bytesRead\r\n this.increaseProgress(bytesRead)\r\n return buf.subarray(0, bytesRead)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\nexport class LocalPathFileDownload extends FileDownload {\r\n private fd: number | null = null\r\n\r\n constructor (private targetPath: string, private mode: number, private size: number) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.targetPath)\r\n }\r\n\r\n getMode (): number {\r\n return this.mode\r\n }\r\n\r\n getSize (): number {\r\n return this.size\r\n }\r\n\r\n async write (buffer: Buffer): Promise<void> {\r\n if (this.isCancelled()) {\r\n return\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.targetPath, 'w')\r\n }\r\n fs.writeSync(this.fd, buffer)\r\n this.increaseProgress(buffer.length)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TabContextMenuItemProvider } from 'tabby-core'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpContextMenuProvider extends TabContextMenuItemProvider {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n async getItems (): Promise<Array<{ label: string, click: () => void }>> {\r\n return [\r\n {\r\n label: 'Open SFTP UI',\r\n click: () => this.sftpUi.open(),\r\n },\r\n ]\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { HotkeyProvider } from 'tabby-core'\r\n\r\n@Injectable()\r\nexport class SftpUiHotkeyProvider extends HotkeyProvider {\r\n async provide (): Promise<Array<{ id: string, name: string }>> {\r\n return [\r\n { id: 'open-sftp-ui', name: 'Open SFTP UI' },\r\n ]\r\n }\r\n}\r\n\r\n","import * as path from 'path'\nimport * as os from 'os'\nimport * as fs from 'fs/promises'\nimport * as fsSync from 'fs'\nimport * as crypto from 'crypto'\n\nimport { Component, Injector, OnInit, HostListener } from '@angular/core'\nimport { AppService, BaseTabComponent, FileTransfer, FileUpload, PlatformService, ProfilesService } from 'tabby-core'\n\nimport { LocalPathFileDownload, LocalPathFileUpload } from './local-transfers'\nimport { SftpConnectionService, SFTPFile, SFTPSessionLike, SSHSessionLike } from './sftp.service'\n\ntype LocalEntry = {\n name: string\n fullPath: string\n isDirectory: boolean\n size?: number\n mtimeMs?: number\n}\n\ntype DragPayload =\n | { kind: 'local-file', fullPath: string, name: string }\n | { kind: 'remote-file', remotePath: string, name: string, size: number, mode: number }\n\n@Component({\n selector: 'tabby-sftp-manager-tab',\n template: `\n <div class=\"sftp-root\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\n <div class=\"top-profiles\" *ngIf=\"profile || recentProfiles.length\">\n <div class=\"current\" *ngIf=\"profile\">\n <span class=\"label\">Device:</span>\n <span class=\"value\">{{ getProfileLabel(profile) }}</span>\n </div>\n <div class=\"recent\" *ngIf=\"recentProfiles.length\">\n <span class=\"label\">Recent:</span>\n <button\n class=\"profile-chip\"\n *ngFor=\"let p of recentProfiles\"\n (click)=\"launchProfileFromSFTP(p)\"\n >\n {{ getProfileLabel(p) }}\n </button>\n </div>\n </div>\n <div class=\"sftp-body\">\n <div class=\"pane\">\n <div class=\"pane-title\">\n <div class=\"pane-label\">Local</div>\n <div class=\"pane-path\">\n <input\n [(ngModel)]=\"localPathInput\"\n (keyup.enter)=\"goToLocalPathInput()\"\n />\n </div>\n <div class=\"pane-actions\">\n <select class=\"path-preset\" (change)=\"onLocalPresetChange($event.target.value)\">\n <option value=\"\">Go to…</option>\n <option *ngFor=\"let p of localPathPresets\" [value]=\"p.id\">\n {{ p.label }}\n </option>\n </select>\n <button\n class=\"fav-toggle\"\n [class.active]=\"isCurrentFavorite()\"\n (click)=\"toggleCurrentFavorite()\"\n title=\"Toggle favorite for this path\"\n >\n ★\n </button>\n <select class=\"path-favorite\" (change)=\"onLocalFavoriteSelect($event.target.value)\">\n <option value=\"\">Favorites…</option>\n <option *ngFor=\"let f of localFavorites\" [value]=\"f.id\">\n {{ f.label }}\n </option>\n </select>\n <button (click)=\"localUp()\" [disabled]=\"!canLocalUp()\">Up</button>\n <button (click)=\"goToLocalPathInput()\">Go</button>\n <button (click)=\"refreshLocal()\">Refresh</button>\n </div>\n </div>\n <div class=\"pane-filters\">\n <div class=\"breadcrumbs\">\n <ng-container *ngFor=\"let part of getLocalBreadcrumbs(); let i = index; let last = last\">\n <button\n class=\"crumb-button\"\n (click)=\"navigateLocalBreadcrumb(i)\"\n (contextmenu)=\"onLocalBreadcrumbContextMenu(i, $event)\"\n >\n {{ part.label }}\n </button>\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\n </ng-container>\n </div>\n <input [(ngModel)]=\"localFilter\" placeholder=\"Filter files...\" />\n <label class=\"show-hidden-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenLocal\" />\n <span>Show hidden</span>\n </label>\n </div>\n <div class=\"pane-list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDropOnLocal($event)\"\n >\n <div class=\"entry header\">\n <span class=\"icon\"></span>\n <span class=\"name sortable\" (click)=\"setLocalSort('name')\">Name</span>\n <span class=\"size sortable\" (click)=\"setLocalSort('size')\">Size</span>\n <span class=\"date sortable\" (click)=\"setLocalSort('modified')\">Modified</span>\n </div>\n <div\n class=\"entry\"\n *ngFor=\"let e of getFilteredLocalEntries()\"\n (click)=\"selectLocal(e, $event)\"\n (dblclick)=\"openLocal(e)\"\n (mousedown)=\"onLocalMouseDown(e, $event)\"\n (contextmenu)=\"onLocalContextMenu(e, $event)\"\n (dragover)=\"onLocalEntryDragOver(e, $event)\"\n (drop)=\"onLocalEntryDrop(e, $event)\"\n [class.drop-target]=\"localDropActive\"\n [class.selected]=\"isLocalSelected(e)\"\n [draggable]=\"true\"\n (dragstart)=\"onDragStartLocal($event, e)\"\n >\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\n <span class=\"name\">{{ e.name }}</span>\n <span class=\"size\">{{ getLocalSizeDisplay(e) }}</span>\n <span class=\"date\">{{ e.mtimeMs ? (e.mtimeMs | date:'yyyy-MM-dd HH:mm') : '' }}</span>\n </div>\n </div>\n <div class=\"pane-actions-bar\">\n <div class=\"selection\" *ngIf=\"selectedLocal.length\">\n Selected: {{ selectedLocal.length === 1 ? selectedLocal[0].name : (selectedLocal.length + ' items') }}\n </div>\n <div class=\"action-inputs\">\n <input [(ngModel)]=\"localActionName\" placeholder=\"Name / new name\" />\n <input [(ngModel)]=\"localActionPerms\" placeholder=\"Perms (e.g. 755)\" />\n </div>\n <div class=\"action-buttons\">\n <button (click)=\"localRename()\" [disabled]=\"selectedLocal.length !== 1\">Rename</button>\n <button (click)=\"refreshLocal()\">Refresh</button>\n <button (click)=\"localDelete()\" [disabled]=\"!selectedLocal.length\">Delete</button>\n <button (click)=\"localNewFolder()\">New Folder</button>\n <button (click)=\"localEditPermissions()\" [disabled]=\"selectedLocal.length !== 1 || !localActionPerms\">Edit Permissions</button>\n <button (click)=\"localShowSize()\" [disabled]=\"selectedLocal.length !== 1 || !selectedLocal[0].isDirectory\">Show Size</button>\n </div>\n </div>\n </div>\n\n <div class=\"pane\">\n <div class=\"pane-title\">\n <div class=\"pane-label\">\n Remote\n <span *ngIf=\"connected && profile?.options?.host\" class=\"pane-sub\">\n — {{ profile.options.host }}\n </span>\n </div>\n <div class=\"pane-path\">\n <input\n [(ngModel)]=\"remotePathInput\"\n (keyup.enter)=\"goToRemotePathInput()\"\n [disabled]=\"!connected\"\n />\n </div>\n <div class=\"pane-actions\">\n <button (click)=\"remoteUp()\" [disabled]=\"!connected || remotePath === '/'\">Up</button>\n <button (click)=\"goToRemotePathInput()\" [disabled]=\"!connected\">Go</button>\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\n </div>\n </div>\n <div class=\"pane-filters\">\n <div class=\"breadcrumbs\" *ngIf=\"connected\">\n <ng-container *ngFor=\"let part of getRemoteBreadcrumbs(); let i = index; let last = last\">\n <button\n class=\"crumb-button\"\n (click)=\"navigateRemoteBreadcrumb(i)\"\n >\n {{ part.label }}\n </button>\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\n </ng-container>\n </div>\n <input [(ngModel)]=\"remoteFilter\" placeholder=\"Filter files...\" />\n <label class=\"show-hidden-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenRemote\" />\n <span>Show hidden</span>\n </label>\n </div>\n <div class=\"pane-list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDropOnRemote($event)\"\n >\n <div class=\"entry dim\" *ngIf=\"!connected\">\n <span class=\"name\">Not connected</span>\n </div>\n <div class=\"entry header\" *ngIf=\"connected\">\n <span class=\"icon\"></span>\n <span class=\"name sortable\" (click)=\"setRemoteSort('name')\">Name</span>\n <span class=\"size sortable\" (click)=\"setRemoteSort('size')\">Size</span>\n <span class=\"date sortable\" (click)=\"setRemoteSort('modified')\">Modified</span>\n </div>\n <div\n class=\"entry\"\n *ngIf=\"connected && remotePath !== '/'\"\n (dblclick)=\"remoteUp()\"\n >\n <span class=\"icon\">⬆</span>\n <span class=\"name\">Go up</span>\n <span class=\"size\"></span>\n <span class=\"date\"></span>\n </div>\n <div\n class=\"entry\"\n *ngFor=\"let e of getFilteredRemoteEntries()\"\n (click)=\"selectRemote(e, $event)\"\n (dblclick)=\"openRemote(e)\"\n (mousedown)=\"onRemoteMouseDown(e, $event)\"\n (contextmenu)=\"onRemoteContextMenu(e, $event)\"\n (dragover)=\"onRemoteEntryDragOver(e, $event)\"\n (drop)=\"onRemoteEntryDrop(e, $event)\"\n [class.drop-target]=\"remoteDropActive\"\n [class.selected]=\"isRemoteSelected(e)\"\n [draggable]=\"connected\"\n (dragstart)=\"onDragStartRemote($event, e)\"\n >\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\n <span class=\"name\">{{ e.name }}</span>\n <span class=\"size\">{{ getRemoteSizeDisplay(e) }}</span>\n <span class=\"date\">{{ e.modified | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n </div>\n <div class=\"pane-actions-bar\">\n <div class=\"selection\" *ngIf=\"selectedRemote.length\">\n Selected: {{ selectedRemote.length === 1 ? selectedRemote[0].name : (selectedRemote.length + ' items') }}\n </div>\n <div class=\"action-inputs\">\n <input [(ngModel)]=\"remoteActionName\" placeholder=\"Name / new name\" />\n <input [(ngModel)]=\"remoteActionPerms\" placeholder=\"Perms (e.g. 755)\" />\n </div>\n <div class=\"action-buttons\">\n <button (click)=\"remoteRename()\" [disabled]=\"selectedRemote.length !== 1\">Rename</button>\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\n <button (click)=\"remoteDelete()\" [disabled]=\"!selectedRemote.length\">Delete</button>\n <button (click)=\"remoteNewFolder()\" [disabled]=\"!connected\">New Folder</button>\n <button (click)=\"remoteEditPermissions()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionPerms\">Edit Permissions</button>\n <button (click)=\"remoteShowSize()\" [disabled]=\"selectedRemote.length !== 1 || !selectedRemote[0].isDirectory\">Show Size</button>\n <button (click)=\"remoteDownload()\" [disabled]=\"!selectedRemote.length\">Download</button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"sftp-transfers\" *ngIf=\"transfers.length\">\n <div class=\"transfer\" *ngFor=\"let t of transfers\">\n <div class=\"transfer-main\">\n <div class=\"transfer-title\">\n <span class=\"direction\">{{ t.direction === 'upload' ? 'Upload' : 'Download' }}</span>\n <span class=\"name\">{{ t.name }}</span>\n </div>\n <div class=\"transfer-path\">\n <span class=\"label\">Remote:</span>\n <span class=\"value\">{{ t.remotePath }}</span>\n </div>\n <div class=\"transfer-path\">\n <span class=\"label\">Local:</span>\n <span class=\"value\">{{ t.localPath }}</span>\n </div>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"getTransferProgress(t.transfer)\"></div>\n </div>\n </div>\n <div class=\"transfer-stats\">\n <div class=\"percent\">{{ getTransferProgress(t.transfer) | number:'1.0-0' }}%</div>\n <div class=\"speed\">{{ formatSpeed(t.transfer.getSpeed()) }}</div>\n <button class=\"btn-cancel\" (click)=\"cancelTransfer(t)\" [disabled]=\"t.transfer.isComplete() || t.transfer.isCancelled()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div class=\"delete-overlay\" *ngIf=\"deleteConfirmVisible\">\n <div class=\"delete-dialog\">\n <div class=\"delete-text\">{{ deleteConfirmText }}</div>\n <div class=\"delete-buttons\">\n <button class=\"danger\" (click)=\"confirmDelete()\">Delete</button>\n <button (click)=\"cancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div class=\"delete-overlay\" *ngIf=\"inputDialogVisible\">\n <div class=\"delete-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-text\">{{ inputDialogTitle }}</div>\n <input\n class=\"dialog-input\"\n [(ngModel)]=\"inputDialogValue\"\n [placeholder]=\"inputDialogPlaceholder\"\n (keyup.enter)=\"confirmInputDialog()\"\n />\n <div class=\"delete-buttons\">\n <button class=\"danger\" (click)=\"confirmInputDialog()\" [disabled]=\"!inputDialogValue.trim()\">OK</button>\n <button (click)=\"cancelInputDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div\n class=\"local-menu\"\n *ngIf=\"localMenuVisible\"\n [style.left.px]=\"localMenuX\"\n [style.top.px]=\"localMenuY\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"local-menu-item\" *ngFor=\"let item of localMenuItems\" (click)=\"onLocalMenuItemClick(item)\">\n {{ item.label }}\n </div>\n </div>\n </div>\n `,\n styles: [`\n .sftp-root { display: flex; flex-direction: column; height: 100%; padding: 10px; gap: 10px; position: relative; }\n button { padding: 6px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.06); color: inherit; cursor: pointer; }\n button:disabled { opacity: 0.5; cursor: default; }\n .top-profiles { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px 8px; gap: 12px; font-size: 11px; opacity: 0.9; }\n .top-profiles .current .label,\n .top-profiles .recent .label { text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.7; margin-right: 4px; }\n .top-profiles .value { font-weight: 600; }\n .top-profiles .profile-chip { padding: 2px 8px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\n .top-profiles .profile-chip:hover { background: rgba(255,255,255,0.12); }\n .sftp-body { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; flex: 1; min-height: 0; }\n .pane { display: flex; flex-direction: column; border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; overflow: hidden; min-height: 0; }\n .pane-title { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; padding: 8px 10px; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); }\n .pane-label { font-weight: 600; display: flex; align-items: baseline; gap: 6px; }\n .pane-sub { font-weight: 400; font-size: 11px; opacity: 0.75; }\n .pane-path { opacity: 0.8; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .pane-path input { width: 100%; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-family: inherit; font-size: 12px; }\n .pane-actions { display: flex; gap: 8px; align-items: center; }\n .pane-actions .path-preset,\n .pane-actions .path-favorite { max-width: 150px; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.22); background: rgba(20,20,20,0.95); color: inherit; font-size: 11px; }\n .pane-actions .path-preset option { background: #151515; color: #f5f5f5; }\n .pane-actions .path-favorite option { background: #151515; color: #f5f5f5; }\n .pane-actions .fav-toggle { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.05); font-size: 11px; line-height: 1; }\n .pane-actions .fav-toggle.active { background: rgba(255,215,0,0.2); border-color: rgba(255,215,0,0.6); color: #ffd700; }\n .pane-filters { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.12); }\n .pane-filters input { flex: 1; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 12px; }\n .show-hidden-toggle { display: flex; align-items: center; gap: 4px; font-size: 11px; opacity: 0.8; white-space: nowrap; }\n .show-hidden-toggle input[type=\"checkbox\"] { margin: 0; }\n .breadcrumbs { display: flex; flex-wrap: wrap; gap: 4px; font-size: 11px; opacity: 0.9; align-items: center; }\n .crumb-button { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\n .crumb-button:hover { background: rgba(255,255,255,0.10); }\n .crumb-separator { opacity: 0.6; }\n .pane-list { flex: 1; overflow: auto; padding: 4px; }\n .entry { display: grid; grid-template-columns: 24px minmax(0, 1.5fr) 80px 140px; gap: 8px; padding: 6px 8px; border-radius: 8px; user-select: none; align-items: center; }\n .entry:hover { background: rgba(255,255,255,0.06); }\n .entry.drop-target { outline: 1px dashed rgba(255,255,255,0.35); background: rgba(80, 160, 255, 0.10); }\n .entry.dim { opacity: 0.7; }\n .icon { text-align: center; opacity: 0.85; }\n .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .size { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; text-align: right; opacity: 0.8; }\n .date { font-size: 11px; opacity: 0.75; text-align: right; white-space: nowrap; }\n .entry.header { font-weight: 600; opacity: 0.9; background: rgba(255,255,255,0.02); }\n .sortable { cursor: pointer; }\n .entry.selected { background: rgba(80,160,255,0.18); }\n .pane-actions-bar { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border-top: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.18); }\n .pane-actions-bar .selection { font-size: 11px; opacity: 0.85; }\n .pane-actions-bar .action-inputs { display: flex; gap: 6px; }\n .pane-actions-bar .action-inputs input { flex: 1; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 11px; }\n .pane-actions-bar .action-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }\n .sftp-transfers { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; max-height: 120px; overflow-y: auto; }\n .transfer { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 6px 8px; border-radius: 8px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); font-size: 11px; }\n .transfer-title { display: flex; gap: 6px; align-items: baseline; margin-bottom: 2px; }\n .transfer-title .direction { text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; font-weight: 600; font-size: 10px; }\n .transfer-title .name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .transfer-path { display: flex; gap: 4px; opacity: 0.75; }\n .transfer-path .label { min-width: 48px; }\n .transfer-path .value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\n .bar { position: relative; height: 4px; border-radius: 999px; background: rgba(255,255,255,0.07); margin-top: 4px; overflow: hidden; }\n .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: inherit; background: linear-gradient(90deg, #4dabff, #78ffce); transition: width 0.15s linear; }\n .transfer-stats { display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 4px; opacity: 0.8; }\n .transfer-stats .percent { font-weight: 600; }\n .transfer-stats .speed { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\n .btn-cancel { padding: 2px 6px; font-size: 10px; border-radius: 999px; }\n .delete-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; z-index: 20; }\n .delete-dialog { min-width: 260px; max-width: 360px; padding: 14px 16px; border-radius: 10px; background: rgba(20,20,20,0.96); border: 1px solid rgba(255,255,255,0.15); box-shadow: 0 18px 45px rgba(0,0,0,0.75); display: flex; flex-direction: column; gap: 10px; }\n .delete-text { font-size: 13px; }\n .dialog-input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 13px; }\n .delete-buttons { display: flex; justify-content: flex-end; gap: 8px; }\n .delete-buttons .danger { background: rgba(255,80,80,0.85); border-color: rgba(255,120,120,0.85); }\n .local-menu { position: absolute; min-width: 180px; max-width: 260px; max-height: 260px; overflow-y: auto; padding: 4px 0; border-radius: 10px; background: rgba(18,18,22,0.98); border: 1px solid rgba(255,255,255,0.16); box-shadow: 0 18px 45px rgba(0,0,0,0.8); z-index: 30; backdrop-filter: blur(12px); }\n .local-menu-item { padding: 6px 12px; font-size: 12px; cursor: pointer; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }\n .local-menu-item:hover { background: linear-gradient(90deg, rgba(120,200,255,0.24), rgba(120,255,206,0.15)); }\n `],\n})\nexport class SftpManagerTabComponent extends BaseTabComponent implements OnInit {\n // injected from the SSH tab when opened via SFTP-UI button\n sshSession: SSHSessionLike | null = null\n profile: any = null\n\n connecting = false\n connected = false\n\n // legacy UI fields kept for now (not used when opened from SSH tab)\n host = ''\n port = 22\n username = ''\n password = ''\n\n localPath = os.homedir()\n localEntries: LocalEntry[] = []\n\n remotePath = '/'\n remoteEntries: SFTPFile[] = []\n\n private sftpSession: SFTPSessionLike | null = null\n\n localDropActive = false\n remoteDropActive = false\n\n transfers: Array<{\n transfer: FileTransfer\n direction: 'upload' | 'download'\n name: string\n remotePath: string\n localPath: string\n }> = []\n\n private transfersTimer: number | null = null\n localFilter = ''\n remoteFilter = ''\n remotePathInput = this.remotePath\n localPathInput = this.localPath\n private localFolderSizeLoading: Set<string> = new Set()\n private remoteFolderSizeLoading: Set<string> = new Set()\n private localSortBy: 'name' | 'size' | 'modified' = 'name'\n private localSortAsc = true\n private remoteSortBy: 'name' | 'size' | 'modified' = 'name'\n private remoteSortAsc = true\n private localCache: {\n entriesRef: LocalEntry[]\n filter: string\n showHidden: boolean\n sortBy: 'name' | 'size' | 'modified'\n asc: boolean\n result: LocalEntry[]\n } | null = null\n private remoteCache: {\n entriesRef: SFTPFile[]\n filter: string\n showHidden: boolean\n sortBy: 'name' | 'size' | 'modified'\n asc: boolean\n result: SFTPFile[]\n } | null = null\n showHiddenLocal = false\n showHiddenRemote = false\n selectedLocal: LocalEntry[] = []\n selectedRemote: SFTPFile[] = []\n localActionName = ''\n localActionPerms = ''\n remoteActionName = ''\n remoteActionPerms = ''\n private localLastSelectedIndex: number | null = null\n private remoteLastSelectedIndex: number | null = null\n\n deleteConfirmVisible = false\n deleteConfirmMode: 'local' | 'remote' | null = null\n deleteConfirmText = ''\n private pendingLocalDelete: LocalEntry[] = []\n private pendingRemoteDelete: SFTPFile[] = []\n\n inputDialogVisible = false\n inputDialogTitle = ''\n inputDialogPlaceholder = ''\n inputDialogValue = ''\n private inputDialogMode: 'local-new-folder' | 'remote-new-folder' | 'local-rename' | 'remote-rename' | null = null\n private inputDialogTargetPath: string | null = null\n private inputDialogRemotePath: string | null = null\n private platform!: PlatformService\n private openedRemoteFiles: Map<string, {\n remotePath: string\n mode: number\n watcher: fsSync.FSWatcher | null\n debounceTimer: number | null\n syncing: boolean\n pending: boolean\n lastUploadedSignature: string | null\n }> = new Map()\n localPathPresets: Array<{ id: string, label: string, path: string }> = []\n localFavorites: Array<{ id: string, label: string, path: string }> = []\n recentProfiles: any[] = []\n localMenuVisible = false\n localMenuX = 0\n localMenuY = 0\n localMenuItems: Array<{ label: string, path: string }> = []\n\n constructor (\n injector: Injector,\n private sftp: SftpConnectionService,\n private profilesService: ProfilesService,\n private app: AppService,\n ) {\n // Tabby runtime BaseTabComponent expects Injector in constructor, but typings in this SDK may differ.\n // @ts-expect-error runtime-compatible super(injector)\n super(injector)\n this.platform = injector.get(PlatformService as any)\n\n // build local path presets (similar to Termius quick locations)\n const home = os.homedir()\n this.localPathPresets.push({ id: 'home', label: 'Home', path: home })\n const desktop = path.join(home, 'Desktop')\n const documents = path.join(home, 'Documents')\n const downloads = path.join(home, 'Downloads')\n if (fsSync.existsSync(desktop)) {\n this.localPathPresets.push({ id: 'desktop', label: 'Desktop', path: desktop })\n }\n if (fsSync.existsSync(documents)) {\n this.localPathPresets.push({ id: 'documents', label: 'Documents', path: documents })\n }\n if (fsSync.existsSync(downloads)) {\n this.localPathPresets.push({ id: 'downloads', label: 'Downloads', path: downloads })\n }\n\n this.loadLocalFavorites()\n void this.refreshLocal()\n\n this.transfersTimer = window.setInterval(() => {\n this.transfers = this.transfers.filter(t => !t.transfer.isComplete() && !t.transfer.isCancelled())\n }, 1000)\n }\n\n ngOnInit (): void {\n // If there's no live SSH session, this tab was likely restored across\n // restart or opened in an invalid context. Close it immediately to avoid\n // an empty, nameless SFTP tab lingering after restart.\n if (!this.sshSession) {\n try {\n this.app.closeTab(this)\n } catch (e) {\n console.error('[SFTP-UI] Failed to close invalid SFTP tab', e)\n }\n return\n }\n\n this.remotePathInput = this.remotePath\n this.localPathInput = this.localPath\n if (this.sshSession) {\n void this.connect()\n }\n this.loadRecentProfiles()\n }\n\n async connect (): Promise<void> {\n if (this.connecting || this.connected) {\n return\n }\n if (!this.sshSession) {\n console.error('[SFTP-UI] No SSH session on current tab')\n return\n }\n this.connecting = true\n try {\n this.sftpSession = await this.sftp.openFromSSHSession(this.sshSession)\n this.connected = true\n this.remotePath = this.getDefaultRemotePath()\n this.remotePathInput = this.remotePath\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] SFTP connection failed', e)\n } finally {\n this.connecting = false\n }\n }\n\n async disconnect (): Promise<void> {\n this.sftpSession = null\n this.connected = false\n this.remoteEntries = []\n }\n\n canLocalUp (): boolean {\n const parent = path.dirname(this.localPath)\n return parent !== this.localPath\n }\n\n localUp (): void {\n const parent = path.dirname(this.localPath)\n if (parent !== this.localPath) {\n this.localPath = parent\n this.localPathInput = this.localPath\n void this.refreshLocal()\n }\n }\n\n remoteUp (): void {\n if (!this.connected || this.remotePath === '/') {\n return\n }\n const next = path.posix.dirname(this.remotePath)\n this.remotePath = next === '.' ? '/' : next\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n }\n\n async refreshLocal (): Promise<void> {\n try {\n const names = await fs.readdir(this.localPath)\n const entries: LocalEntry[] = []\n for (const name of names) {\n const fullPath = path.join(this.localPath, name)\n try {\n const st = await fs.stat(fullPath)\n entries.push({\n name,\n fullPath,\n isDirectory: st.isDirectory(),\n size: st.size,\n mtimeMs: st.mtimeMs,\n })\n } catch {\n // ignore entries that disappeared\n }\n }\n this.localEntries = entries\n } catch (e) {\n console.error('[SFTP-UI] Local listing failed', e)\n }\n }\n\n async refreshRemote (): Promise<void> {\n if (!this.connected) {\n return\n }\n try {\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n this.remoteEntries = await this.sftpSession.readdir(this.remotePath)\n } catch (e) {\n console.error('[SFTP-UI] Remote listing failed', e)\n }\n }\n\n openLocal (e: LocalEntry): void {\n if (!e.isDirectory) {\n return\n }\n this.localPath = e.fullPath\n this.localPathInput = this.localPath\n void this.refreshLocal()\n }\n\n openRemote (e: SFTPFile): void {\n if (!this.connected) {\n return\n }\n if (e.isDirectory) {\n this.remotePath = e.fullPath\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n } else {\n void this.openRemoteFile(e)\n }\n }\n\n onDragOver (ev: DragEvent): void {\n ev.preventDefault()\n }\n\n onLocalMouseDown (entry: LocalEntry, event: MouseEvent): void {\n if (event.button === 2) {\n this.onLocalContextMenu(entry, event)\n }\n }\n\n onRemoteMouseDown (entry: SFTPFile, event: MouseEvent): void {\n if (event.button === 2) {\n this.onRemoteContextMenu(entry, event)\n }\n }\n\n selectLocal (entry: LocalEntry, event: MouseEvent): void {\n const list = this.getFilteredLocalEntries()\n const index = list.indexOf(entry)\n if (index === -1) {\n return\n }\n const isCtrl = event.ctrlKey || event.metaKey\n const isShift = event.shiftKey\n if (isShift && this.localLastSelectedIndex != null) {\n const [from, to] = this.localLastSelectedIndex < index\n ? [this.localLastSelectedIndex, index]\n : [index, this.localLastSelectedIndex]\n const range = list.slice(from, to + 1)\n const set = new Set(this.selectedLocal)\n for (const e of range) {\n set.add(e)\n }\n this.selectedLocal = Array.from(set)\n } else if (isCtrl) {\n const exists = this.selectedLocal.includes(entry)\n if (exists) {\n this.selectedLocal = this.selectedLocal.filter(e => e !== entry)\n } else {\n this.selectedLocal = [...this.selectedLocal, entry]\n }\n this.localLastSelectedIndex = index\n } else {\n this.selectedLocal = [entry]\n this.localLastSelectedIndex = index\n }\n if (this.selectedLocal.length === 1) {\n this.localActionName = this.selectedLocal[0].name\n }\n }\n\n isLocalSelected (entry: LocalEntry): boolean {\n return this.selectedLocal.includes(entry)\n }\n\n selectRemote (entry: SFTPFile, event: MouseEvent): void {\n const list = this.getFilteredRemoteEntries()\n const index = list.indexOf(entry)\n if (index === -1) {\n return\n }\n const isCtrl = event.ctrlKey || event.metaKey\n const isShift = event.shiftKey\n if (isShift && this.remoteLastSelectedIndex != null) {\n const [from, to] = this.remoteLastSelectedIndex < index\n ? [this.remoteLastSelectedIndex, index]\n : [index, this.remoteLastSelectedIndex]\n const range = list.slice(from, to + 1)\n const set = new Set(this.selectedRemote)\n for (const e of range) {\n set.add(e)\n }\n this.selectedRemote = Array.from(set)\n } else if (isCtrl) {\n const exists = this.selectedRemote.includes(entry)\n if (exists) {\n this.selectedRemote = this.selectedRemote.filter(e => e !== entry)\n } else {\n this.selectedRemote = [...this.selectedRemote, entry]\n }\n this.remoteLastSelectedIndex = index\n } else {\n this.selectedRemote = [entry]\n this.remoteLastSelectedIndex = index\n }\n if (this.selectedRemote.length === 1) {\n this.remoteActionName = this.selectedRemote[0].name\n const currentPerms = (this.selectedRemote[0].mode & 0o777).toString(8)\n this.remoteActionPerms = currentPerms\n }\n }\n\n isRemoteSelected (entry: SFTPFile): boolean {\n return this.selectedRemote.includes(entry)\n }\n\n setLocalSort (field: 'name' | 'size' | 'modified'): void {\n if (this.localSortBy === field) {\n this.localSortAsc = !this.localSortAsc\n } else {\n this.localSortBy = field\n this.localSortAsc = true\n }\n }\n\n setRemoteSort (field: 'name' | 'size' | 'modified'): void {\n if (this.remoteSortBy === field) {\n this.remoteSortAsc = !this.remoteSortAsc\n } else {\n this.remoteSortBy = field\n this.remoteSortAsc = true\n }\n }\n\n onDragStartLocal (ev: DragEvent, e: LocalEntry): void {\n const sources = this.selectedLocal.includes(e) && this.selectedLocal.length ? this.selectedLocal : [e]\n const movePayload = sources.map(x => x.fullPath)\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-local-move', JSON.stringify(movePayload))\n\n // Existing cross-device drag (local -> remote) only for files\n if (!e.isDirectory) {\n const payload: DragPayload = { kind: 'local-file', fullPath: e.fullPath, name: e.name }\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\n ev.dataTransfer?.setData('text/plain', e.fullPath)\n }\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\n }\n\n onDragStartRemote (ev: DragEvent, item: SFTPFile): void {\n if (!this.connected) {\n return\n }\n const sources = this.selectedRemote.includes(item) && this.selectedRemote.length ? this.selectedRemote : [item]\n const movePayload = sources.map(x => x.fullPath)\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-remote-move', JSON.stringify(movePayload))\n\n // Existing cross-device drag (remote -> local) only for files\n if (!item.isDirectory) {\n const payload: DragPayload = {\n kind: 'remote-file',\n remotePath: item.fullPath,\n name: item.name,\n size: item.size,\n mode: item.mode,\n }\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\n ev.dataTransfer?.setData('text/plain', item.fullPath)\n }\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\n }\n\n async onDropOnRemote (ev: DragEvent): Promise<void> {\n ev.preventDefault()\n this.remoteDropActive = false\n if (!this.connected) {\n return\n }\n if (!this.sftpSession) {\n return\n }\n\n // Drag & drop from OS file manager (Explorer/Finder) into the remote pane\n const osPaths = this.getDroppedOsPaths(ev)\n if (osPaths.length) {\n try {\n for (const p of osPaths) {\n await this.uploadLocalPathToRemote(this.remotePath, p)\n }\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Upload from OS drop failed', e)\n }\n return\n }\n\n // Fallback: use Tabby's native drag parser (supports directories and HTMLFileUpload)\n try {\n const dirUpload = await (this.platform as any).startUploadFromDragEvent?.(ev, true)\n if (dirUpload && this.sftpSession) {\n await this.uploadDirectoryUploadToRemote(this.remotePath, dirUpload)\n await this.refreshRemote()\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] startUploadFromDragEvent failed', e)\n }\n\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\n if (!raw) {\n return\n }\n let payload: DragPayload\n try {\n payload = JSON.parse(raw) as DragPayload\n } catch {\n return\n }\n if (payload.kind !== 'local-file') {\n return\n }\n try {\n const targetRemotePath = path.posix.join(this.remotePath, payload.name)\n const upload = new LocalPathFileUpload(payload.fullPath)\n this.trackTransfer(upload, 'upload', targetRemotePath, payload.fullPath)\n await this.sftpSession.upload(targetRemotePath, upload)\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Upload failed', e)\n }\n }\n\n async onDropOnLocal (ev: DragEvent): Promise<void> {\n ev.preventDefault()\n this.localDropActive = false\n\n // Drag & drop from OS file manager into the local pane (copy into current local folder)\n const osPaths = this.getDroppedOsPaths(ev)\n if (osPaths.length) {\n try {\n for (const p of osPaths) {\n await this.copyLocalPathIntoLocalDir(this.localPath, p)\n }\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Local copy from OS drop failed', e)\n }\n return\n }\n\n // Fallback: use Tabby's native drag parser, then write files to disk\n try {\n const dirUpload = await (this.platform as any).startUploadFromDragEvent?.(ev, true)\n if (dirUpload) {\n await this.writeDirectoryUploadToLocal(this.localPath, dirUpload)\n await this.refreshLocal()\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] startUploadFromDragEvent (local) failed', e)\n }\n\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\n if (!raw) {\n return\n }\n let payload: DragPayload\n try {\n payload = JSON.parse(raw) as DragPayload\n } catch {\n return\n }\n if (payload.kind !== 'remote-file') {\n return\n }\n try {\n const targetLocalPath = path.join(this.localPath, payload.name)\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n const dl = new LocalPathFileDownload(targetLocalPath, payload.mode, payload.size)\n this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath)\n await this.sftpSession.download(payload.remotePath, dl)\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Download failed', e)\n }\n }\n\n private async uploadLocalPathToRemote (remoteDir: string, localPath: string): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n const st = await fs.stat(localPath).catch(() => null)\n if (!st) {\n return\n }\n const baseName = path.basename(localPath)\n const remoteTarget = path.posix.join(remoteDir, baseName)\n\n if (st.isDirectory()) {\n // Ensure destination folder exists, then recursively upload children\n try {\n await this.sftpSession.mkdir(remoteTarget)\n } catch {\n // ignore (might already exist)\n }\n const children = await fs.readdir(localPath)\n for (const child of children) {\n await this.uploadLocalPathToRemote(remoteTarget, path.join(localPath, child))\n }\n return\n }\n\n const upload = new LocalPathFileUpload(localPath)\n this.trackTransfer(upload, 'upload', remoteTarget, localPath)\n await this.sftpSession.upload(remoteTarget, upload)\n }\n\n private async copyLocalPathIntoLocalDir (destDir: string, srcPath: string): Promise<void> {\n const st = await fs.stat(srcPath).catch(() => null)\n if (!st) {\n return\n }\n const baseName = path.basename(srcPath)\n const destPath = path.join(destDir, baseName)\n\n if (st.isDirectory()) {\n await fs.mkdir(destPath, { recursive: true })\n const children = await fs.readdir(srcPath)\n for (const child of children) {\n await this.copyLocalPathIntoLocalDir(destPath, path.join(srcPath, child))\n }\n return\n }\n\n await fs.copyFile(srcPath, destPath)\n }\n\n private async uploadDirectoryUploadToRemote (remoteDir: string, dirUpload: any): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n const childrens: any[] = dirUpload?.getChildrens?.() ?? []\n for (const item of childrens) {\n // DirectoryUpload\n if (typeof item?.getChildrens === 'function') {\n const name = item.getName?.() || 'folder'\n const nextRemote = path.posix.join(remoteDir, name)\n try {\n await this.sftpSession.mkdir(nextRemote)\n } catch {\n // ignore (might already exist)\n }\n await this.uploadDirectoryUploadToRemote(nextRemote, item)\n continue\n }\n\n // FileUpload (including HTMLFileUpload)\n if (typeof item?.read === 'function' && typeof item?.getName === 'function') {\n const fileUpload = item as FileUpload\n const name = fileUpload.getName()\n const targetRemotePath = path.posix.join(remoteDir, name)\n this.trackTransfer(fileUpload as any, 'upload', targetRemotePath, name)\n await this.sftpSession.upload(targetRemotePath, fileUpload as any)\n }\n }\n }\n\n private async writeDirectoryUploadToLocal (localDir: string, dirUpload: any): Promise<void> {\n const childrens: any[] = dirUpload?.getChildrens?.() ?? []\n for (const item of childrens) {\n if (typeof item?.getChildrens === 'function') {\n const name = item.getName?.() || 'folder'\n const nextLocal = path.join(localDir, name)\n await fs.mkdir(nextLocal, { recursive: true })\n await this.writeDirectoryUploadToLocal(nextLocal, item)\n continue\n }\n\n if (typeof item?.readAll === 'function' && typeof item?.getName === 'function') {\n const name = item.getName()\n const targetLocal = path.join(localDir, name)\n const buf = await item.readAll()\n await fs.writeFile(targetLocal, Buffer.from(buf))\n try {\n item.close?.()\n } catch {\n // ignore\n }\n }\n }\n }\n\n private getDroppedOsPaths (ev: DragEvent): string[] {\n const dt = ev.dataTransfer\n if (!dt) {\n return []\n }\n\n // 1) Electron-style File.path\n const filePaths = Array.from(dt.files ?? [])\n .map(f => (f as any).path as string | undefined)\n .filter((p): p is string => Boolean(p))\n if (filePaths.length) {\n return filePaths\n }\n\n // 2) Sometimes paths are exposed as URIs\n const uriList = dt.getData('text/uri-list') || ''\n const uris = uriList\n .split(/\\r?\\n/g)\n .map(x => x.trim())\n .filter(x => x && !x.startsWith('#'))\n .map(x => {\n if (x.startsWith('file://')) {\n try {\n return decodeURIComponent(x.replace(/^file:\\/\\//, ''))\n } catch {\n return x.replace(/^file:\\/\\//, '')\n }\n }\n return x\n })\n .filter(x => x && (x.includes(':\\\\') || x.startsWith('/') || x.startsWith('\\\\\\\\')))\n if (uris.length) {\n return uris\n }\n\n // 3) Plain text sometimes contains a local path\n const text = dt.getData('text/plain') || ''\n const textLines = text.split(/\\r?\\n/g).map(x => x.trim()).filter(Boolean)\n const textPaths = textLines\n .map(x => {\n if (x.startsWith('file://')) {\n try {\n return decodeURIComponent(x.replace(/^file:\\/\\//, ''))\n } catch {\n return x.replace(/^file:\\/\\//, '')\n }\n }\n return x\n })\n .filter(x => x.includes(':\\\\') || x.startsWith('/') || x.startsWith('\\\\\\\\'))\n return textPaths\n }\n\n getFilteredLocalEntries (): LocalEntry[] {\n const entriesRef = this.localEntries\n const filter = this.localFilter\n const showHidden = this.showHiddenLocal\n const sortBy = this.localSortBy\n const asc = this.localSortAsc\n\n if (this.localCache &&\n this.localCache.entriesRef === entriesRef &&\n this.localCache.filter === filter &&\n this.localCache.showHidden === showHidden &&\n this.localCache.sortBy === sortBy &&\n this.localCache.asc === asc) {\n return this.localCache.result\n }\n\n const term = filter.trim().toLowerCase()\n let entries = entriesRef\n if (!showHidden) {\n entries = entries.filter(e => !e.name.startsWith('.'))\n }\n if (term) {\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\n }\n const result = this.sortLocalEntries(entries.slice())\n this.localCache = { entriesRef, filter, showHidden, sortBy, asc, result }\n return result\n }\n\n getFilteredRemoteEntries (): SFTPFile[] {\n const entriesRef = this.remoteEntries\n const filter = this.remoteFilter\n const showHidden = this.showHiddenRemote\n const sortBy = this.remoteSortBy\n const asc = this.remoteSortAsc\n\n if (this.remoteCache &&\n this.remoteCache.entriesRef === entriesRef &&\n this.remoteCache.filter === filter &&\n this.remoteCache.showHidden === showHidden &&\n this.remoteCache.sortBy === sortBy &&\n this.remoteCache.asc === asc) {\n return this.remoteCache.result\n }\n\n const term = filter.trim().toLowerCase()\n let entries = entriesRef\n if (!showHidden) {\n entries = entries.filter(e => !e.name.startsWith('.'))\n }\n if (term) {\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\n }\n const result = this.sortRemoteEntries(entries.slice())\n this.remoteCache = { entriesRef, filter, showHidden, sortBy, asc, result }\n return result\n }\n\n private sortLocalEntries (entries: LocalEntry[]): LocalEntry[] {\n const dirFirst = (a: LocalEntry, b: LocalEntry) => Number(b.isDirectory) - Number(a.isDirectory)\n const factor = this.localSortAsc ? 1 : -1\n const field = this.localSortBy\n return entries.sort((a, b) => {\n const d = dirFirst(a, b)\n if (d !== 0) return d\n if (field === 'name') {\n return a.name.localeCompare(b.name) * factor\n }\n if (field === 'size') {\n const av = a.size ?? 0\n const bv = b.size ?? 0\n return (av - bv) * factor\n }\n const av = a.mtimeMs ?? 0\n const bv = b.mtimeMs ?? 0\n return (av - bv) * factor\n })\n }\n\n private sortRemoteEntries (entries: SFTPFile[]): SFTPFile[] {\n const dirFirst = (a: SFTPFile, b: SFTPFile) => Number(b.isDirectory) - Number(a.isDirectory)\n const factor = this.remoteSortAsc ? 1 : -1\n const field = this.remoteSortBy\n return entries.sort((a, b) => {\n const d = dirFirst(a, b)\n if (d !== 0) return d\n if (field === 'name') {\n return a.name.localeCompare(b.name) * factor\n }\n if (field === 'size') {\n const av = a.size ?? 0\n const bv = b.size ?? 0\n return (av - bv) * factor\n }\n const av = a.modified?.getTime?.() ?? 0\n const bv = b.modified?.getTime?.() ?? 0\n return (av - bv) * factor\n })\n }\n\n private getLocalMovePayload (ev: DragEvent): string[] | null {\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-local-move')\n if (!raw) {\n return null\n }\n try {\n const arr = JSON.parse(raw) as string[]\n if (Array.isArray(arr)) {\n return arr\n }\n } catch {\n // ignore\n }\n return null\n }\n\n private getRemoteMovePayload (ev: DragEvent): string[] | null {\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-remote-move')\n if (!raw) {\n return null\n }\n try {\n const arr = JSON.parse(raw) as string[]\n if (Array.isArray(arr)) {\n return arr\n }\n } catch {\n // ignore\n }\n return null\n }\n\n formatSize (bytes?: number): string {\n if (bytes === undefined || bytes === null) {\n return ''\n }\n if (bytes === 0) {\n return '0 B'\n }\n const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']\n let value = bytes\n let unitIndex = 0\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024\n unitIndex++\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\n return `${value.toFixed(digits)} ${units[unitIndex]}`\n }\n\n formatSpeed (bytesPerSecond?: number): string {\n if (bytesPerSecond === undefined || bytesPerSecond === null) {\n return ''\n }\n if (bytesPerSecond === 0) {\n return '0 B/s'\n }\n const units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s']\n let value = bytesPerSecond\n let unitIndex = 0\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024\n unitIndex++\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\n return `${value.toFixed(digits)} ${units[unitIndex]}`\n }\n\n getLocalSizeDisplay (e: LocalEntry): string {\n if (!e.isDirectory) {\n return this.formatSize(e.size)\n }\n if (e.size !== undefined) {\n return this.formatSize(e.size)\n }\n if (this.localFolderSizeLoading.has(e.fullPath)) {\n return '…'\n }\n return ''\n }\n\n getRemoteSizeDisplay (e: SFTPFile): string {\n if (!e.isDirectory) {\n return this.formatSize(e.size)\n }\n const key = e.fullPath\n if ((e as any).dirSize !== undefined) {\n return this.formatSize((e as any).dirSize)\n }\n if (this.remoteFolderSizeLoading.has(key)) {\n return '…'\n }\n return ''\n }\n\n onLocalEntryDragOver (entry: LocalEntry, ev: DragEvent): void {\n if (!entry.isDirectory) {\n return\n }\n if (!this.getLocalMovePayload(ev)) {\n return\n }\n ev.preventDefault()\n }\n\n async onLocalEntryDrop (entry: LocalEntry, ev: DragEvent): Promise<void> {\n if (!entry.isDirectory) {\n return\n }\n const sources = this.getLocalMovePayload(ev)\n if (!sources || !sources.length) {\n return\n }\n ev.preventDefault()\n const targetDir = entry.fullPath\n try {\n for (const src of sources) {\n if (!src || src === targetDir) {\n continue\n }\n // avoid moving a directory into its own subtree\n if (targetDir.startsWith(src + path.sep)) {\n continue\n }\n const name = path.basename(src)\n const dst = path.join(targetDir, name)\n if (dst === src) {\n continue\n }\n try {\n await fs.rename(src, dst)\n } catch (e) {\n console.error('[SFTP-UI] Local move failed', e)\n }\n }\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Local move batch failed', e)\n }\n }\n\n onRemoteEntryDragOver (entry: SFTPFile, ev: DragEvent): void {\n if (!entry.isDirectory) {\n return\n }\n if (!this.getRemoteMovePayload(ev)) {\n return\n }\n ev.preventDefault()\n }\n\n async onRemoteEntryDrop (entry: SFTPFile, ev: DragEvent): Promise<void> {\n if (!entry.isDirectory || !this.sftpSession || !this.connected) {\n return\n }\n const sources = this.getRemoteMovePayload(ev)\n if (!sources || !sources.length) {\n return\n }\n ev.preventDefault()\n const targetDir = entry.fullPath\n try {\n for (const src of sources) {\n if (!src || src === targetDir) {\n continue\n }\n // avoid moving a directory into its own subtree\n if (targetDir.startsWith(src + '/')) {\n continue\n }\n const name = src.split('/').filter(Boolean).pop() || ''\n if (!name) {\n continue\n }\n const dst = path.posix.join(targetDir, name)\n if (dst === src) {\n continue\n }\n try {\n await this.sftpSession.rename(src, dst)\n } catch (e) {\n console.error('[SFTP-UI] Remote move failed', e)\n }\n }\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Remote move batch failed', e)\n }\n }\n\n getRemoteBreadcrumbs (): Array<{ label: string, path: string }> {\n const parts = this.remotePath.split('/').filter(Boolean)\n const crumbs: Array<{ label: string, path: string }> = []\n let current = '/'\n crumbs.push({ label: '/', path: '/' })\n for (const p of parts) {\n current = current === '/' ? `/${p}` : `${current}/${p}`\n crumbs.push({ label: p, path: current })\n }\n return crumbs\n }\n\n navigateRemoteBreadcrumb (index: number): void {\n const crumbs = this.getRemoteBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n this.remotePath = crumb.path\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n }\n\n goToRemotePathInput (): void {\n if (!this.connected) {\n return\n }\n const target = this.normalizeRemotePath(this.remotePathInput || '/')\n this.remotePath = target\n this.remotePathInput = target\n void this.refreshRemote()\n }\n\n goToLocalPathInput (): void {\n const target = this.normalizeLocalPath(this.localPathInput || this.localPath)\n this.goToLocalPath(target)\n }\n\n getLocalBreadcrumbs (): Array<{ label: string, path: string }> {\n const currentPath = this.localPath\n const parsed = path.parse(currentPath)\n const root = parsed.root || path.sep\n const withoutRoot = currentPath.slice(root.length)\n const parts = withoutRoot.split(path.sep).filter(Boolean)\n const crumbs: Array<{ label: string, path: string }> = []\n\n const rootLabel = root.replace(/[\\\\\\/]+$/, '') || root\n crumbs.push({ label: rootLabel, path: root })\n\n let accum = root\n for (const p of parts) {\n accum = path.join(accum, p)\n crumbs.push({ label: p, path: accum })\n }\n return crumbs\n }\n\n navigateLocalBreadcrumb (index: number): void {\n const crumbs = this.getLocalBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n this.goToLocalPath(crumb.path)\n }\n\n private goToLocalPath (target: string): void {\n this.localPath = target\n this.localPathInput = target\n void this.refreshLocal()\n }\n\n onLocalPresetChange (id: string): void {\n if (!id) {\n return\n }\n const preset = this.localPathPresets.find(p => p.id === id)\n if (!preset) {\n return\n }\n this.goToLocalPath(preset.path)\n }\n\n isCurrentFavorite (): boolean {\n return this.localFavorites.some(f => f.path === this.localPath)\n }\n\n toggleCurrentFavorite (): void {\n const existingIndex = this.localFavorites.findIndex(f => f.path === this.localPath)\n if (existingIndex >= 0) {\n this.localFavorites.splice(existingIndex, 1)\n this.saveLocalFavorites()\n return\n }\n const label = path.basename(this.localPath) || this.localPath\n const id = `fav-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\n this.localFavorites.push({ id, label, path: this.localPath })\n this.saveLocalFavorites()\n }\n\n onLocalFavoriteSelect (id: string): void {\n if (!id) {\n return\n }\n const fav = this.localFavorites.find(f => f.id === id)\n if (!fav) {\n return\n }\n this.goToLocalPath(fav.path)\n }\n\n onLocalBreadcrumbContextMenu (index: number, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n const crumbs = this.getLocalBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n\n const menuItems: Array<{ label: string, path: string }> = []\n const isWindows = process.platform === 'win32'\n const isRootCrumb = index === 0\n\n const basePath = crumb.path\n\n // Root crumb on Windows: offer other drives as \"siblings\"\n if (isWindows && isRootCrumb) {\n const drives: string[] = []\n for (let code = 67; code <= 90; code++) { // C..Z\n const letter = String.fromCharCode(code)\n const rootPath = `${letter}:\\\\`\n try {\n if (fsSync.existsSync(rootPath)) {\n drives.push(rootPath)\n }\n } catch {\n // ignore\n }\n }\n for (const d of drives) {\n menuItems.push({ label: d, path: d })\n }\n } else {\n // For non-root crumbs (or non-Windows), show sibling folders only\n const parentPath = path.dirname(basePath)\n try {\n const parentEntries = fsSync.readdirSync(parentPath)\n for (const name of parentEntries) {\n const full = path.join(parentPath, name)\n try {\n const st = fsSync.statSync(full)\n if (st.isDirectory()) {\n menuItems.push({ label: name, path: full })\n }\n } catch {\n // ignore\n }\n }\n } catch {\n // ignore\n }\n }\n\n if (!menuItems.length) {\n return\n }\n\n this.localMenuItems = menuItems\n this.localMenuVisible = true\n this.localMenuX = event.clientX\n this.localMenuY = event.clientY\n }\n\n private loadLocalFavorites (): void {\n try {\n if (typeof window === 'undefined' || !window.localStorage) {\n return\n }\n const raw = window.localStorage.getItem('tabby-sftp-ui-local-favorites')\n if (!raw) {\n return\n }\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n this.localFavorites = parsed\n .filter(f => f && typeof f.path === 'string')\n .map(f => ({\n id: String(f.id || `fav-${Math.random().toString(36).slice(2, 8)}`),\n label: String(f.label || path.basename(f.path) || f.path),\n path: String(f.path),\n }))\n }\n } catch {\n // ignore\n }\n }\n\n private saveLocalFavorites (): void {\n try {\n if (typeof window === 'undefined' || !window.localStorage) {\n return\n }\n window.localStorage.setItem('tabby-sftp-ui-local-favorites', JSON.stringify(this.localFavorites))\n } catch {\n // ignore\n }\n }\n\n onLocalMenuItemClick (item: { label: string, path: string }): void {\n this.localMenuVisible = false\n this.goToLocalPath(item.path)\n }\n\n private normalizeLocalPath (p: string): string {\n if (!p) {\n return this.localPath\n }\n let result = p.trim()\n // On Windows allow drive letters and backslashes, but normalize to current OS-style\n if (path.win32.isAbsolute(result) || path.posix.isAbsolute(result)) {\n return result\n }\n // relative path from current localPath\n return path.join(this.localPath, result)\n }\n\n private normalizeRemotePath (p: string): string {\n if (!p) {\n return '/'\n }\n let result = p.trim()\n if (!result.startsWith('/')) {\n result = '/' + result\n }\n // remove duplicate slashes\n result = result.replace(/\\/+/g, '/')\n return result\n }\n\n private getDefaultRemotePath (): string {\n const username = (this.profile && (this.profile.options?.username || this.profile.options?.user)) || ''\n if (username) {\n return `/home/${username}`\n }\n return '/'\n }\n\n private loadRecentProfiles (): void {\n try {\n const rec = this.profilesService.getRecentProfiles?.()\n if (Array.isArray(rec)) {\n this.recentProfiles = rec\n }\n } catch {\n this.recentProfiles = []\n }\n }\n\n getProfileLabel (p: any): string {\n if (!p) {\n return ''\n }\n return p.name || p.options?.host || p.id || 'Profile'\n }\n\n launchProfileFromSFTP (p: any): void {\n try {\n void this.profilesService.launchProfile(p)\n } catch (e) {\n console.error('[SFTP-UI] launchProfile failed', e)\n }\n }\n\n @HostListener('document:click')\n onDocumentClick (): void {\n this.localMenuVisible = false\n }\n\n localRename (): void {\n if (this.selectedLocal.length !== 1) {\n return\n }\n const entry = this.selectedLocal[0]\n this.openInputDialog({\n mode: 'local-rename',\n title: 'Rename (local)',\n placeholder: 'New name',\n value: entry.name,\n targetPath: entry.fullPath,\n })\n }\n\n localDelete (): void {\n if (!this.selectedLocal.length) {\n return\n }\n this.deleteConfirmMode = 'local'\n this.pendingLocalDelete = this.selectedLocal.slice()\n const names = this.pendingLocalDelete.map(e => e.name)\n this.deleteConfirmText = this.buildDeleteConfirmText('local', names)\n this.deleteConfirmVisible = true\n }\n\n localNewFolder (): void {\n this.openInputDialog({\n mode: 'local-new-folder',\n title: 'New folder (local)',\n placeholder: 'Folder name',\n value: 'New folder',\n targetPath: this.localPath,\n })\n }\n\n localEditPermissions (): void {\n if (this.selectedLocal.length !== 1 || !this.localActionPerms?.trim()) {\n return\n }\n const entry = this.selectedLocal[0]\n const mode = parseInt(this.localActionPerms.trim(), 8)\n if (Number.isNaN(mode)) {\n console.error('[SFTP-UI] Invalid local permissions value')\n return\n }\n void fs.chmod(entry.fullPath, mode as any)\n .then(() => this.refreshLocal())\n .catch(e => console.error('[SFTP-UI] Local chmod failed', e))\n }\n\n localShowSize (): void {\n if (this.selectedLocal.length === 1 && this.selectedLocal[0].isDirectory) {\n this.ensureLocalFolderSize(this.selectedLocal[0])\n }\n }\n\n remoteRename (): void {\n if (this.selectedRemote.length !== 1 || !this.sftpSession) {\n return\n }\n const entry = this.selectedRemote[0]\n this.openInputDialog({\n mode: 'remote-rename',\n title: 'Rename (remote)',\n placeholder: 'New name',\n value: entry.name,\n remotePath: entry.fullPath,\n targetPath: this.remotePath,\n })\n }\n\n remoteDelete (): void {\n if (!this.selectedRemote.length || !this.sftpSession) {\n return\n }\n this.deleteConfirmMode = 'remote'\n this.pendingRemoteDelete = this.selectedRemote.slice()\n const names = this.pendingRemoteDelete.map(e => e.name)\n this.deleteConfirmText = this.buildDeleteConfirmText('remote', names)\n this.deleteConfirmVisible = true\n }\n\n remoteNewFolder (): void {\n if (!this.sftpSession) {\n return\n }\n this.openInputDialog({\n mode: 'remote-new-folder',\n title: 'New folder (remote)',\n placeholder: 'Folder name',\n value: 'New folder',\n targetPath: this.remotePath,\n })\n }\n\n private openInputDialog (opts: {\n mode: NonNullable<SftpManagerTabComponent['inputDialogMode']>\n title: string\n placeholder: string\n value: string\n targetPath: string\n remotePath?: string\n }): void {\n this.inputDialogMode = opts.mode\n this.inputDialogTitle = opts.title\n this.inputDialogPlaceholder = opts.placeholder\n this.inputDialogValue = opts.value\n this.inputDialogTargetPath = opts.targetPath\n this.inputDialogRemotePath = opts.remotePath ?? null\n this.inputDialogVisible = true\n }\n\n cancelInputDialog (): void {\n this.inputDialogVisible = false\n this.inputDialogMode = null\n this.inputDialogTitle = ''\n this.inputDialogPlaceholder = ''\n this.inputDialogValue = ''\n this.inputDialogTargetPath = null\n this.inputDialogRemotePath = null\n }\n\n async confirmInputDialog (): Promise<void> {\n if (!this.inputDialogVisible || !this.inputDialogMode) {\n return\n }\n const mode = this.inputDialogMode\n const value = this.inputDialogValue.trim()\n const targetPath = this.inputDialogTargetPath\n const remotePath = this.inputDialogRemotePath\n this.cancelInputDialog()\n\n if (!value || !targetPath) {\n return\n }\n\n try {\n if (mode === 'local-new-folder') {\n const dir = targetPath\n const folderPath = path.join(dir, value)\n await fs.mkdir(folderPath, { recursive: true })\n await this.refreshLocal()\n return\n }\n\n if (mode === 'local-rename') {\n const from = targetPath\n const to = path.join(this.localPath, value)\n if (path.basename(from) === value) {\n return\n }\n await fs.rename(from, to)\n await this.refreshLocal()\n return\n }\n\n if (mode === 'remote-new-folder') {\n if (!this.sftpSession) {\n return\n }\n const dir = targetPath\n const folderPath = path.posix.join(dir, value)\n await this.sftpSession.mkdir(folderPath)\n await this.refreshRemote()\n return\n }\n\n if (mode === 'remote-rename') {\n if (!this.sftpSession || !remotePath) {\n return\n }\n const to = path.posix.join(this.remotePath, value)\n if (path.posix.basename(remotePath) === value) {\n return\n }\n await this.sftpSession.rename(remotePath, to)\n await this.refreshRemote()\n }\n } catch (e) {\n console.error('[SFTP-UI] Input dialog action failed', e)\n }\n }\n\n remoteEditPermissions (): void {\n if (this.selectedRemote.length !== 1 || !this.remoteActionPerms?.trim() || !this.sftpSession) {\n return\n }\n const entry = this.selectedRemote[0]\n const mode = parseInt(this.remoteActionPerms.trim(), 8)\n if (Number.isNaN(mode)) {\n console.error('[SFTP-UI] Invalid remote permissions value')\n return\n }\n void (this.sftpSession as any).chmod(entry.fullPath, mode)\n .then(() => this.refreshRemote())\n .catch((e: any) => console.error('[SFTP-UI] Remote chmod failed', e))\n }\n\n remoteShowSize (): void {\n if (this.selectedRemote.length === 1 && this.selectedRemote[0].isDirectory) {\n this.ensureRemoteFolderSize(this.selectedRemote[0])\n }\n }\n\n remoteDownload (): void {\n if (!this.selectedRemote.length || !this.sftpSession) {\n return\n }\n for (const entry of this.selectedRemote) {\n if (entry.isDirectory) {\n continue\n }\n const targetLocalPath = path.join(this.localPath, entry.name)\n const dl = new LocalPathFileDownload(targetLocalPath, entry.mode, entry.size)\n this.trackTransfer(dl, 'download', entry.fullPath, targetLocalPath)\n void this.sftpSession.download(entry.fullPath, dl)\n .then(() => this.refreshLocal())\n .catch(e => console.error('[SFTP-UI] Remote download failed', e))\n }\n }\n\n ensureLocalFolderSize (entry: LocalEntry): void {\n if (!entry.isDirectory) {\n return\n }\n if (entry.size !== undefined) {\n return\n }\n if (this.localFolderSizeLoading.has(entry.fullPath)) {\n return\n }\n this.localFolderSizeLoading.add(entry.fullPath)\n void this.computeLocalFolderSize(entry.fullPath)\n .then(size => {\n entry.size = size\n })\n .catch(e => {\n console.error('[SFTP-UI] Local folder size failed', e)\n })\n .finally(() => {\n this.localFolderSizeLoading.delete(entry.fullPath)\n })\n }\n\n ensureRemoteFolderSize (entry: SFTPFile): void {\n if (!entry.isDirectory) {\n return\n }\n const key = entry.fullPath\n if ((entry as any).dirSize !== undefined) {\n return\n }\n if (this.remoteFolderSizeLoading.has(key)) {\n return\n }\n if (!this.sftpSession || !this.connected) {\n return\n }\n this.remoteFolderSizeLoading.add(key)\n void this.computeRemoteFolderSize(key)\n .then(size => {\n ;(entry as any).dirSize = size\n })\n .catch(e => {\n console.error('[SFTP-UI] Remote folder size failed', e)\n })\n .finally(() => {\n this.remoteFolderSizeLoading.delete(key)\n })\n }\n\n private async computeLocalFolderSize (root: string): Promise<number> {\n let total = 0\n const stack: string[] = [root]\n const maxEntries = 5000\n let visited = 0\n while (stack.length) {\n const dir = stack.pop() as string\n let names: string[]\n try {\n names = await fs.readdir(dir)\n } catch {\n continue\n }\n for (const name of names) {\n if (visited++ > maxEntries) {\n return total\n }\n const full = path.join(dir, name)\n try {\n const st = await fs.stat(full)\n if (st.isDirectory()) {\n stack.push(full)\n } else {\n total += st.size\n }\n } catch {\n // ignore\n }\n }\n }\n return total\n }\n\n private async computeRemoteFolderSize (root: string): Promise<number> {\n if (!this.sftpSession) {\n return 0\n }\n let total = 0\n const stack: string[] = [root]\n const maxEntries = 5000\n let visited = 0\n while (stack.length) {\n const dir = stack.pop() as string\n let entries: SFTPFile[]\n try {\n entries = await this.sftpSession.readdir(dir)\n } catch {\n continue\n }\n for (const item of entries) {\n if (visited++ > maxEntries) {\n return total\n }\n if (item.isDirectory) {\n stack.push(item.fullPath)\n } else {\n total += item.size\n }\n }\n }\n return total\n }\n\n onLocalContextMenu (entry: LocalEntry, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\n }\n\n onRemoteContextMenu (entry: SFTPFile, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n\n if (!this.sftpSession) {\n return\n }\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\n }\n\n private trackTransfer (transfer: FileTransfer, direction: 'upload' | 'download', remotePath: string, localPath: string): void {\n this.transfers.push({\n transfer,\n direction,\n name: transfer.getName(),\n remotePath,\n localPath,\n })\n }\n\n cancelTransfer (entry: { transfer: FileTransfer }): void {\n try {\n if (entry.transfer.isComplete() || entry.transfer.isCancelled()) {\n return\n }\n entry.transfer.cancel?.()\n } catch (e) {\n console.error('[SFTP-UI] Cancel transfer failed', e)\n }\n }\n\n getTransferProgress (transfer: FileTransfer): number {\n try {\n const total = transfer.getSize?.()\n const done = transfer.getCompletedBytes?.()\n if (typeof total !== 'number' || total <= 0 || typeof done !== 'number' || done < 0) {\n return transfer.isComplete() ? 100 : 0\n }\n const value = (done / total) * 100\n const clamped = Math.max(0, Math.min(100, value))\n return clamped\n } catch {\n return transfer.isComplete() ? 100 : 0\n }\n }\n\n onKeyDown (event: KeyboardEvent): void {\n const target = event.target as HTMLElement | null\n const isTypingTarget = Boolean(target) && (\n target?.tagName === 'INPUT' ||\n target?.tagName === 'TEXTAREA' ||\n (target as any)?.isContentEditable\n )\n\n if (event.key === 'Escape') {\n if (this.inputDialogVisible) {\n event.preventDefault()\n this.cancelInputDialog()\n return\n }\n if (this.deleteConfirmVisible) {\n event.preventDefault()\n this.cancelDelete()\n return\n }\n }\n if (event.key === 'Delete' || event.key === 'Backspace') {\n // Don't intercept Delete/Backspace while typing in inputs\n if (isTypingTarget) {\n return\n }\n event.preventDefault()\n if (this.selectedRemote.length) {\n this.remoteDelete()\n } else if (this.selectedLocal.length) {\n this.localDelete()\n }\n }\n }\n\n override destroy (): void {\n // stop file watchers for opened remote files\n for (const { watcher } of this.openedRemoteFiles.values()) {\n try {\n watcher?.close()\n } catch {\n // ignore\n }\n }\n this.openedRemoteFiles.clear()\n\n void this.disconnect()\n if (this.transfersTimer !== null) {\n clearInterval(this.transfersTimer)\n this.transfersTimer = null\n }\n super.destroy()\n }\n\n // Prevent Tabby from restoring SFTP-UI tabs across restarts, since they rely\n // on a live SSH session from a terminal tab.\n // Typинги допускают RecoveryToken | null, нам достаточно всегда возвращать null.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n override async getRecoveryToken (_options?: any): Promise<null> {\n return null\n }\n\n async confirmDelete (): Promise<void> {\n if (!this.deleteConfirmVisible) {\n return\n }\n const mode = this.deleteConfirmMode\n this.deleteConfirmVisible = false\n\n try {\n if (mode === 'local') {\n const toDelete = this.pendingLocalDelete.slice()\n this.pendingLocalDelete = []\n for (const entry of toDelete) {\n await this.deleteLocalEntry(entry)\n }\n await this.refreshLocal()\n this.selectedLocal = []\n } else if (mode === 'remote' && this.sftpSession) {\n const toDelete = this.pendingRemoteDelete.slice()\n this.pendingRemoteDelete = []\n for (const entry of toDelete) {\n await this.deleteRemoteEntry(entry)\n }\n await this.refreshRemote()\n this.selectedRemote = []\n }\n } catch (e) {\n console.error('[SFTP-UI] Delete failed', e)\n } finally {\n this.deleteConfirmMode = null\n this.deleteConfirmText = ''\n }\n }\n\n cancelDelete (): void {\n this.deleteConfirmVisible = false\n this.deleteConfirmMode = null\n this.deleteConfirmText = ''\n this.pendingLocalDelete = []\n this.pendingRemoteDelete = []\n }\n\n private async deleteLocalEntry (entry: LocalEntry): Promise<void> {\n await this.deleteLocalPathRecursive(entry.fullPath)\n }\n\n private async deleteRemoteEntry (entry: SFTPFile): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n await this.deleteRemotePathRecursive(entry.fullPath)\n }\n\n private buildDeleteConfirmText (scope: 'local' | 'remote', names: string[]): string {\n const total = names.length\n const label = scope === 'local' ? 'local' : 'remote'\n if (!total) {\n return `Delete 0 item(s) from ${label}?`\n }\n const maxShown = 5\n const shown = names.slice(0, maxShown)\n const list = shown.join(', ')\n if (total <= maxShown) {\n return `Delete ${total} item(s) from ${label}: ${list}?`\n }\n const rest = total - maxShown\n return `Delete ${total} item(s) from ${label}: ${list} and ${rest} more?`\n }\n\n private async deleteLocalPathRecursive (target: string): Promise<void> {\n try {\n const st = await fs.stat(target)\n if (!st.isDirectory()) {\n await fs.unlink(target)\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] Local delete failed (stat)', e)\n return\n }\n\n try {\n const names = await fs.readdir(target)\n for (const name of names) {\n const child = path.join(target, name)\n await this.deleteLocalPathRecursive(child)\n }\n await fs.rmdir(target)\n } catch (e) {\n console.error('[SFTP-UI] Local recursive delete failed', e)\n }\n }\n\n private async deleteRemotePathRecursive (target: string): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n try {\n const entries = await this.sftpSession.readdir(target).catch(() => null as any)\n if (!entries) {\n // treat as file\n try {\n await this.sftpSession.unlink(target)\n } catch (e) {\n console.error('[SFTP-UI] Remote delete failed', e)\n }\n return\n }\n for (const item of entries as SFTPFile[]) {\n const full = item.fullPath\n if (item.isDirectory) {\n await this.deleteRemotePathRecursive(full)\n } else {\n try {\n await this.sftpSession.unlink(full)\n } catch (e) {\n console.error('[SFTP-UI] Remote unlink failed', e)\n }\n }\n }\n try {\n await this.sftpSession.rmdir(target)\n } catch (e) {\n console.error('[SFTP-UI] Remote rmdir failed', e)\n }\n } catch (e) {\n console.error('[SFTP-UI] Remote recursive delete failed', e)\n }\n }\n\n private async openRemoteFile (entry: SFTPFile): Promise<void> {\n if (!this.sftpSession || !this.connected || entry.isDirectory) {\n return\n }\n try {\n const tmpRoot = path.join(os.tmpdir(), 'tabby-sftp-ui')\n await fs.mkdir(tmpRoot, { recursive: true })\n const hash = crypto.createHash('sha1').update(entry.fullPath).digest('hex').slice(0, 10)\n const safeName = entry.name.replace(/[<>:\"/\\\\|?*\\x00-\\x1F]/g, '_')\n const localPath = path.join(tmpRoot, `${hash}-${safeName}`)\n\n // если уже есть watcher на этот файл – закроем его и перезапишем\n const existing = this.openedRemoteFiles.get(localPath)\n if (existing?.watcher) {\n try {\n existing.watcher.close()\n } catch {\n // ignore\n }\n }\n if (existing?.debounceTimer != null) {\n try {\n clearTimeout(existing.debounceTimer)\n } catch {\n // ignore\n }\n }\n\n const dl = new LocalPathFileDownload(localPath, entry.mode, entry.size)\n this.trackTransfer(dl, 'download', entry.fullPath, localPath)\n await this.sftpSession.download(entry.fullPath, dl)\n\n // настроим наблюдение за изменениями локального файла\n const schedule = () => this.scheduleSyncBackRemoteFile(localPath)\n const watcher = fsSync.watch(localPath, { persistent: false }, (eventType) => {\n // Many editors save atomically (rename) or emit multiple change events.\n if (eventType === 'change' || eventType === 'rename') {\n schedule()\n }\n })\n this.openedRemoteFiles.set(localPath, {\n remotePath: entry.fullPath,\n mode: entry.mode,\n watcher,\n debounceTimer: null,\n syncing: false,\n pending: false,\n lastUploadedSignature: null,\n })\n\n this.platform.openPath(localPath)\n } catch (e) {\n console.error('[SFTP-UI] Open remote file failed', e)\n }\n }\n\n private scheduleSyncBackRemoteFile (localPath: string): void {\n const info = this.openedRemoteFiles.get(localPath)\n if (!info) {\n return\n }\n if (info.debounceTimer != null) {\n clearTimeout(info.debounceTimer)\n }\n // Debounce a burst of editor save events\n info.debounceTimer = window.setTimeout(() => {\n info.debounceTimer = null\n void this.syncBackRemoteFile(localPath)\n }, 650)\n }\n\n private async waitForStableLocalFile (localPath: string): Promise<{ size: number, mtimeMs: number } | null> {\n // Wait until the file stops changing (editors often write in multiple passes)\n let last: { size: number, mtimeMs: number } | null = null\n for (let i = 0; i < 10; i++) {\n const st = await fs.stat(localPath).catch(() => null)\n if (!st || !st.isFile()) {\n return null\n }\n const cur = { size: st.size, mtimeMs: st.mtimeMs }\n if (last && cur.size === last.size && cur.mtimeMs === last.mtimeMs) {\n // stable for one interval\n return cur\n }\n last = cur\n await new Promise(resolve => setTimeout(resolve, 180))\n }\n return last\n }\n\n private async syncBackRemoteFile (localPath: string): Promise<void> {\n if (!this.sftpSession || !this.connected) {\n return\n }\n const info = this.openedRemoteFiles.get(localPath)\n if (!info) {\n return\n }\n if (info.syncing) {\n info.pending = true\n return\n }\n info.syncing = true\n try {\n const stable = await this.waitForStableLocalFile(localPath)\n if (!stable) {\n return\n }\n const signature = `${stable.size}:${stable.mtimeMs}`\n if (info.lastUploadedSignature === signature) {\n return\n }\n const upload = new LocalPathFileUpload(localPath)\n this.trackTransfer(upload, 'upload', info.remotePath, localPath)\n await this.sftpSession.upload(info.remotePath, upload)\n info.lastUploadedSignature = signature\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Sync-back remote file failed', e)\n } finally {\n info.syncing = false\n if (info.pending) {\n info.pending = false\n this.scheduleSyncBackRemoteFile(localPath)\n }\n }\n }\n}\n\n","import { Injectable } from '@angular/core'\r\nimport { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpTerminalDecorator extends TerminalDecorator {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n override attach (terminal: BaseTerminalTabComponent): void {\r\n super.attach(terminal)\r\n\r\n // Best-effort DOM injection: place button near the existing Reconnect button if present.\r\n const tryInsert = () => {\r\n try {\r\n const host: HTMLElement | null = terminal.element?.nativeElement ?? null\r\n if (!host) {\r\n return false\r\n }\r\n\r\n // Find a likely toolbar area in the tab UI\r\n const toolbar =\r\n (host.querySelector('.terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('.btn-toolbar') as HTMLElement | null)\r\n\r\n const container = toolbar ?? host\r\n\r\n if (container.querySelector('[data-tabby-sftp-ui-button=\"1\"]')) {\r\n return true\r\n }\r\n\r\n const btn = document.createElement('button')\r\n btn.type = 'button'\r\n // Match Tabby's terminal toolbar buttons styling\r\n btn.className = 'btn btn-sm btn-link me-2'\r\n btn.setAttribute('data-tabby-sftp-ui-button', '1')\r\n btn.title = 'SFTP-UI'\r\n btn.textContent = 'SFTP-UI'\r\n btn.style.pointerEvents = 'auto'\r\n btn.style.zIndex = '10'\r\n btn.style.position = 'relative'\r\n btn.addEventListener('mousedown', (ev) => {\r\n ev.stopPropagation()\r\n })\r\n btn.addEventListener('click', (ev) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n this.sftpUi.openForSourceTab(terminal as any)\r\n })\r\n\r\n // If there's a Reconnect button, insert next to it.\r\n const allButtons = Array.from(container.querySelectorAll('button')) as HTMLButtonElement[]\r\n const reconnectButton = allButtons.find(b => {\r\n const t = `${b.textContent ?? ''} ${b.title ?? ''} ${b.getAttribute('aria-label') ?? ''}`.toLowerCase()\r\n return t.includes('reconnect') || t.includes('переподключ')\r\n })\r\n\r\n if (reconnectButton?.parentElement) {\r\n // Put it right after Reconnect to avoid overlay issues\r\n reconnectButton.parentElement.insertBefore(btn, reconnectButton.nextSibling)\r\n } else {\r\n container.appendChild(btn)\r\n }\r\n\r\n return true\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n // try a few times while the view is settling\r\n let attempts = 0\r\n const timer = setInterval(() => {\r\n attempts++\r\n if (tryInsert() || attempts > 20) {\r\n clearInterval(timer)\r\n }\r\n }, 500)\r\n\r\n this.subscribeUntilDetached(terminal, { unsubscribe: () => clearInterval(timer) } as any)\r\n }\r\n}\r\n\r\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, HotkeysService, LogService, NotificationsService, SplitTabComponent } from 'tabby-core'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\n\r\n@Injectable()\r\nexport class SftpUiService {\r\n private logger: any\r\n\r\n constructor (\r\n private app: AppService,\r\n private hotkeys: HotkeysService,\r\n private log: LogService,\r\n private zone: NgZone,\r\n private notifications: NotificationsService,\r\n ) {\r\n this.logger = this.log.create('sftp-ui')\r\n\r\n this.hotkeys.hotkey$.subscribe(h => {\r\n if (h === 'open-sftp-ui') {\r\n this.open()\r\n }\r\n })\r\n\r\n this.logger.info('loaded')\r\n }\r\n\r\n open (): void {\r\n const active = this.app.activeTab\r\n const focused = active instanceof SplitTabComponent ? (active.getFocusedTab?.() ?? null) : active\r\n this.openForSourceTab(focused)\r\n }\r\n\r\n openForSourceTab (sourceTab: any): void {\r\n const sshSession = sourceTab?.sshSession ?? null\r\n const profile = sourceTab?.profile ?? null\r\n\r\n this.zone.run(() => {\r\n try {\r\n if (!sshSession) {\r\n this.notifications.error('SFTP-UI', 'No SSH session on current tab')\r\n return\r\n }\r\n const baseTitle =\r\n sourceTab?.customTitle ||\r\n sourceTab?.title ||\r\n profile?.name ||\r\n profile?.options?.host ||\r\n 'SFTP'\r\n const tab = this.app.openNewTab({\r\n type: SftpManagerTabComponent,\r\n inputs: {\r\n sshSession,\r\n profile,\r\n },\r\n })\r\n tab.setTitle(`${baseTitle} + SFTP`)\r\n this.notifications.notice('SFTP-UI opened')\r\n } catch (e) {\r\n this.notifications.error('SFTP-UI failed to open', String(e))\r\n this.logger.error('openForSourceTab failed', e)\r\n }\r\n })\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\n\r\nexport type SFTPFile = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n isSymlink: boolean\r\n mode: number\r\n size: number\r\n modified: Date\r\n}\r\n\r\nexport type SFTPSessionLike = {\r\n readdir: (p: string) => Promise<SFTPFile[]>\r\n mkdir: (p: string) => Promise<void>\r\n rmdir: (p: string) => Promise<void>\r\n unlink: (p: string) => Promise<void>\r\n rename: (oldPath: string, newPath: string) => Promise<void>\r\n upload: (remotePath: string, transfer: import('tabby-core').FileUpload) => Promise<void>\r\n download: (remotePath: string, transfer: import('tabby-core').FileDownload) => Promise<void>\r\n}\r\n\r\nexport type SSHSessionLike = {\r\n openSFTP: () => Promise<SFTPSessionLike>\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SftpConnectionService {\r\n async openFromSSHSession (sshSession: SSHSessionLike): Promise<SFTPSessionLike> {\r\n return await sshSession.openSFTP()\r\n }\r\n}\r\n\r\n","module.exports = require(\"crypto\");","module.exports = require(\"fs/promises\");","module.exports = require(\"os\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","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](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport { NgModule } from '@angular/core'\r\nimport { HotkeyProvider, TabContextMenuItemProvider } from 'tabby-core'\r\nimport { TerminalDecorator } from 'tabby-terminal'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\nimport { SftpContextMenuProvider } from './sftp-context-menu'\r\nimport { SftpUiHotkeyProvider } from './sftp-hotkey'\r\nimport { SftpUiService } from './sftp-ui.service'\r\nimport { SftpTerminalDecorator } from './sftp-terminal-decorator'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ],\r\n declarations: [\r\n SftpManagerTabComponent,\r\n ],\r\n providers: [\r\n { provide: TabContextMenuItemProvider, useClass: SftpContextMenuProvider, multi: true },\r\n { provide: HotkeyProvider, useClass: SftpUiHotkeyProvider, multi: true },\r\n { provide: TerminalDecorator, useClass: SftpTerminalDecorator, multi: true },\r\n SftpUiService,\r\n ],\r\n})\r\nexport default class SftpUiModule {\r\n constructor (_: SftpUiService) { }\r\n}\r\n\r\nexport { SftpManagerTabComponent }\r\n"],"names":[],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"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","sources":["webpack-tabby-sftp-ui:///webpack/universalModuleDefinition","webpack-tabby-sftp-ui:///./src/local-transfers.ts","webpack-tabby-sftp-ui:///./src/sftp-context-menu.ts","webpack-tabby-sftp-ui:///./src/sftp-hotkey.ts","webpack-tabby-sftp-ui:///./src/sftp-manager-tab.component.ts","webpack-tabby-sftp-ui:///./src/sftp-terminal-decorator.ts","webpack-tabby-sftp-ui:///./src/sftp-ui.service.ts","webpack-tabby-sftp-ui:///./src/sftp.service.ts","webpack-tabby-sftp-ui:///external node-commonjs \"crypto\"","webpack-tabby-sftp-ui:///external node-commonjs \"fs/promises\"","webpack-tabby-sftp-ui:///external node-commonjs \"os\"","webpack-tabby-sftp-ui:///external umd \"@angular/common\"","webpack-tabby-sftp-ui:///external umd \"@angular/core\"","webpack-tabby-sftp-ui:///external umd \"@angular/forms\"","webpack-tabby-sftp-ui:///external umd \"fs\"","webpack-tabby-sftp-ui:///external umd \"path\"","webpack-tabby-sftp-ui:///external umd \"tabby-core\"","webpack-tabby-sftp-ui:///external umd \"tabby-terminal\"","webpack-tabby-sftp-ui:///webpack/bootstrap","webpack-tabby-sftp-ui:///webpack/runtime/compat get default export","webpack-tabby-sftp-ui:///webpack/runtime/define property getters","webpack-tabby-sftp-ui:///webpack/runtime/hasOwnProperty shorthand","webpack-tabby-sftp-ui:///webpack/runtime/make namespace object","webpack-tabby-sftp-ui:///./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"@angular/common\", \"@angular/forms\", \"@angular/core\", \"tabby-core\", \"tabby-terminal\", \"path\", \"fs\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"@angular/common\"), require(\"@angular/forms\"), require(\"@angular/core\"), require(\"tabby-core\"), require(\"tabby-terminal\"), require(\"path\"), require(\"fs\")) : factory(root[\"@angular/common\"], root[\"@angular/forms\"], root[\"@angular/core\"], root[\"tabby-core\"], root[\"tabby-terminal\"], root[\"path\"], root[\"fs\"]);\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_forms__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE_tabby_core__, __WEBPACK_EXTERNAL_MODULE_tabby_terminal__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_fs__) => {\nreturn ","import * as fs from 'fs'\r\nimport * as path from 'path'\r\n\r\nimport { FileDownload, FileUpload } from 'tabby-core'\r\n\r\nexport class LocalPathFileUpload extends FileUpload {\r\n private fd: number | null = null\r\n private position = 0\r\n\r\n constructor (private filePath: string) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.filePath)\r\n }\r\n\r\n getMode (): number {\r\n return 0o644\r\n }\r\n\r\n getSize (): number {\r\n try {\r\n return fs.statSync(this.filePath).size\r\n } catch {\r\n return 0\r\n }\r\n }\r\n\r\n async read (): Promise<Buffer> {\r\n if (this.isCancelled()) {\r\n return Buffer.alloc(0)\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.filePath, 'r')\r\n }\r\n const buf = Buffer.allocUnsafe(256 * 1024)\r\n const bytesRead = fs.readSync(this.fd, buf, 0, buf.length, this.position)\r\n if (!bytesRead) {\r\n return Buffer.alloc(0)\r\n }\r\n this.position += bytesRead\r\n this.increaseProgress(bytesRead)\r\n return buf.subarray(0, bytesRead)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\nexport class LocalPathFileDownload extends FileDownload {\r\n private fd: number | null = null\r\n\r\n constructor (private targetPath: string, private mode: number, private size: number) {\r\n super()\r\n }\r\n\r\n getName (): string {\r\n return path.basename(this.targetPath)\r\n }\r\n\r\n getMode (): number {\r\n return this.mode\r\n }\r\n\r\n getSize (): number {\r\n return this.size\r\n }\r\n\r\n async write (buffer: Buffer): Promise<void> {\r\n if (this.isCancelled()) {\r\n return\r\n }\r\n if (this.fd === null) {\r\n this.fd = fs.openSync(this.targetPath, 'w')\r\n }\r\n fs.writeSync(this.fd, buffer)\r\n this.increaseProgress(buffer.length)\r\n }\r\n\r\n close (): void {\r\n if (this.fd !== null) {\r\n try {\r\n fs.closeSync(this.fd)\r\n } catch {\r\n // ignore\r\n }\r\n this.fd = null\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { TabContextMenuItemProvider } from 'tabby-core'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpContextMenuProvider extends TabContextMenuItemProvider {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n async getItems (): Promise<Array<{ label: string, click: () => void }>> {\r\n return [\r\n {\r\n label: 'Open SFTP UI',\r\n click: () => this.sftpUi.open(),\r\n },\r\n ]\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\nimport { HotkeyProvider } from 'tabby-core'\r\n\r\n@Injectable()\r\nexport class SftpUiHotkeyProvider extends HotkeyProvider {\r\n async provide (): Promise<Array<{ id: string, name: string }>> {\r\n return [\r\n { id: 'open-sftp-ui', name: 'Open SFTP UI' },\r\n ]\r\n }\r\n}\r\n\r\n","import * as path from 'path'\nimport * as os from 'os'\nimport * as fs from 'fs/promises'\nimport * as fsSync from 'fs'\nimport * as crypto from 'crypto'\n\nimport { Component, Injector, OnInit, HostListener } from '@angular/core'\nimport { AppService, BaseTabComponent, FileTransfer, FileUpload, PlatformService, ProfilesService } from 'tabby-core'\n\nimport { LocalPathFileDownload, LocalPathFileUpload } from './local-transfers'\nimport { SftpConnectionService, SFTPFile, SFTPSessionLike, SSHSessionLike } from './sftp.service'\n\ntype LocalEntry = {\n name: string\n fullPath: string\n isDirectory: boolean\n size?: number\n mtimeMs?: number\n}\n\ntype DragPayload =\n | { kind: 'local-file', fullPath: string, name: string }\n | { kind: 'remote-file', remotePath: string, name: string, size: number, mode: number }\n | { kind: 'remote-dir', remotePath: string, name: string }\n\n@Component({\n selector: 'tabby-sftp-manager-tab',\n template: `\n <div class=\"sftp-root\" tabindex=\"0\" (keydown)=\"onKeyDown($event)\">\n <div class=\"top-profiles\" *ngIf=\"profile || recentProfiles.length\">\n <div class=\"current\" *ngIf=\"profile\">\n <span class=\"label\">Device:</span>\n <span class=\"value\">{{ getProfileLabel(profile) }}</span>\n </div>\n <div class=\"recent\" *ngIf=\"recentProfiles.length\">\n <span class=\"label\">Recent:</span>\n <button\n class=\"profile-chip\"\n *ngFor=\"let p of recentProfiles\"\n (click)=\"launchProfileFromSFTP(p)\"\n >\n {{ getProfileLabel(p) }}\n </button>\n </div>\n </div>\n <div class=\"sftp-body\">\n <div class=\"pane\">\n <div class=\"pane-title\">\n <div class=\"pane-label\">Local</div>\n <div class=\"pane-path\">\n <input\n [(ngModel)]=\"localPathInput\"\n (keyup.enter)=\"goToLocalPathInput()\"\n />\n </div>\n <div class=\"pane-actions\">\n <select class=\"path-preset\" (change)=\"onLocalPresetChange($event.target.value)\">\n <option value=\"\">Go to…</option>\n <option *ngFor=\"let p of localPathPresets\" [value]=\"p.id\">\n {{ p.label }}\n </option>\n </select>\n <button\n class=\"fav-toggle\"\n [class.active]=\"isCurrentFavorite()\"\n (click)=\"toggleCurrentFavorite()\"\n title=\"Toggle favorite for this path\"\n >\n ★\n </button>\n <select class=\"path-favorite\" (change)=\"onLocalFavoriteSelect($event.target.value)\">\n <option value=\"\">Favorites…</option>\n <option *ngFor=\"let f of localFavorites\" [value]=\"f.id\">\n {{ f.label }}\n </option>\n </select>\n <button (click)=\"localUp()\" [disabled]=\"!canLocalUp()\">Up</button>\n <button (click)=\"goToLocalPathInput()\">Go</button>\n <button (click)=\"refreshLocal()\">Refresh</button>\n </div>\n </div>\n <div class=\"pane-filters\">\n <div class=\"breadcrumbs\">\n <ng-container *ngFor=\"let part of getLocalBreadcrumbs(); let i = index; let last = last\">\n <button\n class=\"crumb-button\"\n (click)=\"navigateLocalBreadcrumb(i)\"\n (contextmenu)=\"onLocalBreadcrumbContextMenu(i, $event)\"\n >\n {{ part.label }}\n </button>\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\n </ng-container>\n </div>\n <input [(ngModel)]=\"localFilter\" placeholder=\"Filter files...\" />\n <label class=\"show-hidden-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenLocal\" />\n <span>Show hidden</span>\n </label>\n </div>\n <div class=\"pane-list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDropOnLocal($event)\"\n >\n <div class=\"entry header\">\n <span class=\"icon\"></span>\n <span class=\"name sortable\" (click)=\"setLocalSort('name')\">Name</span>\n <span class=\"size sortable\" (click)=\"setLocalSort('size')\">Size</span>\n <span class=\"date sortable\" (click)=\"setLocalSort('modified')\">Modified</span>\n </div>\n <div\n class=\"entry\"\n *ngIf=\"canLocalUp()\"\n (dblclick)=\"localUp()\"\n >\n <span class=\"icon\">⬆</span>\n <span class=\"name\">Go up</span>\n <span class=\"size\"></span>\n <span class=\"date\"></span>\n </div>\n <div\n class=\"entry\"\n *ngFor=\"let e of getFilteredLocalEntries()\"\n (click)=\"selectLocal(e, $event)\"\n (dblclick)=\"openLocal(e)\"\n (mousedown)=\"onLocalMouseDown(e, $event)\"\n (contextmenu)=\"onLocalContextMenu(e, $event)\"\n (dragover)=\"onLocalEntryDragOver(e, $event)\"\n (drop)=\"onLocalEntryDrop(e, $event)\"\n [class.drop-target]=\"localDropActive\"\n [class.selected]=\"isLocalSelected(e)\"\n [draggable]=\"true\"\n (dragstart)=\"onDragStartLocal($event, e)\"\n >\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\n <span class=\"name\">{{ e.name }}</span>\n <span class=\"size\">{{ getLocalSizeDisplay(e) }}</span>\n <span class=\"date\">{{ e.mtimeMs ? (e.mtimeMs | date:'yyyy-MM-dd HH:mm') : '' }}</span>\n </div>\n </div>\n <div class=\"pane-actions-bar\">\n <div class=\"selection\" *ngIf=\"selectedLocal.length\">\n Selected: {{ selectedLocal.length === 1 ? selectedLocal[0].name : (selectedLocal.length + ' items') }}\n </div>\n <div class=\"action-inputs\">\n <input [(ngModel)]=\"localActionName\" placeholder=\"Name / new name\" />\n <input [(ngModel)]=\"localActionPerms\" placeholder=\"Perms (e.g. 755)\" />\n </div>\n <div class=\"action-buttons\">\n <button (click)=\"localRename()\" [disabled]=\"selectedLocal.length !== 1\">Rename</button>\n <button (click)=\"refreshLocal()\">Refresh</button>\n <button (click)=\"localDelete()\" [disabled]=\"!selectedLocal.length\">Delete</button>\n <button (click)=\"localNewFolder()\">New Folder</button>\n <button (click)=\"localEditPermissions()\" [disabled]=\"selectedLocal.length !== 1 || !localActionPerms\">Edit Permissions</button>\n <button (click)=\"localShowSize()\" [disabled]=\"selectedLocal.length !== 1 || !selectedLocal[0].isDirectory\">Show Size</button>\n </div>\n </div>\n </div>\n\n <div class=\"pane\">\n <div class=\"pane-title\">\n <div class=\"pane-label\">\n Remote\n <span *ngIf=\"connected && profile?.options?.host\" class=\"pane-sub\">\n — {{ profile.options.host }}\n </span>\n </div>\n <div class=\"pane-path\">\n <input\n [(ngModel)]=\"remotePathInput\"\n (keyup.enter)=\"goToRemotePathInput()\"\n [disabled]=\"!connected\"\n />\n </div>\n <div class=\"pane-actions\">\n <button (click)=\"remoteUp()\" [disabled]=\"!connected || remotePath === '/'\">Up</button>\n <button (click)=\"goToRemotePathInput()\" [disabled]=\"!connected\">Go</button>\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\n </div>\n </div>\n <div class=\"pane-filters\">\n <div class=\"breadcrumbs\" *ngIf=\"connected\">\n <ng-container *ngFor=\"let part of getRemoteBreadcrumbs(); let i = index; let last = last\">\n <button\n class=\"crumb-button\"\n (click)=\"navigateRemoteBreadcrumb(i)\"\n >\n {{ part.label }}\n </button>\n <span class=\"crumb-separator\" *ngIf=\"!last\">›</span>\n </ng-container>\n </div>\n <input [(ngModel)]=\"remoteFilter\" placeholder=\"Filter files...\" />\n <label class=\"show-hidden-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"showHiddenRemote\" />\n <span>Show hidden</span>\n </label>\n </div>\n <div class=\"pane-list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDropOnRemote($event)\"\n >\n <div class=\"entry dim\" *ngIf=\"!connected\">\n <span class=\"name\">Not connected</span>\n </div>\n <div class=\"entry header\" *ngIf=\"connected\">\n <span class=\"icon\"></span>\n <span class=\"name sortable\" (click)=\"setRemoteSort('name')\">Name</span>\n <span class=\"size sortable\" (click)=\"setRemoteSort('size')\">Size</span>\n <span class=\"date sortable\" (click)=\"setRemoteSort('modified')\">Modified</span>\n </div>\n <div\n class=\"entry\"\n *ngIf=\"connected && remotePath !== '/'\"\n (dblclick)=\"remoteUp()\"\n >\n <span class=\"icon\">⬆</span>\n <span class=\"name\">Go up</span>\n <span class=\"size\"></span>\n <span class=\"date\"></span>\n </div>\n <div\n class=\"entry\"\n *ngFor=\"let e of getFilteredRemoteEntries()\"\n (click)=\"selectRemote(e, $event)\"\n (dblclick)=\"openRemote(e)\"\n (mousedown)=\"onRemoteMouseDown(e, $event)\"\n (contextmenu)=\"onRemoteContextMenu(e, $event)\"\n (dragover)=\"onRemoteEntryDragOver(e, $event)\"\n (drop)=\"onRemoteEntryDrop(e, $event)\"\n [class.drop-target]=\"remoteDropActive\"\n [class.selected]=\"isRemoteSelected(e)\"\n [draggable]=\"connected\"\n (dragstart)=\"onDragStartRemote($event, e)\"\n >\n <span class=\"icon\">{{ e.isDirectory ? '📁' : '📄' }}</span>\n <span class=\"name\">{{ e.name }}</span>\n <span class=\"size\">{{ getRemoteSizeDisplay(e) }}</span>\n <span class=\"date\">{{ e.modified | date:'yyyy-MM-dd HH:mm' }}</span>\n </div>\n </div>\n <div class=\"pane-actions-bar\">\n <div class=\"selection\" *ngIf=\"selectedRemote.length\">\n Selected: {{ selectedRemote.length === 1 ? selectedRemote[0].name : (selectedRemote.length + ' items') }}\n </div>\n <div class=\"action-inputs\">\n <input [(ngModel)]=\"remoteActionName\" placeholder=\"Name / new name\" />\n <input [(ngModel)]=\"remoteActionPerms\" placeholder=\"Perms (e.g. 755)\" />\n </div>\n <div class=\"action-buttons\">\n <button (click)=\"remoteRename()\" [disabled]=\"selectedRemote.length !== 1\">Rename</button>\n <button (click)=\"refreshRemote()\" [disabled]=\"!connected\">Refresh</button>\n <button (click)=\"remoteDelete()\" [disabled]=\"!selectedRemote.length\">Delete</button>\n <button (click)=\"remoteNewFolder()\" [disabled]=\"!connected\">New Folder</button>\n <button (click)=\"remoteEditPermissions()\" [disabled]=\"selectedRemote.length !== 1 || !remoteActionPerms\">Edit Permissions</button>\n <button (click)=\"remoteShowSize()\" [disabled]=\"selectedRemote.length !== 1 || !selectedRemote[0].isDirectory\">Show Size</button>\n <button (click)=\"remoteDownload()\" [disabled]=\"!selectedRemote.length\">Download</button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"sftp-transfers\" *ngIf=\"transfers.length\">\n <div class=\"transfer\" *ngFor=\"let t of transfers\">\n <div class=\"transfer-main\">\n <div class=\"transfer-title\">\n <span class=\"direction\">{{ t.direction === 'upload' ? 'Upload' : 'Download' }}</span>\n <span class=\"name\">{{ t.name }}</span>\n </div>\n <div class=\"transfer-path\">\n <span class=\"label\">Remote:</span>\n <span class=\"value\">{{ t.remotePath }}</span>\n </div>\n <div class=\"transfer-path\">\n <span class=\"label\">Local:</span>\n <span class=\"value\">{{ t.localPath }}</span>\n </div>\n <div class=\"bar\">\n <div class=\"fill\" [style.width.%]=\"getTransferProgress(t.transfer)\"></div>\n </div>\n </div>\n <div class=\"transfer-stats\">\n <div class=\"percent\">{{ getTransferProgress(t.transfer) | number:'1.0-0' }}%</div>\n <div class=\"speed\">{{ formatSpeed(t.transfer.getSpeed()) }}</div>\n <button class=\"btn-cancel\" (click)=\"cancelTransfer(t)\" [disabled]=\"t.transfer.isComplete() || t.transfer.isCancelled()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div class=\"delete-overlay\" *ngIf=\"deleteConfirmVisible\">\n <div class=\"delete-dialog\">\n <div class=\"delete-text\">{{ deleteConfirmText }}</div>\n <div class=\"delete-buttons\">\n <button class=\"danger\" (click)=\"confirmDelete()\">Delete</button>\n <button (click)=\"cancelDelete()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div class=\"delete-overlay\" *ngIf=\"replaceConfirmVisible\">\n <div class=\"delete-dialog\">\n <div class=\"delete-text\">{{ replaceConfirmText }}</div>\n <div class=\"delete-buttons\">\n <button class=\"danger\" (click)=\"confirmReplace()\">Replace</button>\n <button (click)=\"cancelReplace()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div class=\"delete-overlay\" *ngIf=\"inputDialogVisible\">\n <div class=\"delete-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"delete-text\">{{ inputDialogTitle }}</div>\n <input\n class=\"dialog-input\"\n [(ngModel)]=\"inputDialogValue\"\n [placeholder]=\"inputDialogPlaceholder\"\n (keyup.enter)=\"confirmInputDialog()\"\n />\n <div class=\"delete-buttons\">\n <button class=\"danger\" (click)=\"confirmInputDialog()\" [disabled]=\"!inputDialogValue.trim()\">OK</button>\n <button (click)=\"cancelInputDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n\n <div\n class=\"local-menu\"\n *ngIf=\"localMenuVisible\"\n [style.left.px]=\"localMenuX\"\n [style.top.px]=\"localMenuY\"\n (click)=\"$event.stopPropagation()\"\n >\n <div class=\"local-menu-item\" *ngFor=\"let item of localMenuItems\" (click)=\"onLocalMenuItemClick(item)\">\n {{ item.label }}\n </div>\n </div>\n </div>\n `,\n styles: [`\n .sftp-root { display: flex; flex-direction: column; height: 100%; padding: 10px; gap: 10px; position: relative; }\n button { padding: 6px 10px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.15); background: rgba(255,255,255,0.06); color: inherit; cursor: pointer; }\n button:disabled { opacity: 0.5; cursor: default; }\n .top-profiles { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px 8px; gap: 12px; font-size: 11px; opacity: 0.9; }\n .top-profiles .current .label,\n .top-profiles .recent .label { text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.7; margin-right: 4px; }\n .top-profiles .value { font-weight: 600; }\n .top-profiles .profile-chip { padding: 2px 8px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\n .top-profiles .profile-chip:hover { background: rgba(255,255,255,0.12); }\n .sftp-body { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; flex: 1; min-height: 0; }\n .pane { display: flex; flex-direction: column; border: 1px solid rgba(255,255,255,0.12); border-radius: 10px; overflow: hidden; min-height: 0; }\n .pane-title { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; padding: 8px 10px; background: rgba(255,255,255,0.04); border-bottom: 1px solid rgba(255,255,255,0.08); }\n .pane-label { font-weight: 600; display: flex; align-items: baseline; gap: 6px; }\n .pane-sub { font-weight: 400; font-size: 11px; opacity: 0.75; }\n .pane-path { opacity: 0.8; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .pane-path input { width: 100%; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-family: inherit; font-size: 12px; }\n .pane-actions { display: flex; gap: 8px; align-items: center; }\n .pane-actions .path-preset,\n .pane-actions .path-favorite { max-width: 150px; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.22); background: rgba(20,20,20,0.95); color: inherit; font-size: 11px; }\n .pane-actions .path-preset option { background: #151515; color: #f5f5f5; }\n .pane-actions .path-favorite option { background: #151515; color: #f5f5f5; }\n .pane-actions .fav-toggle { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.05); font-size: 11px; line-height: 1; }\n .pane-actions .fav-toggle.active { background: rgba(255,215,0,0.2); border-color: rgba(255,215,0,0.6); color: #ffd700; }\n .pane-filters { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-bottom: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.12); }\n .pane-filters input { flex: 1; padding: 4px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 12px; }\n .show-hidden-toggle { display: flex; align-items: center; gap: 4px; font-size: 11px; opacity: 0.8; white-space: nowrap; }\n .show-hidden-toggle input[type=\"checkbox\"] { margin: 0; }\n .breadcrumbs { display: flex; flex-wrap: wrap; gap: 4px; font-size: 11px; opacity: 0.9; align-items: center; }\n .crumb-button { padding: 2px 6px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18); background: rgba(255,255,255,0.04); color: inherit; cursor: pointer; font-size: 11px; }\n .crumb-button:hover { background: rgba(255,255,255,0.10); }\n .crumb-separator { opacity: 0.6; }\n .pane-list { flex: 1; overflow: auto; padding: 4px; }\n .entry { display: grid; grid-template-columns: 24px minmax(0, 1.5fr) 80px 140px; gap: 8px; padding: 6px 8px; border-radius: 8px; user-select: none; align-items: center; }\n .entry:hover { background: rgba(255,255,255,0.06); }\n .entry.drop-target { outline: 1px dashed rgba(255,255,255,0.35); background: rgba(80, 160, 255, 0.10); }\n .entry.dim { opacity: 0.7; }\n .icon { text-align: center; opacity: 0.85; }\n .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .size { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; text-align: right; opacity: 0.8; }\n .date { font-size: 11px; opacity: 0.75; text-align: right; white-space: nowrap; }\n .entry.header { font-weight: 600; opacity: 0.9; background: rgba(255,255,255,0.02); }\n .sortable { cursor: pointer; }\n .entry.selected { background: rgba(80,160,255,0.18); }\n .pane-actions-bar { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border-top: 1px solid rgba(255,255,255,0.06); background: rgba(0,0,0,0.18); }\n .pane-actions-bar .selection { font-size: 11px; opacity: 0.85; }\n .pane-actions-bar .action-inputs { display: flex; gap: 6px; }\n .pane-actions-bar .action-inputs input { flex: 1; padding: 3px 6px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 11px; }\n .pane-actions-bar .action-buttons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }\n .sftp-transfers { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; max-height: 120px; overflow-y: auto; }\n .transfer { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 6px 8px; border-radius: 8px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); font-size: 11px; }\n .transfer-title { display: flex; gap: 6px; align-items: baseline; margin-bottom: 2px; }\n .transfer-title .direction { text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; font-weight: 600; font-size: 10px; }\n .transfer-title .name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .transfer-path { display: flex; gap: 4px; opacity: 0.75; }\n .transfer-path .label { min-width: 48px; }\n .transfer-path .value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\n .bar { position: relative; height: 4px; border-radius: 999px; background: rgba(255,255,255,0.07); margin-top: 4px; overflow: hidden; }\n .bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: inherit; background: linear-gradient(90deg, #4dabff, #78ffce); transition: width 0.15s linear; }\n .transfer-stats { display: flex; flex-direction: column; justify-content: center; align-items: flex-end; gap: 4px; opacity: 0.8; }\n .transfer-stats .percent { font-weight: 600; }\n .transfer-stats .speed { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\n .btn-cancel { padding: 2px 6px; font-size: 10px; border-radius: 999px; }\n .delete-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; z-index: 20; }\n .delete-dialog { min-width: 260px; max-width: 360px; padding: 14px 16px; border-radius: 10px; background: rgba(20,20,20,0.96); border: 1px solid rgba(255,255,255,0.15); box-shadow: 0 18px 45px rgba(0,0,0,0.75); display: flex; flex-direction: column; gap: 10px; }\n .delete-text { font-size: 13px; }\n .dialog-input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.18); background: rgba(0,0,0,0.3); color: inherit; font-size: 13px; }\n .delete-buttons { display: flex; justify-content: flex-end; gap: 8px; }\n .delete-buttons .danger { background: rgba(255,80,80,0.85); border-color: rgba(255,120,120,0.85); }\n .local-menu { position: absolute; min-width: 180px; max-width: 260px; max-height: 260px; overflow-y: auto; padding: 4px 0; border-radius: 10px; background: rgba(18,18,22,0.98); border: 1px solid rgba(255,255,255,0.16); box-shadow: 0 18px 45px rgba(0,0,0,0.8); z-index: 30; backdrop-filter: blur(12px); }\n .local-menu-item { padding: 6px 12px; font-size: 12px; cursor: pointer; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; }\n .local-menu-item:hover { background: linear-gradient(90deg, rgba(120,200,255,0.24), rgba(120,255,206,0.15)); }\n `],\n})\nexport class SftpManagerTabComponent extends BaseTabComponent implements OnInit {\n // injected from the SSH tab when opened via SFTP-UI button\n sshSession: SSHSessionLike | null = null\n profile: any = null\n\n connecting = false\n connected = false\n\n // legacy UI fields kept for now (not used when opened from SSH tab)\n host = ''\n port = 22\n username = ''\n password = ''\n\n localPath = os.homedir()\n localEntries: LocalEntry[] = []\n\n remotePath = '/'\n remoteEntries: SFTPFile[] = []\n\n private sftpSession: SFTPSessionLike | null = null\n\n localDropActive = false\n remoteDropActive = false\n\n transfers: Array<{\n transfer: FileTransfer\n direction: 'upload' | 'download'\n name: string\n remotePath: string\n localPath: string\n }> = []\n\n private transfersTimer: number | null = null\n localFilter = ''\n remoteFilter = ''\n remotePathInput = this.remotePath\n localPathInput = this.localPath\n private localFolderSizeLoading: Set<string> = new Set()\n private remoteFolderSizeLoading: Set<string> = new Set()\n private localSortBy: 'name' | 'size' | 'modified' = 'name'\n private localSortAsc = true\n private remoteSortBy: 'name' | 'size' | 'modified' = 'name'\n private remoteSortAsc = true\n private localCache: {\n entriesRef: LocalEntry[]\n filter: string\n showHidden: boolean\n sortBy: 'name' | 'size' | 'modified'\n asc: boolean\n result: LocalEntry[]\n } | null = null\n private remoteCache: {\n entriesRef: SFTPFile[]\n filter: string\n showHidden: boolean\n sortBy: 'name' | 'size' | 'modified'\n asc: boolean\n result: SFTPFile[]\n } | null = null\n showHiddenLocal = false\n showHiddenRemote = false\n selectedLocal: LocalEntry[] = []\n selectedRemote: SFTPFile[] = []\n localActionName = ''\n localActionPerms = ''\n remoteActionName = ''\n remoteActionPerms = ''\n private localLastSelectedIndex: number | null = null\n private remoteLastSelectedIndex: number | null = null\n\n deleteConfirmVisible = false\n deleteConfirmMode: 'local' | 'remote' | null = null\n deleteConfirmText = ''\n private pendingLocalDelete: LocalEntry[] = []\n private pendingRemoteDelete: SFTPFile[] = []\n\n replaceConfirmVisible = false\n replaceConfirmText = ''\n private replaceConfirmResolve: ((v: boolean) => void) | null = null\n\n inputDialogVisible = false\n inputDialogTitle = ''\n inputDialogPlaceholder = ''\n inputDialogValue = ''\n private inputDialogMode: 'local-new-folder' | 'remote-new-folder' | 'local-rename' | 'remote-rename' | null = null\n private inputDialogTargetPath: string | null = null\n private inputDialogRemotePath: string | null = null\n private platform!: PlatformService\n private openedRemoteFiles: Map<string, {\n remotePath: string\n mode: number\n watcher: fsSync.FSWatcher | null\n debounceTimer: number | null\n syncing: boolean\n pending: boolean\n lastUploadedSignature: string | null\n }> = new Map()\n localPathPresets: Array<{ id: string, label: string, path: string }> = []\n localFavorites: Array<{ id: string, label: string, path: string }> = []\n recentProfiles: any[] = []\n localMenuVisible = false\n localMenuX = 0\n localMenuY = 0\n localMenuItems: Array<{ label: string, path: string }> = []\n\n constructor (\n injector: Injector,\n private sftp: SftpConnectionService,\n private profilesService: ProfilesService,\n private app: AppService,\n ) {\n // Tabby runtime BaseTabComponent expects Injector in constructor, but typings in this SDK may differ.\n // @ts-expect-error runtime-compatible super(injector)\n super(injector)\n this.platform = injector.get(PlatformService as any)\n\n // build local path presets (similar to Termius quick locations)\n const home = os.homedir()\n this.localPathPresets.push({ id: 'home', label: 'Home', path: home })\n const desktop = path.join(home, 'Desktop')\n const documents = path.join(home, 'Documents')\n const downloads = path.join(home, 'Downloads')\n if (fsSync.existsSync(desktop)) {\n this.localPathPresets.push({ id: 'desktop', label: 'Desktop', path: desktop })\n }\n if (fsSync.existsSync(documents)) {\n this.localPathPresets.push({ id: 'documents', label: 'Documents', path: documents })\n }\n if (fsSync.existsSync(downloads)) {\n this.localPathPresets.push({ id: 'downloads', label: 'Downloads', path: downloads })\n }\n\n this.loadLocalFavorites()\n void this.refreshLocal()\n\n this.transfersTimer = window.setInterval(() => {\n this.transfers = this.transfers.filter(t => !t.transfer.isComplete() && !t.transfer.isCancelled())\n }, 1000)\n }\n\n ngOnInit (): void {\n // If there's no live SSH session, this tab was likely restored across\n // restart or opened in an invalid context. Close it immediately to avoid\n // an empty, nameless SFTP tab lingering after restart.\n if (!this.sshSession) {\n try {\n this.app.closeTab(this)\n } catch (e) {\n console.error('[SFTP-UI] Failed to close invalid SFTP tab', e)\n }\n return\n }\n\n this.remotePathInput = this.remotePath\n this.localPathInput = this.localPath\n if (this.sshSession) {\n void this.connect()\n }\n this.loadRecentProfiles()\n }\n\n async connect (): Promise<void> {\n if (this.connecting || this.connected) {\n return\n }\n if (!this.sshSession) {\n console.error('[SFTP-UI] No SSH session on current tab')\n return\n }\n this.connecting = true\n try {\n this.sftpSession = await this.sftp.openFromSSHSession(this.sshSession)\n this.connected = true\n this.remotePath = this.getDefaultRemotePath()\n this.remotePathInput = this.remotePath\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] SFTP connection failed', e)\n } finally {\n this.connecting = false\n }\n }\n\n async disconnect (): Promise<void> {\n this.sftpSession = null\n this.connected = false\n this.remoteEntries = []\n }\n\n canLocalUp (): boolean {\n const parent = path.dirname(this.localPath)\n return parent !== this.localPath\n }\n\n localUp (): void {\n const parent = path.dirname(this.localPath)\n if (parent !== this.localPath) {\n this.localPath = parent\n this.localPathInput = this.localPath\n void this.refreshLocal()\n }\n }\n\n remoteUp (): void {\n if (!this.connected || this.remotePath === '/') {\n return\n }\n const next = path.posix.dirname(this.remotePath)\n this.remotePath = next === '.' ? '/' : next\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n }\n\n async refreshLocal (): Promise<void> {\n try {\n const names = await fs.readdir(this.localPath)\n const entries: LocalEntry[] = []\n for (const name of names) {\n const fullPath = path.join(this.localPath, name)\n try {\n const st = await fs.stat(fullPath)\n entries.push({\n name,\n fullPath,\n isDirectory: st.isDirectory(),\n size: st.size,\n mtimeMs: st.mtimeMs,\n })\n } catch {\n // ignore entries that disappeared\n }\n }\n this.localEntries = entries\n } catch (e) {\n console.error('[SFTP-UI] Local listing failed', e)\n }\n }\n\n async refreshRemote (): Promise<void> {\n if (!this.connected) {\n return\n }\n try {\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n this.remoteEntries = await this.sftpSession.readdir(this.remotePath)\n } catch (e) {\n console.error('[SFTP-UI] Remote listing failed', e)\n }\n }\n\n openLocal (e: LocalEntry): void {\n if (!e.isDirectory) {\n return\n }\n this.localPath = e.fullPath\n this.localPathInput = this.localPath\n void this.refreshLocal()\n }\n\n openRemote (e: SFTPFile): void {\n if (!this.connected) {\n return\n }\n if (e.isDirectory) {\n this.remotePath = e.fullPath\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n } else {\n void this.openRemoteFile(e)\n }\n }\n\n onDragOver (ev: DragEvent): void {\n ev.preventDefault()\n }\n\n onLocalMouseDown (entry: LocalEntry, event: MouseEvent): void {\n if (event.button === 2) {\n this.onLocalContextMenu(entry, event)\n }\n }\n\n onRemoteMouseDown (entry: SFTPFile, event: MouseEvent): void {\n if (event.button === 2) {\n this.onRemoteContextMenu(entry, event)\n }\n }\n\n selectLocal (entry: LocalEntry, event: MouseEvent): void {\n const list = this.getFilteredLocalEntries()\n const index = list.indexOf(entry)\n if (index === -1) {\n return\n }\n const isCtrl = event.ctrlKey || event.metaKey\n const isShift = event.shiftKey\n if (isShift && this.localLastSelectedIndex != null) {\n const [from, to] = this.localLastSelectedIndex < index\n ? [this.localLastSelectedIndex, index]\n : [index, this.localLastSelectedIndex]\n const range = list.slice(from, to + 1)\n const set = new Set(this.selectedLocal)\n for (const e of range) {\n set.add(e)\n }\n this.selectedLocal = Array.from(set)\n } else if (isCtrl) {\n const exists = this.selectedLocal.includes(entry)\n if (exists) {\n this.selectedLocal = this.selectedLocal.filter(e => e !== entry)\n } else {\n this.selectedLocal = [...this.selectedLocal, entry]\n }\n this.localLastSelectedIndex = index\n } else {\n this.selectedLocal = [entry]\n this.localLastSelectedIndex = index\n }\n if (this.selectedLocal.length === 1) {\n this.localActionName = this.selectedLocal[0].name\n }\n }\n\n isLocalSelected (entry: LocalEntry): boolean {\n return this.selectedLocal.includes(entry)\n }\n\n selectRemote (entry: SFTPFile, event: MouseEvent): void {\n const list = this.getFilteredRemoteEntries()\n const index = list.indexOf(entry)\n if (index === -1) {\n return\n }\n const isCtrl = event.ctrlKey || event.metaKey\n const isShift = event.shiftKey\n if (isShift && this.remoteLastSelectedIndex != null) {\n const [from, to] = this.remoteLastSelectedIndex < index\n ? [this.remoteLastSelectedIndex, index]\n : [index, this.remoteLastSelectedIndex]\n const range = list.slice(from, to + 1)\n const set = new Set(this.selectedRemote)\n for (const e of range) {\n set.add(e)\n }\n this.selectedRemote = Array.from(set)\n } else if (isCtrl) {\n const exists = this.selectedRemote.includes(entry)\n if (exists) {\n this.selectedRemote = this.selectedRemote.filter(e => e !== entry)\n } else {\n this.selectedRemote = [...this.selectedRemote, entry]\n }\n this.remoteLastSelectedIndex = index\n } else {\n this.selectedRemote = [entry]\n this.remoteLastSelectedIndex = index\n }\n if (this.selectedRemote.length === 1) {\n this.remoteActionName = this.selectedRemote[0].name\n const currentPerms = (this.selectedRemote[0].mode & 0o777).toString(8)\n this.remoteActionPerms = currentPerms\n }\n }\n\n isRemoteSelected (entry: SFTPFile): boolean {\n return this.selectedRemote.includes(entry)\n }\n\n setLocalSort (field: 'name' | 'size' | 'modified'): void {\n if (this.localSortBy === field) {\n this.localSortAsc = !this.localSortAsc\n } else {\n this.localSortBy = field\n this.localSortAsc = true\n }\n }\n\n setRemoteSort (field: 'name' | 'size' | 'modified'): void {\n if (this.remoteSortBy === field) {\n this.remoteSortAsc = !this.remoteSortAsc\n } else {\n this.remoteSortBy = field\n this.remoteSortAsc = true\n }\n }\n\n onDragStartLocal (ev: DragEvent, e: LocalEntry): void {\n const sources = this.selectedLocal.includes(e) && this.selectedLocal.length ? this.selectedLocal : [e]\n const movePayload = sources.map(x => x.fullPath)\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-local-move', JSON.stringify(movePayload))\n\n // Existing cross-device drag (local -> remote) only for files\n if (!e.isDirectory) {\n const payload: DragPayload = { kind: 'local-file', fullPath: e.fullPath, name: e.name }\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\n ev.dataTransfer?.setData('text/plain', e.fullPath)\n }\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\n }\n\n onDragStartRemote (ev: DragEvent, item: SFTPFile): void {\n if (!this.connected) {\n return\n }\n const sources = this.selectedRemote.includes(item) && this.selectedRemote.length ? this.selectedRemote : [item]\n const movePayload = sources.map(x => x.fullPath)\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui-remote-move', JSON.stringify(movePayload))\n\n // Existing cross-device drag (remote -> local) only for files\n const payload: DragPayload = item.isDirectory\n ? { kind: 'remote-dir', remotePath: item.fullPath, name: item.name }\n : { kind: 'remote-file', remotePath: item.fullPath, name: item.name, size: item.size, mode: item.mode }\n ev.dataTransfer?.setData('application/x-tabby-sftp-ui', JSON.stringify(payload))\n ev.dataTransfer?.setData('text/plain', item.fullPath)\n ev.dataTransfer?.setDragImage?.((ev.target as HTMLElement) ?? document.body, 0, 0)\n }\n\n async onDropOnRemote (ev: DragEvent): Promise<void> {\n ev.preventDefault()\n this.remoteDropActive = false\n if (!this.connected) {\n return\n }\n if (!this.sftpSession) {\n return\n }\n\n // Drag & drop from OS file manager (Explorer/Finder) into the remote pane\n const osPaths = this.getDroppedOsPaths(ev)\n if (osPaths.length) {\n try {\n for (const p of osPaths) {\n const baseName = path.basename(p)\n const existing = this.remoteEntries.find(e => e.name === baseName)\n if (existing) {\n const ok = await this.showReplaceConfirm(`Replace existing \"${baseName}\" on remote?`)\n if (!ok) {\n continue\n }\n const remoteTarget = path.posix.join(this.remotePath, baseName)\n await this.deleteRemotePathRecursive(remoteTarget)\n }\n await this.uploadLocalPathToRemote(this.remotePath, p)\n }\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Upload from OS drop failed', e)\n }\n return\n }\n\n // Fallback: use Tabby's native drag parser (supports directories and HTMLFileUpload)\n try {\n const dirUpload = await (this.platform as any).startUploadFromDragEvent?.(ev, true)\n if (dirUpload && this.sftpSession) {\n await this.uploadDirectoryUploadToRemote(this.remotePath, dirUpload)\n await this.refreshRemote()\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] startUploadFromDragEvent failed', e)\n }\n\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\n if (!raw) {\n return\n }\n let payload: DragPayload\n try {\n payload = JSON.parse(raw) as DragPayload\n } catch {\n return\n }\n if (payload.kind !== 'local-file') {\n return\n }\n try {\n const targetRemotePath = path.posix.join(this.remotePath, payload.name)\n const existsOnRemote = this.remoteEntries.some(e => e.name === payload.name)\n if (existsOnRemote) {\n const ok = await this.showReplaceConfirm(`Replace existing \"${payload.name}\" on remote?`)\n if (!ok) {\n return\n }\n await this.deleteRemotePathRecursive(targetRemotePath)\n }\n const upload = new LocalPathFileUpload(payload.fullPath)\n this.trackTransfer(upload, 'upload', targetRemotePath, payload.fullPath)\n await this.sftpSession.upload(targetRemotePath, upload)\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Upload failed', e)\n }\n }\n\n async onDropOnLocal (ev: DragEvent): Promise<void> {\n ev.preventDefault()\n this.localDropActive = false\n\n // 1) Tabby's internal drag (remote -> local download)\n const rawInternal = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\n if (rawInternal) {\n let payload: DragPayload\n try {\n payload = JSON.parse(rawInternal) as DragPayload\n } catch {\n payload = null as any\n }\n if (payload && payload.kind === 'remote-file') {\n try {\n const targetLocalPath = path.join(this.localPath, payload.name)\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n if (fsSync.existsSync(targetLocalPath)) {\n const ok = await this.showReplaceConfirm(`Replace existing \"${payload.name}\"?`)\n if (!ok) {\n return\n }\n }\n const dl = new LocalPathFileDownload(targetLocalPath, payload.mode, payload.size)\n this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath)\n await this.sftpSession.download(payload.remotePath, dl)\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Download failed', e)\n }\n return\n }\n\n if (payload && payload.kind === 'remote-dir') {\n try {\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n const targetLocalPath = path.join(this.localPath, payload.name)\n if (fsSync.existsSync(targetLocalPath)) {\n const ok = await this.showReplaceConfirm(`Replace existing folder \"${payload.name}\"?`)\n if (!ok) {\n return\n }\n await this.deleteLocalPathRecursive(targetLocalPath)\n }\n await this.downloadRemoteDirectoryRecursive(payload.remotePath, targetLocalPath)\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Download directory failed', e)\n }\n return\n }\n }\n\n // Drag & drop from OS file manager into the local pane (copy into current local folder)\n const osPaths = this.getDroppedOsPaths(ev)\n if (osPaths.length) {\n try {\n for (const p of osPaths) {\n const baseName = path.basename(p)\n const destPath = path.join(this.localPath, baseName)\n if (fsSync.existsSync(destPath)) {\n const ok = await this.showReplaceConfirm(`Replace existing \"${baseName}\"?`)\n if (!ok) {\n continue\n }\n }\n await this.copyLocalPathIntoLocalDir(this.localPath, p)\n }\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Local copy from OS drop failed', e)\n }\n return\n }\n\n // Fallback: use Tabby's native drag parser, then write files to disk\n try {\n const dirUpload = await (this.platform as any).startUploadFromDragEvent?.(ev, true)\n if (dirUpload) {\n await this.writeDirectoryUploadToLocal(this.localPath, dirUpload)\n await this.refreshLocal()\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] startUploadFromDragEvent (local) failed', e)\n }\n\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui')\n if (!raw) {\n return\n }\n let payload: DragPayload\n try {\n payload = JSON.parse(raw) as DragPayload\n } catch {\n return\n }\n if (payload.kind !== 'remote-file' && payload.kind !== 'remote-dir') {\n return\n }\n try {\n if (payload.kind === 'remote-file') {\n const targetLocalPath = path.join(this.localPath, payload.name)\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n if (fsSync.existsSync(targetLocalPath)) {\n const ok = await this.showReplaceConfirm(`Replace existing \"${payload.name}\"?`)\n if (!ok) {\n return\n }\n await this.deleteLocalPathRecursive(targetLocalPath)\n }\n const dl = new LocalPathFileDownload(targetLocalPath, payload.mode, payload.size)\n this.trackTransfer(dl, 'download', payload.remotePath, targetLocalPath)\n await this.sftpSession.download(payload.remotePath, dl)\n await this.refreshLocal()\n return\n }\n\n // remote-dir -> local-dir (recursive download)\n if (!this.sftpSession) {\n throw new Error('Not connected')\n }\n const targetLocalPath = path.join(this.localPath, payload.name)\n if (fsSync.existsSync(targetLocalPath)) {\n const ok = await this.showReplaceConfirm(`Replace existing folder \"${payload.name}\"?`)\n if (!ok) {\n return\n }\n await this.deleteLocalPathRecursive(targetLocalPath)\n }\n await this.downloadRemoteDirectoryRecursive(payload.remotePath, targetLocalPath)\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Download failed', e)\n }\n }\n\n private async uploadLocalPathToRemote (remoteDir: string, localPath: string): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n const st = await fs.stat(localPath).catch(() => null)\n if (!st) {\n return\n }\n const baseName = path.basename(localPath)\n const remoteTarget = path.posix.join(remoteDir, baseName)\n\n if (st.isDirectory()) {\n // Ensure destination folder exists, then recursively upload children\n try {\n await this.sftpSession.mkdir(remoteTarget)\n } catch {\n // ignore (might already exist)\n }\n const children = await fs.readdir(localPath)\n for (const child of children) {\n await this.uploadLocalPathToRemote(remoteTarget, path.join(localPath, child))\n }\n return\n }\n\n const upload = new LocalPathFileUpload(localPath)\n this.trackTransfer(upload, 'upload', remoteTarget, localPath)\n await this.sftpSession.upload(remoteTarget, upload)\n }\n\n private async copyLocalPathIntoLocalDir (destDir: string, srcPath: string): Promise<void> {\n const st = await fs.stat(srcPath).catch(() => null)\n if (!st) {\n return\n }\n const baseName = path.basename(srcPath)\n const destPath = path.join(destDir, baseName)\n\n if (st.isDirectory()) {\n await fs.mkdir(destPath, { recursive: true })\n const children = await fs.readdir(srcPath)\n for (const child of children) {\n await this.copyLocalPathIntoLocalDir(destPath, path.join(srcPath, child))\n }\n return\n }\n\n await fs.copyFile(srcPath, destPath)\n }\n\n private async uploadDirectoryUploadToRemote (remoteDir: string, dirUpload: any): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n const childrens: any[] = dirUpload?.getChildrens?.() ?? []\n for (const item of childrens) {\n // DirectoryUpload\n if (typeof item?.getChildrens === 'function') {\n const name = item.getName?.() || 'folder'\n const nextRemote = path.posix.join(remoteDir, name)\n try {\n await this.sftpSession.mkdir(nextRemote)\n } catch {\n // ignore (might already exist)\n }\n await this.uploadDirectoryUploadToRemote(nextRemote, item)\n continue\n }\n\n // FileUpload (including HTMLFileUpload)\n if (typeof item?.read === 'function' && typeof item?.getName === 'function') {\n const fileUpload = item as FileUpload\n const name = fileUpload.getName()\n const targetRemotePath = path.posix.join(remoteDir, name)\n this.trackTransfer(fileUpload as any, 'upload', targetRemotePath, name)\n await this.sftpSession.upload(targetRemotePath, fileUpload as any)\n }\n }\n }\n\n private async writeDirectoryUploadToLocal (localDir: string, dirUpload: any): Promise<void> {\n const childrens: any[] = dirUpload?.getChildrens?.() ?? []\n for (const item of childrens) {\n if (typeof item?.getChildrens === 'function') {\n const name = item.getName?.() || 'folder'\n const nextLocal = path.join(localDir, name)\n await fs.mkdir(nextLocal, { recursive: true })\n await this.writeDirectoryUploadToLocal(nextLocal, item)\n continue\n }\n\n if (typeof item?.readAll === 'function' && typeof item?.getName === 'function') {\n const name = item.getName()\n const targetLocal = path.join(localDir, name)\n const buf = await item.readAll()\n await fs.writeFile(targetLocal, Buffer.from(buf))\n try {\n item.close?.()\n } catch {\n // ignore\n }\n }\n }\n }\n\n private async downloadRemoteDirectoryRecursive (remoteDir: string, localDir: string): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n await fs.mkdir(localDir, { recursive: true })\n const entries = await this.sftpSession.readdir(remoteDir).catch(() => null as any)\n if (!entries) {\n return\n }\n for (const e of entries as SFTPFile[]) {\n const targetLocal = path.join(localDir, e.name)\n if (e.isDirectory) {\n await this.downloadRemoteDirectoryRecursive(e.fullPath, targetLocal)\n } else {\n const dl = new LocalPathFileDownload(targetLocal, e.mode, e.size)\n this.trackTransfer(dl, 'download', e.fullPath, targetLocal)\n await this.sftpSession.download(e.fullPath, dl)\n }\n }\n }\n\n private getDroppedOsPaths (ev: DragEvent): string[] {\n const dt = ev.dataTransfer\n if (!dt) {\n return []\n }\n const isWin = os.platform() === 'win32'\n const isLocalPath = (p: string): boolean => {\n if (isWin) {\n return /^[A-Za-z]:\\\\/.test(p) || p.startsWith('\\\\\\\\')\n }\n return p.startsWith('/')\n }\n\n // 1) Electron-style File.path\n const filePaths = Array.from(dt.files ?? [])\n .map(f => (f as any).path as string | undefined)\n .filter((p): p is string => Boolean(p))\n if (filePaths.length) {\n return filePaths\n }\n\n // 2) Sometimes paths are exposed as URIs\n const uriList = dt.getData('text/uri-list') || ''\n const uris = uriList\n .split(/\\r?\\n/g)\n .map(x => x.trim())\n .filter(x => x && !x.startsWith('#'))\n .map(x => {\n if (x.startsWith('file://')) {\n try {\n return decodeURIComponent(x.replace(/^file:\\/\\//, ''))\n } catch {\n return x.replace(/^file:\\/\\//, '')\n }\n }\n return x\n })\n .filter(x => x && isLocalPath(x))\n if (uris.length) {\n return uris\n }\n\n // 3) Plain text sometimes contains a local path\n const text = dt.getData('text/plain') || ''\n const textLines = text.split(/\\r?\\n/g).map(x => x.trim()).filter(Boolean)\n const textPaths = textLines\n .map(x => {\n if (x.startsWith('file://')) {\n try {\n return decodeURIComponent(x.replace(/^file:\\/\\//, ''))\n } catch {\n return x.replace(/^file:\\/\\//, '')\n }\n }\n return x\n })\n .filter(x => x && isLocalPath(x))\n return textPaths\n }\n\n getFilteredLocalEntries (): LocalEntry[] {\n const entriesRef = this.localEntries\n const filter = this.localFilter\n const showHidden = this.showHiddenLocal\n const sortBy = this.localSortBy\n const asc = this.localSortAsc\n\n if (this.localCache &&\n this.localCache.entriesRef === entriesRef &&\n this.localCache.filter === filter &&\n this.localCache.showHidden === showHidden &&\n this.localCache.sortBy === sortBy &&\n this.localCache.asc === asc) {\n return this.localCache.result\n }\n\n const term = filter.trim().toLowerCase()\n let entries = entriesRef\n if (!showHidden) {\n entries = entries.filter(e => !e.name.startsWith('.'))\n }\n if (term) {\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\n }\n const result = this.sortLocalEntries(entries.slice())\n this.localCache = { entriesRef, filter, showHidden, sortBy, asc, result }\n return result\n }\n\n getFilteredRemoteEntries (): SFTPFile[] {\n const entriesRef = this.remoteEntries\n const filter = this.remoteFilter\n const showHidden = this.showHiddenRemote\n const sortBy = this.remoteSortBy\n const asc = this.remoteSortAsc\n\n if (this.remoteCache &&\n this.remoteCache.entriesRef === entriesRef &&\n this.remoteCache.filter === filter &&\n this.remoteCache.showHidden === showHidden &&\n this.remoteCache.sortBy === sortBy &&\n this.remoteCache.asc === asc) {\n return this.remoteCache.result\n }\n\n const term = filter.trim().toLowerCase()\n let entries = entriesRef\n if (!showHidden) {\n entries = entries.filter(e => !e.name.startsWith('.'))\n }\n if (term) {\n entries = entries.filter(e => e.name.toLowerCase().includes(term))\n }\n const result = this.sortRemoteEntries(entries.slice())\n this.remoteCache = { entriesRef, filter, showHidden, sortBy, asc, result }\n return result\n }\n\n private sortLocalEntries (entries: LocalEntry[]): LocalEntry[] {\n const dirFirst = (a: LocalEntry, b: LocalEntry) => Number(b.isDirectory) - Number(a.isDirectory)\n const factor = this.localSortAsc ? 1 : -1\n const field = this.localSortBy\n return entries.sort((a, b) => {\n const d = dirFirst(a, b)\n if (d !== 0) return d\n if (field === 'name') {\n return a.name.localeCompare(b.name) * factor\n }\n if (field === 'size') {\n const av = a.size ?? 0\n const bv = b.size ?? 0\n return (av - bv) * factor\n }\n const av = a.mtimeMs ?? 0\n const bv = b.mtimeMs ?? 0\n return (av - bv) * factor\n })\n }\n\n private sortRemoteEntries (entries: SFTPFile[]): SFTPFile[] {\n const dirFirst = (a: SFTPFile, b: SFTPFile) => Number(b.isDirectory) - Number(a.isDirectory)\n const factor = this.remoteSortAsc ? 1 : -1\n const field = this.remoteSortBy\n return entries.sort((a, b) => {\n const d = dirFirst(a, b)\n if (d !== 0) return d\n if (field === 'name') {\n return a.name.localeCompare(b.name) * factor\n }\n if (field === 'size') {\n const av = a.size ?? 0\n const bv = b.size ?? 0\n return (av - bv) * factor\n }\n const av = a.modified?.getTime?.() ?? 0\n const bv = b.modified?.getTime?.() ?? 0\n return (av - bv) * factor\n })\n }\n\n private getLocalMovePayload (ev: DragEvent): string[] | null {\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-local-move')\n if (!raw) {\n return null\n }\n try {\n const arr = JSON.parse(raw) as string[]\n if (Array.isArray(arr)) {\n return arr\n }\n } catch {\n // ignore\n }\n return null\n }\n\n private getRemoteMovePayload (ev: DragEvent): string[] | null {\n const raw = ev.dataTransfer?.getData('application/x-tabby-sftp-ui-remote-move')\n if (!raw) {\n return null\n }\n try {\n const arr = JSON.parse(raw) as string[]\n if (Array.isArray(arr)) {\n return arr\n }\n } catch {\n // ignore\n }\n return null\n }\n\n formatSize (bytes?: number): string {\n if (bytes === undefined || bytes === null) {\n return ''\n }\n if (bytes === 0) {\n return '0 B'\n }\n const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']\n let value = bytes\n let unitIndex = 0\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024\n unitIndex++\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\n return `${value.toFixed(digits)} ${units[unitIndex]}`\n }\n\n formatSpeed (bytesPerSecond?: number): string {\n if (bytesPerSecond === undefined || bytesPerSecond === null) {\n return ''\n }\n if (bytesPerSecond === 0) {\n return '0 B/s'\n }\n const units = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s']\n let value = bytesPerSecond\n let unitIndex = 0\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024\n unitIndex++\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1\n return `${value.toFixed(digits)} ${units[unitIndex]}`\n }\n\n getLocalSizeDisplay (e: LocalEntry): string {\n if (!e.isDirectory) {\n return this.formatSize(e.size)\n }\n if (e.size !== undefined) {\n return this.formatSize(e.size)\n }\n if (this.localFolderSizeLoading.has(e.fullPath)) {\n return '…'\n }\n return ''\n }\n\n getRemoteSizeDisplay (e: SFTPFile): string {\n if (!e.isDirectory) {\n return this.formatSize(e.size)\n }\n const key = e.fullPath\n if ((e as any).dirSize !== undefined) {\n return this.formatSize((e as any).dirSize)\n }\n if (this.remoteFolderSizeLoading.has(key)) {\n return '…'\n }\n return ''\n }\n\n onLocalEntryDragOver (entry: LocalEntry, ev: DragEvent): void {\n if (!entry.isDirectory) {\n return\n }\n if (!this.getLocalMovePayload(ev)) {\n return\n }\n ev.preventDefault()\n }\n\n async onLocalEntryDrop (entry: LocalEntry, ev: DragEvent): Promise<void> {\n if (!entry.isDirectory) {\n return\n }\n const sources = this.getLocalMovePayload(ev)\n if (!sources || !sources.length) {\n return\n }\n ev.preventDefault()\n const targetDir = entry.fullPath\n try {\n for (const src of sources) {\n if (!src || src === targetDir) {\n continue\n }\n // avoid moving a directory into its own subtree\n if (targetDir.startsWith(src + path.sep)) {\n continue\n }\n const name = path.basename(src)\n const dst = path.join(targetDir, name)\n if (dst === src) {\n continue\n }\n try {\n await fs.rename(src, dst)\n } catch (e) {\n console.error('[SFTP-UI] Local move failed', e)\n }\n }\n await this.refreshLocal()\n } catch (e) {\n console.error('[SFTP-UI] Local move batch failed', e)\n }\n }\n\n onRemoteEntryDragOver (entry: SFTPFile, ev: DragEvent): void {\n if (!entry.isDirectory) {\n return\n }\n if (!this.getRemoteMovePayload(ev)) {\n return\n }\n ev.preventDefault()\n }\n\n async onRemoteEntryDrop (entry: SFTPFile, ev: DragEvent): Promise<void> {\n if (!entry.isDirectory || !this.sftpSession || !this.connected) {\n return\n }\n const sources = this.getRemoteMovePayload(ev)\n if (!sources || !sources.length) {\n return\n }\n ev.preventDefault()\n const targetDir = entry.fullPath\n try {\n for (const src of sources) {\n if (!src || src === targetDir) {\n continue\n }\n // avoid moving a directory into its own subtree\n if (targetDir.startsWith(src + '/')) {\n continue\n }\n const name = src.split('/').filter(Boolean).pop() || ''\n if (!name) {\n continue\n }\n const dst = path.posix.join(targetDir, name)\n if (dst === src) {\n continue\n }\n try {\n await this.sftpSession.rename(src, dst)\n } catch (e) {\n console.error('[SFTP-UI] Remote move failed', e)\n }\n }\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Remote move batch failed', e)\n }\n }\n\n getRemoteBreadcrumbs (): Array<{ label: string, path: string }> {\n const parts = this.remotePath.split('/').filter(Boolean)\n const crumbs: Array<{ label: string, path: string }> = []\n let current = '/'\n crumbs.push({ label: '/', path: '/' })\n for (const p of parts) {\n current = current === '/' ? `/${p}` : `${current}/${p}`\n crumbs.push({ label: p, path: current })\n }\n return crumbs\n }\n\n navigateRemoteBreadcrumb (index: number): void {\n const crumbs = this.getRemoteBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n this.remotePath = crumb.path\n this.remotePathInput = this.remotePath\n void this.refreshRemote()\n }\n\n goToRemotePathInput (): void {\n if (!this.connected) {\n return\n }\n const target = this.normalizeRemotePath(this.remotePathInput || '/')\n this.remotePath = target\n this.remotePathInput = target\n void this.refreshRemote()\n }\n\n goToLocalPathInput (): void {\n const target = this.normalizeLocalPath(this.localPathInput || this.localPath)\n this.goToLocalPath(target)\n }\n\n getLocalBreadcrumbs (): Array<{ label: string, path: string }> {\n const currentPath = this.localPath\n const parsed = path.parse(currentPath)\n const root = parsed.root || path.sep\n const withoutRoot = currentPath.slice(root.length)\n const parts = withoutRoot.split(path.sep).filter(Boolean)\n const crumbs: Array<{ label: string, path: string }> = []\n\n const rootLabel = root.replace(/[\\\\\\/]+$/, '') || root\n crumbs.push({ label: rootLabel, path: root })\n\n let accum = root\n for (const p of parts) {\n accum = path.join(accum, p)\n crumbs.push({ label: p, path: accum })\n }\n return crumbs\n }\n\n navigateLocalBreadcrumb (index: number): void {\n const crumbs = this.getLocalBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n this.goToLocalPath(crumb.path)\n }\n\n private goToLocalPath (target: string): void {\n this.localPath = target\n this.localPathInput = target\n void this.refreshLocal()\n }\n\n onLocalPresetChange (id: string): void {\n if (!id) {\n return\n }\n const preset = this.localPathPresets.find(p => p.id === id)\n if (!preset) {\n return\n }\n this.goToLocalPath(preset.path)\n }\n\n isCurrentFavorite (): boolean {\n return this.localFavorites.some(f => f.path === this.localPath)\n }\n\n toggleCurrentFavorite (): void {\n const existingIndex = this.localFavorites.findIndex(f => f.path === this.localPath)\n if (existingIndex >= 0) {\n this.localFavorites.splice(existingIndex, 1)\n this.saveLocalFavorites()\n return\n }\n const label = path.basename(this.localPath) || this.localPath\n const id = `fav-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\n this.localFavorites.push({ id, label, path: this.localPath })\n this.saveLocalFavorites()\n }\n\n onLocalFavoriteSelect (id: string): void {\n if (!id) {\n return\n }\n const fav = this.localFavorites.find(f => f.id === id)\n if (!fav) {\n return\n }\n this.goToLocalPath(fav.path)\n }\n\n onLocalBreadcrumbContextMenu (index: number, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n const crumbs = this.getLocalBreadcrumbs()\n const crumb = crumbs[index]\n if (!crumb) {\n return\n }\n\n const menuItems: Array<{ label: string, path: string }> = []\n const isWindows = process.platform === 'win32'\n const isRootCrumb = index === 0\n\n const basePath = crumb.path\n\n // Root crumb on Windows: offer other drives as \"siblings\"\n if (isWindows && isRootCrumb) {\n const drives: string[] = []\n for (let code = 67; code <= 90; code++) { // C..Z\n const letter = String.fromCharCode(code)\n const rootPath = `${letter}:\\\\`\n try {\n if (fsSync.existsSync(rootPath)) {\n drives.push(rootPath)\n }\n } catch {\n // ignore\n }\n }\n for (const d of drives) {\n menuItems.push({ label: d, path: d })\n }\n } else {\n // For non-root crumbs (or non-Windows), show sibling folders only\n const parentPath = path.dirname(basePath)\n try {\n const parentEntries = fsSync.readdirSync(parentPath)\n for (const name of parentEntries) {\n const full = path.join(parentPath, name)\n try {\n const st = fsSync.statSync(full)\n if (st.isDirectory()) {\n menuItems.push({ label: name, path: full })\n }\n } catch {\n // ignore\n }\n }\n } catch {\n // ignore\n }\n }\n\n if (!menuItems.length) {\n return\n }\n\n this.localMenuItems = menuItems\n this.localMenuVisible = true\n this.localMenuX = event.clientX\n this.localMenuY = event.clientY\n }\n\n private loadLocalFavorites (): void {\n try {\n if (typeof window === 'undefined' || !window.localStorage) {\n return\n }\n const raw = window.localStorage.getItem('tabby-sftp-ui-local-favorites')\n if (!raw) {\n return\n }\n const parsed = JSON.parse(raw)\n if (Array.isArray(parsed)) {\n this.localFavorites = parsed\n .filter(f => f && typeof f.path === 'string')\n .map(f => ({\n id: String(f.id || `fav-${Math.random().toString(36).slice(2, 8)}`),\n label: String(f.label || path.basename(f.path) || f.path),\n path: String(f.path),\n }))\n }\n } catch {\n // ignore\n }\n }\n\n private saveLocalFavorites (): void {\n try {\n if (typeof window === 'undefined' || !window.localStorage) {\n return\n }\n window.localStorage.setItem('tabby-sftp-ui-local-favorites', JSON.stringify(this.localFavorites))\n } catch {\n // ignore\n }\n }\n\n onLocalMenuItemClick (item: { label: string, path: string }): void {\n this.localMenuVisible = false\n this.goToLocalPath(item.path)\n }\n\n private normalizeLocalPath (p: string): string {\n if (!p) {\n return this.localPath\n }\n let result = p.trim()\n // On Windows allow drive letters and backslashes, but normalize to current OS-style\n if (path.win32.isAbsolute(result) || path.posix.isAbsolute(result)) {\n return result\n }\n // relative path from current localPath\n return path.join(this.localPath, result)\n }\n\n private normalizeRemotePath (p: string): string {\n if (!p) {\n return '/'\n }\n let result = p.trim()\n if (!result.startsWith('/')) {\n result = '/' + result\n }\n // remove duplicate slashes\n result = result.replace(/\\/+/g, '/')\n return result\n }\n\n private getDefaultRemotePath (): string {\n const username = (this.profile && (this.profile.options?.username || this.profile.options?.user)) || ''\n if (username) {\n return `/home/${username}`\n }\n return '/'\n }\n\n private loadRecentProfiles (): void {\n try {\n const rec = this.profilesService.getRecentProfiles?.()\n if (Array.isArray(rec)) {\n this.recentProfiles = rec\n }\n } catch {\n this.recentProfiles = []\n }\n }\n\n getProfileLabel (p: any): string {\n if (!p) {\n return ''\n }\n return p.name || p.options?.host || p.id || 'Profile'\n }\n\n launchProfileFromSFTP (p: any): void {\n try {\n void this.profilesService.launchProfile(p)\n } catch (e) {\n console.error('[SFTP-UI] launchProfile failed', e)\n }\n }\n\n @HostListener('document:click')\n onDocumentClick (): void {\n this.localMenuVisible = false\n }\n\n localRename (): void {\n if (this.selectedLocal.length !== 1) {\n return\n }\n const entry = this.selectedLocal[0]\n this.openInputDialog({\n mode: 'local-rename',\n title: 'Rename (local)',\n placeholder: 'New name',\n value: entry.name,\n targetPath: entry.fullPath,\n })\n }\n\n localDelete (): void {\n if (!this.selectedLocal.length) {\n return\n }\n this.deleteConfirmMode = 'local'\n this.pendingLocalDelete = this.selectedLocal.slice()\n const names = this.pendingLocalDelete.map(e => e.name)\n this.deleteConfirmText = this.buildDeleteConfirmText('local', names)\n this.deleteConfirmVisible = true\n }\n\n localNewFolder (): void {\n this.openInputDialog({\n mode: 'local-new-folder',\n title: 'New folder (local)',\n placeholder: 'Folder name',\n value: 'New folder',\n targetPath: this.localPath,\n })\n }\n\n localEditPermissions (): void {\n if (this.selectedLocal.length !== 1 || !this.localActionPerms?.trim()) {\n return\n }\n const entry = this.selectedLocal[0]\n const mode = parseInt(this.localActionPerms.trim(), 8)\n if (Number.isNaN(mode)) {\n console.error('[SFTP-UI] Invalid local permissions value')\n return\n }\n void fs.chmod(entry.fullPath, mode as any)\n .then(() => this.refreshLocal())\n .catch(e => console.error('[SFTP-UI] Local chmod failed', e))\n }\n\n localShowSize (): void {\n if (this.selectedLocal.length === 1 && this.selectedLocal[0].isDirectory) {\n this.ensureLocalFolderSize(this.selectedLocal[0])\n }\n }\n\n remoteRename (): void {\n if (this.selectedRemote.length !== 1 || !this.sftpSession) {\n return\n }\n const entry = this.selectedRemote[0]\n this.openInputDialog({\n mode: 'remote-rename',\n title: 'Rename (remote)',\n placeholder: 'New name',\n value: entry.name,\n remotePath: entry.fullPath,\n targetPath: this.remotePath,\n })\n }\n\n remoteDelete (): void {\n if (!this.selectedRemote.length || !this.sftpSession) {\n return\n }\n this.deleteConfirmMode = 'remote'\n this.pendingRemoteDelete = this.selectedRemote.slice()\n const names = this.pendingRemoteDelete.map(e => e.name)\n this.deleteConfirmText = this.buildDeleteConfirmText('remote', names)\n this.deleteConfirmVisible = true\n }\n\n remoteNewFolder (): void {\n if (!this.sftpSession) {\n return\n }\n this.openInputDialog({\n mode: 'remote-new-folder',\n title: 'New folder (remote)',\n placeholder: 'Folder name',\n value: 'New folder',\n targetPath: this.remotePath,\n })\n }\n\n private openInputDialog (opts: {\n mode: NonNullable<SftpManagerTabComponent['inputDialogMode']>\n title: string\n placeholder: string\n value: string\n targetPath: string\n remotePath?: string\n }): void {\n this.inputDialogMode = opts.mode\n this.inputDialogTitle = opts.title\n this.inputDialogPlaceholder = opts.placeholder\n this.inputDialogValue = opts.value\n this.inputDialogTargetPath = opts.targetPath\n this.inputDialogRemotePath = opts.remotePath ?? null\n this.inputDialogVisible = true\n }\n\n cancelInputDialog (): void {\n this.inputDialogVisible = false\n this.inputDialogMode = null\n this.inputDialogTitle = ''\n this.inputDialogPlaceholder = ''\n this.inputDialogValue = ''\n this.inputDialogTargetPath = null\n this.inputDialogRemotePath = null\n }\n\n async confirmInputDialog (): Promise<void> {\n if (!this.inputDialogVisible || !this.inputDialogMode) {\n return\n }\n const mode = this.inputDialogMode\n const value = this.inputDialogValue.trim()\n const targetPath = this.inputDialogTargetPath\n const remotePath = this.inputDialogRemotePath\n this.cancelInputDialog()\n\n if (!value || !targetPath) {\n return\n }\n\n try {\n if (mode === 'local-new-folder') {\n const dir = targetPath\n const folderPath = path.join(dir, value)\n await fs.mkdir(folderPath, { recursive: true })\n await this.refreshLocal()\n return\n }\n\n if (mode === 'local-rename') {\n const from = targetPath\n const to = path.join(this.localPath, value)\n if (path.basename(from) === value) {\n return\n }\n await fs.rename(from, to)\n await this.refreshLocal()\n return\n }\n\n if (mode === 'remote-new-folder') {\n if (!this.sftpSession) {\n return\n }\n const dir = targetPath\n const folderPath = path.posix.join(dir, value)\n await this.sftpSession.mkdir(folderPath)\n await this.refreshRemote()\n return\n }\n\n if (mode === 'remote-rename') {\n if (!this.sftpSession || !remotePath) {\n return\n }\n const to = path.posix.join(this.remotePath, value)\n if (path.posix.basename(remotePath) === value) {\n return\n }\n await this.sftpSession.rename(remotePath, to)\n await this.refreshRemote()\n }\n } catch (e) {\n console.error('[SFTP-UI] Input dialog action failed', e)\n }\n }\n\n remoteEditPermissions (): void {\n if (this.selectedRemote.length !== 1 || !this.remoteActionPerms?.trim() || !this.sftpSession) {\n return\n }\n const entry = this.selectedRemote[0]\n const mode = parseInt(this.remoteActionPerms.trim(), 8)\n if (Number.isNaN(mode)) {\n console.error('[SFTP-UI] Invalid remote permissions value')\n return\n }\n void (this.sftpSession as any).chmod(entry.fullPath, mode)\n .then(() => this.refreshRemote())\n .catch((e: any) => console.error('[SFTP-UI] Remote chmod failed', e))\n }\n\n remoteShowSize (): void {\n if (this.selectedRemote.length === 1 && this.selectedRemote[0].isDirectory) {\n this.ensureRemoteFolderSize(this.selectedRemote[0])\n }\n }\n\n remoteDownload (): void {\n if (!this.selectedRemote.length || !this.sftpSession) {\n return\n }\n for (const entry of this.selectedRemote) {\n if (entry.isDirectory) {\n continue\n }\n const targetLocalPath = path.join(this.localPath, entry.name)\n const dl = new LocalPathFileDownload(targetLocalPath, entry.mode, entry.size)\n this.trackTransfer(dl, 'download', entry.fullPath, targetLocalPath)\n void this.sftpSession.download(entry.fullPath, dl)\n .then(() => this.refreshLocal())\n .catch(e => console.error('[SFTP-UI] Remote download failed', e))\n }\n }\n\n ensureLocalFolderSize (entry: LocalEntry): void {\n if (!entry.isDirectory) {\n return\n }\n if (entry.size !== undefined) {\n return\n }\n if (this.localFolderSizeLoading.has(entry.fullPath)) {\n return\n }\n this.localFolderSizeLoading.add(entry.fullPath)\n void this.computeLocalFolderSize(entry.fullPath)\n .then(size => {\n entry.size = size\n })\n .catch(e => {\n console.error('[SFTP-UI] Local folder size failed', e)\n })\n .finally(() => {\n this.localFolderSizeLoading.delete(entry.fullPath)\n })\n }\n\n ensureRemoteFolderSize (entry: SFTPFile): void {\n if (!entry.isDirectory) {\n return\n }\n const key = entry.fullPath\n if ((entry as any).dirSize !== undefined) {\n return\n }\n if (this.remoteFolderSizeLoading.has(key)) {\n return\n }\n if (!this.sftpSession || !this.connected) {\n return\n }\n this.remoteFolderSizeLoading.add(key)\n void this.computeRemoteFolderSize(key)\n .then(size => {\n ;(entry as any).dirSize = size\n })\n .catch(e => {\n console.error('[SFTP-UI] Remote folder size failed', e)\n })\n .finally(() => {\n this.remoteFolderSizeLoading.delete(key)\n })\n }\n\n private async computeLocalFolderSize (root: string): Promise<number> {\n let total = 0\n const stack: string[] = [root]\n const maxEntries = 5000\n let visited = 0\n while (stack.length) {\n const dir = stack.pop() as string\n let names: string[]\n try {\n names = await fs.readdir(dir)\n } catch {\n continue\n }\n for (const name of names) {\n if (visited++ > maxEntries) {\n return total\n }\n const full = path.join(dir, name)\n try {\n const st = await fs.stat(full)\n if (st.isDirectory()) {\n stack.push(full)\n } else {\n total += st.size\n }\n } catch {\n // ignore\n }\n }\n }\n return total\n }\n\n private async computeRemoteFolderSize (root: string): Promise<number> {\n if (!this.sftpSession) {\n return 0\n }\n let total = 0\n const stack: string[] = [root]\n const maxEntries = 5000\n let visited = 0\n while (stack.length) {\n const dir = stack.pop() as string\n let entries: SFTPFile[]\n try {\n entries = await this.sftpSession.readdir(dir)\n } catch {\n continue\n }\n for (const item of entries) {\n if (visited++ > maxEntries) {\n return total\n }\n if (item.isDirectory) {\n stack.push(item.fullPath)\n } else {\n total += item.size\n }\n }\n }\n return total\n }\n\n onLocalContextMenu (entry: LocalEntry, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\n }\n\n onRemoteContextMenu (entry: SFTPFile, event: MouseEvent): void {\n event.preventDefault()\n event.stopPropagation()\n\n if (!this.sftpSession) {\n return\n }\n // TODO: полноценное контекстное меню. Пока все действия — через нижнюю панель.\n }\n\n private trackTransfer (transfer: FileTransfer, direction: 'upload' | 'download', remotePath: string, localPath: string): void {\n this.transfers.push({\n transfer,\n direction,\n name: transfer.getName(),\n remotePath,\n localPath,\n })\n }\n\n cancelTransfer (entry: { transfer: FileTransfer }): void {\n try {\n if (entry.transfer.isComplete() || entry.transfer.isCancelled()) {\n return\n }\n entry.transfer.cancel?.()\n } catch (e) {\n console.error('[SFTP-UI] Cancel transfer failed', e)\n }\n }\n\n getTransferProgress (transfer: FileTransfer): number {\n try {\n const total = transfer.getSize?.()\n const done = transfer.getCompletedBytes?.()\n if (typeof total !== 'number' || total <= 0 || typeof done !== 'number' || done < 0) {\n return transfer.isComplete() ? 100 : 0\n }\n const value = (done / total) * 100\n const clamped = Math.max(0, Math.min(100, value))\n return clamped\n } catch {\n return transfer.isComplete() ? 100 : 0\n }\n }\n\n onKeyDown (event: KeyboardEvent): void {\n const target = event.target as HTMLElement | null\n const isTypingTarget = Boolean(target) && (\n target?.tagName === 'INPUT' ||\n target?.tagName === 'TEXTAREA' ||\n (target as any)?.isContentEditable\n )\n\n if (event.key === 'Escape') {\n if (this.inputDialogVisible) {\n event.preventDefault()\n this.cancelInputDialog()\n return\n }\n if (this.deleteConfirmVisible) {\n event.preventDefault()\n this.cancelDelete()\n return\n }\n if (this.replaceConfirmVisible) {\n event.preventDefault()\n this.cancelReplace()\n return\n }\n }\n if (event.key === 'Delete' || event.key === 'Backspace') {\n // Don't intercept Delete/Backspace while typing in inputs\n if (isTypingTarget) {\n return\n }\n event.preventDefault()\n if (this.selectedRemote.length) {\n this.remoteDelete()\n } else if (this.selectedLocal.length) {\n this.localDelete()\n }\n }\n }\n\n override destroy (): void {\n // stop file watchers for opened remote files\n for (const { watcher } of this.openedRemoteFiles.values()) {\n try {\n watcher?.close()\n } catch {\n // ignore\n }\n }\n this.openedRemoteFiles.clear()\n\n void this.disconnect()\n if (this.transfersTimer !== null) {\n clearInterval(this.transfersTimer)\n this.transfersTimer = null\n }\n super.destroy()\n }\n\n // Prevent Tabby from restoring SFTP-UI tabs across restarts, since they rely\n // on a live SSH session from a terminal tab.\n // Typинги допускают RecoveryToken | null, нам достаточно всегда возвращать null.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n override async getRecoveryToken (_options?: any): Promise<null> {\n return null\n }\n\n async confirmDelete (): Promise<void> {\n if (!this.deleteConfirmVisible) {\n return\n }\n const mode = this.deleteConfirmMode\n this.deleteConfirmVisible = false\n\n try {\n if (mode === 'local') {\n const toDelete = this.pendingLocalDelete.slice()\n this.pendingLocalDelete = []\n for (const entry of toDelete) {\n await this.deleteLocalEntry(entry)\n }\n await this.refreshLocal()\n this.selectedLocal = []\n } else if (mode === 'remote' && this.sftpSession) {\n const toDelete = this.pendingRemoteDelete.slice()\n this.pendingRemoteDelete = []\n for (const entry of toDelete) {\n await this.deleteRemoteEntry(entry)\n }\n await this.refreshRemote()\n this.selectedRemote = []\n }\n } catch (e) {\n console.error('[SFTP-UI] Delete failed', e)\n } finally {\n this.deleteConfirmMode = null\n this.deleteConfirmText = ''\n }\n }\n\n cancelDelete (): void {\n this.deleteConfirmVisible = false\n this.deleteConfirmMode = null\n this.deleteConfirmText = ''\n this.pendingLocalDelete = []\n this.pendingRemoteDelete = []\n }\n\n private async showReplaceConfirm (text: string): Promise<boolean> {\n if (this.replaceConfirmVisible) {\n // Prevent stacking multiple confirmations; choose the latest replacement intent.\n return false\n }\n this.replaceConfirmText = text\n this.replaceConfirmVisible = true\n return new Promise(resolve => {\n this.replaceConfirmResolve = resolve\n })\n }\n\n async confirmReplace (): Promise<void> {\n if (!this.replaceConfirmVisible) {\n return\n }\n this.replaceConfirmVisible = false\n const resolve = this.replaceConfirmResolve\n this.replaceConfirmResolve = null\n this.replaceConfirmText = ''\n resolve?.(true)\n }\n\n cancelReplace (): void {\n if (!this.replaceConfirmVisible) {\n return\n }\n this.replaceConfirmVisible = false\n const resolve = this.replaceConfirmResolve\n this.replaceConfirmResolve = null\n this.replaceConfirmText = ''\n resolve?.(false)\n }\n\n private async deleteLocalEntry (entry: LocalEntry): Promise<void> {\n await this.deleteLocalPathRecursive(entry.fullPath)\n }\n\n private async deleteRemoteEntry (entry: SFTPFile): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n await this.deleteRemotePathRecursive(entry.fullPath)\n }\n\n private buildDeleteConfirmText (scope: 'local' | 'remote', names: string[]): string {\n const total = names.length\n const label = scope === 'local' ? 'local' : 'remote'\n if (!total) {\n return `Delete 0 item(s) from ${label}?`\n }\n const maxShown = 5\n const shown = names.slice(0, maxShown)\n const list = shown.join(', ')\n if (total <= maxShown) {\n return `Delete ${total} item(s) from ${label}: ${list}?`\n }\n const rest = total - maxShown\n return `Delete ${total} item(s) from ${label}: ${list} and ${rest} more?`\n }\n\n private async deleteLocalPathRecursive (target: string): Promise<void> {\n try {\n const st = await fs.stat(target)\n if (!st.isDirectory()) {\n await fs.unlink(target)\n return\n }\n } catch (e) {\n console.error('[SFTP-UI] Local delete failed (stat)', e)\n return\n }\n\n try {\n const names = await fs.readdir(target)\n for (const name of names) {\n const child = path.join(target, name)\n await this.deleteLocalPathRecursive(child)\n }\n await fs.rmdir(target)\n } catch (e) {\n console.error('[SFTP-UI] Local recursive delete failed', e)\n }\n }\n\n private async deleteRemotePathRecursive (target: string): Promise<void> {\n if (!this.sftpSession) {\n return\n }\n try {\n const entries = await this.sftpSession.readdir(target).catch(() => null as any)\n if (!entries) {\n // treat as file\n try {\n await this.sftpSession.unlink(target)\n } catch (e) {\n console.error('[SFTP-UI] Remote delete failed', e)\n }\n return\n }\n for (const item of entries as SFTPFile[]) {\n const full = item.fullPath\n if (item.isDirectory) {\n await this.deleteRemotePathRecursive(full)\n } else {\n try {\n await this.sftpSession.unlink(full)\n } catch (e) {\n console.error('[SFTP-UI] Remote unlink failed', e)\n }\n }\n }\n try {\n await this.sftpSession.rmdir(target)\n } catch (e) {\n console.error('[SFTP-UI] Remote rmdir failed', e)\n }\n } catch (e) {\n console.error('[SFTP-UI] Remote recursive delete failed', e)\n }\n }\n\n private async openRemoteFile (entry: SFTPFile): Promise<void> {\n if (!this.sftpSession || !this.connected || entry.isDirectory) {\n return\n }\n try {\n const tmpRoot = path.join(os.tmpdir(), 'tabby-sftp-ui')\n await fs.mkdir(tmpRoot, { recursive: true })\n const hash = crypto.createHash('sha1').update(entry.fullPath).digest('hex').slice(0, 10)\n const safeName = entry.name.replace(/[<>:\"/\\\\|?*\\x00-\\x1F]/g, '_')\n const localPath = path.join(tmpRoot, `${hash}-${safeName}`)\n\n // если уже есть watcher на этот файл – закроем его и перезапишем\n const existing = this.openedRemoteFiles.get(localPath)\n if (existing?.watcher) {\n try {\n existing.watcher.close()\n } catch {\n // ignore\n }\n }\n if (existing?.debounceTimer != null) {\n try {\n clearTimeout(existing.debounceTimer)\n } catch {\n // ignore\n }\n }\n\n const dl = new LocalPathFileDownload(localPath, entry.mode, entry.size)\n this.trackTransfer(dl, 'download', entry.fullPath, localPath)\n await this.sftpSession.download(entry.fullPath, dl)\n\n // настроим наблюдение за изменениями локального файла\n const schedule = () => this.scheduleSyncBackRemoteFile(localPath)\n const watcher = fsSync.watch(localPath, { persistent: false }, (eventType) => {\n // Many editors save atomically (rename) or emit multiple change events.\n if (eventType === 'change' || eventType === 'rename') {\n schedule()\n }\n })\n this.openedRemoteFiles.set(localPath, {\n remotePath: entry.fullPath,\n mode: entry.mode,\n watcher,\n debounceTimer: null,\n syncing: false,\n pending: false,\n lastUploadedSignature: null,\n })\n\n this.platform.openPath(localPath)\n } catch (e) {\n console.error('[SFTP-UI] Open remote file failed', e)\n }\n }\n\n private scheduleSyncBackRemoteFile (localPath: string): void {\n const info = this.openedRemoteFiles.get(localPath)\n if (!info) {\n return\n }\n if (info.debounceTimer != null) {\n clearTimeout(info.debounceTimer)\n }\n // Debounce a burst of editor save events\n info.debounceTimer = window.setTimeout(() => {\n info.debounceTimer = null\n void this.syncBackRemoteFile(localPath)\n }, 650)\n }\n\n private async waitForStableLocalFile (localPath: string): Promise<{ size: number, mtimeMs: number } | null> {\n // Wait until the file stops changing (editors often write in multiple passes)\n let last: { size: number, mtimeMs: number } | null = null\n for (let i = 0; i < 10; i++) {\n const st = await fs.stat(localPath).catch(() => null)\n if (!st || !st.isFile()) {\n return null\n }\n const cur = { size: st.size, mtimeMs: st.mtimeMs }\n if (last && cur.size === last.size && cur.mtimeMs === last.mtimeMs) {\n // stable for one interval\n return cur\n }\n last = cur\n await new Promise(resolve => setTimeout(resolve, 180))\n }\n return last\n }\n\n private async syncBackRemoteFile (localPath: string): Promise<void> {\n if (!this.sftpSession || !this.connected) {\n return\n }\n const info = this.openedRemoteFiles.get(localPath)\n if (!info) {\n return\n }\n if (info.syncing) {\n info.pending = true\n return\n }\n info.syncing = true\n try {\n const stable = await this.waitForStableLocalFile(localPath)\n if (!stable) {\n return\n }\n const signature = `${stable.size}:${stable.mtimeMs}`\n if (info.lastUploadedSignature === signature) {\n return\n }\n const upload = new LocalPathFileUpload(localPath)\n this.trackTransfer(upload, 'upload', info.remotePath, localPath)\n await this.sftpSession.upload(info.remotePath, upload)\n info.lastUploadedSignature = signature\n await this.refreshRemote()\n } catch (e) {\n console.error('[SFTP-UI] Sync-back remote file failed', e)\n } finally {\n info.syncing = false\n if (info.pending) {\n info.pending = false\n this.scheduleSyncBackRemoteFile(localPath)\n }\n }\n }\n}\n\n","import { Injectable } from '@angular/core'\r\nimport { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'\r\n\r\nimport { SftpUiService } from './sftp-ui.service'\r\n\r\n@Injectable()\r\nexport class SftpTerminalDecorator extends TerminalDecorator {\r\n constructor (\r\n private sftpUi: SftpUiService,\r\n ) {\r\n super()\r\n }\r\n\r\n override attach (terminal: BaseTerminalTabComponent): void {\r\n super.attach(terminal)\r\n\r\n // Best-effort DOM injection: place button near the existing Reconnect button if present.\r\n const tryInsert = () => {\r\n try {\r\n const host: HTMLElement | null = terminal.element?.nativeElement ?? null\r\n if (!host) {\r\n return false\r\n }\r\n\r\n // Find a likely toolbar area in the tab UI\r\n const toolbar =\r\n (host.querySelector('.terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('terminal-toolbar') as HTMLElement | null) ??\r\n (host.querySelector('.btn-toolbar') as HTMLElement | null)\r\n\r\n const container = toolbar ?? host\r\n\r\n if (container.querySelector('[data-tabby-sftp-ui-button=\"1\"]')) {\r\n return true\r\n }\r\n\r\n const btn = document.createElement('button')\r\n btn.type = 'button'\r\n // Match Tabby's terminal toolbar buttons styling\r\n btn.className = 'btn btn-sm btn-link me-2'\r\n btn.setAttribute('data-tabby-sftp-ui-button', '1')\r\n btn.title = 'SFTP-UI'\r\n btn.textContent = 'SFTP-UI'\r\n btn.style.pointerEvents = 'auto'\r\n btn.style.zIndex = '10'\r\n btn.style.position = 'relative'\r\n btn.addEventListener('mousedown', (ev) => {\r\n ev.stopPropagation()\r\n })\r\n btn.addEventListener('click', (ev) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n this.sftpUi.openForSourceTab(terminal as any)\r\n })\r\n\r\n // If there's a Reconnect button, insert next to it.\r\n const allButtons = Array.from(container.querySelectorAll('button')) as HTMLButtonElement[]\r\n const reconnectButton = allButtons.find(b => {\r\n const t = `${b.textContent ?? ''} ${b.title ?? ''} ${b.getAttribute('aria-label') ?? ''}`.toLowerCase()\r\n return t.includes('reconnect') || t.includes('переподключ')\r\n })\r\n\r\n if (reconnectButton?.parentElement) {\r\n // Put it right after Reconnect to avoid overlay issues\r\n reconnectButton.parentElement.insertBefore(btn, reconnectButton.nextSibling)\r\n } else {\r\n container.appendChild(btn)\r\n }\r\n\r\n return true\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n // try a few times while the view is settling\r\n let attempts = 0\r\n const timer = setInterval(() => {\r\n attempts++\r\n if (tryInsert() || attempts > 20) {\r\n clearInterval(timer)\r\n }\r\n }, 500)\r\n\r\n this.subscribeUntilDetached(terminal, { unsubscribe: () => clearInterval(timer) } as any)\r\n }\r\n}\r\n\r\n","import { Injectable, NgZone } from '@angular/core'\r\nimport { AppService, HotkeysService, LogService, NotificationsService, SplitTabComponent } from 'tabby-core'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\n\r\n@Injectable()\r\nexport class SftpUiService {\r\n private logger: any\r\n\r\n constructor (\r\n private app: AppService,\r\n private hotkeys: HotkeysService,\r\n private log: LogService,\r\n private zone: NgZone,\r\n private notifications: NotificationsService,\r\n ) {\r\n this.logger = this.log.create('sftp-ui')\r\n\r\n this.hotkeys.hotkey$.subscribe(h => {\r\n if (h === 'open-sftp-ui') {\r\n this.open()\r\n }\r\n })\r\n\r\n this.logger.info('loaded')\r\n }\r\n\r\n open (): void {\r\n const active = this.app.activeTab\r\n const focused = active instanceof SplitTabComponent ? (active.getFocusedTab?.() ?? null) : active\r\n this.openForSourceTab(focused)\r\n }\r\n\r\n openForSourceTab (sourceTab: any): void {\r\n const sshSession = sourceTab?.sshSession ?? null\r\n const profile = sourceTab?.profile ?? null\r\n\r\n this.zone.run(() => {\r\n try {\r\n if (!sshSession) {\r\n this.notifications.error('SFTP-UI', 'No SSH session on current tab')\r\n return\r\n }\r\n const baseTitle =\r\n sourceTab?.customTitle ||\r\n sourceTab?.title ||\r\n profile?.name ||\r\n profile?.options?.host ||\r\n 'SFTP'\r\n const tab = this.app.openNewTab({\r\n type: SftpManagerTabComponent,\r\n inputs: {\r\n sshSession,\r\n profile,\r\n },\r\n })\r\n tab.setTitle(`${baseTitle} + SFTP`)\r\n this.notifications.notice('SFTP-UI opened')\r\n } catch (e) {\r\n this.notifications.error('SFTP-UI failed to open', String(e))\r\n this.logger.error('openForSourceTab failed', e)\r\n }\r\n })\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core'\r\n\r\nexport type SFTPFile = {\r\n name: string\r\n fullPath: string\r\n isDirectory: boolean\r\n isSymlink: boolean\r\n mode: number\r\n size: number\r\n modified: Date\r\n}\r\n\r\nexport type SFTPSessionLike = {\r\n readdir: (p: string) => Promise<SFTPFile[]>\r\n mkdir: (p: string) => Promise<void>\r\n rmdir: (p: string) => Promise<void>\r\n unlink: (p: string) => Promise<void>\r\n rename: (oldPath: string, newPath: string) => Promise<void>\r\n upload: (remotePath: string, transfer: import('tabby-core').FileUpload) => Promise<void>\r\n download: (remotePath: string, transfer: import('tabby-core').FileDownload) => Promise<void>\r\n}\r\n\r\nexport type SSHSessionLike = {\r\n openSFTP: () => Promise<SFTPSessionLike>\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class SftpConnectionService {\r\n async openFromSSHSession (sshSession: SSHSessionLike): Promise<SFTPSessionLike> {\r\n return await sshSession.openSFTP()\r\n }\r\n}\r\n\r\n","module.exports = require(\"crypto\");","module.exports = require(\"fs/promises\");","module.exports = require(\"os\");","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_common__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_core__;","module.exports = __WEBPACK_EXTERNAL_MODULE__angular_forms__;","module.exports = __WEBPACK_EXTERNAL_MODULE_fs__;","module.exports = __WEBPACK_EXTERNAL_MODULE_path__;","module.exports = __WEBPACK_EXTERNAL_MODULE_tabby_core__;","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](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { CommonModule } from '@angular/common'\r\nimport { FormsModule } from '@angular/forms'\r\nimport { NgModule } from '@angular/core'\r\nimport { HotkeyProvider, TabContextMenuItemProvider } from 'tabby-core'\r\nimport { TerminalDecorator } from 'tabby-terminal'\r\n\r\nimport { SftpManagerTabComponent } from './sftp-manager-tab.component'\r\nimport { SftpContextMenuProvider } from './sftp-context-menu'\r\nimport { SftpUiHotkeyProvider } from './sftp-hotkey'\r\nimport { SftpUiService } from './sftp-ui.service'\r\nimport { SftpTerminalDecorator } from './sftp-terminal-decorator'\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ],\r\n declarations: [\r\n SftpManagerTabComponent,\r\n ],\r\n providers: [\r\n { provide: TabContextMenuItemProvider, useClass: SftpContextMenuProvider, multi: true },\r\n { provide: HotkeyProvider, useClass: SftpUiHotkeyProvider, multi: true },\r\n { provide: TerminalDecorator, useClass: SftpTerminalDecorator, multi: true },\r\n SftpUiService,\r\n ],\r\n})\r\nexport default class SftpUiModule {\r\n constructor (_: SftpUiService) { }\r\n}\r\n\r\nexport { SftpManagerTabComponent }\r\n"],"names":[],"sourceRoot":""}
|
|
@@ -62,6 +62,9 @@ export declare class SftpManagerTabComponent extends BaseTabComponent implements
|
|
|
62
62
|
deleteConfirmText: string;
|
|
63
63
|
private pendingLocalDelete;
|
|
64
64
|
private pendingRemoteDelete;
|
|
65
|
+
replaceConfirmVisible: boolean;
|
|
66
|
+
replaceConfirmText: string;
|
|
67
|
+
private replaceConfirmResolve;
|
|
65
68
|
inputDialogVisible: boolean;
|
|
66
69
|
inputDialogTitle: string;
|
|
67
70
|
inputDialogPlaceholder: string;
|
|
@@ -117,6 +120,7 @@ export declare class SftpManagerTabComponent extends BaseTabComponent implements
|
|
|
117
120
|
private copyLocalPathIntoLocalDir;
|
|
118
121
|
private uploadDirectoryUploadToRemote;
|
|
119
122
|
private writeDirectoryUploadToLocal;
|
|
123
|
+
private downloadRemoteDirectoryRecursive;
|
|
120
124
|
private getDroppedOsPaths;
|
|
121
125
|
getFilteredLocalEntries(): LocalEntry[];
|
|
122
126
|
getFilteredRemoteEntries(): SFTPFile[];
|
|
@@ -193,6 +197,9 @@ export declare class SftpManagerTabComponent extends BaseTabComponent implements
|
|
|
193
197
|
getRecoveryToken(_options?: any): Promise<null>;
|
|
194
198
|
confirmDelete(): Promise<void>;
|
|
195
199
|
cancelDelete(): void;
|
|
200
|
+
private showReplaceConfirm;
|
|
201
|
+
confirmReplace(): Promise<void>;
|
|
202
|
+
cancelReplace(): void;
|
|
196
203
|
private deleteLocalEntry;
|
|
197
204
|
private deleteRemoteEntry;
|
|
198
205
|
private buildDeleteConfirmText;
|