Terminals now pick up OSC 133 prompt/command/output/finished marks,
which the VT parser ignores: a scanner (app/src/osc.rs, split-safe
across reads, bodies capped at 4 KiB) finds them in the output stream
and each mark records the cursor line. Lines are stable indexes that
account for lines a full scrollback rotates out, so marks stay on their
text; clearing the scrollback drops them.
With marks present: Ctrl/Cmd+Shift+Up/Down and Previous/Next Prompt in
the context menu jump between prompts, Copy Last Command Output copies
what the last finished command printed, and a green/red bar beside each
prompt shows the exit status (hover for code and duration). OSC 7
working-directory reports are parsed too (used by the next change).
The manual shows bash and zsh snippets; fish 4 and common prompt themes
already send the marks.
An RDP profile can name a Kerberos KDC; CredSSP then authenticates with
Kerberos instead of NTLM, reaching the KDC through a small TCP client
(RFC 4120 length-prefixed framing, 5 s connect / 10 s read timeouts,
replies capped at 1 MiB so a hostile KDC can't force a huge allocation).
UDP KDCs are refused with a clear message. Tested against a fake KDC
(round trip, oversized reply, UDP); not against a real realm.
Smart-card logon is not implemented: it needs PC/SC hardware and a card
to build and test against.
RDP profiles can go through a Remote Desktop Gateway (MS-TSGU over an
HTTPS WebSocket) with its own username and password, stored like other
credentials (rdp-gateway-password). The gateway stream is bridged to a
loopback socket so the blocking RDP client uses it like any transport.
IronRDP's gateway crate (0.0.1) is vendored with fixes: it used
ironrdp-tls, which accepts any certificate, before sending Basic
credentials — the gateway is now verified against the web PKI; its
asserts on gateway-supplied lengths are errors instead of panics; and
the server port is passed through. Checked against a self-signed
openssl s_server: the connection is refused ('invalid peer certificate')
before any request or credential is sent. Not tested against a real
gateway; Basic-auth gateways only (no NTLM).
An optional 'Nexus Terminal' printer (IronRDP's PostScript driver
announce) appears on the remote desktop; each job is written to
'Nexus print <time>.ps' in Downloads, with a toast saying where. Jobs
are capped at 256 MiB and empty jobs leave no file. The shared drive and
the printer now share one RDPDR backend (rdp_devices); the printer
works on every platform, the drive on Linux and macOS.
Tested with a unit test driving create/write/close; xrdp has no printer
redirection, so not exercised against a server.
- Audio: the RDPSND channel with IronRDP's cpal playback backend (PCM;
Opus left out to avoid another native library). On by default for new
RDP profiles. Building now needs the ALSA headers on Linux
(libasound2-dev), added to CI, release and fuzz jobs and the build docs.
- Shared folder (Linux/macOS): one local folder appears on the remote
desktop as a drive. IronRDP's native backend joins server paths onto
the share unchecked, so it is wrapped in ConfinedDrive: create, list
and rename paths with '..' components, NUL bytes, or that resolve
through a symlink outside the share are refused (ACCESS_DENIED);
tests cover the escapes.
Verified against xrdp (with FUSE): the remote read the shared file, and
writes, mkdir and rename landed in the local folder. Not verified:
audio playback (the test container has no sound module), and xrdp lists
the drive as 'ignored' and can't list its directories (an IronRDP/xrdp
naming and listing mismatch, fixed upstream for the name).
A CLIPRDR channel with a text-only backend (CF_UNICODETEXT): text copied
on the remote desktop is fetched and goes through the app's remote-
clipboard preference like VNC and OSC 52; local text is offered to the
remote when the desktop gains focus, on Ctrl+V and with Paste Clipboard
(which no longer types the text). Backend callbacks run inside the
active stage, so they queue requests that the session loop sends.
Verified against xrdp: the remote X clipboard read back the offered
text, and a remote copy arrived through on_clipboard.
The app now writes a diagnostic log to nexus.log in the data directory
(0600, rotated at 5 MiB): connection attempts and results, remote
closes, reconnect scheduling, host-key/certificate checks with the
policy applied, and credentials that couldn't be stored (kind only).
Credentials and terminal data are never logged. RUST_LOG sets the level
and also mirrors the log to stderr. The remaining eprintln! diagnostics
in storage and URL handling go through it too.
- Protocol::Rdp with RdpConfig (domain, password mode, certificate
policy, TLS-only fallback, fixed or tab-sized resolution, SOCKS5/HTTP
proxy, SSH tunnel); migration 008 adds rdp_config and drops the
protocol CHECK constraint so new protocols no longer need a rebuild.
- Session manager: connect_rdp dials directly, via the shared proxy
module (proxy password from the secret store) or an SSH tunnel; the
server certificate goes through the known-hosts check (key type
rdp-tls); a tab-sized desktop uses the tab's reported pixel size, and
resizes wait until the server opens Display Control. Rejected NLA
passwords count as auth failures, so a saved one is asked again.
- The VNC viewer becomes DesktopView for both protocols; a small adapter
turns its keysyms and pointer masks into RDP scancodes, Unicode keys,
buttons and wheel events. For RDP, Paste Clipboard types the text.
- Profile editor RDP section, Quick Connect, badges, docs.
Verified against xrdp in the app: logon, desktop, input, and connections
through SOCKS5 and HTTP CONNECT relays. Not verified here: Windows/NLA
servers, the SSH tunnel route, and Display Control resizing (xrdp
0.9.24 never opened the channel).
The Go-generated link.db, profiles.link and rec1.cast fixtures and the
tests that read them are removed. Their coverage is kept by tests on
data this build writes: a fresh database round-trips SSH profiles (env
vars, login scripts, forwards), serial profiles, IRC room state, known
hosts, snippets and preferences, and encrypted exports round-trip and
reject a wrong password. The import dialog no longer offers .link files
and the docs stop mentioning them.
Startup no longer looks for an AlchementaryLink data directory to copy
into NexusTerminal, and the 'Imported your Alchementary Link data' toast
and the migration docs are gone. Existing Alchementary Link installs are
no longer picked up automatically.
SshConfig no longer has proxyPassword or totpSecret fields, so neither
can sit in clear in nexus.db or travel in an export. The proxy password
is a SecretKind (profile:<id>:proxy-password) edited like other saved
credentials and purged with the profile; the session manager hands both
it and the TOTP seed to the SSH client from the keychain/vault at
connect time.
This drops compatibility with Go-era profiles and .link/.nexus files
that carry these values inline: they are ignored on read and must be
re-entered (SEC-20261012-011).
OSC 52 and VNC ServerCutText now go through one handler that honours
'allow remote clipboard' and always toasts the first line, so a silent
clipboard swap can't set up a paste into another shell (SEC-20261012-010).
Multi-line pastes into a terminal without bracketed paste ask first, with a
preview (SEC-20261012-017). The launch-time update check can be turned off
and the updater docs no longer claim it is opt-in; the unused GitHub
fallback is removed (SEC-20261012-013, F15).
Renames the product across the codebase: Go module path, config/data
paths, keychain service name, export file extension, build tooling,
docs, and UI text. Sidebar brand mark now reads ">_ AlchementaryLink"
with "Alchementary" in the connection-group gold accent colour, and
the window title is "Alchementary Link".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019T8bJS8BCtY5GeSG2HBj1n
- Updated formatting for better readability, including consistent use of line breaks and indentation.
- Enhanced the clarity of event listener functions in profiles.js.
- Refactored tab management logic in tabs.js for improved maintainability.
- Ensured consistent use of single quotes and double quotes across the files.
- Added aria-label and type attributes to the edit button in the sidebar.
- Implemented a mechanism to prevent multiple edit triggers using requestAnimationFrame.
- Updated mousedown event handling to allow real controls while preventing text selection in WKWebView.
feat: add reconnectSession method to TabManager
- Introduced reconnectSession method to facilitate session reconnections by ID.
feat: implement disconnected overlay in terminal
- Added setDisconnectedOverlay method to show/hide a disconnected overlay for terminal sessions.
- Created _ensureDisconnectOverlay method to manage the overlay's existence and content.
feat: extend Service API with file-related functions
- Added FileExists and FileIsPrivateKey functions to check file existence and identify private keys.
- Introduced ListSSHKeys function to retrieve SSH private key paths from the user's .ssh directory.
- Implemented SFTPStat and SFTPUploadData functions for enhanced SFTP operations.
refactor: clean up code formatting and improve readability
- Adjusted code formatting for better readability across various files, including consistent use of line breaks and indentation.
- Implemented drag-and-drop support for file uploads in the terminal.
- Added a modal for users to choose between uploading files or pasting contents.
- Enhanced SFTP browser with a directory picker for selecting upload destinations.
- Introduced methods for handling file uploads and reading file contents from the local system.
- Added a new API endpoint for uploading raw file data to the server.
- Implemented session management improvements to retrieve the current working directory for SSH sessions.
- Updated documentation to include an overview and quick start guide for Nexus Terminal.