Changelog

All notable changes to VelaTerm, newest first.

v0.1.91 is the first public release; earlier version numbers were internal iterations and are not covered.

v0.2.9

Latest
  • ✨ Rename with AI remembers your selected model and reasoning effort for each agent.
  • ⛔ AI title generation can be cancelled with Cancel, Esc, or a click outside the dialog, and you can try again afterwards.
  • 🧭 New Plan/Execute workflows have independent Review turned off by default; enable it in the launch dialog or with --review when needed.
  • 🤖 The Chat model selector shows loading, error, and empty states with Retry, and Codex model choices reflect the current session's account and configuration.
  • 📊 The Info panel shows an estimate of average output speed, including reported reasoning tokens, and displays a dash when the estimate is unavailable.
  • 🩺 Advanced settings offer optional input latency diagnostics with an adjustable threshold, without recording the text you type.
  • ✂️ The experimental screenshot tool has a title bar button on supported Tauri desktop platforms, even when its keyboard shortcut is disabled.
  • 🌬️ Cyan background-task indicators use a consistent breathing animation in the session tree, status filters, and status bar.
  • 📁 Groups created while a status filter is active remain visible until you refresh the status or change the filter, provided they match any name search.
  • 🎨 Background command logs display colors and text styles with the final progress line, and the run strip leaves the pane's focus indicator visible.

v0.2.8

Latest
  • 🪟 Windows: returning to the window leaves keyboard focus where it is when it is already inside the page.

  • 🛡️ Windows: Huorong antivirus no longer flags VelaTerm and vela-server as Trojan/MSIL.ShellLoader.q. This was a false positive: to run shell commands from the conversation view, VelaTerm created each process in a suspended state and then resumed it, a sequence of calls that malware also uses to inject code. Processes are now started normally, and the code that triggered the detection has been removed.

  • 🔕 Windows: new sessions and model list refreshes no longer run PowerShell in the background, and Cursor session status is now detected from terminal output, which can be less precise.

  • ⛔ Windows: input starting with ! in the conversation view is no longer run as a shell command; a notice appears and the input is kept, while earlier commands in the history still display.

  • 🔐 SSH connections to Windows hosts running the built-in OpenSSH server no longer start PowerShell with -EncodedCommand.

  • 🚀 TUI agent sessions start correctly when PATH is long, without a truncated launch command in the terminal.

  • ⬇️ TUI agent sessions scroll to the bottom when a turn ends or the agent asks for approval, unless you are reading earlier output.

  • 💾 The experimental conversation recovery from v0.2.7 is removed: Chat no longer shows duplicate Saved submission messages or interruption notices, and unsent queued messages are not kept after a restart.

  • 🔁 Plan-and-execute workflows add an optional independent Review role, on by default for new workflows, with its own agent, model and reasoning effort; vspawn --plan-execute accepts --review, --no-review, --review-agent, --review-model and --review-effort.

  • 🏷️ Rename with AI… asks for confirmation first and lets you choose the agent, model and reasoning effort for that rename, with the dialog shown centered while options load.

  • 🔍 Sessions, groups and projects can be dragged while a name search, status filter or mark filter is active.

  • ➕ With a status filter active, a new session stays under its group or parent session until you refresh status or change the filter.

  • 🪟 App windows open larger by default, sized to the display's available area, and connection windows open centered on the display of the main window.

  • 🎨 Collections have a new stacked icon, dark title bar icons are slightly dimmer, the four buttons in the empty sidebar share one width, and form dialogs use a single label style.

v0.2.7

Latest
  • 🪐 Antigravity joins the conversation view as an experimental agent with text, tools, queued messages and native history; images, steering during a reply, interactive approvals, fork and rewind remain unavailable, and full cross-platform recovery testing is pending.

  • 🗂️ Collections support nested collections, projects and session groups, with creation and import from the workspace; deleting a collection preserves its projects and archived sessions.

  • ⚠️ Earlier versions must not use a database migrated from folders to collections; downgrading requires restoring a backup taken before migration.

  • 🏷️ Smart Rename names a session from its conversation using the current agent's settings, with an agent picker when those settings cannot be used.

  • 🌱 New sessions pick up the latest shell environment and newly installed agents without restarting VelaTerm.

  • 💾 Experimental conversation recovery restores saved messages, images and queued input after a restart and pauses interrupted work for explicit resumption; full native and cross-platform acceptance testing is pending.

  • 📸 Experimental screenshot capture in the macOS and Windows Tauri desktop apps lets you select a region, annotate it, copy it or save the original PNG; native desktop acceptance testing is pending, and Electron, browser and remote views do not support it.

  • 🧵 Claude background task tabs show their full native conversation history, including parallel tool calls.

  • 🖼️ A conversation message can contain up to 20 images, with a 5 MiB limit per image.

  • 📍 Conversation message markers offer previews and jump directly to earlier user messages.

  • 🧭 Directory pickers for projects, cloning and Save As share editable paths and location completion.

  • 🪪 vself reads saved session settings and parent-child relationships, while vflow list lists related planning and execution workflows without changing them.

  • ⌨️ Select All in the terminal is configurable in Shortcuts, defaults to Cmd+A on macOS and Ctrl+Shift+A elsewhere, and applies only when the terminal has focus.

  • 🐚 Bash completion handles paths beginning with ~, and older Bash versions open sessions without PS0 errors.

  • 🛑 Child task hooks no longer change their parent's conversation status, and closing a conversation tab stops its active chat process.

  • 🪟 Windows restores terminal keyboard focus when returning to the window and removes the blue line during Chinese text composition.

  • 🎨 Classic Dark has clearer contrast, desktop icons follow the system theme, project icons are blue, and collection rows omit project counts.

  • 📚 Conversation and collection menus use a clearer Add to Knowledge Base label for organizing knowledge.

  • 🌐 Browser access to VelaTerm over plain HTTP on a local network opens correctly.

  • 🌍 Update checks carry the interface language so release notes can match it, and the update service accepts the Linux Electron updater.

  • 🧰 Kimi Code and Grok Build appear without model version numbers in agent names.

v0.2.6

Latest
  • 🐧 The Linux version is now built on Electron. The AppImage keeps its file name and your data, no longer requires WebKitGTK or libfuse2, and existing installations update to it through the built-in updater.

  • 🛰️ Machines that cannot be reached over SSH, such as WSL on another computer or a Docker container, can join your account after installing vela-server with a single command, and then appear in the Remote list for AI chat. Once the owner grants full access on the host, the desktop app can also use its terminal, files, and Git panel.

  • 📂 Folders dragged onto the sidebar from Finder, File Explorer, or a Linux file manager are added as projects.

  • 📝 The Markdown editor adds Typora-style shortcuts for headings, lists, code blocks, and tables, automatic pairing of brackets and quotes, Cmd/Ctrl+click to follow links, focus and typewriter modes, and word and character counts in the status bar. YAML front matter appears in a separate box above the document and stays unchanged unless you edit it.

  • 🗃️ When a folder is not a Git repository itself but contains several, the Git panel offers a repository selector and works on the selected repository.

  • ⏳ In the conversation view, a session whose reply has finished while background tasks are still running shows the new "Tasks running" status with a cyan dot instead of staying on "Working". Sessions running long tasks with vrun show the same status.

  • 🍴 In the conversation view, a forked session starts a conversation of its own the first time it runs, and the source session no longer receives its messages.

  • 🛡️ In the conversation view, the mode label of a Claude session follows the permission mode Claude actually uses, for example after it enters Plan mode, and permission cards show the reason Claude gives for asking.

  • 📏 The input box in the conversation view can be resized by dragging its top edge, and double-clicking the edge restores the default height. The height applies to all panes and is kept after a restart.

  • 🗂️ When several folders are selected in the sidebar, the context menu can archive them together with their sessions.

  • 📚 Collections always appear above projects in the sidebar.

  • 🧠 When a knowledge base processing record created a single entry, its title opens that entry directly, and entry buttons show entry titles instead of numbers.

  • 📊 The Info panel shows the correct context limit for newer Claude models such as Opus 5.5 instead of 200k.

  • 🎨 Smaller changes: the three split options in the session context menu are grouped under an "Open in Split" submenu, the quit confirmation notes that open remote windows will also close, and dropdowns in forms close as soon as an option is selected.

v0.2.5

Latest
  • 🐧 The Windows desktop app can open separate workspaces in WSL1 and WSL2, using the agents, files, and session history inside the selected Linux distribution.

  • 🔄 WSL workspaces can reconnect after the server stops, and closing a workspace lets you stop its server or keep its sessions running.

  • 🌐 Claude sessions have a Chrome option in the composer that turns Claude in Chrome on or off without restarting the conversation. Each session keeps its own choice, and sessions without one use the default.

  • 📟 The tab of a background shell task shows the command it runs and its latest output, refreshed while the task is running.

  • 🧩 When the Vela Skills are not installed, the status bar offers to install them. The dialog describes each skill, installs them directly, and can be told not to remind you again.

  • 🪪 Child sessions created with vspawn receive their parent's ID in VLX_PARENT_SESSION_ID, so an agent can reach the parent with vrefer and vtell. The new vself command shows the current session and the sessions above it.

  • 🖥️ The Linux AppImage no longer opens a blank window on newer distributions such as Fedora 44.

  • 🎨 Smaller changes: "Background tasks" appears below the input box by default and stays in the "More" menu if you move it back there, and a link that cannot be opened shows a message suggesting you right-click it to copy the address.

v0.2.4

