Compare commits

...

19 Commits

Author SHA1 Message Date
Eugene Pankov
a87d8871ad bumped xterm, check bracketedPaste state via terminal modes 2021-09-09 23:07:18 +02:00
Eugene Pankov
d6fa3b02a9 ssh: reworked keyboard-interactive auth UI - fixes #4540 2021-09-09 22:43:39 +02:00
Eugene Pankov
8a514fff17 lint 2021-09-09 22:17:15 +02:00
Eugene Pankov
00b43e88dc fixed saving profiles - fixes #4567, fixes #4330 2021-09-09 22:02:32 +02:00
Eugeny
7048c2c10c Merge pull request #4574 from Eugeny/all-contributors/add-BoYeonJang 2021-09-09 12:00:51 +02:00
Eugene Pankov
3f64789c55 Update README.md 2021-09-09 12:00:39 +02:00
Eugene Pankov
38e7f7f1b6 Update README.md 2021-09-09 12:00:14 +02:00
Eugene Pankov
b337bc5cfd word 2021-09-09 11:56:56 +02:00
allcontributors[bot]
4ac5daed8c docs: update .all-contributorsrc [skip ci] 2021-09-09 09:56:42 +00:00
allcontributors[bot]
82b724174c docs: update README.md [skip ci] 2021-09-09 09:56:41 +00:00
Eugeny
e7ab2bcffd Merge pull request #4548 from BoYeonJang/Korean_translatio 2021-09-09 11:56:23 +02:00
장보연
3518c74508 Update README.md in Korean 2021-09-07 10:21:50 +09:00
Eugene Pankov
a9515d38d1 bumped plugins 2021-09-06 23:38:58 +02:00
Eugene Pankov
e32bce29e0 mention Clippy plugin 2021-09-06 23:38:55 +02:00
Eugeny
48ca696b0b Merge pull request #4512 from Eugeny/dependabot/npm_and_yarn/tabby-ssh/types/ssh2-0.5.48 2021-09-06 14:57:39 +02:00
Eugeny
7bd9a887a6 Merge pull request #4543 from Eugeny/dependabot/npm_and_yarn/ssh2-1.4.0
Bump ssh2 from 1.3.0 to 1.4.0
2021-09-06 14:56:11 +02:00
dependabot[bot]
7bc66e9382 Bump ssh2 from 1.3.0 to 1.4.0
Bumps [ssh2](https://github.com/mscdex/ssh2) from 1.3.0 to 1.4.0.
- [Release notes](https://github.com/mscdex/ssh2/releases)
- [Commits](https://github.com/mscdex/ssh2/compare/v1.3.0...v1.4.0)

---
updated-dependencies:
- dependency-name: ssh2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 04:06:52 +00:00
Eugene Pankov
b7ac65fce0 added msys2 built-in profiles - fixes #2962 2021-09-02 23:52:31 +02:00
dependabot[bot]
79fdba44c6 Bump @types/ssh2 from 0.5.47 to 0.5.48 in /tabby-ssh
Bumps [@types/ssh2](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ssh2) from 0.5.47 to 0.5.48.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ssh2)

---
updated-dependencies:
- dependency-name: "@types/ssh2"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-31 04:20:16 +00:00
38 changed files with 500 additions and 84 deletions

View File

@@ -442,6 +442,15 @@
"contributions": [
"code"
]
},
{
"login": "BoYeonJang",
"name": "장보연",
"avatar_url": "https://avatars.githubusercontent.com/u/59506394?v=4",
"profile": "https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,

View File

@@ -145,4 +145,6 @@ export default class MyModule { }
See `tabby-core/src/api.ts`, `tabby-settings/src/api.ts`, `tabby-local/src/api.ts` and `tabby-terminal/src/api.ts` for the available extension points.
Also check out [the example plugin](https://github.com/Eugeny/tabby-clippy).
Publish your plugin on NPM with a `tabby-plugin` keyword to make it appear in the Plugin Manager.

215
README.ko-KR.md Normal file
View File

@@ -0,0 +1,215 @@
[![](docs/readme.png)](https://tabby.sh)
<p align="center">
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=DOWNLOADS&logo=github&style=for-the-badge"></a> &nbsp; <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> &nbsp; <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a>
</p>
<p align="center">
<a href="https://ko-fi.com/J3J8KWTF">
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=2" width="150">
</a>
</p>
----
### 다운로드:
* [Latest release](https://github.com/Eugeny/tabby/releases/latest)
* [Repositories](https://packagecloud.io/eugeny/tabby): [Debian/Ubuntu-based](https://packagecloud.io/eugeny/tabby/install#bash-deb), [RPM-based](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
* [Latest nightly build](https://nightly.link/Eugeny/tabby/workflows/build/master)
----
**Tabby** (구 **Terminus**)는 Windows, macOS 및 Linux용으로 뛰어난 구성의 터미널 에뮬레이터, SSH 및 시리얼 클라이언트입니다.
* 통합 SSH 클라이언트 및 연결 관리자
* 통합 시리얼 터미널
* 테마 및 색 구성표
* 전체 구성이 가능한 단축키 및 다중 코드 단축키
* 창 분할
* 이전 탭 사용을 기억
* PowerShell (및 PS Core), WSL, Git-Bash, Cygwin, Cmder 및 CMD 지원
* Zmodem을 통한 SSH 세션 간의 직접 파일 전송
* 2바이트 문자를 포함한 전체 유니코드 지원
* 빠르게 출력되는 것에 대해 휩쓸리지 않음
* 탭 완성을 포함한 Windows에서의 적절한 셸 환경 (Clink을 통해)
* SSH 시크릿 및 구성을 위한 통합 암호화 컨테이너
# 목차 <!-- omit in toc -->
- [Tabby는 무엇인가](#about)
- [터미널 기능](#terminal)
- [SSH 클라이언트](#ssh)
- [시리얼 터미널](#serial)
- [포터블](#portable)
- [플러그인](#plugins)
- [테마](#themes)
- [기여](#contributing)
<a name="about"></a>
# Tabby는 무엇인가
* **Tabby는** Windows의 표준 터미널 (conhost), PowerShell ISE, PuTTY 또는 iTerm의 대안 프로그램입니다.
* **Tabby는** 새로운 셸이나 MinGW 또는 Cygwin을 대체하지 **않습니다**. 가볍지도 않습니다. - RAM 사용량이 중요한 경우, [Conemu](https://conemu.github.io) 또는 [Alacritty](https://github.com/jwilm/alacritty)를 고려하십시오.
<a name="terminal"></a>
# 터미널 기능
![](docs/readme-terminal.png)
* A V220 터미널 + 다양한 확장
* 여러 개의 분할 창 중첩
* 모든 측면에 탭이 위치함
* 전역 스폰 단축키가 있는 도킹 가능한 윈도우 ("Quake console")
* 진행률 탐지
* 프로세스 완료 시 알림
* 괄호 붙여넣기, 여러 줄 붙여넣기 경고
* 폰트 합자(ligatures)
* 커스텀 셸 프로필
* RMB 붙여넣기 및 복사 선택 옵션 (PuTTY 스타일)
<a name="ssh"></a>
# SSH 클라이언트
![](docs/readme-ssh.png)
* 연결 관리자가 있는 SSH2 클라이언트
* X11 및 포트 포워딩
* 자동 jump 호스트 관리
* 에이전트 전달 (Pageant 및 Windows 기본 OpenSSH 에이전트 포함)
* 로그인 스크립트
<a name="serial"></a>
# 시리얼 터미널
* 연결 저장
* Readline 입력 지원
* 선택적 hex byte별 입력 및 hexdump 출력
* 개행 변환
* 자동 재접속
<a name="portable"></a>
# 포터블
`Tabby.exe`가 있는 동일한 위치에 `data` 폴더를 생성하면 Windows에서 Tabby가 포터블 앱으로 실행됩니다.
<a name="plugins"></a>
# 플러그인
플러그인과 테마는 Tabby 내부의 설정에서 직접 설치할 수 있습니다.
* [clickable-links](https://github.com/Eugeny/tabby-clickable-links) - m터미널의 경로 및 URL을 클릭 가능하게
* [docker](https://github.com/Eugeny/tabby-docker) - Docker 컨테이너에 연결
* [title-control](https://github.com/kbjr/terminus-title-control) - 접두사, 접미사 및/또는 문자열 제거를 제공하여 터미널 탭의 제목을 수정
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - 하나 또는 모든 터미널 탭에 신속한 명령 전송
* [save-output](https://github.com/Eugeny/tabby-save-output) - 터미널 출력을 파일에 기록
* [sync-config](https://github.com/starxg/terminus-sync-config) - 구성을 Gist 또는 Gitee에 동기화
* [clippy](https://github.com/Eugeny/tabby-clippy) - 항상 당신을 귀찮게 하는 예제 플러그인
<a name="themes"></a>
# 테마
* [hype](https://github.com/Eugeny/tabby-theme-hype) - Hyper에서 영감을 받은 테마
* [relaxed](https://github.com/Relaxed-Theme/relaxed-terminal-themes#terminus) - Tabby를 위해 여유로움을 제공하는 테마
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox)
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10)
* [altair](https://github.com/yxuko/terminus-altair)
# 스폰서 <!-- omit in toc -->
[![](https://assets-production.packagecloud.io/assets/packagecloud-logo-light-scaled-26ce8e96060fddf74afbd4445e63ba35590d4aaa56edc98495bb390ef3cae0ae.png)](https://packagecloud.io)
[**packagecloud**](https://packagecloud.io)가 무료 Debian/RPM 저장소 호스팅을 제공하였습니다.
<a name="contributing"></a>
# 기여
Pull requests and plugins are welcome!
프로젝트 배치 방법에 대한 자세한 내용과 매우 간단한 플러그인 개발 튜토리얼은 [HACKING.md](https://github.com/Eugeny/tabby/blob/master/HACKING.md) 및 [API docs](http://ajenti.org/terminus-docs/)를 참조하십시오.
---
<a name="contributors"></a>
여기있는 멋진 사람들에게 진심으로 감사합니다. ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mezner" title="Code">💻</a></td>
<td align="center"><a href="http://www.morwire.com"><img src="https://avatars1.githubusercontent.com/u/3991658?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ehwarren" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Drachenkaetzchen"><img src="https://avatars1.githubusercontent.com/u/162974?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Drachenkaetzchen" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mikemaccana"><img src="https://avatars2.githubusercontent.com/u/172594?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mikemaccana" title="Tests">⚠️</a> <a href="#design-mikemaccana" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/yxuko"><img src="https://avatars1.githubusercontent.com/u/1786317?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=yxuko" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/BBJip"><img src="https://avatars2.githubusercontent.com/u/32908927?v=4?s=100" width="100px;" alt=""/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BBJip" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Futagirl"><img src="https://avatars2.githubusercontent.com/u/33533958?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Futagirl</b></sub></a><br /><a href="#design-Futagirl" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.levrik.io"><img src="https://avatars3.githubusercontent.com/u/9491603?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=levrik" title="Code">💻</a></td>
<td align="center"><a href="https://kwonoj.github.io"><img src="https://avatars2.githubusercontent.com/u/1210596?v=4?s=100" width="100px;" alt=""/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=kwonoj" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Domain"><img src="https://avatars2.githubusercontent.com/u/903197?v=4?s=100" width="100px;" alt=""/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/commits?author=Domain" title="Code">💻</a></td>
<td align="center"><a href="http://www.jbrumond.me"><img src="https://avatars1.githubusercontent.com/u/195127?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/baflo"><img src="https://avatars2.githubusercontent.com/u/834350?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=baflo" title="Code">💻</a></td>
<td align="center"><a href="http://michael-kuehnel.de"><img src="https://avatars2.githubusercontent.com/u/441011?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mischah" title="Code">💻</a> <a href="#design-mischah" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/NieLeben"><img src="https://avatars3.githubusercontent.com/u/47182955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NieLeben" title="Code">💻</a></td>
<td align="center"><a href="http://www.jubeat.net"><img src="https://avatars3.githubusercontent.com/u/11289158?v=4?s=100" width="100px;" alt=""/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/issues?q=author%3APMExtra" title="Bug reports">🐛</a></td>
<td align="center"><a href="https://jjuhas.keybase.pub//"><img src="https://avatars1.githubusercontent.com/u/6438760?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=IgnusG" title="Code">💻</a></td>
<td align="center"><a href="https://hans-koch.me"><img src="https://avatars0.githubusercontent.com/u/1093709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hammster" title="Code">💻</a></td>
<td align="center"><a href="http://thepuzzlemaker.info"><img src="https://avatars3.githubusercontent.com/u/12666617?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ThePuzzlemaker" title="Code">💻</a></td>
<td align="center"><a href="http://yfwz100.github.io"><img src="https://avatars2.githubusercontent.com/u/983211?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=yfwz100" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jack1142"><img src="https://avatars0.githubusercontent.com/u/6032823?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=jack1142" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/hdougie"><img src="https://avatars1.githubusercontent.com/u/450799?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=hdougie" title="Code">💻</a></td>
<td align="center"><a href="https://chriskaczor.com"><img src="https://avatars2.githubusercontent.com/u/180906?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ckaczor" title="Code">💻</a></td>
<td align="center"><a href="https://www.boxmein.net"><img src="https://avatars1.githubusercontent.com/u/358714?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boxmein" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=CyrilTaylor" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4?s=100" width="100px;" alt=""/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=orin220444" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Goobles"><img src="https://avatars3.githubusercontent.com/u/8776771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gobius Dolhain</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Goobles" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/3l0w"><img src="https://avatars2.githubusercontent.com/u/37798980?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gwilherm Folliot</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=3l0w" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Dimitory"><img src="https://avatars0.githubusercontent.com/u/475955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dmitry Pronin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=dimitory" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/JonathanBeverley"><img src="https://avatars1.githubusercontent.com/u/20328966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Beverley</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=JonathanBeverley" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/zend"><img src="https://avatars1.githubusercontent.com/u/25160?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zenghai Liang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zend" title="Code">💻</a></td>
<td align="center"><a href="https://about.me/matishadow"><img src="https://avatars0.githubusercontent.com/u/9083085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mateusz Tracz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=matishadow" title="Code">💻</a></td>
<td align="center"><a href="https://zergpool.com"><img src="https://avatars3.githubusercontent.com/u/36234677?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pinpin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=pinpins" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TakuroOnoda" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=frauhottelmann" title="Code">💻</a></td>
<td align="center"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=clarkwang" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=iamchating" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/starxg"><img src="https://avatars.githubusercontent.com/u/34997494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>starxg</b></sub></a><br /><a href="#plugin-starxg" title="Plugin/utility libraries">🔌</a></td>
<td align="center"><a href="http://hashnote.net/"><img src="https://avatars.githubusercontent.com/u/546312?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alisue</b></sub></a><br /><a href="#design-lambdalisue" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/ydcool"><img src="https://avatars.githubusercontent.com/u/5668295?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dominic Yin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ydcool" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/bdr99"><img src="https://avatars.githubusercontent.com/u/2292715?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Rothweiler</b></sub></a><br /><a href="#design-bdr99" title="Design">🎨</a></td>
<td align="center"><a href="https://git.io/JnP49"><img src="https://avatars.githubusercontent.com/u/63876444?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Logic Machine</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=logicmachine123" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
</tr>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
이 프로젝트는 [모든 기여자](https://github.com/all-contributors/all-contributors)의 규격을 따릅니다. 어떠한 종류의 기여도 모두 환영합니다!
<img src="https://ga-beacon.appspot.com/UA-3278102-18/github/readme" width="1"/>

View File

@@ -19,17 +19,22 @@
* [Repositories](https://packagecloud.io/eugeny/tabby): [Debian/Ubuntu-based](https://packagecloud.io/eugeny/tabby/install#bash-deb), [RPM-based](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
* [Latest nightly build](https://nightly.link/Eugeny/tabby/workflows/build/master)
<br/>
<p align="center">
This README is also available in: <a href="./README.ko-KR.md">Korean</a>
</p>
----
**Tabby** (formerly **Terminus**) is a highly configurable terminal emulator, SSH and serial client for Windows, macOS and Linux
[**Tabby**](https://tabby.sh) (formerly **Terminus**) is a highly configurable terminal emulator, SSH and serial client for Windows, macOS and Linux
* Integrated SSH client and connection manager
* Integrated SSH and Telnet client and connection manager
* Integrated serial terminal
* Theming and color schemes
* Fully configurable shortcuts and multi-chord shortcuts
* Split panes
* Remembers your tabs
* PowerShell (and PS Core), WSL, Git-Bash, Cygwin, Cmder and CMD support
* PowerShell (and PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder and CMD support
* Direct file transfer from/to SSH sessions via Zmodem
* Full Unicode support including double-width characters
* Doesn't choke on fast-flowing outputs
@@ -108,6 +113,7 @@ Plugins and themes can be installed directly from the Settings view inside Tabby
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quickly send commands to one or all terminal tabs
* [save-output](https://github.com/Eugeny/tabby-save-output) - record terminal output into a file
* [sync-config](https://github.com/starxg/terminus-sync-config) - sync the config to Gist or Gitee
* [clippy](https://github.com/Eugeny/tabby-clippy) - an example plugin which annoys you all the time
<a name="themes"></a>
# Themes
@@ -201,6 +207,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
<td align="center"><a href="https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375"><img src="https://avatars.githubusercontent.com/u/59506394?v=4?s=100" width="100px;" alt=""/><br /><sub><b>장보연</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BoYeonJang" title="Documentation">📖</a></td>
</tr>
</table>

View File

@@ -64,7 +64,7 @@
"source-code-pro": "^2.38.0",
"source-map-loader": "^3.0.0",
"source-sans-pro": "3.6.0",
"ssh2": "^1.3.0",
"ssh2": "^1.4.0",
"style-loader": "^3.2.1",
"svg-inline-loader": "^0.8.2",
"ts-loader": "^9.2.3",

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-community-color-schemes",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Community color schemes for Tabby",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-core",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Tabby core",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -109,7 +109,7 @@ export class ProfilesService {
}))
if (recentProfiles.length) {
options.push({
name: 'Clear recent connections',
name: 'Clear recent profiles',
group: 'Recent',
icon: 'fas fa-eraser',
callback: async () => {

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-electron",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Electron-specific bindings",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-local",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Tabby's local shell plugin",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="36.777mm" height="36.777mm" version="1.1" viewBox="0 0 36.777 36.777" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(-122.71 -169.49)">
<g transform="translate(36.844 36.777)" fill="#999">
<path d="m118.48 154.39c-0.21263-0.77937-0.60053-0.53763-3.7786-0.53763-4.2381 0-4.51 0.21718-2.6541-2.4472 2.457-3.5274 3.4906-5.924 2.8085-6.965-0.4719-0.72022-1.0125-0.62449-1.9271 0.34127-0.84859 0.89603-1.8689 0.41779-1.8689-0.95587 0-2.012 2.8056-3.9999 5.3894-3.9922 1.614 5e-3 2.4364 0.4039 3.2158 1.5604 1.1203 1.6624 0.73145 3.8557-1.134 6.397-1.5438 2.1031-0.73385 3.6126 0.95572 1.7811 1.4629-1.6879 1.5595 0.86073 1.491 1.7028-0.2309 2.6962-2.077 4.6571-2.4976 3.1153z" fill="#999" stroke-width=".26458"/>
</g>
<g stroke-width=".50508">
<path transform="matrix(.26458 0 0 .26458 122.71 169.49)" d="m9.2551 97.323c-1.1562-0.7536-0.31598-3.2576 3.2531-9.6944 5.9813-10.787 19.737-40.139 25.544-54.507 3.4471-8.5282 3.725-10.717 1.5808-12.448-1.1414-0.92159-1.2907-1.285-0.8373-2.0393 1.6696-2.7778 11.294-3.9702 15.358-1.9029 4.5286 2.3035 6.6098 7.8684 9.3407 24.976 2.1781 13.645 3.7862 22.817 4.0853 23.301 0.80633 1.3047 2.407-1.8854 8.4838-16.908 8.5152-21.05 12.267-27.812 16.696-30.091 1.962-1.0097 3.3986-1.3036 7.1792-1.469 6.0598-0.26504 6.2396-0.12365 6.2324 4.9003-9e-3 6.5148-0.30491 7.4305-2.886 8.9432-4.8227 2.8263-8.1944 7.5856-8.2016 11.577-0.0099 5.4798 4.0769 7.1796 7.8338 3.2583 0.7854-0.81978 1.6128-1.4905 1.8386-1.4905s0.4119 2.1024 0.4135 4.672c2e-3 2.5696 0.21897 5.9911 0.48302 7.6033 0.54393 3.3211 0.62062 3.1596-6.937 14.613-4.1978 6.362-4.5659 7.2622-3.4332 8.3967 0.6867 0.6878 2.275 0.85452 9.4046 0.9872l8.5784 0.15964 2.1125 2.798c2.5812 3.4188 2.7454 5.2892 0.6996 7.9714-1.8668 2.4475-5.6125 5.1245-8.1753 5.8427-3.7415 1.0486-8.4103-1.013-12.47-5.5062-5.2081-5.7647-7.5396-14.899-8.239-32.278-0.24251-6.0259-0.52471-8.6733-0.91083-8.5446-0.30771 0.10257-3.7635 7.5753-7.6796 16.606-12.423 28.649-13.924 31.318-17.16 30.506-2.025-0.50825-5.0993-4.014-7.2197-8.2328-4.1934-8.3436-6.5579-19.088-7.6998-34.988-0.32917-4.5836-0.78831-8.5453-1.0203-8.8039-0.51357-0.57238-2.2088 3.1103-7.8764 17.11-7.6151 18.811-10.569 24.729-14.439 28.927-3.2899 3.5691-11.857 7.1072-13.933 5.7541z" fill="#f9f9f9"/>
<g fill="#d35e64">
<path transform="matrix(.26458 0 0 .26458 122.71 169.49)" d="m75.664 122.46c-1.2249-0.96348-1.34-1.3378-1.2045-3.9143l0.14983-2.849h1.7351c1.6821 0 1.7361 0.0617 1.7678 2.0203l0.03266 2.0203 2.6573 0.15286c2.0366 0.11715 2.7277-0.0306 2.9587-0.63248 0.60362-1.573-0.4054-3.3932-3.728-6.7251-1.8658-1.871-3.9062-4.071-4.5342-4.8889-1.4589-1.8999-1.5437-5.2283-0.17634-6.917 0.88504-1.093 1.3438-1.1924 5.5028-1.1924 5.1756 0 6.3427 0.6042 6.8174 3.5294 0.4355 2.6837-0.25445 4.5518-1.6811 4.5518-1.0066 0-1.2918-0.36987-1.7526-2.2728-0.50287-2.0764-0.69656-2.287-2.2406-2.4363-0.92959-0.0899-2.2269-0.0288-2.883 0.13589-2.2502 0.56476-1.4227 2.1852 3.6054 7.0604l4.7982 4.6523v3.4083c0 5.2086-0.1649 5.3622-5.758 5.3622-4.0289 0-4.9088-0.1545-6.0667-1.0653z"/>
<path transform="matrix(.26458 0 0 .26458 122.71 169.49)" d="m95.774 130.77c0.17811-1.0634 0.45153-3.9789 0.60759-6.479 0.26576-4.2574 0.13359-5.1223-2.0838-13.637-1.3021-5.0002-2.4843-9.6028-2.6269-10.228-0.22442-0.98323-0.05554-1.1364 1.2529-1.1364 0.83175 0 1.7665 0.30628 2.0771 0.68062 0.31067 0.37434 1.1434 3.2722 1.8506 6.4397 1.5777 7.0668 1.7138 7.5269 2.2267 7.5269 0.6014 0 1.3464-2.1279 2.8279-8.0775 1.4724-5.913 1.8338-6.5697 3.6148-6.5697 1.4844 0 1.7436-1.6442-2.6503 16.81-1.7714 7.44-3.5154 14.145-3.8755 14.9-0.44524 0.93333-1.1172 1.4255-2.0998 1.5381-1.4138 0.162-1.4381 0.1237-1.1212-1.7678z"/>
<path transform="matrix(.26458 0 0 .26458 122.71 169.49)" d="m123.48 114.84-5e-3 3.943s0.15696 3.7633-0.40862 4.2971c-0.57517 0.54286-2.7589 0.44883-5.7918 0.44883-5.2692 0-5.5498-0.0541-6.3116-1.2168-0.5398-0.82384-0.74743-2.0878-0.64299-3.9143 0.15002-2.6234 0.19573-2.6976 1.6626-2.6976 1.1206 0 1.5476 0.25963 1.6612 1.0102 0.49591 3.2773 0.50129 3.283 3.0918 3.283 5.0292 0 4.4851-2.8078-1.5873-8.1914-3.7309-3.3076-4.9304-5.0912-4.9196-7.3146 0.0189-3.8712 1.6713-5.2021 6.4586-5.2021 5.461 0 7.1715 1.3886 7.1715 5.8219 0 3.2126-3.0514 3.8315-3.5569 0.7215-0.42706-2.6273-0.8307-3.0079-3.1904-3.0079-2.2332 0-3.3512 0.66414-3.3585 1.995-2e-3 0.43058 2.2137 2.8835 4.9245 5.4509"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -32,6 +32,7 @@ import { Cygwin64ShellProvider } from './shells/cygwin64'
import { GitBashShellProvider } from './shells/gitBash'
import { LinuxDefaultShellProvider } from './shells/linuxDefault'
import { MacOSDefaultShellProvider } from './shells/macDefault'
import { MSYS2ShellProvider } from './shells/msys2'
import { POSIXShellsProvider } from './shells/posix'
import { PowerShellCoreShellProvider } from './shells/powershellCore'
import { WindowsDefaultShellProvider } from './shells/winDefault'
@@ -71,6 +72,7 @@ import { LocalProfilesService } from './profiles'
{ provide: ShellProvider, useClass: Cygwin64ShellProvider, multi: true },
{ provide: ShellProvider, useClass: GitBashShellProvider, multi: true },
{ provide: ShellProvider, useClass: POSIXShellsProvider, multi: true },
{ provide: ShellProvider, useClass: MSYS2ShellProvider, multi: true },
{ provide: ShellProvider, useClass: WSLShellProvider, multi: true },
{ provide: ShellProvider, useClass: VSDevToolsProvider, multi: true },

View File

@@ -0,0 +1,40 @@
import * as fs from 'fs/promises'
import * as path from 'path'
import { Injectable } from '@angular/core'
import { HostAppService, Platform } from 'tabby-core'
import { ShellProvider, Shell } from '../api'
/** @hidden */
@Injectable()
export class MSYS2ShellProvider extends ShellProvider {
constructor (
private hostApp: HostAppService,
) {
super()
}
async provide (): Promise<Shell[]> {
if (this.hostApp.platform !== Platform.Windows) {
return []
}
const msys2Path = path.resolve(process.env.SystemRoot ?? 'C:\\Windows', '../msys64')
try {
await fs.access(msys2Path)
} catch {
return []
}
const environments = ['msys', 'mingw64', 'clang64', 'ucrt64']
return environments.map(e => ({
id: `msys2-${e}`,
name: `MSYS2 (${e.toUpperCase()})`,
command: path.join(msys2Path, 'msys2_shell.cmd'),
args: ['-defterm', '-here', '-no-start', '-' + e],
icon: require('../icons/msys2.svg'),
env: {},
}))
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-plugin-manager",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Tabby's plugin manager",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-serial",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Serial connections for Tabby",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-settings",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Tabby terminal settings page",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -94,8 +94,12 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
EditProfileModalComponent,
{ size: 'lg' },
)
const provider = this.profilesService.providerForProfile(profile)
if (!provider) {
throw new Error('Cannot edit a profile without a provider')
}
modal.componentInstance.profile = Object.assign({}, profile)
modal.componentInstance.profileProvider = this.profilesService.providerForProfile(profile)
modal.componentInstance.profileProvider = provider
const result = await modal.result
// Fully replace the config
@@ -105,7 +109,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
}
Object.assign(profile, result)
profile.type = modal.componentInstance.profileProvider.id
profile.type = provider.id
}
async deleteProfile (profile: PartialProfile<Profile>): Promise<void> {

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-ssh",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "SSH connections for Tabby",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -0,0 +1,26 @@
.d-flex
strong Keyboard-interactive auth
.ml-2 {{prompt.name}}
.prompt-text {{prompt.prompts[step]}}
input.form-control.mt-2(
#input,
autofocus,
[type]='isPassword() ? "password": "text"',
placeholder='Response',
(keyup.enter)='next()',
[(ngModel)]='prompt.responses[step]'
)
.d-flex.mt-3
button.btn.btn-secondary(
*ngIf='step > 0',
(click)='previous()'
)
.ml-auto
button.btn.btn-primary(
(click)='next()'
)
span(*ngIf='step < prompt.prompts.length - 1') Next
span(*ngIf='step == prompt.prompts.length - 1') Finish

View File

@@ -0,0 +1,9 @@
:host {
display: flex;
flex-direction: column;
padding: 15px 20px;
}
.prompt-text {
white-space: pre-wrap;
}

View File

@@ -0,0 +1,37 @@
import { Component, Input, Output, EventEmitter, ViewChild, ElementRef, ChangeDetectionStrategy } from '@angular/core'
import { KeyboardInteractivePrompt } from '../session/ssh'
@Component({
selector: 'keyboard-interactive-auth-panel',
template: require('./keyboardInteractiveAuthPanel.component.pug'),
styles: [require('./keyboardInteractiveAuthPanel.component.scss')],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class KeyboardInteractiveAuthComponent {
@Input() prompt: KeyboardInteractivePrompt
@Input() step = 0
@Output() done = new EventEmitter()
@ViewChild('input') input: ElementRef
isPassword (): boolean {
return this.prompt.prompts[this.step].toLowerCase().includes('password')
}
previous (): void {
if (this.step > 0) {
this.step--
}
this.input.nativeElement.focus()
}
next (): void {
if (this.step === this.prompt.prompts.length - 1) {
this.prompt.respond()
this.done.emit()
return
}
this.step++
this.input.nativeElement.focus()
}
}

View File

@@ -45,3 +45,10 @@ sftp-panel.bg-dark(
[session]='session',
(closed)='sftpPanelVisible = false'
)
keyboard-interactive-auth-panel.bg-dark(
*ngIf='activeKIPrompt',
[prompt]='activeKIPrompt',
(click)='$event.stopPropagation()',
(done)='activeKIPrompt = null; frontend.focus()'
)

View File

@@ -5,7 +5,7 @@ import { first } from 'rxjs'
import { PartialProfile, Platform, ProfilesService, RecoveryToken } from 'tabby-core'
import { BaseTerminalTabComponent } from 'tabby-terminal'
import { SSHService } from '../services/ssh.service'
import { SSHSession } from '../session/ssh'
import { KeyboardInteractivePrompt, SSHSession } from '../session/ssh'
import { SSHPortForwardingModalComponent } from './sshPortForwardingModal.component'
import { SSHProfile } from '../api'
@@ -24,6 +24,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
sftpPanelVisible = false
sftpPath = '/'
enableToolbar = true
activeKIPrompt: KeyboardInteractivePrompt|null = null
private sessionStack: SSHSession[] = []
private recentInputs = ''
private reconnectOffered = false
@@ -35,6 +36,9 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
private profilesService: ProfilesService,
) {
super(injector)
this.sessionChanged$.subscribe(() => {
this.activeKIPrompt = null
})
}
ngOnInit (): void {
@@ -126,6 +130,17 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
session.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandler(session.destroyed$, () => {
this.activeKIPrompt = null
})
this.attachSessionHandler(session.keyboardInteractivePrompt$, prompt => {
this.activeKIPrompt = prompt
setTimeout(() => {
this.frontend?.scrollToBottom()
})
})
try {
await this.ssh.connectSession(session)
this.stopSpinner()

View File

@@ -15,6 +15,7 @@ import { SSHSettingsTabComponent } from './components/sshSettingsTab.component'
import { SSHTabComponent } from './components/sshTab.component'
import { SFTPPanelComponent } from './components/sftpPanel.component'
import { SFTPDeleteModalComponent } from './components/sftpDeleteModal.component'
import { KeyboardInteractiveAuthComponent } from './components/keyboardInteractiveAuthPanel.component'
import { SSHConfigProvider } from './config'
import { SSHSettingsTabProvider } from './settings'
@@ -60,6 +61,7 @@ import { CommonSFTPContextMenu } from './sftpContextMenu'
SSHSettingsTabComponent,
SSHTabComponent,
SFTPPanelComponent,
KeyboardInteractiveAuthComponent,
],
})
// eslint-disable-next-line @typescript-eslint/no-extraneous-class

View File

@@ -2,13 +2,12 @@ import colors from 'ansi-colors'
import * as shellQuote from 'shell-quote'
import { Duplex } from 'stream'
import { Injectable, NgZone } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { Client } from 'ssh2'
import { spawn } from 'child_process'
import { ChildProcess } from 'node:child_process'
import { Subject, Observable } from 'rxjs'
import { Logger, LogService, ConfigService, NotificationsService, HostAppService, Platform, PlatformService, PromptModalComponent } from 'tabby-core'
import { SSHSession } from '../session/ssh'
import { Logger, LogService, ConfigService, NotificationsService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { KeyboardInteractivePrompt, SSHSession } from '../session/ssh'
import { ForwardedPort } from '../session/forwards'
import { ALGORITHM_BLACKLIST, SSHAlgorithmType, SSHProfile } from '../api'
import { PasswordStorageService } from './passwordStorage.service'
@@ -21,7 +20,6 @@ export class SSHService {
private constructor (
log: LogService,
private zone: NgZone,
private ngbModal: NgbModal,
private passwordStorage: PasswordStorageService,
private notifications: NotificationsService,
private config: ConfigService,
@@ -83,22 +81,12 @@ export class SSHService {
})
ssh.on('keyboard-interactive', (name, instructions, instructionsLang, prompts, finish) => this.zone.run(async () => {
log(colors.bgBlackBright(' ') + ` Keyboard-interactive auth requested: ${name}`)
this.logger.info('Keyboard-interactive auth:', name, instructions, instructionsLang)
const results: string[] = []
for (const prompt of prompts) {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = prompt.prompt
modal.componentInstance.password = !prompt.echo
try {
const result = await modal.result
results.push(result ? result.value : '')
} catch {
results.push('')
}
}
finish(results)
session.emitKeyboardInteractivePrompt(new KeyboardInteractivePrompt(
name,
instructions,
prompts.map(x => x.prompt),
finish,
))
}))
ssh.on('greeting', greeting => {

View File

@@ -27,6 +27,21 @@ interface AuthMethod {
contents?: Buffer
}
export class KeyboardInteractivePrompt {
responses: string[] = []
constructor (
public name: string,
public instruction: string,
public prompts: string[],
private callback: (_: string[]) => void,
) { }
respond (): void {
this.callback(this.responses)
}
}
export class SSHSession extends BaseSession {
shell?: ClientChannel
ssh: Client
@@ -36,12 +51,14 @@ export class SSHSession extends BaseSession {
proxyCommandStream: ProxyCommandStream|null = null
savedPassword?: string
get serviceMessage$ (): Observable<string> { return this.serviceMessage }
get keyboardInteractivePrompt$ (): Observable<KeyboardInteractivePrompt> { return this.keyboardInteractivePrompt }
agentPath?: string
activePrivateKey: string|null = null
private remainingAuthMethods: AuthMethod[] = []
private serviceMessage = new Subject<string>()
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
private keychainPasswordUsed = false
private passwordStorage: PasswordStorageService
@@ -246,6 +263,17 @@ export class SSHSession extends BaseSession {
this.logger.info(stripAnsi(msg))
}
emitKeyboardInteractivePrompt (prompt: KeyboardInteractivePrompt): void {
this.logger.info('Keyboard-interactive auth:', prompt.name, prompt.instruction)
this.emitServiceMessage(colors.bgBlackBright(' ') + ` Keyboard-interactive auth requested: ${prompt.name}`)
if (prompt.instruction) {
for (const line of prompt.instruction.split('\n')) {
this.emitServiceMessage(line)
}
}
this.keyboardInteractivePrompt.next(prompt)
}
async handleAuth (methodsLeft?: string[] | null): Promise<any> {
this.activePrivateKey = null

View File

@@ -15,9 +15,9 @@
"@types/node" "*"
"@types/ssh2@^0.5.46":
version "0.5.47"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.47.tgz#67a8b35a0527b2bb668f6dea4c84be6ff1abdc19"
integrity sha512-ZhqJg8BRV7OsCi0KVqPr27lUMMmLEeHYw1VXUNGGDlQEDq9HTsKx+wYvi8E6oNC6gRZ7PV99ZMZmMr5vztcYYA==
version "0.5.48"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.48.tgz#0d9e8654a76eaaf4cfeaeb88d74c4489cfcf7aea"
integrity sha512-cmQu0gp/6RtDXe1r2xXGgi0V0TeCdueDSRMEvBX8cTRT/sSREkUpgCYZLyh+iI8Ql+VNV8Az9toQoYa/IdgHbQ==
dependencies:
"@types/node" "*"
"@types/ssh2-streams" "*"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-telnet",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Telnet/socket connections for Tabby",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-terminal",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Tabby's terminal emulation core",
"keywords": [
"tabby-builtin-plugin"
@@ -29,13 +29,13 @@
"ps-node": "^0.1.6",
"runes": "^0.4.2",
"utils-decorators": "^1.8.1",
"xterm": "npm:@tabby-gang/xterm@4.14.0-beta.3",
"xterm": "npm:@tabby-gang/xterm@4.14.0",
"xterm-addon-fit": "^0.5.0",
"xterm-addon-ligatures": "^0.5.0",
"xterm-addon-search": "^0.8.0",
"xterm-addon-serialize": "^0.5.0",
"xterm-addon-unicode11": "^0.2.0",
"xterm-addon-webgl": "^0.11.0",
"xterm-addon-search": "^0.8.1",
"xterm-addon-serialize": "^0.6.0",
"xterm-addon-unicode11": "^0.3.0",
"xterm-addon-webgl": "^0.11.2",
"zmodem.js": "^0.1.9"
},
"peerDependencies": {

View File

@@ -127,7 +127,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
private termContainerSubscriptions = new SubscriptionContainer()
private allFocusModeSubscription: Subscription|null = null
private sessionHandlers = new SubscriptionContainer()
private sessionSupportsBracketedPaste = false
private spinner = new Spinner({
stream: {
write: x => {
@@ -418,19 +417,12 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
}
if (data.includes('\x1b[?2004h')) {
this.sessionSupportsBracketedPaste = true
}
if (data.includes('\x1b[?2004l')) {
this.sessionSupportsBracketedPaste = false
}
this.frontend.write(data)
}
async paste (): Promise<void> {
let data = this.platform.readClipboard()
if (this.config.store.terminal.bracketedPaste && this.sessionSupportsBracketedPaste) {
if (this.config.store.terminal.bracketedPaste && this.frontend?.supportsBracketedPaste()) {
data = `\x1b[200~${data}\x1b[201~`
}
if (this.hostApp.platform === Platform.Windows) {
@@ -723,7 +715,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.spinner.text = text
}
this.spinner.setSpinnerString(6)
this.spinner.start()
this.zone.runOutsideAngular(() => {
this.spinner.start()
})
this.spinnerActive = true
}

View File

@@ -12,7 +12,7 @@ export class TerminalConfigProvider extends ConfigProvider {
fallbackFont: null,
linePadding: 0,
bell: 'off',
bracketedPaste: false,
bracketedPaste: true,
background: 'theme',
ligatures: false,
cursor: 'block',

View File

@@ -76,4 +76,6 @@ export abstract class Frontend {
abstract saveState (): any
abstract restoreState (state: string): void
abstract supportsBracketedPaste (): boolean
}

View File

@@ -324,6 +324,10 @@ export class XTermFrontend extends Frontend {
this.xterm.write(state)
}
supportsBracketedPaste (): boolean {
return this.xterm.modes.bracketedPasteMode
}
private setFontSize () {
const scale = Math.pow(1.1, this.zoom)
this.xterm.setOption('fontSize', this.configuredFontSize * scale)

View File

@@ -183,30 +183,30 @@ xterm-addon-ligatures@^0.5.0:
font-finder "^1.1.0"
font-ligatures "^1.4.0"
xterm-addon-search@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.0.tgz#e33eab918df7eac7e7baf95dd2b3d14133754881"
integrity sha512-MPJGPVPpHRUw9cLIuqQbrVepmENMOybVUSxIALz5h1ryyQBrVqVujq2hL5aroX5/dZJoHx9lGHQTVLQ07SKgKA==
xterm-addon-search@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.1.tgz#dfc557e9bcf5fd8ed96292c0d271aa865bc545d5"
integrity sha512-OtOaC9gxD2Q4ZnjZrCSRZmKLwwUjXX3gP7mIzq8Rs50317DGRDqgTLuHTYv/Nx/LvI5ceVFRYCxK36Ixs1nXNw==
xterm-addon-serialize@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.5.0.tgz#b6967d573e8c231fbb58c06fdc86871ba1e7a4bc"
integrity sha512-NueZvbBGQvWDNBhA02/ZkPDq2yFlCqvwy7XhYLqRWAsvjGYkqZg3Py9eoLw4j7+WIhuLK4czswUYa2ntwKC3QQ==
xterm-addon-serialize@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.6.0.tgz#3c967428de2cfd257a09066ef36e9aeba9817fe9"
integrity sha512-0D7nNdfvRsGhDdLgMIt1jYiYSVlvo18QRVkD4toa+3XcXr4G58FLbKu/gdfCt7da4aj7UIHbnOCexI0BncbVMA==
xterm-addon-unicode11@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.2.0.tgz#9ed0c482b353908bba27778893ca80823382737c"
integrity sha512-rjFDItPc/IDoSiEnoDFwKroNwLD/7t9vYKENjrcKVZg5tgJuuUj8D4rZtP6iVCjSB1LTLYmUs4L/EmCqIyLR/Q==
xterm-addon-unicode11@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.3.0.tgz#e4435c3c91a5294a7eb8b79c380acbb28a659463"
integrity sha512-x5fHDZT2j9tlTlHnzPHt++9uKZ2kJ/lYQOj3L6xJA22xoJsS8UQRw/5YIFg2FUHqEAbV77Z1fZij/9NycMSH/A==
xterm-addon-webgl@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.11.1.tgz#33dd250ab52e9f51d2ff52396447962e6f53e24c"
integrity sha512-xF6DnEoV+rPtzetMBXBZVe1kLKtus7AKdEcyfq2eMHQzhaRvC+pfnU+XiCXC85kueguqu2UkBHXZs5mihK9jOQ==
xterm-addon-webgl@^0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.11.2.tgz#eeb01f85cb35b0e47d1a3b691d4c6de8b2584c8e"
integrity sha512-eEOKEIMZO0IRb+UTHhTaUwxpD1cu7Zqr+jdUfhDv9cfVieg9c4mcRn9RWvNGlprGdlLmOSTUByhm8ve6qAc4HQ==
"xterm@npm:@tabby-gang/xterm@4.14.0-beta.3":
version "4.14.0-beta.3"
resolved "https://registry.yarnpkg.com/@tabby-gang/xterm/-/xterm-4.14.0-beta.3.tgz#2e06e59edcff39710a7c8c79dc1b2ae040f101b0"
integrity sha512-DimzmYmKfwj51ay7IsYOtwfThRYMbAZ4bJHBy7RgiVfsJCrypRlf+s4ofz29Hhw1dohNA67ko34dFaNJt2NKmA==
"xterm@npm:@tabby-gang/xterm@4.14.0":
version "4.14.0"
resolved "https://registry.yarnpkg.com/@tabby-gang/xterm/-/xterm-4.14.0.tgz#4f86c17b5464302f3d011eb79d00b2c7f7b1a548"
integrity sha512-cUh0GyXdL7FgcdizJ83JItY42OhLyxGvUprG91bpLVGPJ6CBK+9cO+fEOl/Kcfx9fUyGW6Y5EzANg9LxXBoqcQ==
yallist@^4.0.0:
version "4.0.0"

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-web-demo",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "tabby-web",
"version": "1.0.156-nightly.2",
"version": "1.0.156",
"description": "Web-specific bindings",
"keywords": [
"tabby-builtin-plugin"

View File

@@ -17,5 +17,5 @@
"resolutions": {
"**/util": "^0.12.0"
},
"version": "1.0.156-nightly.2"
"version": "1.0.156"
}

View File

@@ -7547,10 +7547,10 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
ssh2@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.3.0.tgz#bcd42ef7796250268b6ff6b0bbff2697029e91b9"
integrity sha512-OjBQ5FR+ClYav3fRnvkhycmd5co5qEfofBaZEqVO3I4tKJLZqu+Ku4LN4nJSckjhqQnomqBqlCdvD3iGV+6isA==
ssh2@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.4.0.tgz#e32e8343394364c922bad915a5a7fecd67d0f5c5"
integrity sha512-XvXwcXKvS452DyQvCa6Ct+chpucwc/UyxgliYz+rWXJ3jDHdtBb9xgmxJdMmnIn5bpgGAEV3KaEsH98ZGPHqwg==
dependencies:
asn1 "^0.2.4"
bcrypt-pbkdf "^1.0.2"