Compare commits

...

38 Commits

Author SHA1 Message Date
allcontributors[bot]
e041ddb8b5 update README.id-ID.md [skip ci] 2025-03-27 22:15:34 +00:00
allcontributors[bot]
82a429089d update README.de-DE.md [skip ci] 2025-03-27 22:15:33 +00:00
allcontributors[bot]
4ae59604a7 update README.it-IT.md [skip ci] 2025-03-27 22:15:32 +00:00
allcontributors[bot]
e596fe71f3 update README.ko-KR.md [skip ci] 2025-03-27 22:15:31 +00:00
allcontributors[bot]
2a884868a3 update README.ru-RU.md [skip ci] 2025-03-27 22:15:30 +00:00
allcontributors[bot]
82dc762779 update README.zh-CN.md [skip ci] 2025-03-27 22:15:29 +00:00
allcontributors[bot]
694b9dd662 update README.md [skip ci] 2025-03-27 22:15:28 +00:00
allcontributors[bot]
a44d2e4a90 update README.de-DE.md [skip ci] 2025-03-11 23:48:54 +00:00
allcontributors[bot]
d0804a5ad1 update README.it-IT.md [skip ci] 2025-03-11 23:48:53 +00:00
allcontributors[bot]
b6ed50bbbb update README.ko-KR.md [skip ci] 2025-03-11 23:48:52 +00:00
allcontributors[bot]
3f9b905bed update README.ru-RU.md [skip ci] 2025-03-11 23:48:51 +00:00
allcontributors[bot]
42b88e4e33 update README.zh-CN.md [skip ci] 2025-03-11 23:48:50 +00:00
allcontributors[bot]
ba24069b8a update README.md [skip ci] 2025-03-11 23:48:49 +00:00
gh-log
424b062d5b scroll_terminal_by_line (#10353)
Co-authored-by: gh-log <>
2025-03-12 00:48:34 +01:00
Eugene
5deb725758 bumped russh again 2025-03-10 07:50:20 +01:00
Eugene
4069c22891 bumped russh for EXT_INFO race condition fix 2025-03-09 19:27:48 +01:00
mannjani
4a515d9432 Add support for %h and %r escape characters in IdentityFile for SSH. (#10343)
* Add support for %h and %r escape characters in IdentityFile for SSH.
See section "IdentityFile" on https://linux.die.net/man/5/ssh_config for
details.

* Fix lint warnings.
2025-03-05 09:28:31 +01:00
Eugene
b83b2e5acc Update README.ru-RU.md 2025-02-28 10:11:30 +01:00
Eugene
e407ee8bf1 fixed #9845, fixed #10302 - allow alternative OSC52 suffix 2025-02-25 00:40:28 +01:00
Eugene
c7b39bdca7 bump russh for 1024 bit rsa key support 2025-02-25 00:37:24 +01:00
ianaflous
934cdff0f8 Using ssh default profile(user/password/port) without host (#10076) 2025-02-25 00:14:27 +01:00
Timo Schnaible
ab87099b8b add debian bullseye, bookworm and trixie deb package upload (#10314) 2025-02-25 00:12:45 +01:00
Eugene
47b4b54557 bump russh for agent RSA auth fixes 2025-02-21 10:48:51 +01:00
OpaqueGlass
15f4182e0e Fix: Unable to launch WinSCP for SSH sessions using private key (#10308) 2025-02-19 10:27:59 +01:00
aminelch
4be1e12559 Add Tokyonight color scheme (#10283) 2025-02-03 10:06:20 +01:00
Eugene
5d2d179677 prefer saved password to keyboard interactive auth 2025-01-29 10:37:28 +01:00
Eugene
4197cefdfd bump russh for events fix 2025-01-28 10:57:56 +01:00
Eugene
7c1421ffcf bump russh for async trait 2025-01-28 09:00:50 +01:00
Eugene
380c306d89 added warning when server disconnects during auth 2025-01-27 14:53:44 +01:00
Eugene
cf0da75224 bump russh for best hash selection in agent auth 2025-01-27 14:53:32 +01:00
Eugene
d1c1b48502 bump russh for rsa hash autoselection 2025-01-25 12:56:54 +01:00
Eugene
a3c5b41bb1 electron builder fixes 2025-01-22 23:44:36 +01:00
Eugene
2fa7678bec Squashed commit of the following:
commit 4efcf1bbd6
Author: Eugene <inbox@null.page>
Date:   Wed Jan 22 23:07:24 2025 +0100

    Update build.yml

commit abea964d94
Author: Eugene <inbox@null.page>
Date:   Wed Jan 22 22:59:28 2025 +0100

    Update build.yml

commit 2e7b66ac60
Author: Eugene <inbox@null.page>
Date:   Wed Jan 22 22:40:11 2025 +0100

    native arm64 build
2025-01-22 23:28:47 +01:00
Eugene
c6939b114d updated locales 2025-01-22 23:07:08 +01:00
Eugene
d3e8e2a6af bump electron-builder 2025-01-22 23:01:57 +01:00
Eugene
d1b161364b bump russh for error handling crash fix - fixes #10184, fixes #10244, fixes #10178, fixes #8481, fixes #10215, fixes #10203, fixes #7659 2025-01-22 22:44:47 +01:00
Eugene
c4a514fc4a fixed agent login regression - fixes #10248, fixes #10174 2025-01-22 22:33:26 +01:00
Eugene
d525374061 fixed missing app theme at the initial vault password prompt 2025-01-22 22:16:17 +01:00
34 changed files with 396 additions and 176 deletions

View File

@@ -130,7 +130,7 @@ jobs:
path: artifact-zip
Linux-Build:
runs-on: ubuntu-24.04
runs-on: ${{matrix.os}}
needs: Lint
strategy:
matrix:
@@ -138,14 +138,17 @@ jobs:
- build-arch: x64
arch: amd64
rust_triple: x86_64-unknown-linux-gnu
os: ubuntu-24.04
- build-arch: arm64
arch: arm64
rust_triple: aarch64-unknown-linux-gnu
triplet: aarch64-linux-gnu-
os: ubuntu-24.04-arm
- build-arch: arm
arch: armhf
rust_triple: arm-unknown-linux-gnueabihf
triplet: arm-linux-gnueabihf-
os: ubuntu-24.04
fail-fast: false
env:
@@ -167,6 +170,10 @@ jobs:
with:
node-version: 22
- name: Install FPM
run: |
sudo gem install fpm
- run: rustup target add ${{matrix.rust_triple}}
- name: Install dependencies
@@ -176,12 +183,12 @@ jobs:
- name: Setup tar to run as root
run: sudo chmod u+s "$(command -v tar)"
if: matrix.build-arch != 'x64'
if: matrix.build-arch == 'arm'
- name: Download cached sysroot
uses: actions/cache@v3
id: dl-cached-sysroot
if: matrix.build-arch !='x64'
if: matrix.build-arch == 'arm'
with:
key: sysroot-${{matrix.build-arch}}
path: /${{matrix.build-arch}}-sysroot
@@ -191,7 +198,7 @@ jobs:
sudo apt-get update -y && sudo apt-get install debootstrap qemu-user-static binfmt-support -y
sudo qemu-debootstrap --include=libfontconfig1-dev,libsecret-1-dev,libnss3,libatk1.0-0,libatk-bridge2.0-0,libgdk-pixbuf2.0-0,libgtk-3-0,libgbm1 --variant=buildd --exclude=snapd --components=main,restricted,universe,multiverse --extractor=dpkg-deb --arch ${{matrix.arch}} bionic /${{matrix.build-arch}}-sysroot/ http://ports.ubuntu.com/ubuntu-ports/
sudo find /${{matrix.build-arch}}-sysroot -type l -lname '/*' -exec sh -c 'file="$0"; dir=$(dirname "$file"); target=$(readlink "$0"); prefix=$(dirname "$dir" | sed 's@[^/]*@\.\.@g'); newtarget="$prefix$target"; ln -snf $newtarget $file' {} \; ;
if: matrix.build-arch != 'x64' && steps.dl-cached-sysroot.outputs.cache-hit != 'true'
if: matrix.build-arch == 'arm' && steps.dl-cached-sysroot.outputs.cache-hit != 'true'
- name: Setup env to use ${{matrix.build-arch}} sysroot
run: |
@@ -206,9 +213,9 @@ jobs:
elif [[ ${{matrix.arch}} == 'arm64' ]]; then
echo "PKG_CONFIG_PATH=/${{matrix.build-arch}}-sysroot/usr/lib/pkgconfig/:/${{matrix.build-arch}}-sysroot/usr/lib/aarch64-linux-gnu/pkgconfig/" >> $GITHUB_ENV
fi
if: matrix.build-arch != 'x64'
if: matrix.build-arch == 'arm'
- name: Install npm_modules (amd64)
- name: Install npm_modules (native)
run: |
npm i -g yarn node-gyp
yarn --network-timeout 1000000 --arch=${{matrix.build-arch}} --target-arch=${{matrix.build-arch}}
@@ -225,6 +232,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KEYGEN_TOKEN: ${{ secrets.KEYGEN_TOKEN }}
USE_HARD_LINKS: false
USE_SYSTEM_FPM: true
# DEBUG: electron-builder,electron-builder:*
- name: Build web resources (amd64 only)
@@ -250,7 +258,7 @@ jobs:
repo: 'eugeny/tabby'
dir: 'dist'
rpmvers: 'el/9 el/8 ol/6 ol/7'
debvers: 'ubuntu/bionic ubuntu/focal ubuntu/hirsute ubuntu/impish ubuntu/jammy ubuntu/kinetic ubuntu/noble ubuntu/oracular debian/jessie debian/stretch debian/buster'
debvers: 'ubuntu/bionic ubuntu/focal ubuntu/hirsute ubuntu/impish ubuntu/jammy ubuntu/kinetic ubuntu/noble ubuntu/oracular debian/jessie debian/stretch debian/buster debian/bullseye debian/bookworm debian/trixie'
- uses: actions/upload-artifact@master
name: Upload AppImage (${{matrix.arch}})

View File

@@ -347,6 +347,7 @@ Dank geht an diese wunderbaren Menschen ([emoji key](https://allcontributors.org
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -346,6 +346,7 @@ Terima kasih kepada mereka yang telah membantu ([emoji key](https://allcontribut
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -342,6 +342,7 @@ Grazie a queste persone meravigliose ([emoji key](https://allcontributors.org/do
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -341,6 +341,7 @@ Pull requests and plugins are welcome!
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -365,6 +365,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -31,7 +31,7 @@
* Встроенный SSH- и Telnet-клиент и менеджер подключений;
* Встроенный последовательный терминал;
* Темы и цветовые схемы;
* Полностью настраеваемые сочетания клавиш;
* Полностью настраиваемые сочетания клавиш;
* Панели;
* Запоминание вкладок;
* Поддержка PowerShell (and PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder и CMD;
@@ -342,6 +342,7 @@ Pull-запросы и плагины приветствуются!
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -341,6 +341,7 @@
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/geodic"><img src="https://avatars.githubusercontent.com/u/64704703?v=4?s=100" width="100px;" alt="geodic"/><br /><sub><b>geodic</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=geodic" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/gh-log"><img src="https://avatars.githubusercontent.com/u/16019542?v=4?s=100" width="100px;" alt="gh-log"/><br /><sub><b>gh-log</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=gh-log" title="Code">💻</a></td>
</tr>
</tbody>
</table>

View File

@@ -30,7 +30,7 @@
"native-process-working-directory": "^1.0.2",
"npm": "6",
"rxjs": "^7.5.7",
"russh": "0.1.14",
"russh": "0.1.24",
"source-map-support": "^0.5.20",
"v8-compile-cache": "^2.3.0",
"yargs": "^17.7.2"

View File

@@ -3628,10 +3628,10 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
russh@0.1.14:
version "0.1.14"
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.14.tgz#d97a6435795f97693414c55c93b823bbbbe34465"
integrity sha512-x8n5P/QVm4yuRqRScxbjTt3RRLVLwUGC87OBXrZBOTEjPikGwyy/kcBGf2PjlV8iJ3M8JOro4b1xHj1JM8Khfg==
russh@0.1.24:
version "0.1.24"
resolved "https://registry.yarnpkg.com/russh/-/russh-0.1.24.tgz#dce27a3bc63eb78024db60e6767bc80cbf523b9a"
integrity sha512-lLMtXHJKL5uwRxwoFNDx71T7+qCXiL80qyGCRgQjYMV10gaW2AlI6mqcz3FVH8dXvdgK2ZE8DuSwlhCBK7schA==
dependencies:
"@napi-rs/cli" "^2.18.3"

View File

@@ -37,7 +37,8 @@ asarUnpack:
win:
icon: "./build/windows/icon.ico"
artifactName: tabby-${version}-portable-${env.ARCH}.${ext}
rfc3161TimeStampServer: http://timestamp.sectigo.com
signtoolOptions:
rfc3161TimeStampServer: http://timestamp.sectigo.com
nsis:
oneClick: false
artifactName: tabby-${version}-setup-${env.ARCH}.${ext}

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Indonesian\n"
"Language: id_ID\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"
@@ -23,7 +23,7 @@ msgstr "{name} salin"
#: locale/tmp-html/tabby-terminal/src/components/appearanceSettingsTab.component.html:77
msgid "A second font family used to display characters missing in the main font"
msgstr "Keluarga font kedua digunakan untuk menampilkan karakter yang hilang di font utama"
msgstr "Keluarga huruf kedua digunakan untuk menampilkan karakter yang hilang di huruf utama"
#: tabby-core/src/components/transfersMenu.component.ts:49
msgid "Abort all"
@@ -100,12 +100,12 @@ msgstr "Izinkan buka dengan cepat terminal di direktori terpilih"
#: locale/tmp-html/tabby-core/src/components/welcomeTab.component.html:25
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:11
msgid "Always dark"
msgstr ""
msgstr "Selalu gelap"
#: locale/tmp-html/tabby-core/src/components/welcomeTab.component.html:27
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:13
msgid "Always light"
msgstr ""
msgstr "Selalu terang"
#: locale/tmp-html/tabby-terminal/src/components/appearanceSettingsTab.component.html:2
#: tabby-terminal/src/settings.ts:14
@@ -255,7 +255,7 @@ msgstr "Ubah baud rate"
#: tabby-core/src/tabContextMenu.ts:133
msgid "Change tab color"
msgstr ""
msgstr "Rubah warna label"
#: locale/tmp-html/tabby-settings/src/components/vaultSettingsTab.component.html:12
msgid "Change the master passphrase"
@@ -337,7 +337,7 @@ msgstr "Skema warna"
#: locale/tmp-html/tabby-terminal/src/components/colorSchemeSettingsTab.component.html:2
msgid "Color schemes"
msgstr ""
msgstr "Warna Skema"
#: locale/tmp-html/tabby-serial/src/components/serialProfileSettings.component.html:81
#: locale/tmp-html/tabby-ssh/src/components/sshProfileSettings.component.html:216
@@ -362,7 +362,7 @@ msgstr "Perintah-perintah"
#: tabby-core/src/theme.ts:16
msgid "Compact (legacy)"
msgstr ""
msgstr "Padat (tua)"
#: tabby-settings/src/components/configSyncSettingsTab.component.ts:126
msgid "Config deleted"
@@ -449,7 +449,7 @@ msgstr "Salin jalur saat ini"
#: tabby-electron/src/sftpContextMenu.ts:29
msgid "Copy full path"
msgstr ""
msgstr "Salin alamat lengkap"
#: locale/tmp-html/tabby-terminal/src/components/terminalSettingsTab.component.html:97
msgid "Copy on select"
@@ -1732,7 +1732,7 @@ msgstr "Ganti Nama"
#: tabby-core/src/hotkeys.ts:24
#: tabby-core/src/tabContextMenu.ts:121
msgid "Rename tab"
msgstr ""
msgstr "Ganti nama label"
#: locale/tmp-html/tabby-terminal/src/components/terminalSettingsTab.component.html:3
msgid "Rendering"
@@ -1770,7 +1770,7 @@ msgstr "Mulai ulang sesi SSH saat ini"
#: tabby-telnet/src/hotkeys.ts:10
msgid "Restart current Telnet session"
msgstr ""
msgstr "Mulai ulang sesi Telnet saat ini"
#: tabby-core/src/hotkeys.ts:64
msgid "Restart tab"
@@ -1782,7 +1782,7 @@ msgstr "Mulai ulang aplikasi untuk menerapkan perubahan"
#: tabby-settings/src/components/profilesSettingsTab.component.ts:316
msgid "Restore settings to defaults ?"
msgstr ""
msgstr "Kembali ke settingan sebelumnya ?"
#: tabby-settings/src/components/editProfileGroupModal.component.ts:36
msgid "Restore settings to inherited defaults ?"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Italian\n"
"Language: it_IT\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"
@@ -2177,7 +2177,7 @@ msgstr "Cambia l'implementazione del frontend del terminale (sperimentale)"
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:4
msgid "Sync"
msgstr "Sincronizazione"
msgstr "Sincronizzazione"
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:53
msgid "Sync automatically"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Turkish\n"
"Language: tr_TR\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"
@@ -966,7 +966,7 @@ msgstr "Hazır bir GitHub sorunu oluşturun"
#: locale/tmp-html/tabby-plugin-manager/src/components/pluginsSettingsTab.component.html:25
msgid "Get"
msgstr "Getir"
msgstr "Yükle"
#: locale/tmp-html/tabby-settings/src/components/configSyncSettingsTab.component.html:18
msgid "Get it from the Tabby Web settings window"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: tabby\n"
"Language-Team: Chinese Traditional\n"
"Language: zh_TW\n"
"PO-Revision-Date: 2024-12-24 22:58\n"
"PO-Revision-Date: 2025-01-22 22:02\n"
#: tabby-local/src/components/terminalTab.component.ts:113
msgid "\"{command}\" is still running. Close?"

View File

@@ -40,7 +40,7 @@
"css-loader": "^6.7.3",
"deep-equal": "2.0.5",
"electron": "^32.2.7",
"electron-builder": "^26.0.0-alpha.8",
"electron-builder": "^26.0.0-alpha.10",
"electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0",
"@electron/rebuild": "^3.7.1",

View File

@@ -1,8 +1,8 @@
diff --git a/node_modules/app-builder-lib/out/appInfo.js b/node_modules/app-builder-lib/out/appInfo.js
index 49f6dca..0ea11f2 100644
index 7fbbef7..0821807 100644
--- a/node_modules/app-builder-lib/out/appInfo.js
+++ b/node_modules/app-builder-lib/out/appInfo.js
@@ -112,9 +112,7 @@ class AppInfo {
@@ -116,9 +116,7 @@ class AppInfo {
return this.info.metadata.name;
}
get linuxPackageName() {

View File

@@ -28,9 +28,7 @@ builder({
},
mac: {
identity: !process.env.CI || process.env.CSC_LINK ? undefined : null,
notarize: process.env.APPLE_TEAM_ID ? {
teamId: process.env.APPLE_TEAM_ID,
} : false,
notarize: !!process.env.APPLE_TEAM_ID,
},
npmRebuild: process.env.ARCH !== 'arm64',
publish: process.env.KEYGEN_TOKEN ? [

View File

@@ -28,27 +28,29 @@ builder({
] : undefined,
forceCodeSigning: !!keypair,
win: {
certificateSha1: process.env.SM_CODE_SIGNING_CERT_SHA1_HASH,
publisherName: process.env.SM_PUBLISHER_NAME,
signingHashAlgorithms: ['sha256'],
sign: keypair ? async function (configuration) {
console.log('Signing', configuration)
if (configuration.path) {
try {
const out = execSync(
`smctl sign --keypair-alias=${keypair} --input "${String(configuration.path)}"`
)
if (out.toString().includes('FAILED')) {
throw new Error(out.toString())
signtoolOptions: {
certificateSha1: process.env.SM_CODE_SIGNING_CERT_SHA1_HASH,
publisherName: process.env.SM_PUBLISHER_NAME,
signingHashAlgorithms: ['sha256'],
sign: keypair ? async function (configuration) {
console.log('Signing', configuration)
if (configuration.path) {
try {
const out = execSync(
`smctl sign --keypair-alias=${keypair} --input "${String(configuration.path)}"`
)
if (out.toString().includes('FAILED')) {
throw new Error(out.toString())
}
console.log(out.toString())
} catch (e) {
console.error(`Failed to sign ${configuration.path}`)
console.error(e)
process.exit(1)
}
console.log(out.toString())
} catch (e) {
console.error(`Failed to sign ${configuration.path}`)
console.error(e)
process.exit(1)
}
}
} : undefined,
} : undefined,
},
},
},

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xreources.py
!
*.foreground: #c0caf5
*.background: #1a1b26
*.cursorColor: #c0caf5
!
! Black
*.color0: #15161e
*.color8: #414868
!
! Red
*.color1: #f7768e
*.color9: #f7768e
!
! Green
*.color2: #9ece6a
*.color10: #9ece6a
!
! Yellow
*.color3: #e0af68
*.color11: #e0af68
!
! Blue
*.color4: #7aa2f7
*.color12: #7aa2f7
!
! Magenta
*.color5: #bb9af7
*.color13: #bb9af7
!
! Cyan
*.color6: #7dcfff
*.color14: #7dcfff
!
! White
*.color7: #a9b1d6
*.color15: #c0caf5
!
! Bold, Italic, Underline
*.colorBD: #eeeeee
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xreources.py
!
*.foreground: #3760bf
*.background: #e1e2e7
*.cursorColor: #3760bf
!
! Black
*.color0: #e9e9ed
*.color8: #a1a6c5
!
! Red
*.color1: #f52a65
*.color9: #f52a65
!
! Green
*.color2: #587539
*.color10: #587539
!
! Yellow
*.color3: #8c6c3e
*.color11: #8c6c3e
!
! Blue
*.color4: #2e7de9
*.color12: #2e7de9
!
! Magenta
*.color5: #9854f1
*.color13: #9854f1
!
! Cyan
*.color6: #007197
*.color14: #007197
!
! White
*.color7: #6172b0
*.color15: #3760bf
!
! Bold, Italic, Underline
*.colorBD: #eeeeee
!*.colorIT:
!*.colorUL:

View File

@@ -0,0 +1,44 @@
!
! Generated with :
! XRDB2Xreources.py
!
*.foreground: #c0caf5
*.background: #24283b
*.cursorColor: #c0caf5
!
! Black
*.color0: #1d202f
*.color8: #414868
!
! Red
*.color1: #f7768e
*.color9: #f7768e
!
! Green
*.color2: #9ece6a
*.color10: #9ece6a
!
! Yellow
*.color3: #e0af68
*.color11: #e0af68
!
! Blue
*.color4: #7aa2f7
*.color12: #7aa2f7
!
! Magenta
*.color5: #bb9af7
*.color13: #bb9af7
!
! Cyan
*.color6: #7dcfff
*.color14: #7dcfff
!
! White
*.color7: #a9b1d6
*.color15: #c0caf5
!
! Bold, Italic, Underline
*.colorBD: #eeeeee
!*.colorIT:
!*.colorUL:

View File

@@ -23,6 +23,7 @@ export class ThemesService {
) {
this.rootElementStyleBackup = document.documentElement.style.cssText
this.applyTheme(standardTheme)
this.applyThemeVariables()
config.ready$.toPromise().then(() => {
this.applyCurrentTheme()
this.applyThemeVariables()
@@ -37,6 +38,11 @@ export class ThemesService {
})
}
private getConfigStoreOrDefaults (): any {
/// Theme service is active before the vault is unlocked and config is available
return this.config.store ?? this.config.getDefaults()
}
private applyThemeVariables () {
if (!this.findCurrentTheme().followsColorScheme) {
document.documentElement.style.cssText = this.rootElementStyleBackup
@@ -60,7 +66,7 @@ export class ThemesService {
}
let background = Color(theme.background)
if (this.config.store?.appearance.vibrancy) {
if (this.getConfigStoreOrDefaults().appearance.vibrancy) {
background = background.fade(0.6)
}
// const background = theme.background
@@ -148,13 +154,13 @@ export class ThemesService {
vars['--bs-form-switch-bg'] = `url("data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%27-4 -4 8 8%27%3e%3ccircle r=%273%27 fill=%27${switchBackground}%27/%3e%3c/svg%3e")`
}
vars['--spaciness'] = this.config.store.appearance.spaciness
vars['--spaciness'] = this.getConfigStoreOrDefaults().appearance.spaciness
for (const [bg, fg] of contrastPairs) {
const colorBg = Color(vars[bg]).hsl()
const colorFg = Color(vars[fg]).hsl()
const bgContrast = colorBg.contrast(colorFg)
if (bgContrast < this.config.store.terminal.minimumContrastRatio) {
if (bgContrast < this.getConfigStoreOrDefaults().terminal.minimumContrastRatio) {
vars[fg] = this.ensureContrast(colorFg, colorBg).string()
}
}
@@ -163,7 +169,7 @@ export class ThemesService {
document.documentElement.style.setProperty(key, value)
}
document.body.classList.toggle('no-animations', !this.config.store.accessibility.animations)
document.body.classList.toggle('no-animations', !this.getConfigStoreOrDefaults().accessibility.animations)
}
private ensureContrast (color: Color, against: Color): Color {
@@ -178,7 +184,7 @@ export class ThemesService {
while (
(step < 1 && color.color[2] > 1 ||
step > 1 && color.color[2] < 99) &&
color.contrast(against) < this.config.store.terminal.minimumContrastRatio) {
color.contrast(against) < this.getConfigStoreOrDefaults().terminal.minimumContrastRatio) {
color.color[2] *= step
}
return color
@@ -189,22 +195,22 @@ export class ThemesService {
}
findCurrentTheme (): Theme {
return this.findTheme(this.config.store.appearance.theme) ?? this.standardTheme
return this.findTheme(this.getConfigStoreOrDefaults().appearance.theme) ?? this.standardTheme
}
/// @hidden
_getActiveColorScheme (): any {
let theme: PlatformTheme = 'dark'
if (this.config.store.appearance.colorSchemeMode === 'light') {
if (this.getConfigStoreOrDefaults().appearance.colorSchemeMode === 'light') {
theme = 'light'
} else if (this.config.store.appearance.colorSchemeMode === 'auto') {
} else if (this.getConfigStoreOrDefaults().appearance.colorSchemeMode === 'auto') {
theme = this.platform.getTheme()
}
if (theme === 'light') {
return this.config.store.terminal.lightColorScheme
return this.getConfigStoreOrDefaults().terminal.lightColorScheme
} else {
return this.config.store.terminal.colorScheme
return this.getConfigStoreOrDefaults().terminal.colorScheme
}
}
@@ -215,7 +221,7 @@ export class ThemesService {
document.querySelector('head')!.appendChild(this.styleElement)
}
this.styleElement.textContent = theme.css
document.querySelector('style#custom-css')!.innerHTML = this.config.store?.appearance?.css
document.querySelector('style#custom-css')!.innerHTML = this.getConfigStoreOrDefaults().appearance.css
this.themeChanged.next(theme)
}

View File

@@ -195,7 +195,13 @@ export class VaultService {
if (!vault) {
return null
}
return vault.secrets.find(s => s.type === type && this.keyMatches(key, s)) ?? null
let vaultSecret = vault.secrets.find(s => s.type === type && this.keyMatches(key, s))
if (!vaultSecret) {
// search for secret without host in vault (like a default user/password used in multiple servers)
key['host'] = null
vaultSecret = vault.secrets.find(s => s.type === type && this.keyMatches(key, s))
}
return vaultSecret ?? null
}
async addSecret (secret: VaultSecret): Promise<void> {

View File

@@ -1,7 +1,8 @@
// import * as fs from 'fs/promises'
import * as fs from 'fs/promises'
import * as crypto from 'crypto'
import * as tmp from 'tmp-promise'
import { Injectable } from '@angular/core'
import { ConfigService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { ConfigService, FileProvidersService, HostAppService, Platform, PlatformService } from 'tabby-core'
import { SSHSession } from '../session/ssh'
import { SSHProfile } from '../api'
import { PasswordStorageService } from './passwordStorage.service'
@@ -15,6 +16,7 @@ export class SSHService {
private config: ConfigService,
hostApp: HostAppService,
private platform: PlatformService,
private fileProviders: FileProvidersService,
) {
if (hostApp.platform === Platform.Windows) {
this.detectedWinSCPPath = platform.getWinSCPPath()
@@ -47,14 +49,35 @@ export class SSHService {
const args = [await this.getWinSCPURI(session.profile, undefined, session.authUsername ?? undefined)]
let tmpFile: tmp.FileResult|null = null
if (session.activePrivateKey) {
tmpFile = await tmp.file()
// await fs.writeFile(tmpFile.path, session.activePrivateKey)
const winSCPcom = path.slice(0, -3) + 'com'
await this.platform.exec(winSCPcom, ['/keygen', tmpFile.path, `/output=${tmpFile.path}`])
args.push(`/privatekey=${tmpFile.path}`)
try {
if (session.activePrivateKey && session.profile.options.privateKeys && session.profile.options.privateKeys.length > 0) {
tmpFile = await tmp.file()
let passphrase: string|null = null
for (const pk of session.profile.options.privateKeys) {
let privateKeyContent: string|null = null
const buffer = await this.fileProviders.retrieveFile(pk)
privateKeyContent = buffer.toString()
await fs.writeFile(tmpFile.path, privateKeyContent)
const keyHash = crypto.createHash('sha512').update(privateKeyContent).digest('hex')
// need to pass an default passphrase, otherwise it might get stuck at the passphrase input
passphrase = await this.passwordStorage.loadPrivateKeyPassword(keyHash) ?? 'tabby'
const winSCPcom = path.slice(0, -3) + 'com'
try {
await this.platform.exec(winSCPcom, ['/keygen', tmpFile.path, '-o', tmpFile.path, '--old-passphrase', passphrase])
} catch (error) {
console.warn('Could not convert private key ', error)
continue
}
break
}
args.push(`/privatekey=${tmpFile.path}`)
if (passphrase != null) {
args.push(`/passphrase=${passphrase}`)
}
}
await this.platform.exec(path, args)
} finally {
tmpFile?.cleanup()
}
await this.platform.exec(path, args)
tmpFile?.cleanup()
}
}

View File

@@ -58,7 +58,7 @@ function sshAuthTypeForMethod (m: AuthMethod): string {
case 'saved-password': return 'password'
case 'keyboard-interactive': return 'keyboard-interactive'
case 'publickey': return 'publickey'
case 'agent': return 'agent'
case 'agent': return 'publickey'
}
}
@@ -111,7 +111,7 @@ export class SSHSession {
private logger: Logger
private refCount = 0
private remainingAuthMethods: AuthMethod[] = []
private allAuthMethods: AuthMethod[] = []
private serviceMessage = new Subject<string>()
private keyboardInteractivePrompt = new Subject<KeyboardInteractivePrompt>()
private willDestroy = new Subject<void>()
@@ -125,6 +125,7 @@ export class SSHSession {
private translate: TranslateService
private knownHosts: SSHKnownHostsService
private privateKeyImporters: AutoPrivateKeyLocator[]
private previouslyDisconnected = false
constructor (
private injector: Injector,
@@ -150,7 +151,7 @@ export class SSHSession {
}
private addPublicKeyAuthMethod (name: string, contents: Buffer) {
this.remainingAuthMethods.push({
this.allAuthMethods.push({
type: 'publickey',
name,
contents,
@@ -158,12 +159,14 @@ export class SSHSession {
}
async init (): Promise<void> {
this.remainingAuthMethods = [{ type: 'none' }]
this.allAuthMethods = [{ type: 'none' }]
if (!this.profile.options.auth || this.profile.options.auth === 'publicKey') {
if (this.profile.options.privateKeys?.length) {
for (const pk of this.profile.options.privateKeys) {
for (let pk of this.profile.options.privateKeys) {
// eslint-disable-next-line @typescript-eslint/init-declarations
let contents: Buffer
pk = pk.replace('%h', this.profile.options.host)
pk = pk.replace('%r', this.profile.options.user)
try {
contents = await this.fileProviders.retrieveFile(pk)
} catch (error) {
@@ -187,30 +190,32 @@ export class SSHSession {
if (!spec) {
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Agent auth selected, but no running Agent process is found`)
} else {
this.remainingAuthMethods.push({
this.allAuthMethods.push({
type: 'agent',
...spec,
})
}
}
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
if (savedPassword) {
this.remainingAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
}
this.remainingAuthMethods.push({ type: 'keyboard-interactive' })
}
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
if (this.profile.options.password) {
this.remainingAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
this.allAuthMethods.push({ type: 'saved-password', password: this.profile.options.password })
}
const password = await this.passwordStorage.loadPassword(this.profile)
if (password) {
this.remainingAuthMethods.push({ type: 'saved-password', password })
this.allAuthMethods.push({ type: 'saved-password', password })
}
this.remainingAuthMethods.push({ type: 'prompt-password' })
}
this.remainingAuthMethods.push({ type: 'hostbased' })
if (!this.profile.options.auth || this.profile.options.auth === 'keyboardInteractive') {
const savedPassword = this.profile.options.password ?? await this.passwordStorage.loadPassword(this.profile)
if (savedPassword) {
this.allAuthMethods.push({ type: 'keyboard-interactive', savedPassword })
}
this.allAuthMethods.push({ type: 'keyboard-interactive' })
}
if (!this.profile.options.auth || this.profile.options.auth === 'password') {
this.allAuthMethods.push({ type: 'prompt-password' })
}
this.allAuthMethods.push({ type: 'hostbased' })
}
private async getAgentConnectionSpec (): Promise<russh.AgentConnectionSpec|null> {
@@ -323,9 +328,14 @@ export class SSHSession {
}
})
this.previouslyDisconnected = false
this.ssh.disconnect$.subscribe(() => {
if (this.open) {
this.destroy()
if (!this.previouslyDisconnected) {
this.previouslyDisconnected = true
// Let service messages drain
setTimeout(() => {
this.destroy()
})
}
})
@@ -508,6 +518,22 @@ export class SSHSession {
}
async handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
const subscription = this.ssh.disconnect$.subscribe(() => {
// Auto auth and >=3 keys found
if (!this.profile.options.auth && this.allAuthMethods.filter(x => x.type === 'publickey').length >= 3) {
this.emitServiceMessage('The server has disconnected during authentication.')
this.emitServiceMessage('This may happen if too many private key authentication attemps are made.')
this.emitServiceMessage('You can set the specific private key for authentication in the profile settings.')
}
})
try {
return await this._handleAuth()
} finally {
subscription.unsubscribe()
}
}
private async _handleAuth (): Promise<russh.AuthenticatedSSHClient|null> {
this.activePrivateKey = null
if (!(this.ssh instanceof russh.SSHClient)) {
@@ -523,6 +549,7 @@ export class SSHSession {
return noneResult
}
let remainingMethods = [...this.allAuthMethods]
let methodsLeft = noneResult.remainingMethods
function maybeSetRemainingMethods (r: russh.AuthFailure) {
@@ -533,13 +560,13 @@ export class SSHSession {
while (true) {
const m = methodsLeft
const method = this.remainingAuthMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
const method = remainingMethods.find(x => m.length === 0 || m.includes(sshAuthTypeForMethod(x)))
if (!method) {
if (this.previouslyDisconnected || !method) {
return null
}
this.remainingAuthMethods = this.remainingAuthMethods.filter(x => x !== method)
remainingMethods = remainingMethods.filter(x => x !== method)
if (method.type === 'saved-password') {
this.emitServiceMessage(this.translate.instant('Using saved password'))
@@ -576,15 +603,12 @@ export class SSHSession {
if (method.type === 'publickey') {
try {
const key = await this.loadPrivateKey(method.name, method.contents)
const possibleHashAlgs = ['ssh-rsa', 'rsa-sha2-256', 'rsa-sha2-512'].includes(key.algorithm) ? ['sha256', 'sha512', 'sha1'] as const : [null] as const
this.emitServiceMessage(`Trying private key: ${method.name}`)
for (const alg of possibleHashAlgs) {
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, alg)
if (result instanceof russh.AuthenticatedSSHClient) {
return result
}
maybeSetRemainingMethods(result)
const result = await this.ssh.authenticateWithKeyPair(this.authUsername, key, null)
if (result instanceof russh.AuthenticatedSSHClient) {
return result
}
maybeSetRemainingMethods(result)
} catch (e) {
this.emitServiceMessage(colors.bgYellow.yellow.black(' ! ') + ` Failed to load private key ${method.name}: ${e}`)
continue

View File

@@ -309,10 +309,16 @@ export class BaseTerminalTabComponent<P extends BaseTerminalProfile> extends Bas
case 'scroll-to-top':
this.frontend?.scrollToTop()
break
case 'scroll-up':
case 'scroll-page-up':
this.frontend?.scrollPages(-1)
break
case 'scroll-up':
this.frontend?.scrollLines(-1)
break
case 'scroll-down':
this.frontend?.scrollLines(1)
break
case 'scroll-page-down':
this.frontend?.scrollPages(1)
break
case 'scroll-to-bottom':

View File

@@ -101,8 +101,10 @@ export class TerminalConfigProvider extends ConfigProvider {
'⌘-⌥-Shift-I',
],
'scroll-to-top': ['Shift-PageUp'],
'scroll-up': ['⌥-PageUp'],
'scroll-down': ['⌥-PageDown'],
'scroll-page-up': ['⌥-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['⌥-PageDown'],
'scroll-to-bottom': ['Shift-PageDown'],
},
},
@@ -152,8 +154,10 @@ export class TerminalConfigProvider extends ConfigProvider {
'Ctrl-Alt-Shift-I',
],
'scroll-to-top': ['Ctrl-PageUp'],
'scroll-up': ['Alt-PageUp'],
'scroll-down': ['Alt-PageDown'],
'scroll-page-up': ['Alt-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['Alt-PageDown'],
'scroll-to-bottom': ['Ctrl-PageDown'],
},
},
@@ -201,8 +205,10 @@ export class TerminalConfigProvider extends ConfigProvider {
'Ctrl-Alt-Shift-I',
],
'scroll-to-top': ['Ctrl-PageUp'],
'scroll-up': ['Alt-PageUp'],
'scroll-down': ['Alt-PageDown'],
'scroll-page-up': ['Alt-PageUp'],
'scroll-up': ['Ctrl-Shift-Up'],
'scroll-down': ['Ctrl-Shift-Down'],
'scroll-page-down': ['Alt-PageDown'],
'scroll-to-bottom': ['Ctrl-PageDown'],
},
},

View File

@@ -77,6 +77,7 @@ export abstract class Frontend {
abstract visualBell (): void
abstract scrollToTop (): void
abstract scrollLines (amount: number): void
abstract scrollPages (pages: number): void
abstract scrollToBottom (): void

View File

@@ -357,6 +357,10 @@ export class XTermFrontend extends Frontend {
this.xterm.scrollPages(pages)
}
scrollLines (amount: number): void {
this.xterm.scrollLines(amount)
}
scrollToBottom (): void {
this.xtermCore._scrollToBottom()
}

View File

@@ -86,11 +86,19 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
name: this.translate.instant('Scroll terminal to top'),
},
{
id: 'scroll-up',
id: 'scroll-page-up',
name: this.translate.instant('Scroll terminal one page up'),
},
{
id: 'scroll-up',
name: this.translate.instant('Scroll terminal one line up'),
},
{
id: 'scroll-down',
name: this.translate.instant('Scroll terminal one line down'),
},
{
id: 'scroll-page-down',
name: this.translate.instant('Scroll terminal one page down'),
},
{
@@ -113,3 +121,4 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
return this.hotkeys
}
}

View File

@@ -3,7 +3,7 @@ import { Subject, Observable } from 'rxjs'
import { SessionMiddleware } from '../api/middleware'
const OSCPrefix = Buffer.from('\x1b]')
const OSCSuffix = Buffer.from('\x07')
const OSCSuffixes = [Buffer.from('\x07'), Buffer.from('\x1b\\')]
export class OSCProcessor extends SessionMiddleware {
get cwdReported$ (): Observable<string> { return this.cwdReported }
@@ -14,11 +14,22 @@ export class OSCProcessor extends SessionMiddleware {
feedFromSession (data: Buffer): void {
let startIndex = 0
while (data.includes(OSCPrefix, startIndex) && data.includes(OSCSuffix, startIndex)) {
const params = data.subarray(data.indexOf(OSCPrefix, startIndex) + OSCPrefix.length)
const oscString = params.subarray(0, params.indexOf(OSCSuffix)).toString()
while (data.includes(OSCPrefix, startIndex)) {
const si = startIndex
if (!OSCSuffixes.some(s => data.includes(s, si))) {
break
}
startIndex = data.indexOf(OSCSuffix, startIndex) + OSCSuffix.length
const params = data.subarray(data.indexOf(OSCPrefix, startIndex) + OSCPrefix.length)
const [closesSuffix, closestSuffixIndex] = OSCSuffixes
.map((suffix): [Buffer, number] => [suffix, params.indexOf(suffix)])
.filter(([_, index]) => index !== -1)
.sort(([_, a], [__, b]) => a - b)[0]
const oscString = params.subarray(0, closestSuffixIndex).toString()
startIndex = data.indexOf(closesSuffix, startIndex) + closesSuffix.length
const [oscCodeString, ...oscParams] = oscString.split(';')
const oscCode = parseInt(oscCodeString)

View File

@@ -321,16 +321,7 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@electron/asar@3.2.17":
version "3.2.17"
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.17.tgz#91d28087aad80d1a1c8cc4e667c6476edf50f949"
integrity sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==
dependencies:
commander "^5.0.0"
glob "^7.1.6"
minimatch "^3.0.4"
"@electron/asar@^3.2.7":
"@electron/asar@3.2.18", "@electron/asar@^3.2.7":
version "3.2.18"
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.18.tgz#fa607f829209bab8b9e0ce6658d3fe81b2cba517"
integrity sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==
@@ -363,21 +354,6 @@
optionalDependencies:
global-agent "^3.0.0"
"@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2":
version "10.2.0-electron.1"
resolved "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2"
dependencies:
env-paths "^2.2.0"
exponential-backoff "^3.1.1"
glob "^8.1.0"
graceful-fs "^4.2.6"
make-fetch-happen "^10.2.1"
nopt "^6.0.0"
proc-log "^2.0.1"
semver "^7.3.5"
tar "^6.2.1"
which "^2.0.2"
"@electron/node-gyp@https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2":
version "10.2.0-electron.1"
resolved "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2"
@@ -1500,13 +1476,13 @@ app-builder-bin@5.0.0-alpha.12:
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz#2daf82f8badc698e0adcc95ba36af4ff0650dc80"
integrity sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==
app-builder-lib@26.0.0-alpha.8:
version "26.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0-alpha.8.tgz#2ecc525692fa300414e4906dc001adec0ecb2567"
integrity sha512-IvvGAa/RXwuNPiSckIBPjBxI4et8PWb+TsJnhKa/XtxOH64ncs6hDtV7bSxIeUmbvUj3R8dm32dej7UO0Cgtng==
app-builder-lib@26.0.0-alpha.10:
version "26.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-26.0.0-alpha.10.tgz#3eb3f64ffa5e995595ad61497c5e7a0c2d64b817"
integrity sha512-9K3MulGK7j+En4KjH3aq7AzDqe8nn35x7O9l5kwl16nWFdBthcdy1IKsx9CgjMSF+eTNctOZlXwnYiPiGzY+GQ==
dependencies:
"@develar/schema-utils" "~2.6.5"
"@electron/asar" "3.2.17"
"@electron/asar" "3.2.18"
"@electron/fuses" "^1.8.0"
"@electron/notarize" "2.5.0"
"@electron/osx-sign" "1.3.1"
@@ -1516,7 +1492,7 @@ app-builder-lib@26.0.0-alpha.8:
"@types/fs-extra" "9.0.13"
async-exit-hook "^2.0.1"
bluebird-lst "^1.0.9"
builder-util "26.0.0-alpha.8"
builder-util "26.0.0-alpha.10"
builder-util-runtime "9.3.0-alpha.0"
chromium-pickle-js "^0.2.0"
config-file-ts "0.2.8-rc1"
@@ -1524,7 +1500,7 @@ app-builder-lib@26.0.0-alpha.8:
dotenv "^16.4.5"
dotenv-expand "^11.0.6"
ejs "^3.1.8"
electron-publish "26.0.0-alpha.8"
electron-publish "26.0.0-alpha.10"
fs-extra "^10.1.0"
hosted-git-info "^4.1.0"
is-ci "^3.0.0"
@@ -2054,10 +2030,10 @@ builder-util-runtime@9.3.0-alpha.0:
debug "^4.3.4"
sax "^1.2.4"
builder-util@26.0.0-alpha.8:
version "26.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0-alpha.8.tgz#83369a6b66d8659281d72ae41102caee7dd6f0f9"
integrity sha512-qQLArPCYUvlx1Ess7Bwsdbx7F4lnPRZBMOeoVuofcdBWIg1HbGdgYp9I0VNcD2O9D2+lVUHI1gSkCj03oRXRnQ==
builder-util@26.0.0-alpha.10:
version "26.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.0-alpha.10.tgz#f445a530c28da6e3650b93e92263c06c6f89a2cc"
integrity sha512-RMVOAgdd+tzwpyF5C8gx9KjzwdUvkUEubpsHTvb2JwlQnBcyBc6hyVCU2gt2MivQCLbjCOEgsUX1/zHrWDqGfg==
dependencies:
"7zip-bin" "~5.2.0"
"@types/debug" "^4.1.6"
@@ -2065,7 +2041,7 @@ builder-util@26.0.0-alpha.8:
bluebird-lst "^1.0.9"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
cross-spawn "^7.0.3"
cross-spawn "^7.0.6"
debug "^4.3.4"
fs-extra "^10.1.0"
http-proxy-agent "^7.0.0"
@@ -2725,7 +2701,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0:
cross-spawn@^7.0.0, cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
@@ -2962,13 +2938,13 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
dmg-builder@26.0.0-alpha.8:
version "26.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0-alpha.8.tgz#d9766adef7124fbaa21300256b53c4bf6c89f62b"
integrity sha512-H53RkHuUBIgiZtTTdjGigD5BVKYoH6t7Y+ZNmjdzMuptL6rCni7K0mrqvVycCkYRvdeM8BWZeUvw4iOwRQIhmQ==
dmg-builder@26.0.0-alpha.10:
version "26.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-26.0.0-alpha.10.tgz#d4d908922005a0c852d0919a7dd0b8f77d3c4bd0"
integrity sha512-RWzCNLLu4dGIvBf8kBzjF/zI5aMOSA149S1V2NgAA4La8f8ghdJAm/DI5crSb2zDijFLyTNmUGTtvU6eHgiZyQ==
dependencies:
app-builder-lib "26.0.0-alpha.8"
builder-util "26.0.0-alpha.8"
app-builder-lib "26.0.0-alpha.10"
builder-util "26.0.0-alpha.10"
builder-util-runtime "9.3.0-alpha.0"
fs-extra "^10.1.0"
iconv-lite "^0.6.2"
@@ -3091,16 +3067,16 @@ ejs@^3.1.8:
dependencies:
jake "^10.8.5"
electron-builder@^26.0.0-alpha.8:
version "26.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0-alpha.8.tgz#61529b4e977deedf2612a5ca152ee14f69a2aba2"
integrity sha512-sx9ObBOEPiHdmDkTRehZWZG2Z26dL6v+Ue3PMji6bj6q5EwY+3h8Q0qZk5JEvUYO2LRuGFbkYpnzdOZrbxRd7A==
electron-builder@^26.0.0-alpha.10:
version "26.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-26.0.0-alpha.10.tgz#6f629f5f1f3340286af71cabd12d94edc53f15ea"
integrity sha512-QTitqOlP5aZ/8zhnxqjRb6BxSR7Kvwv07PoBGeIXADwSPHQhKhZ+S+GRFzUSYQrMTTJLGzUHbnAes6fZ3uThEA==
dependencies:
app-builder-lib "26.0.0-alpha.8"
builder-util "26.0.0-alpha.8"
app-builder-lib "26.0.0-alpha.10"
builder-util "26.0.0-alpha.10"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
dmg-builder "26.0.0-alpha.8"
dmg-builder "26.0.0-alpha.10"
fs-extra "^10.1.0"
is-ci "^3.0.0"
lazy-val "^1.0.5"
@@ -3190,13 +3166,13 @@ electron-localshortcut@^3.1.0:
keyboardevent-from-electron-accelerator "^2.0.0"
keyboardevents-areequal "^0.2.1"
electron-publish@26.0.0-alpha.8:
version "26.0.0-alpha.8"
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0-alpha.8.tgz#8e2234905e3a1a1909170543b159283600919562"
integrity sha512-IGHPQkfSL+LYAIiqJ2E1mVTxNPFh4XRvQ+OPmBFrgpZrR32NrMlxssUyx1B0N1bGLjevjBMMitlwKFNM5WPnXg==
electron-publish@26.0.0-alpha.10:
version "26.0.0-alpha.10"
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-26.0.0-alpha.10.tgz#16ac95acca2d796ca00c7a90ca27ebf31855f284"
integrity sha512-yUkCJD7MLN57d6PJ8PMcBCR35xytA+jHyrOiS/H0hlmTOWq1sXN+tIBylX4h0dD/C6mn75/y5eE156Pe2nccPw==
dependencies:
"@types/fs-extra" "^9.0.11"
builder-util "26.0.0-alpha.8"
builder-util "26.0.0-alpha.10"
builder-util-runtime "9.3.0-alpha.0"
chalk "^4.1.2"
form-data "^4.0.0"