Latest
  • 📋 Copying from a conversation gives you the text as it appears on screen: no backticks around inline code, no asterisks around emphasis, links as their text, code blocks without fences, table cells separated by tabs, and lists keeping the markers you see. Rich formatting is still placed on the clipboard alongside it, and the right-click menu gains "Copy as Markdown" for the Markdown source of the selection.

  • ⏳ Continuing automatically after a usage limit resets is now on by default. If you changed the setting yourself, your choice is kept.

  • ↩️ Rolling back a conversation is no longer blocked by a task that has already finished: a foreground task counts as finished when its turn ends, and progress arriving afterwards no longer marks it as running again. When a background task really is still running, the message names it.

  • 🧹 Codex subagent threads no longer appear in the session history list, the same as Claude's sidechains.

  • ⌨️ Terminal completion: after moving through the candidates with the arrow keys, Enter accepts the highlighted one just as Tab does. Enter still goes to the shell if you have not moved the selection, if you kept typing after selecting, or if a modifier key is held.

  • 📱 Android is built in two channels. The default build carries the Getui, Huawei, Xiaomi, OPPO, vivo, Meizu and Honor push channels; the Play build ships without them and reports task notifications as having no push channel configured.

  • 🎨 Smaller interface changes: task lists no longer repeat the checkbox, the notification bar and the auto-continue notice sit between the conversation and the composer at the same width as the message text, and on the phone the send button stays beside the input when the options are collapsed.

v0.2.3

Latest
  • 🪟 Existing sessions can be moved into splits. The sidebar's context menu opens a session in a right split, a bottom split or the focused pane; dragging a session onto the edge of a pane splits in that direction, and dropping it in the middle replaces what that pane shows. Two to four selected sessions can be tiled into one evenly divided tab, and sessions shown in the current tab's other panes are marked in the sidebar.

  • 🗂️ Background tasks started by an agent open in their own tabs next to the conversation, with status, elapsed time, tokens, tool calls, the last reported tool and each agent's phases. A task has its own address, and leaving it returns to the pane it was opened from.

  • 💬 In the conversation view, a message that begins with ! runs in the session's shell. Output streams in as it arrives, the exit code is shown, the command can be cancelled while it runs, and it stays in the reading history of Claude, Codex, OpenCode, Pi and OMP sessions.

  • ⏱️ The new vrun command starts a long-running command and waits for it in a single call, so an agent finds out when the work has actually finished. Commands started this way are listed above the terminal with their running time, a log window and a stop button that asks for confirmation.

  • ⌨️ New agent sessions have their own page and keyboard shortcut: search agents and presets, reuse the one you used last, and choose whether the session is created next to the current one or under it.

  • 🧰 The composer toolbar is configurable in Settings — choose which items sit beside the message and in which order. Items you switch off, and items that do not fit the width, remain available from the More menu.

  • 📥 Downloading a file in a URL or SSH connection window starts with a save dialog on this machine and then shows the download's progress, with a button to cancel it.

  • 🗃️ Kiro sessions can be imported into a project and read: import matches sessions by working directory, and each one opens in a read-only history view with search. Text-only records are supported for now.

  • 🧠 Organizing the knowledge base works with Grok, OpenCode, Pi and OMP in addition to Claude and Codex, and the agent is chosen from the same kind of dropdown used elsewhere in the app.

  • 📱 iOS and Android: the start page keeps your SSH and URL connections, signs in to a VelaTerm account and lists the devices sharing with it. A host fingerprint is confirmed once and remembered, a QR code fills in the service address, and every native screen and system prompt is translated into all 11 interface languages.

  • 🔐 Claude sessions start in the permission mode you chose: additional launch arguments keep their intended precedence, the mode is reconciled with what the CLI reports at startup, and a session started with confirmations skipped stays marked that way.

  • 🧩 The model menu lists Opus 5.5 and adds the extra models the selected CLI reports while keeping the built-in order; a model that arrives with a CLI update appears without restarting the app.

  • 🌱 Child-session requests survive interruptions: a request whose answer was lost can be recovered after reconnecting, a launch that was already confirmed reuses the same session and settings when it is retried, and a worktree that could not be created is rolled back without touching anything that existed before.

  • ⚡ The app starts faster — the code loaded at startup is roughly half its previous size, and the knowledge base, security audit, session import and shared-projects pages load when you open them.

  • 🖼️ Images pasted or dropped into a message are scaled down to 1568 pixels on the long side before they are sent.

  • 🐚 Bash sessions load shell completion from a startup file, so a new Bash session no longer opens with a command already typed into it. Login profiles are still read in Bash's own order.

  • ✍️ Markdown: a single tilde no longer strikes through the rest of the line, so a pasted shell prompt stays readable, and bold or italic text that ends next to Chinese, Japanese or Korean characters closes properly instead of leaving asterisks on screen.

  • 📨 vtell --steer delivers a message into the turn the recipient is currently running instead of waiting for that turn to end. A recipient stopped on a question is reported as blocked, because the message is only read once that question has been answered.

  • 🔁 In the conversation view a session's status ends as soon as its turn does, the unread mark clears when work really starts, and a session whose background work is still running stays marked as running.

  • 🪟 Windows: Cursor hooks start correctly, and the window layer has been updated for the keyboard input problems reported after an RDP reconnection or a virtual-desktop switch.

  • 🛡️ Security audit: the model list and the agent names come from the same launch catalogue as the rest of the app, so earlier runs show each agent's current name.

  • 🩹 Smaller fixes: error messages in the conversation line up with the centre column, both launch dialogs can always be closed and a confirmed launch that failed can be cancelled, messages and queued messages show who sent them, a long queue scrolls within a fixed height, empty HTML anchors no longer show a marker while editing a document, and the phone's status filter picks up sessions that start matching it later.

v0.2.2

Latest
  • ⏳ Auto-continue after usage limits, off by default in Settings: when Claude or Codex stops at a 5-hour or weekly limit, the session resumes on its own once the limit resets. A banner above the composer shows the reset time with a Cancel button, the wait survives an app restart, and sending a message, rolling back, clearing the session or turning the setting off ends it.

  • 🪟 Windows: one-click installs for OpenCode, Grok and Crush pass --allow-scripts so npm produces the executable, Cursor, OMP and Antigravity are found in their real install folders under %LOCALAPPDATA%, and OMP also honors PI_INSTALL_DIR.

  • 🪟 Windows: files still being downloaded or copied no longer count as installed, the install card waits for the install to finish before reporting success, and a stale saved path is replaced with the newly located one.

  • 🧩 Conversation view: a turn's thinking, tool calls and interim replies can be hidden with "Hide steps" to leave only the final reply, and the toolbar hides or shows every turn at once; search expands a hidden turn to locate a match.

  • 🔐 The permission button now shows the mode a session was started with instead of "Current permissions unconfirmed", the duplicate launch-setting line is gone, and a session started with permissions already skipped highlights in the status bar.

  • 🔐 A session without its own permission setting follows the global default for its agent type in both views, and editing a session no longer turns the inherited value into a fixed choice.

  • ↩️ Knowledge base pages gain an "Up one level" button: an entry goes back to its session, then its project, then the home page, and archived sessions, notes and folders walk up the same way.

  • 🌱 A child session opens in the same view as its parent: from a conversation-view session the task arrives as the first message with images as attachments, and from a terminal session it starts in the terminal with the task passed as a launch argument.

  • 🎨 macOS: the window and title bar strip take on the theme colors before the window appears, and switching themes while running redraws them immediately.

  • 🗜️ Claude sessions keep the turns from before a compaction in the reading history, while a rollback still drops the branch it abandons.

  • 🔎 Conversation search keeps the selected match in place while earlier history loads; Enter moves to the previous match and Shift+Enter to the next.

  • 🩹 Returning to a conversation parked in the middle of its history restores the reading position instead of showing a blank pane.

  • 🧭 Model catalog diagnostics appear only when the model menu is opened with Option held down; error lines align with the message text, and the English knowledge base shows "Archived Sessions".

v0.2.1

Latest
  • 🔎 The knowledge base home page gains a search box: one query searches session knowledge and local notes together and groups the results by source. Exact matches come first; a fuzzy pass covering abbreviations, subsequences and typos runs only when nothing matches exactly, while Chinese queries stay substring-based.

  • 🗂️ Archived sessions move into the knowledge base. The sidebar button jumps there instead of opening its own panel, the tree gains an "Archived sessions" root grouped by the project they came from, and the main area lists every archived session with restore, reorganize, export and delete available in place.

  • 🔍 Archived sessions have their own full-text search: results group by session with a hit count, and the preview pane steps through each hit with the same highlighting as global search. An open session switches between its conversation and its knowledge entries.

  • 🤖 Conversation view: when an agent's executable is missing, an install guide appears under the message instead of a raw startup error, and "Install now" hands off to the terminal view to run the recommended command. If the agent is installed outside PATH, the guide accepts an executable path directly, with a system file picker on desktop.

  • 🩹 Installs that look present but are broken are now detected: a global npm wrapper whose target was removed or replaced counts as not installed, and a configured path that points at such a wrapper opens the install guide without rewriting your setting.

  • 🔐 The permission mode entry shows the mode you picked, and its menu marks each row with whether the choice is already running or waits for the next turn.

  • 🔽 Every dropdown now uses the built-in Select component instead of the native control, so they look the same on macOS 15 and 26 without the stacked system appearance.

  • ℹ️ Projects and collections have an Info dialog in their right-click menus.

  • 🪟 Windows: subprocesses started by the conversation view (agents, model catalog and git checks) no longer flash console windows.

  • 💡 The feedback button in the title bar moves after the share button.

v0.2.0

