Architecture (Entwickler)¶
korTTY ist ein modularer JavaFX-SSH-Client, der auf einer mehrschichtigen Architektur basiert. Dieser Anleitung beschreibt die Kernmodule, ihre Verantwortlichkeiten, Abhängigkeiten und wie sie interagieren, um ein nahtloses Terminalerlebnis mit erweiterten Funktionen wie Jobplanung, KI-Integration und Terminaleffekt-Plugins zu bieten.
Architekturübersicht¶
Das folgende Diagramm zeigt die Hauptkomponenten von korTTY und ihre Beziehung:
Module und Abhängigkeiten¶
KorTTY ist in verschiedene Funktionsmodule unterteilt. Das folgende Diagramm gruppiert sie nach Funktion:
Modulaufschlüsselung¶
| Modul | Zweck | Schlüsselklassen |
|---|---|---|
| Kern | SSH-Konnektivität, gemeinsames interaktives Host-Key-Vertrauen, Sitzungsverwaltung, KI-Integration, Terminalautomatisierung | SshTtyConnector, SshHostKeyTrustManager, AiChatManager, TerminalAgentService, Mosh4jTtyConnector |
| ai | Signierter Modell-/Eingabeaufforderungskatalog, Hugging Face-Metadaten/Downloads, eingebettete llama.cpp- und MLX-Laufzeiten und signierte Laufzeitpakete | AiCatalogService, HuggingFaceClient, LlamaRuntimeManager, LlamaRuntimePackageInstaller, EmbeddedMlxAiService, MlxRuntimeLocator |
| rag | Sicherer Quellscanning, Extraktion, Chunking, Embeddings, Vektor-Speicher, Synchronisation und begrenztes Abrufen | RagSourceScanner, RagSourceSynchronizer, LocalHnswStore, RagRuntimeService |
| ui | JavaFX-Benutzeroberfläche, Dialoge, Terminalansichten, SFTP-Manager | TerminalView, TerminalTab, ConnectionEditDialog, SFTPManagerTab, SnippetEditDialog |
| Modell | Domänenobjekte für Verbindungen, Anmeldeinformationen, Snippets, Jobs | ServerConnection, StoredCredential, Snippet, JobSchedule |
| Jobscheduler | Hintergrundjobplanung und -ausführung | JobSchedulerService, JobSchedulerJobRunner, JobJournalEntry |
| Sicherheit | Master-Passwort, Verschlüsselung/Entschlüsselung, Passwort-Tresor | MasterPasswordManager, EncryptionService, PasswordVault |
| Persistenz | XML-Serialisierung, Datei-E/A, Repository-Muster | XMLConnectionRepository, HistoryStorage |
| Plugin | Terminaleffekt-Plugins (ServiceLoader SPI) | TerminalEffectPlugin, TerminalEffectSession |
| Leistung | Aktivitätsbewusstes Schlaf- und App-Nap-Management pro Plattform | PowerManagementCoordinator, MacPowerManagementBackend |
| Telemetrie | Anonyme Nutzungsereignisse nach Zustimmung | TelemetryService, Telemetry |
| control | Standardmäßig ausgeschaltete lokale Steuerungs-API: Transport, Token, Verben, Ereignisbus (siehe Steuerungs-API) | ControlApiServer, ControlVerbs, ControlSurface, ControlEventBus, ControlApiGate |
| cli | Der Client kortty-cli, der die Steuerungs-API spricht (siehe Steuerungs-CLI) |
KorttyCli |
| Teamarbeit | Funktionen für Zusammenarbeit und Fernzugriff | Teambasierte Sitzungsfreigabe und -koordination |
| jmx | Überwachung der Java-Verwaltungserweiterungen | SSHClientMonitor, SSHClientMonitorMBean |
| Coding-Agents | Coding-Agent-Bewusstsein: erkennt Terminal-Coding-Agents in Fenstern, verfolgt ihren Status und speist das Coding-Agents-Panel sowie Benachrichtigungen | CodingAgentDetector, CodingAgentMonitor, CodingAgentRegistry, CodingAgentService |
| Sitzungs-Isolation | Sitzungs-Isolationsstufen und die sandboxed lokalen Shells; SSH-Sitzungen laufen in Sitzungs-Worker-Prozessen (core.worker) |
IsolationLevel, IsolationSettings, SandboxBackend, MacSandboxBackend, BubblewrapSandboxBackend, SessionWorkerProcess |
| Einfügeschutz | Einfügeschutz: prüft eingefügten Text und entscheidet, ob er bestätigt, bereinigt oder verzögert werden soll | PasteGuard, PasteInspection, PasteRules, PastePacer |
| policy | Unternehmensrichtlinien-Datei (kortty-policy.toml): verwaltete Einstellungen, Einschränkungen und verschlüsselte Richtlinienwerte |
PolicyManager, PolicyLoader, EffectivePolicy, ServerAccessPolicy, PolicyValueCipher |
| shellintegration | Shell-Integration (Prompt-Markierungen, Befehlsstatus, Benachrichtigungen) und pro-Pane-Aktivitätstracking | ShellIntegrationInjection, ShellIntegrationWrapperDirectory, PromptNavigator, CommandBlockStore |
| perf | Optionale UI-Zeitverfolgung für Leistungsoptimierung | PerfTrace |
| platform | Plattformunterstützung für verpackte Builds, z. B. Flatpak | FlatpakSupport |
| Update | Versionsprüfung und Update-Benachrichtigungen | Update-Dienst und Versionsmetadaten |
SithTermFX Terminal-Engine¶
korTTY verwendet SithTermFX 1.2.7 als primären Terminal-Emulator, der während des Build-Prozesses aus dem Quellcode kompiliert wird. SithTermFX bietet:
- Terminalemulation: VT100/xterm-kompatibles Terminal-Rendering, unterstützt durch ein benutzerdefiniertes JavaFX-Steuerelement
- OSC-8-Hyperlinks: Klickbare explizite Hyperlinks, die Programme ausgeben. korTTY ersetzt in jedem Bereich den Standard-Link-Handler von SithTermFX durch eine eigene Zulassungsliste (
http,https,ftp,ftps,mailto, streng geparst, höchstens 8 KB, keine Steuer- oder Bidi-Zeichen,mailtobeschränkt auf Empfänger, Betreff, Text und in-reply-to) und öffnet Links über JavaFXHostServices. Links öffnen sich nur bei einem einzelnen, unbewegten Cmd/Strg+Klick ohne Alt (TerminalLinkClickPolicy.isFollowLinkGesture, Benutzerentscheidung D2). Der Einstellungs-Provider von korTTY beantwortetisFollowLinkGesturevon SithTermFX mit dieser Regel, und SithTermFX 1.2.3 folgt einem OSC-8-Link nur bei einem unbewegten, einzelnen Primärklick, den die Regel akzeptiert, sodass ein einfacher Klick, ein Doppel- oder Dreifachklick und das Loslassen nach einem Ziehen auf einem Link wie auf anderem Text wirken, Wort- und Zeilenauswahl eingeschlossen. DieKorttyLinkInfo, die SithTermFX dann ansteuert, übergibt sich an ihren Bereich (KorttyTerminalPanel.followLink), der sie nur öffnet, wenn der primäreMOUSE_CLICKED-Filter, denTerminalLinkClickPolicyauf dem Canvas installiert, genau diesen Klick mit der Geste auf genau diesem Link vermerkt hat, sodass die Geste unter jedem Einstellungs-Provider gilt und keine Navigation die unten beschriebenen Prüfungen umgeht. Derselbe Filter öffnet einen Link, den korTTY im Klartext gefunden hat, selbst, nach einer reinen Entscheidungstabelle, und konsumiert diesen Klick mit einer Fokusanforderung, damit die Split-Ansicht weiterhin den fokussierten Bereich verfolgt.news:und andere Ziele bleiben Klartext, und einfile:-Ziel wird nur in einem Bereich zum Link, der Dateien als Text öffnet (siehe unten), sodass Terminalausgabe niejava.awt.Desktop.openerreicht und keine lokale Datei starten kann. Bereiche behalten den StandardmodusHOVER_WITH_BOTH_COLORSvon SithTermFX bei, in dem verlinkter Text seine eigenen Farben und Attribute behält, SGR-Änderungen innerhalb des Links eingeschlossen (seit SithTermFX 1.2.3), und unterstrichen wird, solange die Geste über ihm gehalten wird, undTerminalScreenRendererzeichnet eine Link-Zelle mitHyperlinkStyle.getUnderlyingStyle()auf, dem Stil des Textes unter dem Link. korTTY registriert keinen SithTermFX-HyperlinkFilter: Links im Klartext werden stattdessen bei Bedarf gefunden, sodass sie nichts kosten, während Ausgabe eintrifft, und sich nur über die Prüfung von korTTY öffnen;NoHyperlinkFilterGuardTestlässt den Build fehlschlagen, wenn ein Filter hinzugefügt wird.TerminalLinkResolverist der Trefferauflöser der Klick-Policy: Unter der Puffersperre liefert er den OSC-8-Link der angeklickten Zelle oder führt andernfallsTerminalLinkDetectorfür Web- und E-Mail-Adressen über die logische Zeile um die Zelle aus, begrenzt auf ±16 umgebrochene Zeilen und 4096 Zeichen, und verwirft ein Token, das über dieses Fenster hinauslaufen könnte, statt es abgeschnitten zu öffnen. Die Arten kommen von einem Lieferanten pro Bereich, derGlobalSettings.terminalLinkDetectionEnabledbei jedem Klick liest, sodass die Erkennung nichts kostet, während Ausgabe eintrifft.TerminalLinkHoverControllerlöst auf dieselbe Weise auf, aber nur, wenn die Maus eine andere Zelle erreicht: EinMOUSE_MOVED-Handler, der nach dem von SithTermFX hinzugefügt wird, setzt den Canvas-Cursor bei jedem Zellwechsel explizit (HAND nur für einen Link, der sich öffnen lässt), zeichnet die Unterstreichung eines Klartext-Links alsLines in dieLINKS-Ebene des Bereichs (TerminalSplitPane.paneOverlay, ein nicht verwaltetes, für die Maus transparentesPaneim Wrapper des Bereichs mit negativer View-Order, positioniert über Szenenkoordinaten, weil der Wrapper auch die Zeitstempel-Spalte und das Agent-Panel enthält) und zeigt einen Tooltip mitTerminalLinkOpener.displayTarget(Punycode-Host, prozentkodierte Steuer- und Bidi-Zeichen, auf etwa 200 Zeichen gekürzt, ohne den Host abzuschneiden). Er baut alles wieder ab bei Verlassen, Ziehen, Scrollen, einer Nicht-Modifikatortaste, Fokusverlust von Bereich oder Fenster und Entfernen aus der Szene, und solange ein Link angezeigt wird, folgt er einem Listener auf das Puffermodell (auf den FX-Thread zusammengefasst) und Größenänderungen des Canvas, um neu aufzulösen. Ein OSC-8-Klick, dessen sichtbarer Text eine URL auf einem anderen Host als das Ziel ist (TerminalLinkOpener.visibleHostMismatch), öffnet erst nachTerminalLinkMismatchDialog, der nach der Verarbeitung des Klicks fragt, mit Abbrechen als Standardschaltfläche. Das Terminal-Kontextmenü erreicht dieselben Links ohne Modifikator:TerminalLinkContextMenufügt einenMOUSE_PRESSED-Filter auf dem Canvas hinzu, der den Link unter jedem Druck der rechten Maustaste auflöst (jeder andere Druck vergisst ihn), undTerminalSplitPane.createFullContextMenusetzt für einen Link mit Ziel Link öffnen (der Öffnungsweg des Klicks, Abweichungs-Rückfrage eingeschlossen) und Linkadresse kopieren (überKorttyClipboard, sodass der interne Zwischenablagemodus gilt; bei einem OSC-8-Link dastoASCIIString()-Ziel, bei einer Klartextadresse die Adresse wie ausgegeben) über die Bearbeitungseinträge. Dateien gehen dieselben Wege ohne Browser:TerminalFileLinkist ein Pfad, den der Detektor gefunden hat (Kind.PATH, zerlegt durchTerminalPathToken), oder ein OSC-8-file:-Ziel, dasfromFileUriakzeptiert (absoluter Pfad, keine//-Netzwerkfreigabe, kein Backslash, nach dem Dekodieren keine Steuer-, Bidi- oder Formatzeichen, ein Host ohne Benutzername oder Port).KorttyOsc8LinkInfoProvidererstellt einenfile:-Link nur, solange derTerminalFileLinkHandlerdes Bereichs aktiviert ist (auf dem Emulator-Thread abgefragt), wasTerminalViewnur für SSH- und lokale Shell-Bereiche wahr macht, solange einTerminalPathOpenHandlergesetzt ist, undMainWindowsetzt einen solchen nur, wennloadIntoSnippetEditorder Richtlinie nichtDENYist; dieselbe Bedingung fügtPATHzu den Klartext-Linkarten des Bereichs hinzu. Das gemeinsame Lookup des Bereichs verwirft die Datei eines Links, den der Handler nicht akzeptiert (ein OSC-8-Host, der nicht leer,localhost, der Verbindungshost, der Prompt-Host oder der lokale Hostname ist, verglichen am ersten DNS-Label), sodass Hover, Klick und Kontextmenü übereinstimmen. Das Öffnen löst den Pfad mitRemoteTextFileSelectionSupport.resolveRemotePath/resolveLocalPathauf (absolut,~und relativ zum Arbeitsverzeichnis zum Klickzeitpunkt, das nur für einen relativen Pfad ermittelt wird; UNC- und Gerätepfade werden vor und nach dem Auflösen abgelehnt) und liest ihn über denselben Leser wie Im Snippet-Editor öffnen, mit dem Schutz gegen fremde Sitzungen, den Prüfungen auf reguläre Datei und UTF-8 sowie einer 10-MB-Grenze für SFTP- und lokale Lesevorgänge, die auch eine Datei stoppt, die während des Lesens wächst. Eine Datei aus einem OSC-8-Link öffnet sich schreibgeschützt:ExternalFileActionConfigerhält keine Überschreiben- oder Speichern-unter-Aktion und einenlockedReason.TerminalLinkHoverControllerfügt seinenMOUSE_MOVED-Handler inKorttyTerminalPanel.init()hinzu, nachdem SithTermFX dort seinen eigenen hinzugefügt hat, sodass der Cursor, den korTTY setzt, auch bei einem OSC-8-Link gewinnt, den korTTY nicht öffnet. - Schnellauswahl: Bearbeiten → Schnellauswahl (Cmd/Strg+Shift+Leertaste) versieht das, was der fokussierte Bereich anzeigt, mit Kürzeln. Die Tastenkombination ist eine
MainWindow-Konstante, die über den Shortcut-Router der Szene geleitet wird (Geltungsbereich: ein Terminal-Tab, in dem der Tastaturfokus liegt; Rest: Leerzeichen oder NUL) und am Menüeintrag gesetzt ist, der außerhalb von Terminal-Tabs deaktiviert ist.QuickSelectScreenliest unter der Puffersperre die sichtbaren Zeilen am Scroll-Ursprung des Panels, fügt umgebrochene Zeilen innerhalb des Sichtbereichs zusammen (zugeschnitten auf die 16-KB-Eingabegrenze des Detektors) und führtTerminalLinkDetectorfür jede Art aus, wobei ein Token verworfen wird, das über den Sichtbereich hinausläuft; die eigenen Muster des Benutzers (QuickSelectPatterns, ausGlobalSettings.terminalQuickSelectPatterns: höchstens 16 mit je höchstens 512 Zeichen, einmal pro Änderung der Liste kompiliert) laufen über denselben gescannten Text und ergebenKind.CUSTOM, jeweils über eineDeadlineCharSequencemit 10 ms pro Zeile und 100 ms für eine ganze Erfassung, wobei ein Muster, das seine Zeit überschreitet, für den Rest der Erfassung übersprungen wird, und ein Mustertreffer ersetzt die eingebauten Treffer, die er überlappt, wenn er mindestens so lang ist wie jeder von ihnen;QuickSelectLabelsvergibt präfixfreie Kürzel aus dem Alphabet des Benutzers (terminalQuickSelectAlphabet, geprüft vonalphabetProblem, bei Unbrauchbarkeit der Standard; ein Buchstabe pro Text bis zur Größe des Alphabets, sonst zwei), beginnend mit der untersten Zeile, eines pro verschiedenem Text;QuickSelectSessionist ein reiner Zustandsautomat überKeyCodeund Shift (Modifikatortasten und die Start-Tastenkombination werden ignoriert, ein Kürzel kopiert, Shift auf seinem letzten Buchstaben öffnet, Backspace bearbeitet das Präfix, Escape und jede andere Taste brechen ab).TerminalQuickSelectControllerinstalliert die erstenKEY_PRESSED-,KEY_TYPED- undINPUT_METHOD_TEXT_CHANGED-Filter der Split-Ansicht (vor denen vonTerminalView, also vor der Agent-Eingabesperre und dem Broadcast-Spiegel pro Bereich): Solange eine Sitzung läuft, wird jede Taste, jedes getippte Zeichen und jedes Eingabemethoden-Ereignis konsumiert, undQuickSelectInputGuardverwendetKeyTypedResidueGuard, um dasKEY_TYPEDder letzten Taste einmal sowie jeden Eingabemethoden-Text bis zum nächsten Tastendruck zu verschlucken. Er zeichnetRectangle-Rahmen und inline gestylteLabel-Chips (Farben des Bereichs invertiert, Terminalschrift) über Szenenkoordinaten (TerminalCellGeometry.boxes) in dieLINKS-Ebene des Bereichs, kopiert überKorttyClipboard, öffnet eine URL, eine E-Mail-Adresse oder, wo der Bereich Dateien öffnet (KorttyTermWidget.opens), einen Pfad überopenLinkdes Widgets (den Cmd/Strg+Klick-Weg) und kopiert alles, was er nicht öffnet, und endet bei einem Mausdruck, Fokusverlust des Canvas, einer Verschiebung oder Größenänderung des Canvas, einer Änderung der Scrollleiste, einer Änderung der Schriftgröße (TerminalView.reinitPaneFont) oder dem Entfernen aus der Szene; ein Listener auf das Puffermodell, auf den FX-Thread zusammengefasst, verwirft die Treffer, deren Zellen ihren erfassten Text nicht mehr enthalten, und beendet die Sitzung, wenn keiner mehr übrig ist. - Sitzungsintegration: Direktes JAXB-Marshalling des Terminalstatus für Sitzungsaufzeichnung und -wiedergabe
- Farbunterstützung: Konfigurierbare ANSI- und TrueColor-Verarbeitung mit Überschreibungen pro Verbindung
- Scrollback-Speicherlimit und -kompression: Seit SithTermFX 1.2.6 ist der Verlauf eines Fensters durch eine Schätzung seines Heap-Speichers sowie durch seine Zeilenanzahl begrenzt.
KorTTYSettingsProviderbeantwortetgetBufferMaxMemoryBytes()undisScrollbackCompressionEnabled()ausConnectionSettings.scrollbackMemoryMbundscrollbackCompression, undTerminalView.applyScrollbackMemoryübergibt eine gespeicherte Änderung an dasTerminalTextBufferjedes offenen Fensters. Bei aktivierter Kompression packt ein SithTermFX-Thread mit niedriger Priorität Verlaufszeilen in deflatierte Blöcke von bis zu 128 Zeilen, sobald ein Fenster seit 1,5 s keine Ausgabe mehr hatte, wobei die Puffersperre jeweils nur für wenige Millisekunden gehalten wird; die Zeilen auf dem Bildschirm samt eines Bildschirms um sie herum, der neueste Bildschirm und Zeilen mit einer benutzerdefinierten Hervorhebung bleiben ungepackt, und nichts wird gepackt, während Suchergebnisse angezeigt werden. Eine gepackte Zeile behält ihreTerminalLine-Identität, ihr Umbruch-Flag und ihre Stile bei, sodassScrollbackTrimTracker, die Befehlsmarkierungen und der Schlüsselwort-Hervorheber, die alle an der Zeilenidentität andocken, unberührt bleiben; das Zeichnen einer Zeile oder das Lesen ihrer Einträge packt ihren Block auf,getText()dekodiert ohne Aufpacken - Grenzkorrektur für Hyperlinks: Der Hyperlink-Treffertest lehnt die nicht vorhandene Zeile bei
line == heightab und verhindert soTerminalTextBuffer-Bereichsfehler in der untersten Zeile. korTTY hat dies als angehefteten Patch mitgeführt, bis er in SithTermFX 1.2.3 ausgeliefert wurde;TerminalPanelBoundaryPatchTesthält das Verhalten fest - Shortcut-Akkord-Korrektur: Shortcut-Akkord-
KEY_TYPED-Zeichen (z. B. Cmd+Shift+D) erreichen die PTY- oder Broadcast-Bereiche nicht mehr. Wurde bis SithTermFX 1.2.3 als korTTY-Patch mitgeführt;TerminalPanelShortcutKeyTypedPatchTesthält das Verhalten fest - Längenbegrenzung für Steuersequenzen: Der 1024 Zeichen große Rückschiebepuffer, über den
ControlSequencedie Zeichen, die es in einer CSI nicht unterbringen kann, vor der Sequenz erneut liest, ist begrenzt: Nicht zuordenbare Zeichen und danach ganze Parameter, die nicht hineinpassen, werden verworfen, und die neu ausgegebene Sequenz behält immer ihr Abschlusszeichen, sodass eine überlange Sequenz in der Ausgabe der Gegenstelle keineArrayIndexOutOfBoundsExceptionmehr im Emulator-Thread auslöst und die Sitzung beendet.OscEventSplitterspielt dieselben Zeichen erneut ab. Wurde als korTTY-Patch mitgeführt, bis er in SithTermFX 1.2.3 ausgeliefert wurde (vendor-patches/0003-control-sequence-push-back-bounds.patch);ControlSequenceBoundsPatchTesthält das Verhalten fest - Korrektheit des Bildlaufbereichs: Der Bildlaufbereich schränkt den Cursor nicht ein, während der Ursprungsmodus (DECOM) deaktiviert ist. Text, der oberhalb des oberen Rands oder unterhalb des unteren Rands adressiert wird, bleibt in dieser Zeile, anstatt in den Bereich gezogen zu werden, und nur ein Zeilenvorschub oder ein automatischer Zeilenumbruch, der tatsächlich den unteren Rand überschreitet, scrollt – so landen die erste Bereichszeile von tmux, seine Statuszeile und der Cursor alle dort, wo die Anwendung sie platziert hat. Wird als korTTY-Patch getragen, bis er in SithTermFX 1.2.2 ausgeliefert wird
Build-Integration¶
Der Build-Prozess automatisch:
- Kloniert SithTermFX mit dem Tag
v1.2.7invendor/sithtermfx(kein GitHub-Token erforderlich) - Erstellt es lokal mit Maven über die
installSithtermfxLocal-Aufgabe – den veröffentlichten Tag unverändert, da korTTY keine SithTermFX-Patches mitführt - Installiert Artefakte im lokalen Maven-Repository (
mavenLocal()); die Aufgabe läuft erneut, sobald dort das Kern- oder UI-JAR der angehefteten Version fehlt - Verknüpft SithTermFX-Kern- und UI-Module mit der korTTY-JAR
Nach dem Klonen ist kein Netzwerkzugriff erforderlich; Alle Build-Schritte sind deterministisch und reproduzierbar.
Persistenz und Konfiguration¶
KorTTY speichert seine Hauptkonfiguration, Anmeldeinformationen und Sitzungsstatus unter ~/.kortty/, hauptsächlich als JAXB-XML. Die lokale Modellregistrierung verwendet ebenfalls JAXB-XML, während die Konfiguration des Wissensspeichers strikt JSON ist und das lokale Vektordiagramm ein regenerierbarer binärer Snapshot ist. Dieser Ansatz gewährleistet:
- Portabilität: Einfache manuelle Inspektion und Migration zwischen Systemen
- Verschlüsselung: Sensible Daten (Passwörter, SSH-Schlüsselpassphrasen, Master-Passwort-Hash) werden mit AES-256-GCM verschlüsselt
- Atomere Schreibvorgänge: Dateiaktualisierungen verwenden temporäre Dateien und eine atomare Umbenennung, um eine Beschädigung bei einem Absturz zu verhindern
- Keine erforderliche Datenbank: Lokales HNSW ist eigenständig; Qdrant ist ein optionales zweites Vektor-Backend
Konfigurationsdateistruktur¶
~/.kortty/
├── connections.xml # Saved SSH/Mosh connections
├── credentials.xml # Stored usernames/passwords for env-specific targets
├── ssh-keys.xml # SSH key references and encrypted passphrases
├── gpg-keys.xml # GPG key management for backup encryption
├── global-settings.xml # Application-wide settings (theme, language, AI profiles)
├── llm/
│ ├── models.xml # Local GGUF registrations and typed launch settings
│ ├── models/ # Managed GGUF weights (regenerable; excluded from backup)
│ ├── runtime/ # Versioned native llama.cpp packages
│ ├── catalog/ # Regenerable signature-verified catalog cache
│ └── run/ # Temporary sidecar key files and logs
├── rag/
│ ├── stores.json # Knowledge-store and source configuration
│ └── stores/ # Regenerable local HNSW snapshots
├── job-scheduler.xml # JobScheduler jobs, host-key pins, sudo secrets, journal
├── ssh-host-keys.properties # Shared interactive Terminal/SFTP/Mosh host-key pins
├── terminal-effect-plugins.disabled # Disabled terminal-effect plugin IDs (one per line)
├── master.key # PBKDF2-hashed master password (310,000 iterations)
├── logs/ # Application log (kortty.log) and its archives
├── history/ # Project screen snapshots (gzip, one per terminal tab)
├── plugins/ # Imported external terminal-effect plugin JARs
├── bundled-plugins/ # Runtime copies of bundled exportable plugin JARs
├── projects/ # Project files (connection sets with saved layout)
├── i18n/ # Dynamically generated language property files
└── ssh-keys/ # Optional: copied SSH keys (included in backups)
Serialisierung und Verschlüsselung¶
JAXB Marshaling konvertiert Domänenobjekte in/aus XML mit automatischer Schemavalidierung. Zu den wichtigsten Repositories gehören:
XMLConnectionRepository: VerwaltetServerConnection-Objekte mit SFTP-, Jump-Server- und TunneldetailsCredentialManager: Speichert umgebungsspezifische AnmeldeinformationsmusterSSHKeyManager: Umschließt importierte SSH-Schlüssel mit verschlüsselten PassphrasenJobSchedulerRepository: SpeichertJobScheduleObjekte und das Ausführungsjournal
AES-256-GCM-Verschlüsselung schützt vertrauliche Felder:
- Das Master-Passwort wird bei der ersten Anmeldung einmal gehasht und gespeichert als
master.key - Alle verschlüsselten Felder verwenden AES-256-GCM mit zufälligen IVs, unter einem Schlüssel abgeleitet vom Master-Passwort
- SSH-Schlüsselpassphrasen, Verbindungskennwörter und Sudo-Geheimnisse werden vor der Persistenz verschlüsselt
- Backup-Archive können mit passwortgeschütztem ZIP oder GPG verschlüsselt werden
Kernmodulorganisation¶
SSH und Sitzungsverwaltung¶
| Komponente | Verantwortung |
|---|---|
SshTtyConnector |
Apache SSHD Terminalverbindung eines Panels: Sprunghost, Authentifizierung, Shell-Kanal und Trennungserkennung |
ActiveConnectionRegistry |
Live-Liste der offenen SSH- und Mosh-Terminalverbindungen (eine pro Panel), gelesen vom JMX-MBean |
SshTunnelManager |
Die SSH-Tunnel (-L, -R, -D) eines Terminal-Tabs: werden nach dem Login in der ersten SSH-Sitzung des Tabs geöffnet, vor einer Wiederverbindung gestoppt und danach wieder geöffnet, in ein anderes Paneel desselben Servers verschoben, wenn dieses Paneel geschlossen wird; geteilte Paneele öffnen nie ihre eigenen |
SshTunnelApprovals |
Einmalige Bestätigung pro Verbindung und Tunnel-Set vor dem Öffnen der Tunnel, gespeichert als Fingerabdruck in ssh-tunnel-approvals.properties |
SshHostKeyTrustManager |
Gibt normalisierte Host:Port-TOFU-Pins über interaktive Terminal-, SFTP- und Mosh-Bootstrap-Verbindungen mit atomarer, prozessübergreifender Persistenz frei |
SSHKeyManager |
Zentralisierte SSH-Schlüsselspeicherung mit verschlüsselter Passphrase-Unterstützung |
Mosh4jTtyConnector |
Mosh-Protokoll-Connector unter Verwendung der mosh4j-Bibliothek (dynamisch geladen) |
NativeMoshTtyConnector |
Native OS Mosh-Unterstützung (Fallback) |
TemporarySSHKeyManager |
Zeitlich begrenzte SSH-Schlüssel (z. B. von CyberArk) |
AI und Agentenintegration¶
| Komponente | Verantwortung |
|---|---|
AiChatManager |
Verwaltet KI-Chatsitzungen und den Gesprächsverlauf |
AiServiceFactory |
Ordnet ein Profil dem HTTP-, Anthropic-, lokalen CLI- oder eingebetteten llama.cpp-Transport zu und fügt dann Eingabeaufforderungsvoreinstellungen und optionales RAG hinzu |
AiCatalogService |
Gibt sofort einen erneut verifizierten Cache/Bootstrap zurück und plant eine signierte Stable-Channel-Aktualisierung für Empfehlungen und voreingestellte Familienzuordnungen |
LlamaRuntimeManager |
Gibt einen isolierten authentifizierten Sidecar pro kompatibler GGUF-Konfiguration gemeinsam und gewährt referenzgezählte Anforderungsleasings |
RagAugmentedAiService |
Ruft begrenzte Auszüge für gewöhnliche KI-Aktionen ab und fügt den nicht vertrauenswürdigen Kontext vor der Modellvoreinstellung hinzu |
TerminalAgentService |
Führt Agenten-Workflows aus: SSH-Sitzung prüfen, Aufgabe an Modell senden, Befehle validieren/ausführen |
AiInternetAccessConfiguration |
Konfiguriert Web-Tools (Tavily, Brave Search, SearXNG usw.) pro Profil |
AiChatExportService |
Exportiert KI-Chats nach Markdown, PDF, YAML, JSON, XML, Asciidoctor |
Jobplanung¶
| Komponente | Verantwortung |
|---|---|
JobSchedulerService |
Hauptplanerdienst; verwaltet geplante Jobs und die Ausführungswarteschlange |
JobSchedulerJobRunner |
Führt einzelne Jobs aus (SSH-Befehl, Skript, KI-Agent, SFTP, Rsync) |
JobJournalEntry |
Führen Sie Journal-Einträge in job-scheduler.xml aus, wobei Geheimnisse ausgeblendet und die konfigurierte Aufbewahrungszeit (standardmäßig 14 Tage) gelten |
Sitzungsjournal¶
| Komponente | Verantwortung |
|---|---|
SessionJournalService |
Erstellt und speichert ein Journal pro Sitzung in journals/: das kuratierte journal.xml und das rotiertes Aufnahmelog |
SessionJournalExportService |
Exportiert ein Journal in seine unterstützten Formate |
SessionJournalCrossSearchService |
Durchsucht alle Journale, mit den pro Journal Suchkarten |
SessionJournalSearchCardIndex |
Speichert eine Suchkarte pro Journal in search-card.json, neu aufgebaut wenn sich das Journal ändert |
SessionJournalSemanticIndex |
Optionaler semantischer Suchindex im Journale-Ordner (.semantic-index/), erstellt mit dem lokalen Einbettungsmodell |
UI-Modulorganisation¶
Die UI-Ebene basiert auf JavaFX und ist in logische Komponenten unterteilt:
| Komponente | Zweck |
|---|---|
MainWindow |
Anwendungsfenster der obersten Ebene mit Menüleiste, Registerkartenleiste, Terminalbereichen, Dashboard, SFTP-Browser |
TerminalTab |
Ein Terminal-Tab mit Split-Pane-Unterstützung (in TerminalView) und inline KI-Aktivitätspanel |
ConnectionEditDialog |
Multi-Tab-Editor für Verbindungsdetails (SSH, Tunnel, Jump-Server, Protokollierung usw.) |
SFTPManagerTab |
Zweispaltiger Dateimanager-Tab für lokale und entfernte Dateioperationen |
SnippetEditDialog |
Snippet-Editor mit einem Monaco-Code-Editor, Syntaxhervorhebung, KI-Unterstützung und Mermaid-Flussdiagrammen |
LocalModelManagerPane |
Sucht/lädt/importiert GGUF-Dateien und steuert gleichzeitige llama.cpp-Sidecars |
RagKnowledgeStorePane |
Erstellt Wissensspeicher, zeigt Quellenvorschau an, zeigt den persistierten Indexzustand an, synchronisiert sie und führt Abfragen zur Wiederfindung durch |
JobSchedulerDialog |
Joberstellung, Planung und Journalprüfung |
QuickConnectDialog |
Schnelle Verbindungssuche und häufig verwendete Verbindungsverknüpfungen |
Sicherheitsarchitektur¶
Master-Passwort und Verschlüsselung¶
- Erster Start: Der Benutzer erstellt ein Master-Passwort (mindestens 6 Zeichen, Stärke überprüft über zxcvbn)
- Speicherung: Das Passwort wird mit PBKDF2 mit 310.000 Iterationen gehasht und gespeichert
~/.kortty/master.key - Entsperren: Das Master-Passwort entsperrt alle verschlüsselten Daten (Verbindungspasswörter, SSH-Schlüsselpassphrasen, Anmeldeinformationen, Backup-Archiv-Passwörter)
- Verschlüsselung: AES-256-GCM mit zufälligen IVs; Die Verschlüsselung/Entschlüsselung erfolgt bei Bedarf beim Zugriff auf vertrauliche Felder
Host-Schlüsselüberprüfung¶
- Interaktives Terminal/SFTP/Mosh Bootstrap: Ein gemeinsamer TOFU-Verifizierer wird durch den normalisierten Hostnamen und Port gekennzeichnet. Die erste Verwendung zeigt den OpenSSH-SHA-256-Fingerabdruck mit Nein als Vorgabe; eine exakte Übereinstimmung bleibt still, während ein geänderter Schlüssel ohne erneuten Versuch hart blockiert wird. Nur eine Verbindung, die der Benutzer in einem Terminal-Tab oder im SFTP-Manager geöffnet hat, kann einen geänderten Schlüssel ersetzen, nachdem eine explizite Fingerabdruckbestätigung erfolgt ist und als Compare-and-Swap gegen den überprüften Schlüssel dient; Hintergrundaufrufe bauen ihren Verifizierer mit der Nie-Ersetzen-Politik auf.
- Interaktiver Speicher:
ssh-host-keys.propertiesspeichert Public-Key-Material durch einen atomaren Ersatz, der sowohl durch prozessinterne als auch prozessübergreifende Sperren geschützt ist. Sein vorübergehender Begleiter.lockwird nicht gesichert. - JobScheduler: Unbeaufsichtigtes SSH, SFTP und Rsync verwenden separate verbindungs-ID-basierte Pins in
job-scheduler.xml, einschließlich OpenSSH-Public-Key-Material, das von Rsync benötigt wird. Durch eine Außerkraftsetzung pro Auftrag kann diese Überprüfung nur dann deaktiviert werden, wenn das Risiko ausdrücklich akzeptiert wird.
Anmeldeinformationsverwaltung¶
- Umgebungsspezifisch: Anmeldeinformationen können auf Produktion, Entwicklung, Test oder Staging beschränkt werden
- Glob-Muster: Servermuster wie
*.example.comoder10.0.0.*stimmen automatisch mit Verbindungen überein - Verschlüsselt gespeichert: Alle Anmeldedaten-Passwörter verwenden AES-256-GCM
Eingebettete KI- und RAG-Isolation¶
- Jeder eingebettete Modellprozess bindet nur an
127.0.0.1an einem zufälligen Port und erfordert einen generierten API-Schlüssel, der in einer temporären Datei nur für Besitzer gespeichert ist. - Der feste Startbefehl llama.cpp aktiviert den Offline-Modus und deaktiviert die Web-Benutzeroberfläche, den Agenten, den UI-MCP-Proxy und den Slot-Endpunkt. Die geerbten Token-Variablen
LLAMA_ARG_*und Hugging Face wurden entfernt. - Hugging Face-Tokens und KI-Profil-API-Schlüssel werden mit dem Master-Passwort verschlüsselt. Modelldownloads werden an eine unveränderliche Revision angeheftet und mit SHA-256 überprüft.
- RAG akzeptiert nur zentral zugelassenen, inhaltsvalidierten Text. Abgerufene Auszüge werden als explizit nicht vertrauenswürdige Daten begrenzt und verpackt, sodass indizierte Anweisungen den System-/Aktionsvertrag von korTTY nicht ersetzen können.
- Runtime-Update-Indizes werden mit Ed25519 als exakte Bytes überprüft, bevor Paket-URLs analysiert werden; Pakete verfügen außerdem über signierte Größen-/SHA-256-Metadaten und sichere ZIP-Extraktionsbeschränkungen.
- Runtime-Entnahmen werden vor dem Herunterfahren des Prozesses durch eine Runtime-Root-Denylist plus Paketmarkierung beibehalten. Aktive Zeiger und unsichere Rollback-Verlaufseinträge werden entfernt, registrierte Modelle werden an eine nicht ausführbare Quarantänemarkierung zurückgebunden und der Startpfad überprüft die Markierung erneut, sodass ein veralteter Registrierungsstatus eine zurückgezogene Binärdatei nicht wiederbeleben kann.
- Ein Paket, das die Integritätsprüfung der Lightweight-Version besteht, bleibt bis zum ersten echten GGUF-gestützten authentifizierten API-Start in der Warteschleife.
LlamaRuntimeFirstLaunchRecoverybestätigt die Bereitschaft oder stellt nach einem Startfehler die neueste fehlerfreie, nicht widerrufene Installation und Modellbindungen wieder her. - Der unabhängige Modell-/Prompt-Katalog verfügt über einen eigenen Ed25519 Trust Root und ein eigenes striktes Schema. Sein Cache wird vor der Verwendung erneut überprüft; Ein fehlender Schlüssel deaktiviert sowohl die Cache-Vertrauensstellung als auch die Netzwerkaktualisierung und wählt den kompilierten Bootstrap aus.
- Remote Qdrant verwendet HTTPS, wobei einfaches HTTP auf einen Loopback-Test/lokalen Dienst beschränkt ist.
Plugin-System¶
KorTTY unterstützt Terminaleffekt-Plugins über Java ServiceLoader zum Anpassen des Erscheinungsbilds und Verhaltens des Terminals.
Plugin-Architektur¶
| SPI-Schnittstelle | Verantwortung |
|---|---|
TerminalEffectPlugin |
Plugin-Metadaten (ID, Name, Beschreibung) und Sitzungsfabrik |
TerminalEffectSession |
Lebenszyklus-Hooks (Init, Render, Cleanup) und optionaler TtyConnector-Wrapping |
TerminalEffectContext |
Zugriff auf Overlay-API, aktuelle SithTermFX-Widgets, Animationsgeschwindigkeit, Erscheinungsbild |
TerminalEffectAppearance |
Optionale Schriftart/Farbe/Cursor überschreibt |
TerminalEffectConnectorWrapper |
Transparenter Befehlsstream-Wrapper; KorTTY kann sicher ausgepackt werden |
Plugin wird geladen¶
- Gebündelte Plugins: Aus dem Klassenpfad der Anwendung geladen (z. B. MOTHER-Effekt)
- Externe Plugins: Importiert als
.jarDateien in~/.kortty/plugins/ - Verwaltung: Einzelne Plugins über
Plugins → Terminal Effectsohne Deinstallation aktivieren/deaktivieren - Exportierbare Plugins: Einige Plugins können als eigenständige JARs zur Verteilung exportiert werden
Sicherheitshinweis¶
Externe Plugins sind vertrauenswürdiger lokaler Code und unterliegen keiner Sandbox. Importieren Sie JARs nur aus Quellen, denen Sie vertrauen. Abhängigkeiten, die nicht bereits mit korTTY gebündelt sind, müssen in der Plugin-JAR schattiert werden.
Externe Abhängigkeiten¶
KorTTY basiert auf sorgfältig kuratierten, produktionsgetesteten Abhängigkeiten:
| Kategorie | Bibliothek | Version | Zweck |
|---|---|---|---|
| SSH | Apache SSHD (Core, Common, SFTP) | 2.19.0 | SSH-Protokollimplementierung |
| BouncyCastle (bcprov, bcpkix) | 1.86 | Kryptografieanbieter, SSH-Schlüsselanalyse und Ed25519/EdDSA-Schlüsselunterstützung | |
| Terminal | SithTermFX (core, ui) | 1.2.7 | Terminal-Emulations-Engine |
| Lanterna | 3.1.5 | Textbasierte UI-Komponenten | |
| pty4j (JetBrains) | 0,12,25 | PTY-Zuweisung für Mosh | |
| jSerialComm | 2.11.4 | Verbindungen über serielle Schnittstellen | |
| Plattform | JNA (JNA, JNA-Plattform) | 5.19.1 | Native Desktop-Energieverwaltungsintegration |
| Daten | Jakarta XML Bind | 4.0.5 (jaxb-runtime 4.0.9) | JAXB-Serialisierung |
| Gson | 2.14.0 | JSON-Analyse | |
| zip4j | 2.11.6 | ZIP-Verschlüsselung | |
| jtokkit | 1.1.0 | Tokenzählung für KI-Anfragen | |
| PDFBox | 3.0.8 | PDF-Export und RAG-Textextraktion | |
| Archiv | Apache Commons Compress | 1.28.0 | TAR, BZ2, XZ-Unterstützung |
| Tukaani xz | 1.12 | XZ-Komprimierung | |
| zstd-jni | 1.5.7-16 | zstd-Komprimierung für gedrehte Sitzungsjournalteile | |
| UI | JavaFX | 21.0.12 | Anwendungsframework |
| AtlantaFX Base | 2.1.0 | Sieben wählbare Primer-, Nord-, Cupertino- und Dracula-JavaFX-Benutzeragententhemen; seine transitive OpenJFX-Abhängigkeit ist ausgeschlossen | |
| Monaco-Editor | 0.56.0 | Code-Editor-Komponente | |
| Mermaid | 12.0.0 | Lokale Diagrammanalyse, SVG-Rendering und PNG-Rasterisierung | |
| MathJax | 3.2.2 | Lokales KI-Chat-Formel-Rendering | |
| google-java-format | 1.36.1 | Java-Codeformatierung | |
| Dienstprogramme | jfiglet | 0.0.9 | ASCII-Art-Banner |
| zxcvbn | 1.9.0 | Passwortstärke (offline) | |
| Protokollierung | SLF4J / Logback | 2.0.19 / 1.6.3 | Strukturierte Protokollierung |
| Optional | mosh4j | 2.0.3 | Mosh-Protokoll (dynamisch geladen) |
| Lokale KI | llama.cpp llama-server |
Quellfixiertes Laufzeitpaket | Lokaler GGUF-Chat-Vervollständigungs- und Einbettungs-Sidecar |
Dynamische Abhängigkeiten¶
- mosh4j: Seine fünf SHA-256-fixierten, architekturspezifischen Release-JARs und Protobuf werden in nativen Builds gebündelt und nur dann dynamisch geladen, wenn Mosh benötigt wird. Der untergeordnete Lader verwendet Bouncy Castle aus der übergeordneten Anwendung wieder, anstatt eine zweite Kopie zu versenden.
- rsync / ssh: Externe Befehle, die von JobScheduler Rsync-Jobs verwendet werden
- ffmpeg: Optional; Wird für die Terminalaufzeichnung und den Videoexport verwendet
- llama.cpp-Laufzeit: Unabhängig heruntergeladen unter
~/.kortty/llm/runtime/; CPU-Pakete decken alle unterstützten Plattformen ab, Metal ist auf macOS verfügbar und Vulkan ist für unterstützte Windows/Linux-Ziele verfügbar. Es wird niemals in den Basis-Installer eingeklappt. - Qdrant: Optionaler externer Vektordienst. Remote-Endpunkte erfordern HTTPS; HTTP ist nur Loopback. Lokales HNSW ist abhängigkeitsfrei und bleibt das Standard-Wissensspeicher-Backend.
Build-Prozess¶
Zusammenstellung und Verpackung¶
- SithTermFX-Build: Lokal geklont und erstellt (Maven); seine versehentlich veröffentlichte JUnit-Abhängigkeit wird von der Laufzeit ausgeschlossen.
- Browser-Assets: Ein isoliertes, angeheftetes Node.js wird nur zur Erstellungszeit für Monaco und für die JavaFX-WebKit-Kompatibilitätsverarbeitung des SHA-256-angehefteten Mermaid-Bundles verwendet. Die Editor- und Diff-Seiten von Monaco teilen sich ein modusbewusstes IIFE/CSS-Paar, während alle fünf Worker und Sprachdienste beibehalten werden. Mermaid und MathJax bleiben getrennte Lazy-Ressourcen; Prettier Standalone mit fünf ausgewählten Plugins und dem SQL-Formatter UMD Build läuft ohne Node zur Laufzeit.
- Nutzlast des externen Formatierers: Nur shfmt, Perl::Tidy und deren Manifest werden neben der App bereitgestellt; Das Logo-Video wird einmal pro Quelloberfläche als H.264/yuv420p bei 640×360 ohne Audio gespeichert.
- Sauberes natives Staging:
prepareJpackageverwendet ein finales GradleSync, wodurch veraltete Abhängigkeiten, Formatter-Bäume und Mosh-Architekturen gelöscht werden. Bouncy Castle wird dedupliziert, und JNA, pty4j, zstd-jni und jSerialComm werden nur mit den nativen Pfaden und der Binärarchitektur des aktuellen Ziels neu gepackt. - Native Verpackung und Gates: Die ausgewählte Gradle JDK 25-Toolchain stellt
jpackagefür die Ausgabe von .app/.dmg, .exe/.msi, .deb und .rpm bereit.scripts/package-size-report.pygibt JSON-/Markdown-Komponentenberichte aus und CI erzwingt den Commit-Release-Vergleich, eine Reduzierung des Installationsprogramms um mindestens 10 %, absolute App-/DMG-Grenzwerte und eingefrorene verifizierte Größenbudgets mit einer Toleranz von 2 %. - JavaFX-Abhängigkeitsausrichtung:
verifyJavaFxDependencyAlignmentüberprüft jeden aufgelösten Kompilierungs-, Laufzeit- und Testklassenpfad vor der Kompilierung und Verpackung. Standard-OpenJFX-Module müssen bei 21.0.12 bleiben; Nur diejdk-jsobject-Brücke zur Kompilierungszeit verwendet ihre separat angeheftete Version und gibt möglicherweise keinen Laufzeitklassenpfad ein. - llama.cpp-Laufzeitpaketierung: Separate Gradle-Aufgaben überprüfen das angeheftete Upstream-Tag/Commit/Archiv SHA-256, erstellen nur
llama-serverplus erforderliche gemeinsam genutzte Bibliotheken, stellen einen Backend-spezifischen Baum bereit und erzeugen eine reproduzierbare unveränderliche ZIP- und signierte Index-Deskriptoreingabe. Der wöchentliche Laufzeitworkflow öffnet Kandidaten-PRs; Ein Scope-Job führt die vollständige Plattform-/Backend-Matrix nur aus, wenn sich die Pin-Datei, der Workflow oder die Lama-Java-Quellen geändert haben (eine reinebuild.gradle.kts-Änderung führt zu einem einzelnen Smoke-Leg); Jedes erstellte Bein führt einen nativen Link-Smoke aus, das Referenzpaket führt den vollständig authentifizierten Chat-/Einbettungs-/JSON-/Sleep-/Parallel-Sidecar-Vertrag und eine geschütztellama-runtime-signing-Umgebung mit der erforderlichen manuellen Stable-Promotion für Prüfer-Gates vonmainaus. - Modell-/Prompt-Katalog-Werbung: Ein separater manueller Workflow, der nur für
maingilt, validiert das kanonische JSON mit strengem Schema, erfordert eine größere Sequenz als die neueste unveränderliche Version, führt Schema-/Vertrauenskettentests aus, gleicht den Signaturschlüssel mit dem Vertrauensstammverzeichnis der Anwendung ab, signiert die genauen Bytes und veröffentlicht über die durch Prüfer geschützteai-catalog-signing-Umgebung ohne Vorschaukanal.
Classpath und Modulpfad¶
- Kompilierungszeit: Auf JDK 25 wird das JavaFX
jdk-jsobject-Artefakt im Upgrade-Modulpfad bereitgestellt, sodass WebView-Brücken konsistent kompiliert werden. Das Modul fehlt in JDK 26. - Packaging-time: Gradle löst die gleiche Temurin JDK 25-Toolchain auf und ruft sie auf, die für die Kompilierung verwendet wurde, sodass die gekürzte Laufzeit
jdk.jsobjectenthält, auch wenn das Systemjava/jpackageneuer ist. - Modulpfad: JavaFX, SithTermFX und Apache SSHD sind während der Kompilierung verfügbar; Ungenutzte
javafx.fxmlundjava.scriptingsind nicht in der Paketlaufzeit enthalten.
Datenfluss und Integrationspunkte¶
SSH-Verbindungsablauf¶
User Input (Schnellverbindung)
↓
Connection Manager (lookup saved or new connection)
↓
Worker-thread SSH handshake + progress UI
↓
Shared host:port TOFU verification (Terminal/SFTP/Mosh bootstrap)
↓
SshTtyConnector (Apache SSHD) or Mosh connector
↓
Terminal Pane (SithTermFX rendering)
↓
Dashboard (status display, job monitor)
KI-Integrationsablauf¶
Selected Terminal Text
↓
AI Action + deterministic Text/Coding role
↓
AI profile (HTTP / CLI / embedded GGUF)
↓
Action contract → AI Skills → optional bounded RAG → model preset
↓
AiServiceFactory (remote provider, local CLI, or runtime lease)
↓
AI Response Tab (render with follow-up composer)
↓
Persistence (saved chats stored in global-settings.xml)
Jobplanungsablauf¶
User creates scheduled job
↓
JobSchedulerService stores in job-scheduler.xml
↓
JobSchedulerJobRunner runs on schedule (background thread)
↓
JobJournalEntry records output with redaction
↓
Menu-bar status displays next runs / live countdown
Protokollierung und Diagnose¶
- Protokolldatei:
~/.kortty/logs/kortty.log, rollt täglich, mit dem Log-Verzeichnis und der Aufbewahrung unter Einstellungen → Logs (SLF4J mit Logback-Backend). - JMX-Überwachung: MBean
de.kortty:type=SSHClientgibt die Live SSH- und Mosh-Terminalverbindungen (jedes geteilte Panel zählt, lokale Shells nicht), Speicher und Betriebszeit aus;BufferedTextSizewird nicht verfolgt und bleibt 0 - JobScheduler-Journal: Detaillierte Ausführungsprotokolle mit konfigurierbarer Aufbewahrung (standardmäßig 14 Tage, unbegrenzt, wenn auf 0 gesetzt)
- Projekt-Bildschirm-Snapshots: Der zuletzt sichtbare Bildschirm jedes Terminal-Tabs eines gespeicherten Projekts, gzip-komprimiert in
~/.kortty/history/und lokal angezeigt (nie an den Server gesendet), wenn das Projekt mit Auto-Reconnect wieder geöffnet wird - Terminalaufzeichnung: Optionale Wiedergabedateien in
~/.kortty/recordings/ - Testisolation: Die Test-Logback-Konfiguration schreibt nur auf die eigene Konsole und erstellt niemals die Konsole des echten Benutzers oder hängt an diese an
~/.kortty/logs
Thread-Modell¶
- UI-Thread: Der JavaFX-Anwendungsthread übernimmt das gesamte Rendering und die Benutzerinteraktion
- SSH-Sitzungsthreads: Ein Thread pro aktiver SSH-Verbindung (Apache SSHD-Pool)
- Split-Connection-Handshake: Gleiche Server- und neu ausgewählte Split-Verbindungen führen die Netzwerkeinrichtung auf einem Worker durch, während ein JavaFX-Fortschrittsdialog dafür sorgt, dass Host-Tasten und interaktive Tastatureingabeaufforderungen reagieren.
- Job Executor Threads: Hintergrund-Thread-Pool für die JobScheduler-Ausführung
- KI-Chat-Threads: Hintergrundthreads für API-Anfragen (nicht blockierende Benutzeroberfläche)
- KI-Katalogaktualisierung: Der erste Katalogkonsument erhält sofort verifizierte Cache-/Bootstrap-Daten und startet höchstens eine Hintergrundaktualisierung über den stabilen Kanal.
- Bereitstellung lokaler Modelle: Metadatenprüfung durch Setup-Assistent, signierte Laufzeitinstallation, fortsetzbarer GGUF-Download/-Überprüfung, Registrierung und echte Chat-/Einbettungstests, die auf Hintergrund-Futures ausgeführt werden; JavaFX erhält nur Fortschritts- und Endzustandsaktualisierungen. Text-/Codierungs-/RAG-Zuweisungen bleiben bestehen, nachdem jedes ausgewählte Modell bestanden wurde.
- llama.cpp-Sidecars: Ein nativer Prozess pro kompatibler geladener GGUF-Konfiguration; Verschiedene Modelle können gleichzeitig geladen und generiert werden, während Leases verhindern, dass aktive Anforderungen gestoppt werden. Die Laufzeitkonfiguration speichert die erste Anforderung eines Leerlaufstopps und wird abgelehnt, während eine Lease beschäftigt ist.
- RAG-Worker: Quellvorschauen, Extraktion, Einbettungsbatches und HNSW-Kandidaten-Builds werden außerhalb des JavaFX-Threads ausgeführt; Ein Daemon-WatchService-Thread entprellt automatische Quelländerungen. Der Bereich lässt nur einen aktiven Scan-/Indexvorgang zu und gibt die überprüfte Vorschau vor Konfigurations- oder Indexierungsänderungen an JavaFX zurück.
- RAG-Koordinator: Ein serialisierter Worker und Watcher pro Speicher verhindert überlappende Schreibvorgänge, gleicht automatische Quellen während des Anwendungsstarts unabhängig vom Start von Anmeldeinformationen/JobScheduler ab, behält Quell-Hashes/Zählungen/Status bei und lädt den UI-Status nach Abschluss neu.
- Datei-E/A-Threads: Asynchrone Schreibvorgänge für Verlauf, Journal und Aufzeichnungen
- Webformatter-Anfragen: Hintergrundaufrufer werden mit einer Gesamtzeitüberschreitung serialisiert; Erstellung, Laden und Aufruf des Lazy Prettier/SQL WebView bleiben auf den JavaFX-Anwendungsthread beschränkt, und bei Fehlern wird die Engine-Generierung verworfen.
- Mermaid-Rendering-Anfragen: Hintergrundaufrufer erhalten
CompletableFuture-Ergebnisse, während der gesamte Zugriff auf den einzelnen Lazy-Renderer WebView im JavaFX-Anwendungsthread verbleibt. Anfragen werden serialisiert; Bei einem Abbruch, einem 30-Sekunden-Timeout oder einem WebEngine-Fehler wird die Engine-Generierung verworfen, und die Leerlaufbereinigung gibt die ausgeblendete WebView frei.
Erweiterungspunkte¶
Für Plugin-Entwickler¶
- Terminale Auswirkungen:
TerminalEffectPluginimplementieren und überServiceLoaderregistrieren (sieheTERMINAL_EFFECT_PLUGINS.adoc) - Benutzerdefinierte Formatierer: Unterstützung für neue Sprachen im Snippet-Editor hinzugefügt
- KI-Skills: Importieren Sie benutzerdefinierte KI-Auflistungen über
AI → KI-Manager → AI Skills
Für Integratoren¶
- JAXB-Repositorien: Erweitern
XMLConnectionRepositoryoder fügen Sie einen Speicher nebenCredentialManagerfür benutzerdefinierte Datenquellen. - JobScheduler-Aktionen: Neue Aktionstypen zu
JobSchedulerJobRunnerhinzufügen (z. B. benutzerdefinierte SFTP-Vorgänge)
Leistungsüberlegungen¶
- Lazy Loading: Verbindungsdetails werden bei Bedarf geladen, nicht alle auf einmal
- Kompression: Projekt-Bildschirm-Snapshots und Terminal-Logs verwenden gzip; rotierte Session-Journal-Teile nutzen zstd (veraltete
.gz-Teile bleiben lesbar) - Drosselung: Terminal-Rendering-Updates werden stapelweise durchgeführt, um die Belastung des UI-Threads zu reduzieren
- Speicherpooling: Große Puffer für Terminaltext und SFTP-Dateiauflistung werden wiederverwendet
Best Practices für die Sicherheit¶
- Master-Passwort: Legen Sie ein sicheres, eindeutiges Passwort fest; es wird niemals übertragen oder protokolliert
- SSH-Schlüssel: Zur Einbindung von Backups in
~/.kortty/ssh-keys/speichern; Passphrasen werden inssh-keys.xmlverschlüsselt und das AES-256/GPG-verschlüsselte Backup enthält die Schlüsseldateien - Hostschlüsselüberprüfung: Überprüfen Sie den OpenSSH SHA-256-Fingerabdruck, bevor Sie eine interaktive Aufforderung zur ersten Verwendung akzeptieren. Halten Sie die Hostschlüssel-Anheftung für die unbeaufsichtigte JobScheduler-Ausführung aktiviert
- Backup-Verschlüsselung: Verwenden Sie passwortgeschützte ZIP- oder GPG-Verschlüsselung
- KI-Profile: Bevorzugen Sie ein integriertes lokales GGUF-Modell für sensible Daten; Überprüfen Sie die Vertrauens- und Datenrichtlinie jedes Remote-Endpunkts
- Protokollierungsgeheimnisse vermeiden: Das JobScheduler-Journal schwärzt gespeicherte Geheimnisse vor der Persistenz