Årsager
Den tidligere editor uploadede sin arbejdsfil i målets forældremappe, som ofte ikke kan skrives af SSH-kontoen under
/etc
eller
/var
. SFTP omdøbe leveret ingen autoriseret sudo sti, baseline konflikt check, sikkerhed metadata verifikation eller pålidelig overskrive semantics. Dens fejl handler slettet den midlertidige kopi, fjerne inddrivelse materiale, selv når færdiggørelsen var usikker.
Sessionsstatus har tidligere kun afsløret forbindelsestilstanden. Der var ingen ICMP eller autentificeret SSH responsmåling fodring terminal indikator.
Gem protokol
- En fast SSH hjælper åbner en regelmæssig, enkelt-link fil ved hjælp af deskriptor-relativ
operationer og
O_NOFOLLOWfor hver kanal komponent. Det fanger indholdet, SHA-256 hash, enhed / inode, UID, GID, komplet tilladelse bits, nanosekund modifikation / ændring gange og alle læsbare udvidede attributter. Core kontrollerer hash og afkoder streng UTF-8, bevare en BOM. Hvert dokument får en uigennemsigtigeditId, scored til sin plugin, terminal session og server identitet. - En ufordelagtig forberedelsesoperation løser den bekræftede kontos
hjem gennem
pwd.getpwuid(os.getuid()), skaber$HOME/ch-j-sm/med tilstand0700og skaber en privat, eksklusiv recovery tidsskrift. Et usikkert hjem, symlink arbejdsområde eller arbejdsplads ejet af en anden konto afvises. - Core uploader en skjult, tilfældig 128-bit
.tmparbejder fil gennem SFTP med eksklusiv oprettelse (wx), tilstand0600og en 60-sekunders kanal / upload timeout. Tidsskriftet indeholder målet, den oprindelige basislinje og forventet arbejdshash; det indeholder ingen legitimationsoplysninger. - One SSH exec udfører hele finalization , eventuelt gennem eksisterende sudo eksekutor. Hjælperen åbner sikkert og hashes den private arbejdskopi og skyller det ud. Det låser den oprindelige inode, kontrollerer dens basislinje, skaber en eksklusiv destination fil ved siden af målet, skriver alt indhold, anvender og verificerer metadata, kontrollerer originalen igen, og skyller udskiftning.
- En samme-mappe
os.replaceatomisk erstatter målet. Moderen mappen skylles ud og den endelige sti, hash, inode og metadata verificeres. Den oprindelige sti forbliver tilgængelig indtil udskiftning. Arbejdsfilen flyttes aldrig på tværs af filsystemer og fjernes aldrig ved færdiggørelse. - Efter Core modtager en verificeret succes, en separat oprydning rechecks den endelige
indhold og sikkerhedsmetadata, før du fjerner arbejdsfilen og journalen. Oprydningsfejl rapporterer stadig en bekræftet gem med
recoveryAvailable: true.
En fejlslagen upload, mislykket sudo, konflikt, metadatafejl eller mislykkedes udskiftning holder originalen og ethvert iscenesat materiale. Ufuldstændige uploads er identificeret som sådan og kan ikke inddrives som et fuldstændigt redigeret dokument. Lost SSH kommunikation, manglende exit status, timeouts og uventede finalization resultater er rapporteret som unknown , aldrig som gemt. Kernen blokerer en anden gemme på et usikkert dokument; der er ingen automatisk udskiftning prøve igen.
Metadata, privilegier og sikkerhedsgrænser
Hjælperen bevarer og kontrollerer UID, GID og alle POSIX tilladelse bits, herunder eksekverbare, setuid, setgid og klæbrige bits. Det gengiver Linux udvidede attributter byte for byte, herunder POSIX ACLs, kapaciteter og SELinux etiketter. Ejerskab og filindhold er sat før sikkerhedsattributter, fordi skriver / known kan rydde kapaciteter eller særlige tilladelse bits. Arvelige destinationsattributter, der ikke findes på originalen, fjernes. Ændringstid afspejler den nye skrivning og kopieres ikke fra originalen.
En ulæselig eller ikke-præsentativ attribut afbryder operationen; metadata er ikke lydløst droppet. IMA/EVM-signaturer afvises udtrykkeligt, fordi kopiering af indhold/inodebundne integritetssignaturer ville ugyldiggøre dem. Symlinks i målet eller hjem stien, hard-linkede filer og ikke-regelmæssige filer afvises. Ingen in-place eller svagere SFTP overskrive fallback bruges.
Almindelige skrivbare gemmer køre som SSH konto. Beskyttede gemmer kræver eksplicit
{ sudo: true }
; en sudo password er valgfri for adgangskodeløs sudo. Adgangskoder valideres og sendes kun på kanal stdin, aldrig inde i kommandoen, journalen, arbejder fil, logger eller ekstern fejl. Root SSH sessioner bruge den eksisterende direkte rod eksekver. Den manglende godkendelse efterlader originalen og arbejdskopien intakt. Alle gemmer henrettet som root (direkte rod SSH eller sudo) afviser også målmapper/dansere, der ejes eller kan skrives af andre konti, eller bærer en adgang ACL, i stedet for at stole på et privilegeret stinavn kontrolleret af en anden konto.
Den faste hjælper kører med
python3 -I -B
: det ignorerer brugeren Python stier, arbejdsmappen og bruger site pakker, og skriver ingen bytecode. Stier og JSON argumenter er shell-citeret i Core. Plugins modtager aldrig vilkårlige SSH exec eller SFTP håndtag. Eksisterende sandkasse, CSP, manifest tilladelser, værts-nøgle verifikation og opdatering verifikation forbliver i brug.
Plugin API og resterende Monaco integration
Den separat distribueret Monaco / File Manager UI er fraværende fra denne checkout. Dens UI integration, sudo prompt, beskidt-buffer håndtering og oversættelser kunne ikke implementeres eller testes her. Den bundtede plugin kilde er Hash & Checksum plugin. Ingen erstatningsfilhåndteringskilde blev opfundet.
De eksisterende metoder er stadig til rådighed. Tilsætningsstoffets metoder/indstillinger udsættes af den forudbelastede sandkasse og tilladelsestjekket køretid:
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.
Recovery metoder acceptere en valgfri endelig
{ sudo: true, sudoPassword }
argument, når inspicere et mål kræver elevation. De bevarer den bekræftede brugers arbejdsområde, selv når de udføres gennem sudo. Journaler overleve app genstart og SSH reconnect; opsving aldrig automatisk gentager færdiggørelse. Gennemgå en gendannet buffer mod et friskåbnet mål, før eksplicit gemme det.
files.read
vagter læser, inspektion og håndtere frigivelse.
files.write
vagter gemmer og inddrivelse oprydning.
writeText
stadig afviser på fiasko for eksisterende plugins;
saveText
returnerer en struktureret
{ ok, value/error }
konvolut fordi Electron falder brugerdefinerede egenskaber på afviste Fejl objekter. En arv tre-argument
writeText
kan bruge basislinjen for et enkelt åbent dokument. Flere live-dokumenter til samme sti kræver
editId
; tvetydige arv opkald mislykkes sikkert i stedet for at vælge et andet dokuments basislinje. Plugins bør frigive ubrugte håndtag.
Den eksterne brugergrænseflade skal vise besparelse med det samme, holde buffere beskidte på fejl, tilbyde sudo kun efter tilladelse / autonisering fiaskoer, vise konflikter uden at overskrive, og tilbyde inddrivelse efter tilslutning tab eller et ukendt resultat. Det skal oversætte disse stater på tjekkisk, tysk og engelsk. Foreslået statskopi:
| 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 |
Latens definitioner og livscyklus
Ping
er latency rapporteret af en faktisk klient-side ICMP ekko svar på den løste IP, der anvendes af SSH. Core påberåber platform ping eksekverbar asynkront med et fast argument array, uden en shell eller administrator opstart krav. Linux, macOS (herunder
ping6
) og Windows argumenter vælges separat. Blokeret ICMP, en manglende eksekverbar, en timeout, ugyldig output eller et øvre-bundt kun Windows svar såsom
<1ms
producere en utilgængelig værdi, ikke et opfundet nummer.
SSH RTT
er den monotone
performance.now()
varighed af en fast
true
exec anmodning over den eksisterende autentificerede SSH klient. Det omfatter kanal setup, server behandling og svar levering; det er ikke ren netværk RTT eller SSH login varighed. Den oversatte indikator værktøjstip forklarer denne sondring.
Overvågningen starter, så snart terminalen forbinder sig. Probes kører samtidig og asynkront med en fem-sekunders anmodning / proces timeout. Den næste prøve er planlagt 12 sekunder efter, at den foregående prøve er færdig, hvilket forhindrer overlapning. Afbryd afbryde ICMP, rydder timere, annullerer igangværende SSH arbejde og rydder værdier. Optag identitetskontrol forhindre en forudgående forbindelse fra offentliggørelse efter gentilslutning. ICMP-fejl ændrer aldrig SSH-forbindelsestilstand.
Latency rejser inde i den eksisterende
state
begivenhed /
ssh:state
IPC nyttelast:
latency: { pingMs: 24.1, sshRttMs: 31.25, measuredAt: "…" }
Utilgængelige numre er
null
. Den kompakte terminal indikator bruger millisekunder, lokaliseret utilgængelig tekst og Czech/German/English etiketter. Den gemmer sig på afbrydelsen. Ingen yderligere renderer udførelse kapacitet eller IPC anmodning var nødvendig.
Validerings- og driftsgrænser
- Kør fra
app/:npm ci, derefternpm test. - Endeligt lokalt resultat:
179 test 163 bestået 0 mislykkedes 16 sprunget over
. Alle spring
er Linux filsystem tilfælde på denne macOS vært.
npm ci, Python syntaks kompilering oggit diff --checkafsluttet med succes. - Testene dækker Core gemmer / inddrivelse, sudo protokol og password reaction, ægte POSIX shell citat af fjendtlige stier, konflikter, uploads, mislykkedes oprydning, usikre resultater, samtidige dokumenter, IPC tilladelser og latens levetid livscyklus.
- Linux filsystem tests udøve den afsendte Python indgang, ved hjælp af en privat
test konto-home opslag: ejerskab/mode/xattrs, POSIX ACLs, symlinks / hardlinks, FIFOer, upload og metadata fejl, udskiftning fiaskoer, mål løb, ukendte post-erstatning resultater og opsving. Cross-filsystem iscenesættelse bruger
/dev/shmog et andet filsystem, når det er tilgængeligt. Disse tests springe over på ikke-Linux værter; manglende ACL/separat-filsystem faciliteter er udtrykkeligt springet over. - Den tilføjede Linux GitHub Handlinger job kører den komplette suite og gentager filsystemet tilfælde som rod. Denne arbejdsgang er ikke blevet afsendt fra dette arbejdstræ.
- Lokal validering var på macOS. Python kilde syntaks blev kontrolleret med den direkte
Kommandolinjeværktøjer Python- kørbar. En rigtig macOS loopback ICMP røgkontrol returnerede
0.071 ms. Ingen direkte fjernbetjening SSH server Windows driftstid Linux runtime, SELinux implementering eller ekstern Monaco UI blev testet lokalt. - Fjerntekstredigering kræver nu Linux og Python 3 med deskriptor-relativ filesystem/xattr- understøttelse. En manglende tolk svigter udtrykkeligt. Denne Core nægter bevidst usikre metadata, links og mappekonfigurationer.
- Låsning er rådgivende: ikke-samarbejdende processer kan stadig køre i den smalle interval mellem den sidste baseline kontrol og atomomregn. Linux leverer ingen generel atomic content-hash sammenligning-og-erstat operation. Kontrol opdager ændringer før dette interval; Beholdte arbejdskopier understøtter inddrivelse bagefter.
- Genopretning data forbliver på den eksterne konto, indtil en bekræftet oprydning. Ufuldstændig Konflikte og usynlige tidsskrifter bliver aldrig smidt ud i stilhed. Der er ingen automatisk recovery-fil udløb og ingen tvungen overskrive mulighed.
npm cirapporterede 17 afhængighed revisionsresultater (9 moderat, 8 høj). Denne ændring ændrer ikke afhængigheder eller programmets opdatering tillid model.
Brugeren anmodede om at beholde ændringer i det eksisterende arbejdstræ, i øjeblikket
feature/hash-checksum-plugin
; ingen gren switch eller ikke-forretningsmæssigt forbundne oprydning blev udført.
Filer ændret til denne opgave
src/main/files/remoteFileService.jssrc/main/files/remoteEditor.py(ny)src/main/sessions/sessionManager.jssrc/main/sessions/latencyMonitor.js(ny)src/main/plugins/pluginRuntime.jssrc/preload/pluginPreload.jssrc/renderer/app.jssrc/renderer/index.htmlsrc/renderer/styles.csssrc/renderer/i18n.jstest/remoteFileService.test.jstest/sessionManager.test.jstest/pluginRuntime.test.jstest/remoteEditor.test.js(ny)test/remoteEditorProtocol.test.js(ny)test/remoteEditorLinux.test.js(ny)test/fixtures/remoteEditorLinux.py(ny)test/latencyMonitor.test.js(ny)README.mddocs/remote-editor-latency.md(denne fil)../.github/workflows/remote-editor-tests.yml(ny)