Latest
  • 📱 VelaTerm for iOS and Android (early build): connect to a machine over SSH or a URL after confirming its fingerprint, load the full remote interface inside the app, fill in connection details by scanning a QR code, and sign in to a remote account.

  • 🛡️ Experimental code audit: run a whole-repository, directory or file, or working-tree audit with Codex or Claude Code, review findings against the source, and export a Markdown or JSON report.

  • 📓 Local knowledge base: open a folder of Markdown notes beside Files, Info and Git, edit notes in the WYSIWYG editor, search paths and full text, organize tags and favorites, and restore deleted notes from the trash. Agents can query notes with vkb; folder imports run in the background and keep a record you can expand, revisit or cancel.

  • 🤖 Plan-and-execute sessions: vspawn --plan-execute opens a planner session that splits the task into execution sessions; vflow proposes the split, vtell --report returns each executor's result for acceptance, and rework reuses the original executor. Worktrees can be shared by every role or created per session.

  • 🔗 Shared projects and sessions now load the host's real interface behind the shared URL, forwarded over an outbound tunnel and limited to the granted project or session. Devices and grants can be managed from the account pages.

  • 🧠 Session knowledge adds project, session and entry groups with drag-and-drop, renaming and deletion; a new reorganization of the same session replaces the queued one.

  • 💬 Conversation view: long histories load page by page back to the first message, every chat-capable agent (including OMP) opens in the conversation view by default, and consecutive turns from the same agent share one author row.

  • ⌨️ Terminal: shell-native suggestions offer Tab completion for zsh, bash, fish and PowerShell on macOS and Linux, the arrow keys keep recalling previous commands while suggestions are open, and the terminal core moves to xterm 6.

  • 📊 Info shows per-turn stats for Claude, Codex, Grok, OpenCode, Pi and OMP: input and output tokens, cache hit rate, generation speed, tool calls and recorded file edits. Less-used composer controls move under More.

  • 🔐 The composer shows the configured, effective and pending permission mode, and asks for confirmation when a restart is required to apply a change.

  • 🔔 Notifications show the session name and a short preview, clicking one opens the session, and the mobile app can receive them through the system push service.

  • 🌐 Claude's model list now comes from the published model catalog, cached locally and refreshed every six hours, merged with the models the CLI reports.

  • 🧵 Up and down arrows in the composer recall your earlier messages, including queued and pending ones, and restore the unsent draft at the end.

  • ↩️ Rolling back a message returns its images to the composer so they can be sent again.

  • 🔑 Agents started on macOS inherit the full login-shell environment, so tools installed outside the default PATH are found.

  • 💡 A feedback entry in the title bar opens the feedback page.

  • 🕹️ A game center entry in the tab bar opens the website's Game Center (PIXEL WING); desktop clicks open the game in the built-in browser.

v0.1.108

Latest
  • 💬 Experimental conversation view for Claude, Codex and OpenCode, with streaming replies, thinking, tool details, permissions and question forms. New configurations still default to the terminal view.

  • 🎛️ Conversation controls now support model settings, queued messages, steering, file completion and image attachments, according to each engine’s capabilities.

  • 🔎 Conversation search, file links, image actions and separate conversation fonts make long sessions easier to read. Remote history loads progressively, with tool details fetched on demand.

  • 📨 Message submission receipts help reconcile interrupted connections. Uncertain submissions stay pending instead of being retried automatically.

  • 🤝 New vrefer and vsearch commands read and search other sessions; vrefer --ask delegates reading to an agent. vorch and vstat add multi-agent coordination and status inspection.

  • 🧠 Memory entries support tags and direct text editing, with unsaved-change protection and configurable organization settings. History import gains filtering and selection improvements; graph navigation is improved.

  • 🌐 Public sharing client support adds account/device binding, scoped AI-session access and encrypted relay connections. Guest image uploads and complex MCP forms remain unsupported.

  • 🔄 Codex resume IDs are checked against persisted history. Confirmed missing history now produces an explicit error instead of silently starting an empty session; existing running terminals can still be reattached.

  • ↩️ Rollback follows engine capabilities: Codex restores conversation state only, without restoring files. OpenCode rollback range handling and directory prechecks remain known limitations.

  • 📦 Release version bumps preserve locked dependency versions. Cross-platform installation/upgrade checks and live AI integration acceptance remain pending; automated checks do not replace them.

v0.1.107

Latest
  • 🧠 Global Memory (experimental): Claude or Codex turns your conversations into a shared wiki organized by topic
  • 🕸️ Code Graph (experimental): index a working directory, browse symbol relationships, and link them to memories
  • 🔎 Agents can look up code and memory during a session with vknowledge
  • 🖥️ SSH can mirror the remote desktop app: same tabs, splits, and active session on both machines
  • 🪟 SSH remote machines can now be Windows
  • 📥 Import existing Codex, Claude, and OpenCode sessions from a project folder
  • 🤖 New agent: OMP
  • 🎚️ vspawn can pick the model and reasoning effort for a child session
  • 🌿 vspawn-tree works in collections, and running worktree sessions show a branch icon
  • 🔤 Search matches whole words first and highlights exactly what it matched
  • 🖱️ Middle-click a tab to close it
  • ⌨️ macOS browsers: ⌘D and ⌘⇧D split panes
  • 💬 IME composition no longer shifts the view, and the caret stays visible while composing
  • 🪓 A split from the menu only affects the focused window, and every split is written to logs/split.log
  • 📁 The remote folder picker keeps the path you type
  • ℹ️ Info panel: start time and uptime share one row, and macOS shows load average
  • 🔑 Password fields no longer show the browser's own reveal button

v0.1.106

Latest

Workspace

  • The sidebar has collections: top-level containers that are not tied to a folder on disk. Some sessions never belonged to a repository — such as remote sessions, browser pages, or a terminal opened just to try something. Until now, the only place to put them was inside a project, where they felt out of place. A collection is a standalone row with a name and no backing folder on disk. Because there is no project root, irrelevant actions are hidden upfront rather than failing after the fact: "New Worktree Session", "Move to Worktree…", and the worktree picker in the new-session dialog are all hidden for collections instead of throwing an error when clicked. In their place, the new-session dialog includes a Working directory field that defaults to your home directory, complete with a native folder picker on desktop. Sessions started without a specified directory now begin in your home directory instead of inheriting the app's launch path (which was / on macOS).

  • The Resources panel shows the whole machine, not just the current session. Previously, the panel only reported CPU and memory for the session's own process tree, making it impossible to tell whether the session was consuming all your resources or the machine was already overloaded. The panel is now split into THIS SESSION and SYSTEM. The SYSTEM section displays progress bars for CPU, memory, and swap (turning amber above 70% and red above 90%), along with a platform-specific line: memory pressure on macOS, load averages normalised by core count on Linux, and neither on Windows (which has no equivalent metric). If you only care about your own session, uncheck "system" in the panel header — the system rows disappear and background sampling stops entirely. This preference is remembered and applies to every session's panel.

  • Windows and Linux have a menu bar, accessed with the Alt key. macOS features native system menus, but on Windows and Linux, settings, update checks, and split panes were previously reachable only behind the title bar icon. Pressing and releasing the Alt key alone now toggles a menu bar. Key combinations with Alt remain untouched — since Alt serves as the Meta prefix in terminals, shortcuts like Alt+B and Alt+F continue to pass through to the shell; only a bare Alt press, which sends nothing to the terminal, triggers the menu. The bar includes File (settings, check for updates), Terminal (new terminal, split right, split down), and Help (website, feedback, share), showing shortcut hints based on your custom keybindings. It supports both mouse and keyboard navigation: pressing Esc closes the open menu, then hides the bar, and returns focus to the terminal.

  • "Clear notification badges" in the menu clears a badge that nothing else could. The dock badge counts unread sessions plus unanswered spawn confirmation cards. However, the sidebar's clear button only appeared when unread sessions were present and only cleared those sessions. If an unanswered prompt card was left over — such as from a closed window or a deleted session where the card could no longer be drawn — the dock badge showed 1 with no way to dismiss it. The new menu item marks all sessions as read, resolves all pending spawn requests as declined, and directly resets the OS badge count to zero. This is especially important on macOS, which persists dock badge counts across app restarts.

  • The window no longer freezes while commands read files or wait on the system. Synchronous Tauri commands execute on the main thread, freezing the user interface for their entire duration. An audit of all 43 commands revealed 13 performing main-thread I/O: requesting macOS notification permissions could block for up to a minute waiting for user confirmation; reading session recordings from long-running sessions walked tens of megabytes in 64 KB chunks; pasting screenshots wrote directly to disk; and fetching a session's working directory spawned lsof. All 13 now run off the main thread. Keystroke handling remains on the fast path, unchanged.

Remote access

  • Hosts now show which remote clients are connected. Because session mirroring is bidirectional, a remote client can rearrange the host's layout — yet the host previously had no way to know anyone was connected, let alone who. The title bar now displays a "Mirrored by N" badge; clicking it reveals a list of connected clients with their names, IP addresses, and connection timestamps. The client name is reported during the encrypted handshake (falling back to "Unnamed" if none is provided).

