Releases: Villoh/tunnel-agent
Tunnel Agent 1.0.0
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage · .deb · .rpm | — |
| Linux arm64 | .AppImage · .deb · .rpm | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Added
- Edit custom provider dialog (
ProviderCatalogService,MainWindowViewModel,ProvidersView.axaml,MainWindow.axaml,MainWindow.axaml.cs,Resources/Strings.resx): custom OpenAI-compatible providers now have a pencil Edit provider action that opens an in-place popup mirroring the Add dialog, pre-filled with the provider's current name, base URL and API key. Confirming saves the changes via the newUpdateCustomProviderAsync, which rewritesproxy-config.yamland rebuilds the provider list. The dialog supports click-outside/Escape to dismiss and Enter to save. - Quotio-style Model Fallback bridge (
FallbackConfiguration,FallbackProxyService,EngineService,ConfigService,FallbackViewModel,FallbackView.axaml,MainWindowViewModel,Resources/Strings*.resx): added virtual models that map to ordered provider/model chains and automatically retry the next entry when quota/exhaustion-style responses are returned (429, selected5xx, auth/quota bodies). When Fallback is enabled, CLIProxyAPI is started behind an internal port and a lightweight local bridge owns the public port; when disabled, CLIProxyAPI runs directly so existing traffic is unaffected. The bridge rewrites chat/completions model ids, caches successful routes, publishes virtual models through/v1/models, reports active route state (N/M provider model) back to the UI, and is fully localized across all fourteen supported languages. - Fallback management UI and Local Proxy status (
FallbackView.axaml,Controls.axaml,MainWindow.axaml,ConfigurationView.axaml,ProviderIconRegistry,Resources/Strings*.resx): added a polished Fallback page with Quotio-inspired cards, icon-only actions, provider logos, add-model/add-entry flyouts, minimum-one-entry enforcement, animated expand/collapse (collapsed by default), active-route badges, Quotio credit link, and tooltips. The sidebar now shows consistent clickable status cards for CLIProxyAPI, Perplexity and Local Proxy, each with a status dot and localized tooltip; CLIProxyAPI/Perplexity route to their Providers tabs while Local Proxy scrolls directly to its CLIProxyAPI settings section. The CLIProxyAPI settings page includes a Local Proxy summary card with Providers-style endpoint copy, split route-cache enable/duration controls (including an until-restart cache mode), and internal-port details when the bridge is active. Fallback chains can be reordered with up/down controls (hidden at the ends instead of disabled), cached routes can be reset per virtual model, and individual entries can be marked as the route to use now. Virtual model header actions were reorganized (reset · delete · enable toggle), icon buttons gained hover/press scale animations, the remove-entry button is hidden when only one entry remains, and the experimental badge was removed. Destructive trash icons are now consistently red across Fallback, Home, Logs and Providers. - OAuth login feedback toast for every entry point (
OAuthService,OAuthConnectResult/OAuthConnectStatus,ProviderCatalogService,MainWindowViewModel,ProvidersView.axaml.cs,MainWindow.axaml,Resources/Strings*.resx): the "Add account → OAuth login" dialog button previously calledConnectOAuthAsyncand discarded its result, so adding an account for a provider that already had one (Claude, Codex, …) ran the flow with no visible feedback.OAuthService.ConnectAsyncnow returns a structuredOAuthConnectResult(status + dynamic detail) instead of an English string, andMainWindowViewModel.ConnectOAuthAsynccentralizes the status toast so both the provider-card button and the add-account dialog surface it. NewOAuth_Status_*strings localized across all fourteen languages. - Headless sign-in URL fallback (
OAuthService,MainWindowViewModel,MainWindow.axaml,MainWindow.axaml.cs): when the login process stays alive, the captured stdout is scanned for anhttp(s)URL (ExtractAuthUrl) and surfaced in the toast as a dedicated accent-colored, monospace "endpoint"-style row with an icon-only copy button (Copy→Check), so environments where the binary cannot open a browser can still complete the flow. The toast stays open while a URL is shown. - Auto-dismiss on successful authentication (
OAuthTokenDetector.GetLatestTokenWriteUtc,ProviderCatalogService.LatestOAuthTokenWriteUtc,MainWindowViewModel): the OAuth status toast now closes itself once the awaited provider gains a new account or its token file is rewritten (re-authenticating an existing account), detected via the auth-dir watcher against a baseline captured when the flow started, with a synchronous post-show check covering fast re-auth.
Changed
- Custom provider edit persistence and model refresh (
ProviderCatalogService,MainWindowViewModel,ModelFetchService,MainWindow.axaml,ProviderCatalogServiceTests): editing custom OpenAI-compatible providers now writes the provider name to the proxy-supportedname:field (not the unsupporteddisplay-name), validates URL/API key with the same localized error toast as Add, labels the model-selection confirm button as Save changes while editing, and restarts CLIProxyAPI after provider/model edits so Available Models refresh deterministically once the edited provider's models are registered. - Fallback master switch governs the Local Proxy lifecycle (
EngineService,FallbackViewModel,Resources/Strings*.resx): the local proxy bridge is now started/stopped solely by the Enable Fallback toggle instead of the combinedHasActiveRoutes(enabled + at least one usable virtual model). Disabling fallback now always stops the proxy, and enabling it starts the proxy even when no virtual models are configured (traffic is forwarded transparently). Adding/removing virtual models no longer restarts the engine since the bridge reads its configuration live; the engine only restarts when the toggle itself changes. TheEnable Fallbackdescription was updated to explain this across all fourteen supported languages. - Monogram fallback for unknown/custom provider icons (
ProviderIconRegistry,FallbackViewModel,AvailableModelViewModel,ProviderViewModel,QuotaProviderViewModel,ModelFetchService,FallbackView.axaml,ProvidersView.axaml,QuotaProvidersView.axaml): providers without a known brand glyph previously rendered the generic OpenAI swirl over a flat gray box, which was misleading for custom providers (whose name is user-chosen and arbitrary, e.g.Ohjbsdfjh). Unknown providers now show a monogram (the first letter of the display name) over a stable accent colour derived from the name (FNV-1a hash into a fixed palette), so custom providers are no longer mislabeled as OpenAI and are visually distinguishable from one another.ProviderIconRegistrygainedIsKnown,Monogram,FallbackColorand aGetDisplayhelper that centralizes the icon-vs-monogram decision; known brands (OpenAI, Claude, Gemini, Kimi, Cursor, …) are unchanged. Applies consistently across the Fallback page (model picker, entry rows, active-route badge), the Providers tab (configured providers and the available-models list) and the Quota providers tab. A user-selectable icon/colour picker remains possible as future work on top of this.
Fixed
- Local Proxy sidebar card now scrolls to the section content (
ConfigurationView.axaml,ConfigurationView.axaml.cs): clicking the sidebar Local Proxy status card switched to the CLIProxyAPI configuration tab but the follow-up scroll usually failed — a single delayed jump to the scroll extent raced Avalonia layout while the just-shown CLIProxy panel was still measuring, so the offset was computed against a stale/clamped extent and left the view at the top. The scroll is now retried on a short timer until the Local Proxy section is laid out and thenBringIntoView()is called on the section card, so the card reliably comes into view. - Home momentarily showed hardcoded fallback prices instead of cached OpenRouter pricing (
OpenRouterContextService,MainWindowViewModel): on launch the dashboard seeded persisted us...
Tunnel Agent 0.9.2
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage · .deb · .rpm | — |
| Linux arm64 | .AppImage · .deb · .rpm | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Changed
- Smaller Scoop zip (
.github/workflows/release.yml): theTunnelAgent-<version>-win-<arch>-scoop.zipis now produced from a dedicated single-file publish (PublishSingleFile=true,EnableCompressionInSingleFile=true,IncludeNativeLibrariesForSelfExtract=true) instead of the multi-file Velopack publish output. The zip now contains justTunnelAgent.exe(no loose runtime DLLs) and is substantially smaller. The Velopack packages are unaffected — they still use the multi-fileartifacts/publishoutput.
Tunnel Agent 0.9.1
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage · .deb · .rpm | — |
| Linux arm64 | .AppImage · .deb · .rpm | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Added
- Updater-free Scoop zip (
.github/workflows/release.yml): Windows releases now also publish a plainTunnelAgent-<version>-win-x64-scoop.zip(andwin-arm64) built straight from the publish output, without the Velopack shim,Update.exeor.portablemarker. The Scoop manifest consumes this instead of the Velopack portable zip, soUpdateManager.IsInstalledisfalse, the in-app updater stays disabled, and Scoop — not Velopack — owns updates (no more self-updates writing into the Scoop directory). The hash is exposed underplatforms.<rid>.scoopinlatest.json. - Linux
.deband.rpmpackages (.github/workflows/release.yml): Linux releases now ship native.deband.rpmpackages forlinux-x64andlinux-arm64alongside the existing.AppImage. Velopack only emits AppImages, so the release build now also stages the published app under/opt/TunnelAgentwith a/usr/bin/tunnel-agentsymlink, a.desktopentry and a hicolor icon, and packages it withfpm. The release notes installation table links the new artifacts; auto-update remains AppImage/Velopack-driven (deb/rpm are managed by the system package manager).
Fixed
- Engine stuck in
Errorafter a failed start (ProcessService,EngineService,IManagedEngine,EngineErrorKind,MainWindowViewModel,ProvidersView.axaml,Resources/Strings*.resx): when CLIProxyAPI (or Perplexity) was already running in a terminal or another app, starting the managed engine failed andStartServerAsynconly allowed (re)starting fromStopped/NotInstalled, so the Start button became a no-op and the whole app had to be restarted. The Start/Restart commands now also start fromError. A port pre-flight (TcpListener) makes the port-in-use case deterministic instead of racing the foreign instance's health response (which previously surfaced a misleading "Process exited unexpectedly"). Failures now raise a localized error toast (translated for all fourteen languages via the newToast_EngineError_PortInUse/_Timeout/_LaunchFailed/_Crashedstrings) driven by a structuredEngineErrorKind; the toast re-shows on every explicit retry, and the persistentErrorstatus label gains a tooltip with the reason so the cause stays visible after the toast fades. Addedscripts/add_resx_keys.pyto insert/translate resource keys across everyStrings*.resxidempotently. - Tests overwriting the real
TUNNEL_AGENT_PERPLEXITY_TOKEN(UserEnvironmentService,PerplexityAccountCatalogServiceTests):PerplexityAccountCatalogService.SyncEnvVarAsynccallsUserEnvironmentService.Set/Remove, which on Windows persists toHKCU\Environment. Because the static facade went straight to the OS with no injection seam, everyAddAsync/SetDefaultAsync/RemoveAsyncin the catalog tests wrote real values (token-1,token-2, …) into the developer's actual user environment and most tests never cleaned up. AddedUserEnvironmentService.SetImplementation()so tests can inject an in-memory fake (restoring the previous implementation on dispose); the catalog tests now run fully isolated and no longer touch the OS environment. - Empty CLIProxy API key written to agent configs (
AgentConfigurationService,MainWindowViewModel): whenTUNNEL_AGENT_CLIPROXY_API_KEYhad no value, the Pi and OpenCode config builders still emitted the placeholder reference (${TUNNEL_AGENT_CLIPROXY_API_KEY}/{env:...}) becauseHasApiKeywas checking the env var name (ModelEntry.ApiKey), which is never empty, instead of its resolved value. The placeholder then expanded to an emptyapiKeyand the agent failed. The builders now useHasResolvedApiKey, which resolves the variable throughUserEnvironmentServiceand falls back to"no-key"only when it is genuinely unset. Additionally, the API-key reconcile inRefreshApiKeyItemsAsyncnow heals the reverse drift: if the env var is empty butproxy-config.yaml(the source of truth) hasapi-keys, the first one is adopted as the default env var, so configs reference a key the proxy actually accepts instead of falling back to"no-key"against an auth-required proxy. - Dashboard usage chart axis dates (
DashboardViewModel): the Home usage chart axis and hover labels only switched fromHH:mmto a dated format when the data span was>= 2 days. With two calendar days of data the actual min→max span fell below that threshold, so both axis ends and the tooltips showed bare times and the days were indistinguishable. The format is now chosen from the real calendar range (HH:mmwithin a day,MM-dd HH:mmacross days,yyyy-MM-ddacross months,yyyy-MMacross years), so days, months and years can be told apart.
Added
- Logs request model filter (
LogsViewModel,RequestLogEntry,LogsView.axaml,Resources/Strings*.resx): the Logs → Requests tab now exposes a model filter alongside the provider filter and shows each request asProvider · modelabove the path. Request search and CSV export also include the model.
Removed
- Aider agent (
AgentCatalog,AgentConfigurationService,Strings*.resx,README.md): removed Aider from the Agents window. Its catalog entry, the env-var config generation (AiderEnv/EnvExportRawand the"aider"branches inGenerateRaw/WriteConfigSync), and the now-unusedAgent_aider_Descriptionlocalization strings across all fourteen languages were dropped. - API-key account labels (
AppSettings,ConfigService,ProviderCatalogService,MainWindowViewModel,MainWindow.axaml): removed the per-key label feature for upstream API-key accounts. Labels were written toproxy-config.yaml, but CLIProxyAPI has no per-keylabelfield and strips it whenever it rewrites/normalizes the config (so labels silently disappeared on engine start, and were lost entirely when a native API-key provider was disabled). Since the label added no functional value, it was dropped instead of reworked: the label input is gone from the add-account and add-custom-provider dialogs,ProviderAccountSettings.Labeland the label read/write paths inConfigServiceare removed, andAddAccountAsync/AddCustomProviderAsyncno longer take a label. API-key rows now display the masked key. (Perplexity account labels are unaffected.) - Dead
CustomProviderCredentialStore(ProviderCatalogService,ConfigService): removed the unusedopenai-compat-*.jsoncredential store and its one-timeMigrateLegacyCredentialStoreAsyncmigration (which read, migrated, and deleted the legacy files), plus the unusedcredentialStoreconstructor parameter onConfigService. Credentials live inproxy-config.yaml.
Tunnel Agent 0.9.0
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Fixed
- Engine update toast localization (
MainWindowViewModel,Resources/Strings*.resx): the "<engine> <version> is ready to install." body of the CLIProxyAPI/Perplexity update toast was hardcoded in English while its title was translated. It now resolves through the newToast_EngineUpdateAvailable_Bodyformat string, translated for all fourteen supported languages.
Added
- Dashboard summary by provider or model (
DashboardViewModel,DashboardView.axaml,Resources/Strings*.resx): the usage summary table now has a sliding tab to group rows by provider or by model, reusing the same per-row metrics (calls, success/fail, rate, tokens, estimated cost, last request). The headline cards and chart remain provider-agnostic aggregates. AddedDashboardView_Summary_ByProvider,DashboardView_Summary_ByModelandDashboardView_Summary_Modeltranslations for all fourteen languages. - Dashboard/Home usage view and usage-backed requests (
DashboardView,DashboardViewModel,LogsViewModel,UsageChart,UsageService,UsageStore,UsageEvent,ModelPricing,MainWindow): added Home as the default sidebar section with usage range tabs, headline metrics, provider summary, an interactive hoverable usage chart, and CLIProxyAPI usage telemetry backed by SQLite persistence. Tunnel Agent enables CLIProxyAPI usage statistics, continuously drains the destructive/v0/management/usage-queue, deduplicates events by hash, estimates model token costs, parses cache/reasoning token details, and keeps persisted history across restarts. Dashboard and the Logs → Requests tab now use this telemetry store as their source of truth, while Logs → Proxy logs remains a raw log-file view with separate clear/delete actions and its own renamed auto-refresh setting; clearing usage history is available from Dashboard and Requests and deletes only stored usage events. - Dynamic model pricing with on-disk cache (
OpenRouterContextService,ModelPricing,DashboardViewModel,MainWindowViewModel): dashboard cost estimates resolve per-model prices from OpenRouter's live/v1/modelslist (input, output, cache-read and cache-write rates), falling back to a built-in table for models OpenRouter does not list. This avoids mispricing models newer than the table, which previously fell back to an older prefix match. The fetched model map is persisted toopenrouter-models.jsonunder the local data directory and seeded into memory on startup (instant, offline-capable), refreshing from the network only when the cache is missing or older than 24h. Agents configuration reuses the same cached map for context window, reasoning and image-modality metadata. - Per-provider cost accounting (
ModelPricing): cost estimation distinguishes cache-creation (write) from cache-read tokens and applies the correct token model per provider — Anthropic-style events billinputas cache-free with separate write/read rates, while OpenAI-style events use the aggregate-cached subtraction. - Dashboard/Home localization across all languages (
Resources/Strings*.resx,MainWindow.axaml,DashboardView.axaml,LogsView.axaml): the Home/Dashboard view and the clear-usage-history dialog now ship full translations (DashboardView_*,Sidebar_Home,Dialog_ClearUsageHistory_*) for all fourteen supported languages instead of only English and Spanish, and the clear-usage confirmation dialog uses its ownDialog_ClearUsageHistory_Cancelkey. The shared clear-usage-history tooltip (used on Home and the Logs → Requests tab) was renamed fromLogsView_ClearUsageHistoryTooltipto the view-neutralCommon_ClearUsageHistoryTooltipand translated for every language.
Tunnel Agent 0.8.0
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Added
- Pi model reasoning flag (
OpenRouterContextService,AgentConfigurationService): when configuring Pi, each model's reasoning support is now resolved from OpenRouter's public/v1/modelsendpoint (presence of the per-modelreasoningobject or"reasoning"insupported_parameters) and written as"reasoning": trueper-model inmodels.json. The field is omitted for models without reasoning support, so it does not add redundant noise to the config. The manual preview resolves the same flag, so what you see matches what Apply writes. - Custom provider model selection (
UpstreamModelFetchService,MainWindowViewModel,ConfigService,ProviderSettings,MainWindow.axaml): adding a custom OpenAI-compatible provider now probes{base-url}/models; on HTTP 200 a model-selection popup lists the upstream models (search + select-all, all unchecked, at least one required) and the chosen models are persisted under the provider'smodels:block inproxy-config.yaml. A non-200 or unreachable URL aborts the add and shows a top-right error toast without creating the provider. - Edit custom provider models (
ProviderCatalogService,MainWindowViewModel,ProvidersView): custom provider rows now have an edit-models button that re-fetches{base-url}/modelsand reopens the selection popup with the currently exposed models pre-checked, so newly released or changed models can be added/removed without recreating the provider. The button shows a per-provider loading spinner and is disabled while the upstream fetch is in flight, so it no longer appears to hang on click. - Upstream API key providers (
ProviderCatalogService,ConfigService,ProvidersView,MainWindow): added native API-key flows for Claude, OpenAI, and Gemini plus custom OpenAI-compatible providers stored inproxy-config.yaml, with add/edit dialogs, duplicate-key toast feedback, custom-provider add/remove actions, and localized UI strings. - Custom provider key deletion (
ConfigService,ProviderCatalogService): deleting the last API key from a custom OpenAI-compatible provider now keeps the provider entry but removes the entireapi-key-entriesblock, instead of deleting the provider or writing an emptyapi-key/labelplaceholder. - Custom provider API-key editing (
ProviderCatalogService,MainWindowViewModel,ProviderViewModel,MainWindow.axaml.cs): editing an existing API key no longer shows the duplicate-key alert, label-only edits refresh the UI immediately, and clearing a label persists the empty label state back toproxy-config.yaml. - Quota account filtering (
MainWindowViewModel,QuotaFetchService): API-key accounts are excluded from OAuth quota views and refresh loops so they no longer collide with OAuth token lookup or appear as quota-capable accounts.
Changed
- Provider credentials source of truth (
ConfigService,ProviderCatalogService): upstream provider API keys, labels, base URLs, disabled custom providers, and OpenAI-compatible provider entries now round-trip throughproxy-config.yaml; legacyopenai-compat-*.jsonfiles are migrated and removed. - Provider/account display (
ProviderViewModel,ProvidersView): built-in providers now display as Claude, OpenAI, and Gemini; custom providers show their base URL on the provider row; API-key rows show the label with a maskedxxxx...yyyykey underneath (or only the masked key when unlabeled); API-key credentials display asN API key(s), OAuth credentials asN connected account(s), and mixed providers asN connected account(s) / N API key(s); per-key enable toggles are hidden for API-key credentials that CLIProxyAPI cannot disable individually. - Gemini provider scope (
ProviderCatalogService,ConfigService,OAuthService,QuotaView): Gemini support is now API-key-only viagemini-api-key; removed Gemini CLI OAuth/login, agent configuration, and quota UI paths after CLIProxyAPI dropped Gemini CLI support. - Unified alert/toast system (
Themes/Brushes.axaml,Themes/Controls.axaml,Controls/ToastBehavior.cs,MainWindow,ConfigurationView,ProvidersView,MainWindowViewModel): replaced the previous ad-hoc, semi-transparent banners with a single cohesive alert system — info / warning / error tonalities on solid surfaces with severity-colored icons and titles, larger padding and type, and consistent light/dark brushes. Every transient toast (provider status, configuration status such as a duplicate listen port, management-key-repaired, engine/app “no update available”, and the bottom-center app/engine “update available” notices) now uses this styling, stacks in a window-pinned region so it stays visible regardless of page scroll, fades in/out via the reusablectrl:Toast.IsOpenbehavior (animating opacity and collapsing from layout once hidden), and auto-dismisses where appropriate. Toasts were moved out of the scrollable provider/configuration views into shared window-level overlays and dismiss commands, removing the old inline banners and floating cards.
Fixed
- System default language switch (
LocalizationService,MainWindowViewModel): switching from a manually-selected language back to System default now correctly follows the OS language.SetCulturemutatesCultureInfo.CurrentUICulture, so resolving the system language from it returned the previously-selected override instead of the real OS culture. The OS UI culture is now captured once at process start (LocalizationService.SystemCulture) and used to resolve System default. - Provider row count localization (
ProviderViewModel,Resources/Strings*.resx): the provider sub-line (N connected account(s),N API key(s), and the mixed… / …form) now resolves through localized resources and refreshes on language change instead of showing hardcoded English. - Built-in Gemini provider actions (
ProviderViewModel,ProviderCatalogService): the edit-models and remove-provider buttons no longer appear on the built-in Gemini API-key provider —IsCustomProvideris now an explicit flag set only for user-added OpenAI-compatible providers instead of being inferred from API-key support. - Debug diagnostics startup (
MainWindow.axaml.cs): debug builds now initialize Avalonia diagnostics conditionally so release deployments do not require the diagnostics assembly.
Tunnel Agent 0.7.2
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Changed
- System language mode (
LocalizationService,MainWindowViewModel): the Language combo now includes System default;Language: nullremains the explicit setting for following the current OS language, while selecting a specific locale stores that locale as a manual override.
Tunnel Agent 0.7.1
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Fixed
- Detected language persistence (
MainWindowViewModel,SettingsService): first-run system language detection is now saved tosettings.jsoninstead of leavingLanguageasnull, keeping the selected Language combo and persisted settings in sync.
Tunnel Agent 0.7.0
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Added
-
Additional UI languages (
Resources/Strings.it-IT.resx,Strings.uk-UA.resx,Strings.ru-RU.resx,Strings.hi-IN.resx,Strings.ko-KR.resx,Strings.tr-TR.resx,Services/LocalizationService.cs): added Italian, Ukrainian, Russian, Hindi, Korean, and Turkish translations to the Language combo, bringing the localized UI to 14 languages. -
Runtime localization and language selector (
Resources/Strings*.resx,Services/LocalizationService.cs,Services/LocExtension.cs,Views/*.axaml): added runtime localization across the Avalonia UI for English, Spanish, Portuguese (Portugal), French, German, Simplified Chinese, Japanese, and Arabic, including the new Language combo under Configuration → General → Theme, persisted language preference, localized formatted strings, provider/agent descriptions, tray popup, overlays, dialogs, and quota/provider views.
Changed
-
Localization infrastructure (
Resources/Strings*.resx,Services/LocExtension.cs): replaced hardcoded UI text with{l:Loc ...}/{l:LocFormat ...}bindings backed by resx resources, with live refresh when the selected language changes. -
Localized configuration combo boxes (
MainWindowViewModel,ConfigurationView.axaml): theme mode and routing strategy combo boxes now display localized labels while preserving their stored internal values. -
Listen port editing (
MainWindowViewModel,ConfigurationView.axaml): the listen port is now edited as a draft and applied with an explicit Apply button (enabled only for a valid, changed port) instead of saving on every keystroke; the row is laid out as port, Apply, then Reset. -
Engine update toast layout (
Views/MainWindow.axaml): the toast title can wrap to two lines so longer localized titles (for example Spanish) are not clipped.
Fixed
-
Configuration update badge (
MainWindowViewModel): the orange update indicator now stays visible when any managed engine has an available update, instead of disappearing when switching focus to another engine tab. -
Sliding tab localization refresh (
Controls/SlidingTabBar.cs): tab titles and tooltips now stay bound to their localized headers, so configuration tabs such as General update when the language changes. -
Runtime localization gaps (
LogsViewModel,QuotaFetchService,ProviderViewModel): provider filters, quota reset countdowns, model selection labels, Chinese agent labels, and generated provider/agent texts now refresh correctly when the language changes. -
Duplicate engine port (
MainWindowViewModel,ConfigurationView.axaml): applying a listen port already used by the other engine is now blocked and surfaces an error toast instead of silently allowing a conflict.
Tunnel Agent 0.6.3
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Changed
-
Tray usage popup primary action (
Views/TrayUsagePopup.axaml): Open app moved from the footer to the bottom of the left rail (always visible) as the popup's primary action, and Configuration moved to the footer, since opening the full app is the more common action. -
Tray usage popup Home view (
Views/TrayUsagePopup.axaml(.cs),MainWindowViewModel): the popup now opens on Home, which combines the engine status/controls with a Usage section below listing every connected provider and its quota usage (plan badge, usage bars, per-account and refresh-all controls), or a No accounts to show empty state when nothing is connected. The separate Usage rail button was dropped — the per-provider rail icons still drill into a single provider's quota. This makes Home a single at-a-glance dashboard and matches the main Quota window's empty state.
Fixed
- Tray usage popup forgetting the last view (
Services/TrayService.cs): the popup forced the Home view on every open, so switching to a provider's quota and reopening always reset to Home. The forced reset was removed; since the popup window and itsDataContextare reused, it now reopens on the last viewed tab (Home or the selected provider), while still defaulting to Home on the first open after launch.
Tunnel Agent 0.6.2
Installation
| Platform | Installer | Portable |
|---|---|---|
| Windows x64 | Setup.exe | .zip |
| Windows arm64 | Setup.exe | .zip |
| Linux x64 | .AppImage | — |
| Linux arm64 | .AppImage | — |
| macOS x64 (Intel) | .pkg | .zip |
| macOS arm64 (Apple Silicon) | .pkg | .zip |
Existing installations update automatically via Velopack.
Fixed
-
App update toast dismiss button (
MainWindowViewModel): dismissing the "Tunnel Agent update available" toast now refreshes the computed visibility state immediately, so the toast hides when Dismiss is clicked. -
Update toast stacking (
MainWindow.axaml): Tunnel Agent and engine update toasts now share the same bottom-center stack and width, so simultaneous update notices no longer overlap or appear misaligned.