> Езиковата редакция на този превод е в ход. При неясноти сравнете с [английския оригинал](https://www.sm.ch-j.eu/docs/i18n/en/remote-editor-latency.md). # Дистанционно записване на редактори и латентност ## Коренни причини Предишният редактор е качил работния си файл в директорията майка на целта, който често не може да бъде написан от сметката SSH под `/etc` или `/var`. SFTP преименуване не е предоставен оторизиран път судо, основна проверка на конфликтите, проверка на метаданните за сигурност или надеждна презапис на семантиката. Нейният манипулатор за грешки изтрито временно копие, премахване на материал за възстановяване дори когато завършване е несигурно. Състояние на сесията преди това разкри само състоянието на връзката. Не е имало ICMP или заверени SSH измерване на отговора подаващи индикатора терминал. ## Запис на протокола 1. Фиксиран помощник на SSH отваря обикновен файл с единично свързване, като използва дескриптор-относителен операции и `O_NOFOLLOW` за всеки компонент на пътя. Той улавя съдържанието, SHA-256 хаш, устройство/инод, UID, GID, пълни части за разрешение, наносекунда модификация/промяна пъти и всички четими разширени атрибути. Ядрото проверява хашиша и декодира стриктен UTF-8, запазвайки BOM. Всеки документ получава непрозрачна `editId`, в обхвата на плъгина, терминалната сесия и самоличността на сървъра. 2. Операцията за подготовка на непривилегировани хора решава случая с автентичната сметка. дом чрез `pwd.getpwuid(os.getuid())`, създава `$HOME/ch-j-sm/` с режим `0700` и създава частно, изключително списание за възстановяване. Небезопасен дом, симлинк работно място, или работно пространство собственост на друг акаунт се отхвърля. 3. Ядрото качва скрито, случайно 128- Бит. `.tmp` работен файл чрез SFTP с ексклузивно създаване (`wx`), режим `0600` и 60 секунден канал/източване. Дневникът съдържа целта, първоначалната база и очакваната работна хеш; той не съдържа пълномощия. 4. **Едно. SSH Изпълнението на цялата финализация**, по избор чрез съществуващ изпълнител на судо. Помощникът се отваря безопасно, за да се освободи частното работно копие и го пуска. Той заключва оригиналния инод, проверява изходната му линия, създава изключителен файл на дестинацията до целта, пише цялото съдържание, прилага и проверява метаданните, проверява оригинала отново, и премахва подмяната. 5. Една и съща посока `os.replace` атомно заменя целта. Родителят. директорията е зачервена и се проверява крайният път, хеш, инод и метаданни. Оригиналният път остава на разположение до замяната. Работният файл никога не се премества през файлови системи и никога не се отстранява чрез финализиране. 6. След като Core получи проверен успех, отделно почистване проверява финалната метаданни за съдържание и сигурност преди премахване на работния файл и дневника. Провалът в почистването все още отчита потвърден запис с `recoveryAvailable: true`. Неуспешно качване, провалено судо, конфликт, грешка в метаданните или неуспешна замяна запазва оригиналния и всеки нагласен материал. Непълен качване са идентифицирани като такива и не могат да бъдат възстановени като пълен редактиран документ. Изгубена комуникация SSH, липсващ статус на изход, таймаут и неочаквани резултати от финализирането се отчитат като **unknown**. Ядрото блокира друг запис на несигурен документ; няма автоматично заместване. ## Метаданни, привилегии и граници на безопасност Помощникът запазва и проверява UID, GID и всички части за разрешение POSIX, включително изпълними, сетуидни, залепващи и лепкави битове. Той възпроизвежда Linux разширени атрибути байт за байт, включително POSIX ACLs, възможности и SELinux етикети. Собствеността и съдържанието на файла са зададени преди атрибутите за сигурност, защото пише / shown може да изчистите възможности или специални части разрешение. Наследените атрибути на местоназначение, които липсват в оригинала, се премахват. Промяната на времето отразява новия запис и не е копирана от оригинала. Нечетлив или непредставим атрибут прекратява операцията; метаданните не се изпускат тихо. Подписите на IMA/EVM се отхвърлят изрично, тъй като копирането на съдържание/свързани с интегритет подписи би ги обезсилвало. Отхвърлят се симлинковете в пътя към целта или дома, твърдите файлове и нередовните файлове. Не се използва на място или по-слабо SFTP презаписване на резервното копие. Обикновените записвания се изпълняват като SSH сметка. Защитените записания изискват изрични `{ sudo: true }`; парола sudo е незадължителна за судото без пароли. Паролите се валидират и предават само на канал stdin, никога в рамките на командата, дневника, работния файл, логера или отдалечена грешка. Root SSH сесиите използват съществуващия директен администратор. Неуспешното разрешение оставя оригинала и работещото копие непокътнато. Всички записи, изпълнени като корен (директен корен SSH или судо) също така отхвърлят целеви директории / спонсори, притежавани или записани от други акаунти, или носещи достъп ACL, вместо да се доверяват на привилегировано име на път, контролирано от друга сметка. Фиксираната помощничка работи с `python3 -I -B`: тя игнорира потребителските Python пътеки, работната директория и потребителските пакети на сайта, и не пише байтекод. Пътищата и аргументите на JSON са цитирани в Core. Приставките никога не получават произволни SSH exec или SFTP дръжки. Съществуващ пясъчен бокс, CSP, се използват ясни разрешения, проверка на ключа домакин и проверка на актуализацията. ## Приставка API и оставаща интеграция на Монако **Разпределената отделно Монако/Архив мениджър UI отсъства от тази каса. Неговата UI интеграция, sudo бързо, мръсна-буфер обработка и преводи не могат да бъдат приложени или тествани тук.** В пакетен източник на плъгин е Hash & Checksum плъгин. Не е изобретено заместване на източника на файловия мениджър. Съществуващите методи остават на разположение. Методите/опциите на добавката са изложени на предварително натоварване в пясъчника и разрешено време за изпитване: ```js const opened = await chjPlugin.files.readText(sessionId, path); // For a protected read, explicitly pass { sudo: true, sudoPassword }. const result = await chjPlugin.files.saveText(sessionId, path, editor.getValue(), { editId: opened.editId, sudo: true, // Include only after the user authorizes elevation. sudoPassword // Omit for passwordless sudo; never persist this value. }); if (result.ok && result.value.status === "saved") { // Mark this exact submitted editor version as saved. Later edits stay dirty. } else { // Keep the Monaco model dirty. Translate result.error.code/status. // result.error.recoveryId/recoveryPath identify retained working material. } await chjPlugin.files.closeText(opened.editId); const recovery = await chjPlugin.files.listRecovery(sessionId); const copy = await chjPlugin.files.readRecovery(sessionId, recoveryId); // Review copy.status and copy.text; open a fresh document before another save. await chjPlugin.files.cleanupRecovery(sessionId, recoveryId); // Cleanup rejects anything whose target is not currently confirmed. ``` Методите за възстановяване приемат незадължителен окончателен аргумент на `{ sudo: true, sudoPassword }`, когато се проверява дадена цел, изисква повишаване. Те запазват автентичното работно място на потребителя, дори когато се изпълнява чрез судо. Журналите оцеляват при рестартиране на приложението и SSH се свързва отново; възстановяването никога не се повтаря автоматично. Преглед на възстановения буфер срещу прясно открита цел, преди изричното му спестяване. `files.read` пазачи чете, проверява и дръжка освобождаване. `files.write` пазачи спестява и възстановяване почистване. `writeText` все още отхвърля неуспеха при съществуващите плъгини; `saveText` връща структуриран `{ ok, value/error }` плик, защото Electron пуска потребителски свойства върху отхвърлени обекти за грешка. Завещание с три аргумента `writeText` може да използва изходното ниво на един отворен документ. Многото живи документи за същия път изискват `editId`; двусмислените завещания се провалят безопасно, вместо да избират друга база. Приставките трябва да освобождават неизползвани дръжки. Външният UI трябва да показва спестяване незабавно, поддържа буфери мръсни при провал, предлага sudo само след откази за разрешение/автентичност, показва конфликти без пренаписване и предлага възстановяване след загуба на връзка или неизвестен резултат. Тя трябва да преведе тези държави на чешки, немски и английски език. Предложено копие: | State | Czech | German | English | | --- | --- | --- | --- | | Saving | Ukládání… | Wird gespeichert… | Saving… | | Confirmed | Uloženo | Gespeichert | Saved | | Failure | Uložení selhalo | Speichern fehlgeschlagen | Save failed | | Sudo required | Vyžadováno oprávnění sudo | sudo-Autorisierung erforderlich | Sudo authorization required | | Conflict | Původní soubor byl změněn | Originaldatei wurde geändert | Original file changed | | Disconnected | Spojení bylo přerušeno | Verbindung unterbrochen | Connection lost | | Unknown | Výsledek uložení není znám | Speicherergebnis unbekannt | Save result unknown | | Recovery | Obnova je dostupná | Wiederherstellung verfügbar | Recovery available | ## Дефиниции за латентност и жизнен цикъл **Пинг** е латентността, докладвана от действителен клиент-страна ICMP ехо отговор на решения IP използван от SSH. Core се позовава на платформата пинг изпълнимо асинхронно с фиксирана масив аргумент, без обвивка или администратор startup изискване. Linux, macOS (включително `ping6`) и Windows аргументи се избират отделно. Блокиран ICMP, липсващ изпълним, пауза, невалиден изход или отговор само по-горна граница Windows като `<1ms` произвеждат недостъпна стойност, а не измислен номер. **SSH RTT** е монотонното `performance.now()` продължителност на фиксирано `true` Искане за изпълнение на съществуващото заверено SSH клиент. Тя включва настройка на канала, обработка на сървъра и доставка на отговор; тя не е чиста мрежа RTT или SSH продължителност на вход. Преведеният индикатор подсказка обяснява това разграничение. Наблюдението започва веднага щом терминалът се свърже. Сондите работят едновременно и асинхронно, с петсекундна заявка/процедура. Следващата проба е планирана дванадесет секунди след приключването на предишната извадка, като се предотвратява припокриването. Прекъсване на ICMP, изчиства таймери, отменя чакането на SSH работа и изчиства стойности. Проверката на самоличността не позволява да се публикува предварителна връзка след повторното им публикуване. Грешката в ICMP никога не променя състоянието на връзка SSH. Латентност пътува в рамките на съществуващото `state` събитие / `ssh:state` IPC полезен товар: ```js latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" } ``` Недостъпните номера са `null`. Компактният терминален индикатор използва милисекунди, локализиран недостъпен текст и чешки/German/English Етикети. Крие се при прекъсване. Не са необходими допълнителни възможности за изпълнение на изпълнителя или IPC заявка. ## Гранични стойности за валидиране и експлоатация - Бягай от `app/`: `npm ci`, след това `npm test`. - Окончателен локален резултат: **179 изпитвания; 163 преминах, 0 неуспешно, 16 пропускане**. Всички пропускания са случаите на Linux файлова система на този macOS хост. `npm ci`, Python синтаксис компилация и `git diff --check` завърши успешно. - Тестовете обхващат Core спестява/възстановяване, sudo протокол и парола redaction, истински POSIX черупка цитиране на враждебни пътища, конфликти, качване, неуспешно почистване, несигурни резултати, едновременно документи, IPC разрешения и латентност жизнен цикъл. - Linux тестове файлова система упражняват изпращаната Python входна точка, като се използва частен проверка на сметката-домашен преглед: собственост /mode/xattrs, POSIX ACLs, симлинки/хардвръзки, FIFOs, качване и метаданни неизправности, заместване неуспехи, целеви раси, неизвестни резултати след заместване и възстановяване. Напречната схема на файловата система използва `/dev/shm` и друга файлова система, когато е налична. Тези тестове пропускат на не-Linux хостове; липсват ACL/отделяща файлова система са изрично пропуснати. - Добавените Linux GitHub Действия работа работи на пълен апартамент и повтаря файлова система случаи като корен. Този работен процес не е изпратен от това работещо дърво. - Локалното потвърждение беше на macOS. Синтаксисът на източника на питон е бил проверен директно Инструменти за команден ред Python изпълними. Истински macOS ICMP димна проверка обратно `0.071 ms`. Няма дистанционно SSH сървър, Windows runtime, Linux тичам, SELinux внедряване или външен Монако UI е тестван локално. - Дистанционно редактиране на текст сега изисква Linux и Python 3 с дескриптор-относителен поддръжка на файловата система/ксатр. Липсващият преводач се проваля изрично. Това ядро умишлено отказва опасни метаданни, връзки и настройки на директориите. - Заключването е консултиране: несътрудничещите процеси все още могат да се състезават в тесни интервал между последната основна проверка и атомното преименуване. Linux не доставя общо атомно съдържание-хаш операция за сравнение и замяна. Проверката установява промени преди този интервал; запазването на работни копия поддържа възстановяване след това. - Данните за възстановяването остават в отдалечената сметка до потвърдено почистване. Непълен, Конфликтираните и непроследими списания никога не се изхвърлят мълчаливо. Няма автоматично изтичане на файла за възстановяване и няма опция за принудително презаписване. - `npm ci` докладва резултатите от одита на зависимостта 17 (9 умерено, 8 високо). Тази промяна. не променя зависимостите или актуализира модела на доверие в приложението. Потребителят поиска запазване на промените в съществуващото работещо дърво, в момента `feature/hash-checksum-plugin`; не е бил извършван разклонителен ключ или несвързани почиствания. ## Файловете са променени за тази задача - `src/main/files/remoteFileService.js` - `src/main/files/remoteEditor.py` (нова) - `src/main/sessions/sessionManager.js` - `src/main/sessions/latencyMonitor.js` (нова) - `src/main/plugins/pluginRuntime.js` - `src/preload/pluginPreload.js` - `src/renderer/app.js` - `src/renderer/index.html` - `src/renderer/styles.css` - `src/renderer/i18n.js` - `test/remoteFileService.test.js` - `test/sessionManager.test.js` - `test/pluginRuntime.test.js` - `test/remoteEditor.test.js` (нова) - `test/remoteEditorProtocol.test.js` (нова) - `test/remoteEditorLinux.test.js` (нова) - `test/fixtures/remoteEditorLinux.py` (нова) - `test/latencyMonitor.test.js` (нова) - `README.md` - `docs/remote-editor-latency.md` (този файл) - `../.github/workflows/remote-editor-tests.yml` (нова)