AI agents

  • Account usage is fetched once per machine instead of once per session. Usage limits belong to the account, but every session's Info panel previously fetched them independently. Having ten open sessions resulted in ten duplicate requests for the same numbers — often triggering Claude's strict rate limits and blanking out the panel. A centralized backend poller now maintains a single snapshot that all sessions read from, broadcasting updates whenever the data changes. It only polls providers you actively use — detected by the presence of ~/.claude, ~/.codex, or ~/.grok/auth.json — without touching the system keychain to avoid unnecessary permission prompts. Snapshots are saved to disk so the panel displays cached numbers immediately upon restart without waiting for the initial poll. Waking a laptop from sleep also refreshes the data right away instead of waiting for the next scheduled interval. Consecutive poll failures back off up to 8x. In Settings, the refresh interval now features an explicit on/off toggle alongside the interval input, replacing the ambiguous 0-second setting.

  • Failed usage refreshes are clearly marked as stale instead of appearing up to date. Previously, when a refresh request failed, the client silently returned its cached copy while recording a successful refresh — advancing the timestamp, clearing errors, and resetting the backoff timer. When hitting rate limits, this made the panel appear healthy even as it continued polling every five minutes. Failed requests now retain cached values but display an amber stale badge next to the provider. Hovering over the badge shows a tooltip with the failure time, the error reason, and the age of the displayed reading. The "Updated" timestamp reflects the last successful sync, and retry-after requests from rate-limited servers are respected, though manual refreshes will still trigger immediately.

  • Per-model weekly quotas appear in the usage panel. In addition to account-wide 5-hour and 7-day limits, the usage endpoint reports model-specific weekly quotas. These were previously ignored, meaning users working with models like Fable could only see total account usage rather than their remaining model-specific allowance. These breakdown rows are now displayed below the totals, categorized by model family.

  • Reopening an OpenCode session restores its chat history. The app previously checked whether a session still existed using opencode session list, which only queries sessions under the current working directory. Because the desktop app runs from its launch directory (/ on macOS), existing session IDs were never found, causing resume attempts to silently open blank sessions. Session checks now query the specific session ID directly and only consider it deleted if the command explicitly confirms it. Other errors are treated as indeterminate and the app proceeds with resuming, avoiding accidental loss of session history.

Interface

  • Typing with an Input Method Editor (IME) now displays composition text. Text composed using an IME (such as Pinyin or Kana) was previously invisible until submitted with Enter across all three platforms. This was caused by a custom CSS rule: xterm renders composition text inside an unconstrained overlay container, where our added right constraint (intended to wrap long terminal lines) resolved to zero width, while overflow: hidden clipped the text entirely. That rule is gone, and the only thing still overridden is the overlay's default black-on-white colour scheme, which matches no theme. A related problem was fixed at the same time: xterm expanded its hidden textarea to match the overlay size for IME candidate positioning but never shrank it back, leaving an invisible overlay that blocked mouse clicks and text selection on that line.

  • On macOS, Ctrl shortcuts no longer trigger Command keybindings. Modifier key checks previously treated Cmd and Ctrl as interchangeable on macOS. As a result, standard terminal shortcuts conflicted with app keybindings: Ctrl+D (EOF) split panes, Ctrl+W (delete word) closed panes, and shortcuts like Ctrl+F, Ctrl+T, and Ctrl+O were intercepted by the app. Because new panes spawn silently, it often seemed like split panes appeared out of nowhere. The macOS desktop app now exclusively uses Cmd for shortcuts, while other platforms (as well as web browsers connected to a Mac) exclusively use Ctrl.

  • Dropdown menus no longer reopen immediately upon selecting an option. A wrapping <label> element was propagating clicks across the row back to the trigger button, causing the dropdown menu to reopen as soon as an item was selected.

Fixed

  • Linux: the AppImage starts again. The 0.1.105 AppImage crashed on Ubuntu 22.04 before a window appeared, unable to spawn WebKit's helper processes. AppImage packaging tools rewrite literal /usr paths in binaries to ././ (preserving string length for in-place patching), requiring the launcher script to change working directory into $APPDIR/usr so those paths resolve. In 0.1.105, our custom launcher script — introduced to prevent environment variable leakage into child shells — forwarded environment variables but missed this directory change. The launcher now correctly changes directories, backed by a build-time assertion to prevent regressions. Versions 0.1.104 and earlier were not affected.

  • Windows: notifications play a sound again, and clicking one jumps to its session. Windows notifications previously sent a macOS sound identifier to the notification plugin. Because the name couldn't be parsed, it was turned into silence — meaning Windows notifications never played sound regardless of settings. Windows notifications had been routed through the plugin two releases ago as a workaround for an issue resolved in that same release. That detour is now undone: notifications go back through the native channel, which restores both the sound and click-to-jump session navigation.

  • Windows: box-drawing and block characters line up. Terminal frames were previously rendered with a proportional fallback font, causing visual smearing. Even after addressing that, block characters (used in progress bars and the Claude Code mascot) still showed a hairline vertical gap along the right edge of each cell because the fallback font was slightly narrower than the primary terminal font. Both character ranges are now served by a bundled subset of JetBrains Mono, ensuring exact glyph width matching.

  • Windows: git works in the full Git Bash variant. Although full Git Bash installations succeeded, running git in the terminal reported "command not found", repeatedly prompting users to install full Git Bash. Git Bash only adds mingw64/bin to PATH when told which directory tree it is running in. Because our shell launcher omitted this parameter, binaries located exclusively in that directory — such as git and curl — could not be found. In addition, the download prompt now selects the installer matching the host system's architecture rather than defaulting to 64-bit.

  • Windows: removing a worktree works, and reinstalling Kiro hooks stops duplicating them. Worktree removal commands were previously executed from within the target worktree directory. Because Windows prevents deleting the current working directory of an active process, the operation consistently failed with a permission error; Git commands now execute from the main repository root. Additionally, the hook detection logic compared forward-slash paths against Windows backslash paths, causing the check to fail and append duplicate hook entries upon every reinstallation.

v0.1.105

Latest

Workspace

  • Session status, unread marks and whether a session is still running are now decided by the backend, and every client sees the same answer. Each client used to work these out from whatever it happened to observe, so "unread" really meant "not read in this window": reading a session in the browser left the desktop copy unread, and the dynamic status filter kept pushing that row back into the shared list, where even "Refresh status" could not remove it. Status events were also registered only once a client had spawned a session itself, so a browser that had just connected showed dots for the sessions it had opened and nothing for the rest. The backend now keeps one authoritative record per session — the agent, its state, whether its process is alive, and the unread flag — answers a bulk query when a client connects or reconnects, and broadcasts every change to everyone. Clients report what they observe; the backend draws the conclusions. Reading a session on a phone clears the mark on the desktop, a browser that has just connected shows the right dots for sessions it has never opened, and the arbitration rules that used to live in the frontend moved across with their reasons and their tests: a hook that has reported once locks out anything inferred from raw output, continuous output only implies busy for a session that has an agent, is not Codex and has no authoritative report yet, and a 1200ms hold keeps a task that has just started from being cancelled by a finish event arriving right behind it. Screen reading is the exception, because it needs the rendered grid and that only exists in a client: the client that owns the terminal size reports what it read, and the backend decides whether to accept it — a report from any other client is refused. If any of this goes wrong, setting vlx-arbitration to frontend in localStorage hands arbitration back to the old frontend chain.

  • Restarting a session no longer closes its tab on the other client. pty://killed carried no payload, so the other side could not tell a restart from a close: it treated everything as a close, removed the pane, and then mirrored that layout back. The event now says which client killed the process and why, so a restart keeps the pane and waits for the new process to arrive. A missing or unrecognised reason still counts as a close — leaving a pane open for a session that is never coming back puts a dead terminal on screen, which is worse than closing one that was about to restart.

  • A browser connecting to a desktop that has just restored its workspace no longer starts every session for real. Restoring a workspace renders placeholder cards instead of launching processes, but that decision only existed on the desktop; the browser followed the mirrored layout, could not tell "not running" from "running, just never opened here", and mounted the terminals — and mounting one is launching it. A leaf that arrives with someone else's layout now renders a placeholder when the backend says there is no process behind it. Opening a session yourself is still an intent to start it, and a terminal you are currently looking at is never replaced by a card when its process exits, because you may still want to read what it printed.

  • A settings change reaches the other clients immediately. The backend has always held the authoritative settings, but it changed them without telling anyone, so the other client found out at its next launch. Over a remote connection that is more than a display mismatch: turning off "grow status filter dynamically" on one client did nothing while another one kept adding rows to the shared list, and the client with the smaller live-tab limit evicted background tabs out from under everyone else. Writing a setting now broadcasts which key changed, and each client re-reads it through the same path it uses at startup, so the rules that hide protected values from remote callers still apply — the broadcast carries key names only, never values. Phones, which previously neither sent nor received settings, now take part as well.

  • A browser waits for the mirrored layout before restoring its own. A remote window has two sources of layout — the one in its own localStorage and the one the host pushes under mirror mode — and whichever arrived first was overwritten by the other. Putting the local one up first cost more than a flicker: mounting a terminal leaf launches a real process, and for a session whose process was already gone that meant starting a shell nobody would ever look at, which then stayed, because a browser detaches its terminals instead of killing them. The browser now waits for the first alignment to settle before restoring anything, for at most two seconds; if the backend is slow or unreachable it falls back to the local layout rather than sitting on an empty window. Phones, and any client with mirroring off, are let through immediately.

