Skip to content

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 07 Jun 00:56
· 79 commits to main since this release

Oryxis 0.8.0: an AI assistant that runs commands, Kubernetes, standalone port forwarding, split panes and session groups

Disclosure: this release note was drafted with assistance from Claude (Anthropic's LLM) and edited by Wilson Glasser, the project author. The engineering decisions are mine; the LLM helped the code and turn the changelog into prose.

Oryxis is a Rust-native SSH client built on iced with a russh engine. 0.8.0 is the largest release so far: the AI chat stops narrating and starts doing, a Kubernetes provider lands next to AWS, port forwarding graduates into a first-class entity you manage independently of any terminal, and the terminal itself learns to split into panes you can save as reusable layouts.

An AI assistant that actually runs the command

Until now the terminal-side AI chat would print a command and leave you to copy-paste it. 0.8.0 gives it a real execute_command tool: ask it to check disk usage, restart a service, or find why a deploy failed, and it runs the command in the focused pane and reads the output back, in the same turn.

Letting an LLM run commands on a live server is exactly as dangerous as it sounds, so auto-exec sits behind three independent layers, and a destructive command has to clear all of them:

  • A deterministic floor. A hard-coded, uncheatable list of catastrophic, host-level commands (rm -rf, mkfs, dd to a raw device, reboot, fork bombs, DROP DATABASE, ...) that always force a confirmation prompt no matter how the model classified them. It runs first and needs no network call, so it stands even if the judge is wrong, jailbroken by the command text, or unreachable.
  • An independent LLM judge. A second-opinion model call that vets the nuanced rest and fails safe: any error, timeout, or ambiguous answer blocks and asks you first. It can only ever escalate to a prompt, never approve something the model flagged as risky.
  • A guarded "always run" list. When you click "always run X" the decision is keyed to a single simple command, and the shortcut refuses anything carrying shell chaining, a pipe, a redirection, or command substitution. A trusted ls can never be used to smuggle ls; rm -rf ~ past the gates.

The chat also warns up front, before the first command, that the assistant executes on your real servers.

Kubernetes, the kubectl way

Cloud Accounts gains a Kubernetes provider alongside AWS. Point it at a kubeconfig (with an optional path and context), and it discovers your Deployments, StatefulSets and DaemonSets across namespaces, imports the ones you pick as dynamic groups that resolve to their live pods on expand, and opens an interactive shell straight into a pod.

It is deliberately thin: rather than pull in a heavyweight Kubernetes SDK, the provider drives the kubectl CLI you already trust. Discovery and resolve shell out to kubectl get ... -o json and parse the result; the pod shell spawns kubectl exec -it in a local PTY. kubectl has to be on your PATH, and a missing binary surfaces a clear dialog instead of a cryptic failure. The dynamic-group editor lets you retarget an imported group's context, namespace and label selector after the fact.

Port forwarding, finally its own thing

Port forwards used to be a property of a host that only existed while a terminal was open and only spoke -L. 0.8.0 promotes them to a standalone entity with its own sidebar area. Each PortForwardRule has a per-row on/off toggle that opens a dedicated, PTY-less SSH connection holding just the tunnel, plus an "auto-start on launch" option, so you can keep a database tunnel up all day with no terminal in sight.

All three directions are supported:

  • Local (-L) the classic forward into a private network through a bastion.
  • Remote (-R) via tcpip-forward, the self-hosted answer to ngrok, with a reminder that the server needs GatewayPorts yes to bind 0.0.0.0.
  • Dynamic SOCKS5 (-D) a local SOCKS5 proxy that opens a direct-tcpip channel per request, the poor man's VPN through SSH. Because a dynamic forward is an unauthenticated proxy, binding it to a non-loopback address now warns you that it would expose an open proxy into the remote network.

Toggling a rule on for an untrusted host shows the same host-key prompt the terminal uses; boot auto-start stays known-hosts-only and silent. Rules sync over P2P and travel in portable export/import, and your old inline Connection.port_forwards are migrated into Local rules on first launch (the legacy field is kept as a "raise it with the terminal" shortcut).

Split panes and session groups

A terminal tab can now split into an arbitrary grid of panes, tmux / iTerm style, on iced's pane_grid. Ctrl+Shift+E splits side-by-side, Ctrl+Shift+O stacks, and you can also split from the + button's hover popover or a tab's right-click menu. Each new pane opens the connection picker, so it can be any saved host or a local shell; each pane keeps its own session, scrollback and output, and keyboard, paste, snippets and the AI assistant all target the focused pane.

Once you have an arrangement you like, save it as a session group: a credential-free entity that records a reference to each pane and the exact split tree, lives in a folder with its own name, color and icon, and can give every pane its own startup script (overriding the host's initial command). Open the group and it rebuilds the whole splitted tab and connects every pane at once; a host deleted in the meantime is dropped with a warning rather than failing the open. Groups show up on the dashboard next to hosts, sync, and export.

File copy between two remote servers

The dual-pane SFTP browser can now transfer files directly between two remote hosts, streaming the bytes host-to-host through the app without a full local round-trip to disk, with a live byte-level progress bar. A failed transfer cleans up the partial file on the destination instead of leaving a truncated one behind. The browser also got a broader UX pass: type-ahead row selection, drag-and-drop (including from the Windows / WSL host), and modal operations that block the panes underneath.

Make it yours: custom themes and icons

You can now build your own color schemes, both terminal palettes (the 16 ANSI colors plus foreground / background / cursor) and full UI / chrome themes (21 colors), each with a built-in graphical color picker (a saturation/value square and hue bar, no third-party crate) and a live preview. Custom terminal themes can also be imported by pasting an iTerm .itermcolors, a Windows Terminal JSON, or a base16 YAML. The per-host icon picker was overhauled to use the same color picker and gained a search box over the entire Lucide glyph library.

Tabs that behave like a browser

Tabs can be pinned (they render first, survive "close others" / "close all", and come back on the next launch, restoring lazily so startup stays fast) and dragged to reorder (the dragged tab lifts into a floating ghost while the others slide aside to open the drop slot). Pinned order persists across restarts.

Also

  • Six new languages: Korean, Polish, Turkish, Indonesian, Vietnamese and Ukrainian, bringing the UI to 17. The i18n tables moved to a module per language and the UI font switched to Noto Sans (plus Noto Sans Arabic and a CJK menu fallback) for full script coverage.
  • Multi-hop host chaining gets a dedicated chain editor in the host editor.
  • Snippets grow into a multi-line editor for small scripts.
  • Cloud-provider plugins are now drained gracefully on shutdown (in-flight requests finish, a shutdown notification is sent, stdin is closed) instead of being hard-killed, with the hard kill kept only as a time-bounded fallback.
  • The full AGPL-3.0 license text is shipped in the repo.
  • Modal overlays no longer leak hover / scroll events to the content behind them, and the "Hosts" top tab stays selected across every vault sub-section.

Detailed changelog / merged PRs below.

Full Changelog: v0.7.4...v0.8.0