Remote access

  • An SSH connection can turn mirror mode on for the service it starts. The switch lives in the Remote access panel, but SSH starts a headless service on the far machine and there is no panel there to click. Hold Option while clicking "Connect remote" and the SSH form now offers a "Mirror UI across clients" checkbox, off by default. The value travels with the connection and is held in the service's memory rather than written to the far machine's database: when you also reuse the remote desktop's own database, one SSH connection should not quietly flip a switch on somebody's panel. The choice is remembered per host, so picking the same machine out of the history brings it back. Reusing a service that is already running now requires the version, the data mode and the mirror mode to all match — if any of the three differs the old service is replaced, which ends the sessions running on it, so this option sits behind Option alongside the database switch.

  • A client that is being mirrored says so. Tabs and splits on a following client used to rearrange themselves with nothing on screen to explain where the change came from. The title bar now carries a Mirrored badge, with an explanation on hover. The host does not show one — it has the switch.

  • Files can be moved between your machine and the one running the terminal. Remote access showed you the far machine's files but gave you no way to take one home or put one there — the only route was a shell command in a terminal. The Files panel now offers Download on a file's context menu and Upload in its header, and dragging files from your desktop onto a folder row sends them there. Both directions ride the same authenticated connection everything else uses, so this works from a browser on the local network, from a phone, and from a remote-connection window alike. Transfers move in chunks with a progress queue below the tree, and they keep running while you look at another panel. Download is an ordinary download link, so your browser's own download manager handles it: it streams to disk, shows speed and time remaining, and can be paused and resumed, at any file size and in every browser including a phone. The link carries a ticket minted for that one file and valid for a few minutes, because this server keeps credentials in a header and a browser fetching a link sends none. An upload writes to a temporary name and is renamed into place only once it is complete, so an interrupted transfer never leaves a half-written file where a whole one should be; a name that is already taken is refused before anything moves rather than after. Uploads show their speed and time remaining, and they survive the connection dropping: a failed chunk backs off and retries for about a minute, asking the server how far its temporary file actually got rather than resending a chunk that may already have landed. Giving up keeps those bytes — drop the same file on the same folder again and it continues from where it stopped, even after a reload, because only cancelling throws the partial file away.

AI agents

  • Antigravity and Copilot sessions are named after their first message. Both were missing from automatic renaming, which left rows of "Antigravity 1, 2, 3" in the sidebar. Antigravity's hook events carry no user text at all, only a conversation id and a transcript path, so the first message is read out of the transcript instead; the metadata block that follows it is left out of the title. Copilot's events carry no event name either, and are told apart by shape, so a body with a prompt and no tool name is now taken as a submission — which leaves the prompt a session is started with, and tool calls, correctly out of it.

  • An Antigravity session reopens with its history. Resuming needs the conversation id, and the parser that pulls a session id out of the launch arguments did not recognise Antigravity's spelling of it, so --conversation=<id> never had an anchor to point at and every reopened session came up empty.

  • vspawn --yes spawns without the confirmation card. Anyone who keeps "confirm before spawning" on had to click through a card for every child session in a run. The flag — also spelled -y or --no-confirm — skips the card for that one call and starts the session with the default settings. It does not change the setting itself, so the next spawn without it asks again.

  • The model field on the spawn card takes anything you type. It was a plain dropdown, so only the models in the list could be chosen — and an agent understands far more identifiers than that: dated names like claude-opus-4-6, vendor-prefixed names, aliases configured locally. It is now a text field with the known models hanging off a dropdown beside it as shortcuts. The list is a suggestion, not a whitelist: whatever you type is what gets passed, an empty field means no --model at all, and the list filters as you type and folds away when a custom identifier matches nothing.

Interface

  • One dropdown, used everywhere. The dropdowns around the app had been copied from the same code more than a dozen times and then drifted apart: three panel backgrounds, four shadows, three hover colours, trigger heights of 26, 28 and 32 pixels, and ticks on selected rows that only a multi-select list needs. A single component now backs the branch pickers on merge, the language, default shell and font pickers in settings, the agent picker, the worktree dialogs, the agent type on new and restored sessions, and the last native select in the form modal. It also brings keyboard control, which none of them had: arrow keys to move, Enter to choose, Escape to close without closing the dialog behind it, Home and End to jump. The two menus in the status bar behave as they did, and the status filter in the sidebar keeps its ticks, because it really is multi-select.

  • The password field in the Remote access panel can be revealed. It was a bare password input, so you could not see what you had typed; the eye button existed, but only inside the connect panel's own file. Both now share one component, and the revealed state resets when the panel closes.

  • The IP picker no longer looks like a system control. It was a native select, which WKWebView dresses in system chrome that sits badly on a dark panel — the same complaint as the dropdowns replaced above. It now uses the shared component, and its label is shortened to "IP", since the text beside it already says what it is for.

Fixed

  • Checking for updates asks the server every time. A client left running was pinned to the first version it ever saw: having found 0.1.101 it went on offering 0.1.101 after 0.1.104 shipped, and "Check for updates" only reopened the same dialog, because the old code returned early whenever a notice was already pending. Every check is now a real request. A newer version replaces the notice on screen, the same version or a download in progress leaves it alone, and a server that reports no update at all takes down a notice that has gone stale — the version was pulled, or you installed it yourself in the meantime. The "Download manually" button now opens the download page on the website; it used to hand over the updater's own package, which unpacks in place and cannot be installed by hand.

  • A full-screen error overlay no longer appears when terminals are torn down quickly. xterm's viewport schedules a scroll-area sync when it is constructed and another when it resets, and cancels neither on dispose, so a terminal opened and closed within the same task — which is exactly what rebuilding the session tree during a remote connection does — still ran those callbacks, found a renderer that had already been cleared, and threw. The throw comes from a timer, where neither try/catch nor an error boundary can reach it, so it is caught globally and matched narrowly: only a stack or message naming that sync, together with a mention of the renderer or its dimensions, is swallowed as harmless and written to the request log. Real crashes still raise the overlay.

v0.1.104

Latest

AI agents

  • The child-task card now offers each agent's real models, and the effort flag that agent actually understands. The card built its launch arguments with --model and --effort for everything, but only Claude, Kiro and Antigravity spell reasoning effort that way — Grok and Zoo call it --reasoning-effort, Cline calls it --thinking. Picking an effort level for any of the others handed the CLI a flag it had never heard of, and the session failed to start. Every agent now contributes its own flag names and its own values. The model control follows what each CLI can tell us: the ones that can list their catalogue (OpenCode, Grok, Crush, Antigravity, Cursor, pi, Kiro) are asked for it and offer the real list, the ones with a fixed set (Claude, Codex, Kimi Code) offer that set, and the rest give you a text field with an example of the shape they expect. An agent that is not installed or not signed in says so instead of spinning forever. Choosing "Default" now clears an inherited override rather than leaving the old value in place, and picking an effort level no longer drops the model inherited from the parent session.

  • A child task spawned from a Kimi Code session stays Kimi Code. Kimi Code was missing from the list the spawn path uses to inherit the parent's agent, so its child sessions quietly came back as the default agent instead.

Workspace

  • A group can be moved to a worktree after it was created. The worktree was chosen when the group was created and fixed from then on; changing your mind meant deleting the group and building it again. Right-click a group and pick "Move to Worktree…" to create a new worktree, bind an existing one, or re-point a group that is already bound. Only the group itself changes: sessions already inside keep the directory they were created with — a running session cannot be moved to another directory underneath itself — while sessions created afterwards start in the worktree.

  • Mirror mode now covers the whole sidebar tree. It shared the selection and the collapsed panels; the search box and the status and marker filters stayed local, on the theory that syncing them interrupts whoever is looking something up. That reasoning was backwards: mirroring means both windows hold the same state, not that one replays the other's keystrokes — a filter that is on here is on there. What actually interrupts people is the two sides showing different trees. Every sidebar projection now travels: the split layout, each projection's name, its search text, its status and marker filters, and its own collapse state. The snapshot format moved to version 2, and a client running an older version stops mirroring rather than applying half of a frame, so reload any window you left open through the upgrade.

Interface

  • Closing the window on macOS asks the same question as quitting. ⌘Q and the menu item went through the app's own confirmation, but the red close button destroyed the window outright — and that window holds the webview the confirmation dialog lives in. You either got no confirmation at all or the stripped-down native fallback, with no "save workspace" checkbox and untranslated text. All three platforms now hold the window open until you answer.

  • "Save workspace" is on by default, and it stays where you put it. Losing a layout costs more than an unwanted snapshot, so the box starts checked. It also used to forget: the setting was written to the database through a 400ms debounce, and quitting killed the process inside that window, so the next launch reconciled against the old value and put your change back. The write is now flushed before exit, with a 600ms ceiling so a stalled backend cannot leave the confirm button spinning. (Contributed by FarhadGSRX.)

  • Passwords in the remote-connection panel can be revealed. Both the URL password and the SSH password have an eye button that switches between masked and plain text. The revealed state is local to the field and resets when the panel closes, so a password is never left sitting on screen.

  • The sidebar filter badge counts every filter that is on. A marker filter only lit the button up without saying anything, so the badge could read 1 while two filters were active. It now counts statuses and markers together and matches the ticks in the dropdown; a single status filter keeps its coloured dot.

Fixed

  • Automatic updates on macOS work again. The v0.1.103 packages carried AppleDouble companion entries (._VelaTerm.app), which the updater strips the first path component from — leaving an empty path — and it then refused to unpack the archive at all. Both architectures were affected, so every macOS user on v0.1.103 was stuck there. Packaging no longer writes those entries.

  • Native controls follow the app's theme when it differs from the system's. Applying a theme set the app's own colours but never updated color-scheme, which was seeded once at startup from the system preference and never changed again, so checkboxes, dropdowns and scrollbars stayed dark under a light app on a dark system. (Contributed by FarhadGSRX.)

  • A fresh clone builds again. The Rust crate embeds ../dist at compile time, and the dev command does not produce it, so a newly cloned repository failed to compile before it could run. The build script now creates the directory when it is missing. (Contributed by FarhadGSRX.)

v0.1.103

Latest

Fixed

  • Codex sessions on Windows no longer refuse to start. Every Codex session failed immediately with unexpected argument '--codex-hook' because the lifecycle-hook TOML table passed on the command line contains spaces and double quotes, and npm-installed codex.cmd re-parses that through cmd.exe, which strips the quotes and splits the value into separate arguments. Hook injection is now skipped on Windows; status detection falls back to the existing notify / screen / busy heuristics, which still report idle and busy states — just less precisely than hooks. macOS and Linux are unaffected and continue to use hooks.

  • Rolled back the Windows IME pre-edit fix from v0.1.102. The fix that restored the composition overlay for Chinese, Japanese and Korean input also gave it a visible background, border and rounded corners, which drew a small box around the pre-edit text inside the terminal — something that should not appear there. Because the overlay sizing, the helper-container geometry and the textarea cleanup were all interdependent, the entire change had to be reverted together. The underlying issue — typing CJK blind on Windows — remains open and tracked in issue #6.

v0.1.102

Latest

AI agents

  • Agent presets: run several compatible CLIs side by side. Every agent kind was hard-wired to one executable, so a fork, a nightly build or a second CLI that speaks the same protocol had no way in — you edited the launch arguments of an existing kind and lost the original. A preset now names its own executable, icon and launch arguments, and appears in the new-session menu next to the built-in kinds. Sessions record which preset created them, so forking one keeps the same executable, and a preset created on the desktop shows up on paired browsers and remote clients as well, icon included, because the icon travels as data rather than as a path on one machine. Existing sessions are untouched: a database from an earlier version starts exactly as it did before.

  • The child-task card picks the model and the effort level, and one answer settles it everywhere. When an agent asks to spawn a child task, the confirmation card now offers the model and — where the agent supports it — the reasoning effort, prefilled from the parent's own launch arguments so the common case is a single click. Switching the card to a different agent re-derives both, so a model name from one CLI can no longer end up on another's command line. The card appears on every connected client, and answering it on one now dismisses it on the others; the first answer also claims the task on the server, so confirming on a phone and a desktop within the same second creates one worktree and one child session instead of two.

Workspace

  • Mirror mode: one shared layout across every client. The terminal stream was always shared — one PTY, one byte stream — but the arrangement around it lived only in each client's browser storage, so a browser opened over the LAN showed its own tabs and splits and rearranging one screen did nothing to the other. With mirror mode on, tabs, splits, the active session, the sidebar selection and the collapsed panels are published to every client and followed by all of them. The host controls the switch from the remote-access panel. Rearranging on either side takes effect on the other; a session that leaves this window's layout is detached rather than killed, so following a peer never ends someone's process; and applying a peer's layout does not steal the keyboard from whoever is typing locally. Phones stay out of it — the two-level phone navigation is a different shape of UI, and copying a desktop split tree onto it helps nobody.

  • The Git tab in the right sidebar became a usable Git client. It only listed changed files before. It now stages and unstages individual files or whole groups, discards changes, writes a commit (with amend), and shows the commit history with each commit's files and diffs — grouped into staged, changed, untracked and committed sections that fold away. Paths are handled from the repository root, so a session opened in a subdirectory operates on the files it says it does, and a detached HEAD is labelled as such instead of showing a branch called HEAD.

Interface

  • ⌘Q now asks the same question closing the window does. The Quit item in the application menu was the system's own, which terminates the process outright: pressing ⌘Q skipped the "save workspace" confirmation that the close button shows, so the same intent behaved differently depending on how you expressed it. Both paths now go through one confirmation. If the window that shows it has reloaded or crashed in the meantime, pressing ⌘Q again re-asks and falls back to a native dialog rather than leaving the app unquittable.

  • Shortcut hints show the keys that actually work. The defaults differ per platform, and a browser reserves ⌘/Ctrl letter combinations for itself — ⌘D bookmarks, ⌘T opens a tab — so on macOS the app's own ⌘ shortcuts never reached the page when VelaTerm was opened as a URL. Plain browser tabs now use the Ctrl+Alt bindings on every operating system, while desktop apps and remote-connection windows keep ⌘. Tooltips and the empty-tab hint render whatever binding is in effect, including one you rebound yourself, instead of a hardcoded ⌘ combination; and the terminal blocks exactly the combinations the app has claimed, so rebinding an action moves that key with it.

  • Font presets cover Nerd Fonts and CJK, and a custom font that is not installed says so. The preset list gained the common Nerd Font and CJK families, and a font typed in by hand is echoed back and checked: if the system does not have it, the settings page says so instead of silently falling back to a default that looks nothing like what you asked for.

  • Text fields on macOS no longer capitalise or correct what you type. The system's automatic capitalisation, autocorrect and spellcheck applied to every input in the app, including session names and command fields, where "npm" became "Npm". They are off everywhere now.

Windows

  • Typing Chinese, Japanese or Korean shows the pre-edit text and the candidate window again. Both were invisible — you typed blind and only saw the result after pressing Enter. Two of our own CSS rules were responsible: the container holding the pre-edit overlay collapsed to zero width, and the overlay's right offset resolved inside it to nothing at all. The candidate window followed, because the operating system positions it from the overlay's rectangle. The overlay is drawn again and themed with the app's colours, and the invisible input element it sits on releases its geometry once composing ends, so clicking and dragging over that patch reaches the terminal rather than an empty element that used to keep covering it.

  • The native title bar follows the light/dark setting. The app keeps the system title bar, and Windows paints it light until told otherwise, so a dark interface carried a white strip above it. It now matches the app, including windows opened later such as SSH and remote-connection windows. Choosing "follow system" hands control back to the OS instead of pinning a value.

  • The stray square on cold start is gone. The single-instance plugin creates a hidden message window and never gave it the transparency its own style promised, so Windows occasionally grew the zero-sized window to its minimum and painted a small square during startup. It is properly transparent now; single-instance behaviour is unchanged.

Performance

  • Remote access loads far less on first paint. Static assets are now compressed on demand and served with cache validators, so a second visit revalidates instead of re-downloading, and the language packs and the terminal's optional renderers load only when something needs them rather than being part of the first payload. Together the initial transfer drops to roughly a fifth of what it was.

Fixed

  • A spawned child now starts like the session that asked for it. Children inherited neither the parent's permission mode nor its launch arguments, so a child of a session running with confirmations skipped came up asking for them, and a model pinned on the parent was dropped. Both are inherited now, falling back to the agent kind's global defaults — the same ones the "new agent session" menu applies.

  • Reconnecting a remote window no longer reports a false "authentication failed". When the window reconnected, the new WebSocket and the one it replaced raced each other; the loser's teardown was reported as an authentication failure, and the banner accused a perfectly valid pairing of being rejected.

  • A group can no longer be dragged into its own subtree. Dropping a group onto one of its own descendants detached that whole branch from the tree, and the sessions inside it disappeared from the sidebar until the database was repaired by hand. The move is now rejected.

  • Agent output keeps its colours when VelaTerm is launched from another tool. A terminal inherits the environment of whatever started it, so launching from an IDE or an agent harness that exports NO_COLOR, CI or FORCE_COLOR=0 made every agent TUI render monochrome inside VelaTerm, even though the terminal advertises full colour. Those inherited values are dropped when a session starts; the same variables exported from your own shell profile still apply, because that profile runs inside the session.

v0.1.101

Latest

Remote access

  • Pick which address the share link uses — Tailscale addresses now show up. The address list only accepted the classic private IPv4 ranges, so VPN meshes such as Tailscale, which assign addresses from the carrier-grade NAT range (100.64.0.0/10), were silently dropped from the remote-access panel and the pairing link — even though the server was already reachable through them. These addresses are now listed, with VPN tunnels ranked last so they never become the default. A new IP selector in the panel — shown before starting and while running — lists every candidate with its interface name and marks VPN tunnels; choosing one moves its URL to the front and regenerates the pairing link with exactly that host, so the link you copy works on a device that can only reach this machine over the VPN, without editing the URL by hand. A QR code under the pairing link lets a phone scan it directly. The choice is remembered; if the chosen interface disappears, the panel falls back to automatic without forgetting it. The server itself is unchanged and keeps listening on all interfaces. Choosing an address that only appeared after the server started — a VPN that connected later, say — now also updates the copied URL and the QR code immediately, instead of only the pairing link until the next restart; VPN tunnels are ranked behind LAN addresses on every platform, an address picked while the server is stopped drives the very first pairing link after it starts, and overlapping link regenerations can no longer overwrite a newer link with an older one.

  • Sharing survives a restart. The pairing token used to be regenerated every time the server started, so quitting and reopening VelaTerm silently invalidated every shared link, and every phone had to be paired again. The token, the paired devices and the device blocklist are now saved to an owner-only file in the data directory: a previously paired device reconnects with its saved URL after a restart — the access password stays a required second factor — and a revoked device stays revoked. VelaTerm also remembers that sharing was on: quit while the server is running and the next launch brings it back on the same port, in the desktop app and on a headless --serve server alike; stop it yourself and nothing starts automatically. If the automatic start fails, because the port is taken for example, the app starts normally and the remote-access panel shows the reason. The port field now remembers the port you actually used instead of resetting to the default, and "Regenerate link" remains the explicit kill switch: it issues a new token at once, invalidates every old link, and overwrites the saved state. The access password itself is never written to disk — only a memory-hard hash (Argon2id) is stored.

Security

  • A paired device can no longer manage the sharing itself. Any paired browser could invoke the same management commands as the desktop app — create a new pairing link (which also clears the device blocklist), list and revoke other devices, or stop and reconfigure the server — and the settings store handed every client the complete settings map, including the memory-hard hash of the access password and the autostart settings the next launch reads. Management commands are now reserved for the desktop app and the Electron shell; the settings API filters the remote-access keys and the Gitea token out of every read from a paired device and rejects writes to them. A paired device keeps what pairing is for — its terminal sessions with full shell access — but it can no longer read the password verifier, invite or evict other devices, or redirect the port the next start uses. Commands that read, write or delete stored secrets — the Gitea token and remembered host passwords — are refused for a paired device as well, and the path-taking commands — reading, previewing, writing, creating, renaming and deleting, and likewise showing a file's git diff or picking the folder a repository is cloned into — resolve symbolic links first and reject paths inside VelaTerm's own data directory, where the pairing state and keys live, while every other path keeps working so remote file browsing and editing stay intact. A test enumerates every remote command that accepts a path, so a new command cannot slip past this check unnoticed. When one of these protections rejects a request, the browser now shows a properly translated message instead of a raw English error.

  • Revoking a device or regenerating the link now also survives the dual-instance setup. On a headless --serve server with automatic start enabled, two server instances each held their own copy of the saved pairing state and wrote it back whole: a revocation or a fresh pairing link made through one could be silently undone by the other. All instances in one process now share a single pairing state per data directory: revocation and rotation take effect everywhere immediately, and exactly one writer persists the file, which remains the source of truth across real restarts.

  • Repeated failed logins are throttled. Checking the access password uses Argon2id, deliberately expensive — and anyone who can reach the port can try. After five failed attempts from one address, further attempts are rejected for a minute before any hashing work happens, and the hashing itself now runs outside the server's event loop with a hard cap on concurrent verifications: a flood of wrong passwords can no longer saturate the server with memory-hard hashing or slow it down for devices that are already connected. The throttle lives in memory and resets with the server; the pairing token and the password remain the actual barrier. The limit is now shared by every server instance using the same data directory, so the dual-instance --serve setup no longer doubles the attempt budget, and an attempt is reserved before the password check starts, so parallel requests from one address cannot slip under the limit. A throttled browser now sees a dedicated rate-limit message on the login screen instead of being told the password was wrong, and being throttled is no longer remembered like a wrong password: once the pause is over, the next attempt goes through again without reloading the page. An attempt abandoned midway — the tab closed while the password was still being checked — now frees its reserved slot immediately instead of counting against the address for the rest of the minute, and a successful login releases only its own reservation instead of clearing the address's whole record: behind a shared network address, one person signing in correctly no longer resets an attacker's attempt budget, and recorded failures expire only with their minute.

  • Secrets on disk and in logs are handled more carefully. The file with the pairing state and the end-to-end encryption key are now created owner-only readable from the start instead of being restricted after the first write, and the session database — which holds the password hash — is restricted to the owner as well. A headless --serve no longer prints the pairing link's long-lived secret into logs: when output is not a terminal the link is withheld and a hint is printed instead; --print-pairing explicitly opts back in. The device registry is capped at 32 entries with length-limited names so a paired client cannot grow the saved file without bound, and when saving a revocation or a new pairing link fails, the error now reaches the caller instead of a log line. Automatic start no longer replaces a server already started by hand, and a stale autostart error clears once you stop the server yourself.

Fixed

  • Pairing can be managed from the Electron shell. Creating a pairing link, listing paired devices and revoking a device existed only as desktop (Tauri) commands; the WebSocket dispatcher used by the Electron shell and browser clients answered "Unknown command", leaving the remote-access panel broken there. All three commands now go through the same core functions on both transports, so the two cannot drift apart, and regression tests cover the new dispatch routes — including creating a real pairing link against a running local server.

v0.1.100

Latest

AI agents

  • Kiro CLI is now a first-class session type. Kiro sessions get their own node in the tree, an authoritative Working/Waiting status dot driven by Kiro's own lifecycle hooks, notifications when a turn ends, automatic resume of the same conversation when you reopen the node, launch arguments and a skip-confirmations toggle, and spawning through vspawn — everything the other agents already had. VelaTerm clones your default Kiro agent into its own vlx-term agent, adds observe-only lifecycle hooks to the copy, and launches that — your own agent file is never edited, and your prompt, tools and MCP servers come along unchanged. Kiro has no permission-request hook, so the dot stays Working while it waits for your approval.

Fixed

  • Programs started from the terminal no longer inherit the AppImage's own environment (Linux). The AppImage launcher points PYTHONHOME, PYTHONPATH, PERLLIB, QT_PLUGIN_PATH and the GStreamer plugin paths at the bundle's temporary mount directory, and puts bundle directories ahead of everything else in PATH and LD_LIBRARY_PATH. A terminal hands its whole environment to the shell it starts, so the system python3 looked for its standard library inside the bundle and refused to run at all, and other dynamically linked programs loaded the bundle's copy of a library in preference to the system one. VelaTerm now strips those bundle paths before starting a shell or an external tool, and leaves values you set yourself untouched. APPDIR and APPIMAGE stay visible, so programs that check whether they are running from an AppImage still get their answer. Only AppImage builds were affected; the deb package, macOS and Windows behave as before.

v0.1.99

Latest

Terminal

  • Shift+Enter writes a new line instead of submitting. Terminals have no encoding for Enter with a modifier, so agent CLIs such as Claude Code and Codex received a plain carriage return and sent the prompt while you were still writing it. VelaTerm now emits ESC+CR, the same sequence those tools expect from an iTerm2 key mapping, so multi-line prompts work — including on macOS, where the custom key handler was previously not installed at all. Composition in an input method is left alone, so Enter still confirms a candidate word.

Projects and organisation

  • Refresh the status of a single session. Sessions in a status-filtered pane gain a Refresh status action that re-evaluates only that session against the pane's own conditions, adding or removing it while every other session keeps its place. The action belongs to the pane its menu was opened from, so recursive splits never borrow another pane's filter, and the result is stored per pane and restored after restart.
  • Clearing a mark takes one click. Choosing the emoji already applied now removes it, so the separate entry for clearing a mark and its divider are gone. The filter button also drops its emoji badge: the highlight already says a mark filter is active, and the menu says which one.

Fixed

  • Linux AppImage desktop integration installs on any machine. The bundled icon was a symbolic link to an absolute path on the build machine, so tools such as Gear Lever and AppImageLauncher failed to extract it, even though the application itself ran normally. The link is now relative. The published glibc requirement was also corrected to 2.35 after measuring the bundled libraries rather than the executable alone, which makes Ubuntu 22.04 the oldest supported release for the desktop application.

v0.1.98

Latest

AI agents

  • Grok Build joins VelaTerm as a first-class agent. Install, start and resume Grok 4.5 with stable session IDs, official lifecycle hooks, accurate working and permission states, merged transcripts, usage details and a theme-aware official icon across desktop, browser and mobile views.

Projects and organisation

  • Split the project sidebar into independent working views. Any tree pane can split downward again, with its own search, status and emoji filters, collapse state and resize ratio restored after restart. Every pane remains a projection of the same backend-owned project tree, so edits stay in sync without duplicating business data.
  • Mark nodes and filter without losing context. Projects, groups and sessions can carry emoji markers. A marked container keeps its full subtree visible, status membership remains stable while you work, dynamic additions and manual refresh are both available, and status plus emoji conditions combine as a union.
  • Create an empty project in place. Choose a parent directory, validate the name and create then import the folder in one flow. Partial failures retry the import without creating duplicate directories.

Interface

  • Share VelaTerm where your community is. The share dialog now covers WeChat Moments, Weibo, Xiaohongshu, X, Reddit, Hacker News, LinkedIn, Facebook, Telegram and WhatsApp, with a QR flow for WeChat and a share prompt in the update dialog.
  • Small interactions feel more deliberate. Temporary terminal tabs can be renamed before they become saved sessions, and ordinary inputs disable automatic capitalisation on mobile keyboards without changing terminal input.

v0.1.97

Latest

AI agents

  • Sessions no longer stay stuck on “working”. Codex reported tool activity and turn completion through separate short-lived processes whose callbacks could arrive out of order, leaving a finished turn shown as still working. Mid-turn reports that arrive after their own turn ended are now discarded, and an additional session-end hook covers sessions that exit without a completion event.
  • Interrupted turns settle within seconds. Pressing Esc, or a stream error, ends a Claude or Codex turn without any completion callback at all. Six seconds of terminal silence now quietly corrects such a session to waiting, without raising a “replied” notification.

Interface

  • Reliable split shortcuts on macOS. Split Right (Cmd+D) and Split Down (Cmd+Shift+D) are now registered as native Terminal menu commands, so macOS no longer intercepts the key combination before VelaTerm receives it.
  • Documents save exactly once per keystroke. Cmd+S was handled by both the global shortcut and the focused editor, which could write the same file twice in a single keypress.

v0.1.96

Latest

AI agents

  • Trust Codex lifecycle hooks, not terminal guesses. Modern Codex sessions now use official lifecycle hooks as their only activity source. A SessionStart handshake verifies the bridge, missing callbacks are shown as “Status unavailable,” and terminal text or output activity can no longer overwrite working, confirmation or completed states.
  • Fresher Codex usage after every turn. The Info panel shows the local rollout snapshot immediately, reconciles it with live rate limits, refreshes again after Codex finishes writing its final token snapshot, and ignores late responses from an older session.

Interface

  • Reliable project-tree targeting on macOS. Virtual rows no longer depend on compositor transforms, preventing stale WKWebView hit-test coordinates from sending hover, click or drag actions to a different row after scrolling or tree updates.

v0.1.95

Latest

AI agents

  • Kimi Code and Zoo Code join the session tree. VelaTerm can now launch, resume, install and configure both agents. Kimi uses its official lifecycle hooks for authoritative working, permission and waiting states; Zoo Code keeps a stable task identity and uses terminal detection where external hooks are not available.
  • Live Codex usage refresh. The Info panel can actively query Codex's app server for current rate limits, while retaining the local rollout snapshot as a compatibility fallback.

Projects and terminals

  • Open projects with vela <path>. Packaged builds can install a VS Code-style shell command. A second invocation forwards the project to the existing VelaTerm window instead of opening a duplicate app instance.
  • Visible, cancellable Git clones. Clone Project now reports Git stages, percentage and elapsed time, warns when progress stalls, and can cancel the entire Git process tree without leaving a half-cloned target. Credentials and query tokens are redacted from displayed errors and audit logs.
  • WSL terminals on Windows. Every installed WSL distribution is detected and offered alongside PowerShell, cmd and Git Bash for plain terminal sessions. Agent sessions remain on the Windows host shell so hooks and executable paths stay reliable.

Interface and reliability

  • Clearer background-session control. Background-tab menus now show every session's live state, and the over-limit dialog can end several selected tabs at once.
  • Safer app lifecycle and release notes. Quitting now confirms before stopping live sessions; Codex lifecycle identity wins over ambiguous rollout scans; and automatic-update notes can be delivered in every bundled interface language.

v0.1.94

Latest

Localization

  • Vietnamese interface. Tiếng Việt is now available in the language picker and is selected automatically for Vietnamese system locales.

Browser

  • Faster starts in the built-in browser. Every browser tab now has one-click shortcuts for ChatGPT, Claude, Gemini and Google. Project and group context menus can also create a permanent browser page directly in that part of the session tree.

Images and documents

  • Reliable image-path paste on macOS. When WebKit does not expose a copied image as a file, VelaTerm now reads it from the native clipboard and still uploads it as a file path instead of silently falling through to an agent's native image placeholder. Remote windows always show the image-paste setting, explain why file-path mode is required, and disable the unavailable native option.

  • Paste images into source documents. The source editor now accepts clipboard images. Saved Markdown documents store them beside the document under assets/ and insert portable Markdown image syntax; unsaved drafts embed the image data so it is not lost when temporary files are cleaned up.

Interface

  • Context menus stay visible and target the right item. Menus opened near the right edge are measured and shifted correctly. Right-clicking a tree node now highlights only the menu target without changing the existing selection, and group menus include a terminal scoped to that group.

  • Cleaner editing and status labels. Source text no longer renders arrow-like font ligatures for sequences such as HTML comments, usage percentages are explicitly labelled as used, and the host WebView's unrelated native context menu no longer appears behind VelaTerm's own menus.

Fixed

  • Codex stays in normal terminal history. Codex sessions launched by VelaTerm now use inline terminal mode, so pressing Esc to interrupt or step back no longer switches terminal screen buffers and jumps the scrollback viewport to the top. Your own Codex configuration is left untouched.

v0.1.93

Latest

Updates

  • See what changed before you install. When a new version is available, a status-bar chip and a dedicated dialog now show this version's release notes. You can update now, skip this version, keep downloading in the background, or open the installer download manually; progress is shown live and the app restarts to finish. If you skipped several versions, the notes for every one in between are shown together, not just the latest.

AI agents

  • Codex sessions name themselves. A Codex session is renamed from your first message the moment you send it — the same way Claude sessions already were — so the tree no longer fills up with "Codex 1", "Codex 2". A name you set by hand is never overwritten.

  • vspawn and vopen now work in Codex too. The built-in vspawn, vspawn-tree and vopen skills are installed into Codex's skill directory as well as Claude's, so $vspawn <task> and $vopen <file> work from a Codex session.

  • More reliable Codex resume. Capturing a Codex conversation for later resume no longer gives up on a fixed timer, so it still works if you pause before typing the first message; and two Codex sessions started in the same folder can no longer end up wired to each other's conversation.

  • Model and context usage for Codex. The Info panel now shows the current model, context-window usage and the tool in flight for Codex sessions, the same as it already did for Claude, read live from the session's rollout.

Remote and terminal

  • Rebuilt remote file browser. The directory picker for remote sessions gains search-as-you-type, jump-to-path (with ~), Up / Home / Recent navigation, and inline New Folder.

  • Links open on your own machine. Clicking a link in the terminal — including an agent's login link — now opens in your local browser, from remote windows too.

  • The "reuse remote database" option is tucked away. It appears only when you Option/Alt-click Connect to Remote; a normal click always connects with an independent database.

Fixed

  • Tools are found when launched from the Dock. Starting VelaTerm from the Dock or Finder no longer left it with a stripped-down PATH, so git and other Homebrew-installed tools that agents rely on are located correctly.

  • New terminals open in the right folder. Creating a terminal from a project or group in the sidebar now opens it in that node's directory, instead of reusing the last active session's folder.

v0.1.92

Latest

Fixed

  • No more false "SSH link lost" warnings. The tunnel monitor used to treat the exit of the port-forwarding child process as a dropped link, showing the red banner and rebuilding the tunnel. In reality the forwarding listener lives in the ControlMaster process, so forwarding keeps working after the child exits — the terminal stayed perfectly usable while the UI claimed the link was down, and the rebuild would tear down a healthy connection for nothing.

    The link is now checked in two stages: when the child process exits, VelaTerm first probes whether the local forwarding port still has a listener. If it does, nothing happens. Only when the port is gone as well is the link considered dead and rebuilt. The red banner is also debounced — it appears only after the first rebuild attempt fails, so a hiccup that heals within a few seconds no longer flashes a warning.

    Genuine disconnects still recover on their own. If the ControlMaster process is killed or the network drops for an extended period, the tunnel rebuilds automatically; once retries are exhausted the banner switches to "SSH link is down", and Reconnect now restores the session — remote processes are still running and pick up where they left off.

v0.1.91

Latest

First public release. Everything below shipped in this version.

AI agents as first-class citizens

  • Built-in support for nine agents — Claude Code, Codex, OpenCode, Copilot CLI, Cursor CLI, Cline, Pi, Antigravity (Gemini CLI) and crush. Pick a type when creating a session and it launches ready to go.

  • Agent status is reported, not guessed. VelaTerm injects each vendor's official callback mechanism at launch (hooks for Claude, notify for Codex, a plugin for OpenCode, and so on), so every state change is pushed back immediately. The session tree shows a status dot for working, waiting on you, and finished-but-unseen; the sidebar filters by status and the status bar keeps a live count.

  • System notifications fire when an agent needs a permission decision or finishes a task, and clicking one jumps straight to that session. Screen detection acts as a fallback for anything without a callback.

  • Conversations survive everything. Each agent's own session id is captured and stored, so closing a session, restarting the app, or restoring an archived session all resume the original conversation — after verifying it still exists. Claude Code, Codex and Pi can also fork the current conversation into a parallel session.

  • Sessions spawn sessions. Subtasks become child sessions, spawned by the agent itself or by you, optionally in an isolated git worktree so several agents can work on the same repository at once. A graphical merge dialog brings the branches back together when they are done.

  • Missing agents get an install card with a recommended command and one-click install, with automatic path discovery afterwards. A side panel shows Claude and Codex usage quotas, and any conversation can be viewed in place or exported as a full Markdown transcript.

Session organisation

  • A three-level tree — project, group, session — with unlimited group nesting and child sessions beneath sessions. Nodes drag freely and collapse state persists across restarts.

  • Any subtree can be archived: hidden into the archive panel without deleting data, restorable at any time, and still able to resume its conversation.

  • Global content search (⌘⇧F) is backed by a SQLite FTS5 index and covers both agent transcripts and terminal output, with a result tree on the left, a linked preview on the right, and step-through navigation across sessions.

A proper terminal, first

  • Real PTYs (portable-pty, from wezterm), so vim, htop and the agent TUIs themselves all run exactly as they should.

  • Multiple tabs with arbitrary splits — each tab holds its own split tree, divided horizontally or vertically however you like.

  • Browser-style tab lifecycle: background tabs stay alive and their processes keep running, the live-tab budget is configurable, and exceeding it retires the oldest inactive session. Closing a tab is what ends a process.

  • Typing stays responsive under load, thanks to input-priority scheduling and output frame coalescing — an agent flooding the screen no longer costs you keystrokes.

  • In-terminal search (⌘F), session recording and replay, paste or drag images straight to an agent, and free switching between cmd, PowerShell and Git Bash on Windows.

Beyond the terminal

  • Run vopen <file> in any session to open a document tab in place, alongside your terminals: Markdown opens as a WYSIWYG editor and exports to vector PDF, images open in the built-in viewer, and source files get syntax highlighting.

  • A built-in browser tab can be used as a scratch tab or pinned into the project tree as a permanent node.

Remote and multi-device

  • The desktop app serves the same interface over the web, sharing one live set of sessions. Output streams to every client in real time and any of them can type — desktop and browser see and drive the same terminal.

  • End-to-end encryption with per-frame NaCl box, pairing by QR code or link, and per-device management including individual revocation.

  • Headless mode: --serve runs the same service on a server with no GUI, ready for a browser to connect.

  • SSH remote connections put remote machines in your tree. VelaTerm connects directly from the desktop, deploys a slim vela-server on the far side, and remote sessions behave like local ones. The tunnel heals and reconnects on its own.

  • Mobile: the service ships a mobile web view, and a native app shell (xterm rendering with native input and an accessory key bar) is available as well.

Platform and polish

  • macOS, Linux and Windows.

  • Automatic updates, with notarised macOS builds.

  • Light and dark themes follow the system, and running agent sessions are told about the switch through the standard terminal notification (DEC 2031) — TUI colours change instantly, no restart needed.

  • English by default, with 10 bundled languages following the system locale.

Every release ships with automatic updates — VelaTerm will offer the newest build on its own. Grab it yourself from the download page.