mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-28 09:12:08 +08:00
ff1ce92facfd17ef66d4e8d150b224a94741c80a
155
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ff1ce92fac |
feat(dns): remember override state per profile
Save the DNS override switch and session confirmation per profile so automatic protection only disables the affected profile. Preserve the legacy switch as the initial preference and show the profile scope beside the settings gear and in the DNS editor. Refs #7993 |
||
|
|
bffe91db5e |
fix(service): prompt reinstallation after path permission rejection
Address #7983 with a recovery dialog for Windows service error 1003, including startup refusals received before the UI subscribes. Reinstall the service and require service mode before reporting recovery. |
||
|
|
7bf8e1dcf5 | feat(enhance): warn when extensions write app-owned keys | ||
|
|
07825afb1e |
Reapply "feat(dns): protect provider DNS from unconfirmed overrides (#7902)"
This reverts commit
|
||
|
|
df79ed3efb |
Revert "feat(dns): protect provider DNS from unconfirmed overrides (#7902)"
This reverts commit
|
||
|
|
9a879dd8d8 |
fix(service): fall back to elevated sidecar on path permission rejection
Preserve TUN settings and restore proxy operation after fallback. Deliver fallback notices after UI subscription and stop retrying deterministic bundle refusals. Publish fallback state atomically and avoid conflicting service startup notifications. |
||
|
|
bea03e1a09 |
fix: preserve custom TUN fields and sync service provider caches
Limit GUI authority to saved TUN fields while preserving custom overrides. Sync provider caches after service startup, reloads and updates. Publish copies atomically with session, runtime and cache metadata checks. |
||
|
|
35a2b6c75c |
feat(dns): protect provider DNS from unconfirmed overrides (#7902)
Fixes #7292 |
||
|
|
695fadf21e |
fix(security): restrict external URL opening
Close: 7800 |
||
|
|
1b75ea34f9 |
fix(core): upgrade mihomo atomically instead of letting it self-update
mihomo's updater truncates its own running executable in place; macOS kills that under Hardened Runtime and leaves a 0-byte core. Verge now downloads the release, verifies a staged copy next to the target, and renames it into place, which never touches the inode the running core executes from. Closes #6834 |
||
|
|
807f9a206d | chore: trim excessive comments | ||
|
|
daadb126e0 |
feat: allow manually unfixing proxy nodes (#7756)
* feat(proxy): add ability to clear persisted node selection for groups * feat(hooks): make proxy selection operations asynchronous * chore: update tauri-plugin-mihomo deps * refactor: rename clear_selected_node to forget_selected_node * refactor(hooks): rename isFixed to isFixedProxy in useProxySelection * docs: update changelog with manual node cancellation support * chore(layout): remove dev-only mihomo websocket debugging interval |
||
|
|
22947632c0 |
refactor: Rewrite and improve sysproxy logic (#7744)
* fix(cmd): preserve anyhow context in coded errors Use alternate error formatting so coded failures retain the full anyhow context chain without changing their wire format. * fix(macos): skip redundant proxy disable writes When both proxy modes are off, read macOS state first and skip networksetup if the OS is already clean. Update the guard target only after a successful write. * feat(proxy): classify system proxy failures Attach stable, actionable proxy failure codes to anyhow chains while preserving the original diagnostic causes. * feat(cmd): return structured command failures Replace encoded error strings with serializable code and detail fields, and update frontend notice consumers to handle the structured shape. * fix(scripts): use the js-yaml namespace import Import js-yaml through its ESM namespace so the i18n cleanup script can access load and dump. * feat(proxy): localize classified proxy failures Map privilege and direct-fallback codes to localized explanations, and let mapped causes outrank generic operation keys in notices. * fix(ui): bound notice text and render failure details Limit resolved notice text without truncating clipboard content, and normalize structured failures embedded in translation parameters. * feat(proxy): persist unseen proxy failures Store unresolved classified failures by code, notify the frontend when the table changes, and show each failure sequence once when a visible window can receive it. * feat(proxy): report tray and hotkey toggle failures Record classified failures from tray and hotkey proxy toggles so they appear when a visible window is available. * fix(ui): restore the proxy switch after failed toggles Refresh frontend proxy state after a failed toggle so the switch reflects the rolled-back configuration. * feat(proxy): stop the guard after repeated failures Report guard outcomes, stop after the failure threshold, and persist the classified failure for the frontend. * fix(macos): preserve proxy during service handoff Stop a sidecar being handed to the service without clearing proxy state that the new owner must inherit. * feat(macos): classify misplaced sidecar state Distinguish a refused sidecar proxy write from a machine that still needs the privileged service installed. * feat(ui): recover misplaced sidecar notices Offer a restart action for macOS proxy failures caused by a ready service while the core still runs as a sidecar. * feat(ui): install the service from proxy notices Let privilege notices install the macOS service, restart the core, and report the runtime mode that was actually reached. * feat(cmd): attach requested proxy operations Carry the requested proxy direction with structured command failures when the originating command knows it. * feat(sysproxy): drain guards before OS access Wait for the local proxy guard to stop before OS reads, service handoff, or final writes, and refuse transitions when it does not drain. * feat(sysproxy): recover partial proxy writes Use write progress to choose whether to restore the old guard or compensate with a disabled proxy state, while preserving actionable errors. * feat(sysproxy): skip already-applied proxy writes Compare macOS proxy snapshots with global, PAC, and disabled targets so matching state avoids redundant privileged writes. * feat(proxy): report background proxy failures Persist and surface classified proxy failures from lifecycle paths that have no direct caller awaiting the result. * feat(ui): move proxy recovery into a dialog Guide users through installing or switching to the service after a refused proxy write, and suppress duplicate toast reports. * fix(ui): close proxy dialog after service recovery Dismiss the recovery dialog once the core reaches service mode, even when the original proxy request remains pending. * feat(ui): retry proxy request after service recovery Replay the requested proxy direction after the core reaches service mode, while leaving incidental restores unchanged. * fix(proxy): refresh state after successful apply Publish the proxy refresh from the shared apply path after releasing the lifecycle lock, and remove the tray-specific duplicate. * feat(ui): show proxy recovery progress Display installation, restart, and proxy-apply stages while keeping the primary action spinner visible during recovery. * feat(ui): route unavailable TUN through service recovery Let the TUN switch request service recovery and restore its requested state after the core restarts in service mode. * fix(ui): avoid duplicate TUN recovery errors Roll back deferred TUN toggles without reporting an error, and publish configuration refreshes from the transaction commit path. * chore: update changelog & pinlock * fix(core): resolve platform-specific clippy warnings * fix(core): detect Windows wildcard TCP conflicts Windows permits a specific exclusive bind beside an existing non-exclusive wildcard listener. Consult the system TCP listener table so the probe reports that overlap as a conflict. |
||
|
|
3d8d7731e1 |
fix: node selection persistence (#7620)
* fix(core): put the user's node choices back when the core starts mihomo restores the node picked in each group from the `cache.db` it keeps in the directory it was started against. The app relied on that entirely, and it does not hold: `profile.store-selected` comes from a merge template a user is free to replace, and a service older than the durable runtime generation starts every core in a directory nothing has ever run in. Both end the same way — every `select` group falls back to the first entry in its `proxies:` list. The app already knows better. It records each selection in the profile, and `activate_selected_nodes` already reconciles that record against the running core — it was only ever called when switching profiles, never when a core came up. Call it from the three places a core process becomes ready. Repeat calls supersede each other, so no coordination is needed between the start paths. That makes the profile authoritative, which turns any selection it does not know about into one the next start silently undoes. The chain proxy moved a group without recording it, so recording is now one shared hook that both it and the proxy list go through. Restoration is spawned, not awaited: it polls the core until its groups are readable, and a start must not wait for that. * fix(tray): record the node the tray switched to Restoring the profile's selections when a core starts made the profile authoritative, which turns any selection it never learned about into one the next start silently undoes. The proxy list and the chain proxy both record; the tray did not. So switching node from the tray survived only until the next restart, and then reverted to whatever the profile last knew — a regression the restoration itself introduced, and only for the tray. `record_selected_node` is the backend counterpart of the frontend's `useRecordSelection`. Failing to record does not fail the switch: the core is already on the new node by then, and reporting the switch as failed would be wrong. It is logged instead. * fix(core): restoring selections must not prune what the core has not loaded Putting the profile's selections back when a core starts reused the reconciliation written for profile switches, and that one also *repairs*: a record whose group is absent from two snapshots a second apart is dropped, and the reduced list is written to profiles.yaml. After a profile switch the configuration is loaded, so absence is evidence. After a core start it is not — a provider-backed group can be empty or missing for seconds — and a record pruned on that evidence is gone for good, because the provider finishing later cannot bring it back. Restoring now keeps the records and only applies what it can match; pruning stays with the caller entitled to conclude it. The restore is also asynchronous: it reads the profile, polls the core until its groups are readable, then puts its selections. A choice the user makes inside that window is newer than what it captured, so letting it finish pushed the core back to the older node while the profile already held the newer one. Recording a selection now supersedes any activation in flight — from the tray, and from the UI and chain proxy through `patch_profile`. * fix(core): activate the selections of the profile that is actually running The activation worker read the profiles draft. A profile switch stages its target there before validating it, so a switch that fails — leaving the previous profile running — could still have handed an activation the rejected profile's selections, which it would then apply to whichever same-named groups the running profile has. Reading the committed state removes the window. The switch that succeeds commits before it activates, so nothing changes for that caller; what changes is that a restore running at core start can no longer observe a switch that never happened. * fix(core): stop a restoration from undoing a choice made while it runs Two gaps in making the profile authoritative, both found by adversarial review of the commits that introduced it. A restoration reads the profile's selections once, then polls the core until its groups can be read — seconds, on a cold start. A selection made inside that window is newer than what the restoration is carrying, and nothing told the restoration so: it went on to apply the older choice over the user's. The UI accepted the new node and traffic snapped back to the old one, with the profile and the running core then disagreeing. Recording a selection now abandons any restoration still in flight, through the same generation counter every other superseding caller uses. The other gap is the home card in global mode, which passed `skipConfigSave` and so recorded nothing. That was harmless while nothing re-applied the profile; now it means the next start undoes the choice. It was the only caller that ever set the flag, so the flag is gone rather than flipped — a parameter whose one use was a bug is not worth keeping. * fix(core): wait for the selections that can be put back, keep trying for the rest Two gaps in restoring the profile's selections when a core starts, both found by adversarial review. Restoring re-checked once, a second later, and stopped. That is enough after a profile switch, which happens with the configuration already loaded. A core start is the opposite case: a provider-backed group is present but empty until its provider finishes loading, and a `select` can fail while the core is still settling. Neither produces an activation, so the restore reported success having applied nothing and the group stayed on the first entry of its `proxies:` list — the outcome restoring exists to prevent. It now keeps looking, on a deadline, at what the core is actually on rather than at what it managed to send. Restoring was also spawned, and the caller enables the system proxy the moment the start returns — so traffic could be pointed at a core still on the wrong node. The first pass is now awaited, bounded, and the rest keeps settling in the background: a core that will not answer delays a start rather than blocking it, because being proxied through the wrong node beats not being proxied at all. TUN is deliberately not covered, and cannot be by anything here: it is configured in the core's own file, so it carries traffic from the moment the process starts. What puts a TUN user on the right node from the first packet is the core's own `cache.db`, which is why the service keeps an owner's runtime generation across restarts. `supersede_selected_activation` and `cancel_selected_node_activation` were the same function under two names, added independently for the same reason, and `patch_profile` called both. One survives, called once, after the profile is written — the only placement that needs to exist, since an activation that read the older profile is cancelled by it and one starting afterwards reads the newer one. * fix(core): record a selection by naming it, not by resending the list Recording a node selection sent the whole selection list, built from the profile the frontend had rendered. Two selections made before that list refreshed were therefore built from the same stale snapshot, and the later write dropped the earlier group's choice. Since a core start re-applies whatever the profile holds, the dropped one came back on the next restart — the profile and the running core disagreeing, in the direction the user would least expect. The tray already avoided this, because it went through `record_selected_node`, which merges one group into the profile inside `with_data_modify`. Exposing that as a command and pointing the frontend at it leaves one way to record a selection instead of two, and removes the list from the wire: what a caller knows is the group and the node, and that is now all it says. `useRecordSelection` no longer reads the profile at all, which also makes it stable across renders rather than changing identity whenever the profile does. * test(core): make every way of declining to stage answer for itself `CoreRestarted` was added to `StageRejection` upstream and reached production without a test. It inherited the right verdict — every `RestartRequired` is matched together — but nothing said so, and nothing would have noticed if it had inherited the wrong one. The list of rejections now goes through a wrapper whose `match` is exhaustive, so the next variant added upstream fails to compile here. That is the part worth having: it does not prove the list is complete, but it does mean nobody can add a way to decline without being sent to this test to say what it should lead to. * build(deps): pin the service protocol to v2.6.1 The pin tracked `feat/stage-runtime` because the protocol change it carried had no tag yet. It has one now, and a branch pin makes the build irreproducible: an upstream force-push silently changes what this compiles against. v2.6.1 carries the runtime generation an owner keeps across restarts, which is what lets the core hold on to the `cache.db` its node selections and fake-ip leases live in. The protocol itself is untouched — epoch, revision and both compatibility floors are byte-identical to v2.6.0 — so this is a fix release in both directions: an older service still works with this app, and this app still works with an older service, only without the durable generation. The lockfile change is the two lines that name it. Reaching for `cargo update -p` instead re-resolved a subtree and quietly downgraded `windows-sys`, `windows-core` and `getrandom` along the way. |
||
|
|
c90de1355e |
refactor: core runstate (#7602)
* refactor(core): introduce core::runstate as the owner of Run State
"Is the Service available?" had five caches and three predicates, and
prepare_startup consulted all three within thirty lines. This lands the
foundation for collapsing that, with no behaviour change: the old owners
now delegate into one store.
The state model splits observation from intent. Five of ServiceStatus's
ten variants were never observations — cmd/service.rs passed
ServiceStatus::InstallRequired as the "which operation do you want"
argument — which is why narrowing to ServiceInstallState had to be lossy.
ServiceHealth now records what we saw, PendingAction records what the
session asked for, and ServiceStatus::from_run_state flattens the pair
for call sites that still expect the single slot.
Reads differ only in freshness: state() is cached, settled() waits for an
in-flight privileged operation, probe() forces IPC. What an answer means
lives on the snapshot (service_usable, tun_capable), so callers stop
writing their own formulas — the tray now asks tun_capable() instead of
recomputing "admin or ready".
Effects sit behind RunStateEnv with two adapters, RealEnv and FakeEnv.
That retires the seven tests that hand-built a private ServiceManager
struct literal, and makes the probe and detection paths testable for the
first time.
Two distinctions are now explicit rather than incidental:
- A single failed probe is not an observation and leaves confirmed
health intact; exhausting a poll's whole retry budget is one and
records unavailable. Both are tested, protecting
|
||
|
|
e599a9d02c | fix(service): avoid sticky availability probes | ||
|
|
7796259b03 |
feat: automatic mixed port fallback (#7579)
* feat: automatically select an available mixed proxy port * fix: coordinate listener port changes * fix: detect Windows listener port conflicts |
||
|
|
23dda47641 |
feat: add launch guard and secure multi-user service ownership (#7569)
* feat(service): isolate macOS launch and owner runtime * ci(windows): run owner security tests * chore(deps): use kode-bridge v0.4.1 tag * fix(macos): classify installed service state * fix(macos): classify marked unavailable service * fix(macos): gate core startup on service migration * fix(macos): scope service init to supported platforms * feat(macos): prompt before migrating installed service * fix(macos): shorten sidecar IPC path * build(service): pin helper protocol and artifacts * fix(core): require confirmed service and sidecar readiness * fix(macos): harden launch roots and singleton state * fix(ui): refresh migration state before restart * fix(macos): linearize service migration lifecycle * fix(ui): keep service migration state fresh * feat(service): track authenticated owner sessions * fix(service): preserve newer owner sessions * feat(macos): route service proxy changes through helper * fix(macos): serialize service proxy guard * fix(macos): close service proxy owner lifecycle * fix(macos): close remaining proxy stop races * fix(app): do not cancel controlled service stop * fix(lifecycle): keep controlled updates cancellation-safe * fix(macos): stage dev core for service * test(macos): exercise staged core cleanup * fix(dev): await controlled macOS exit * chore: update changelog * fix(macos): recover sidecar after service install failure Allow the existing sidecar to continue when service installation leaves the manager in InstallRequired, then settle the session state as SidecarAllowed. Show neutral status text while the migration dialog waits for its final state. * fix(macos): stage dev service tools before elevation * fix(macos): localize launch guard prompts * fix(service): address cross-platform integration issues * feat: support seamless service migration * fix: pass Windows service installer path safely * fix(prebuild): derive service release from Cargo dependency * fix(dev): preserve service installation state * fix: resolve clippy warnings in service lifecycle |
||
|
|
304f5bade9 |
perf(proxy): consolidate proxy data into a single IPC (#7542)
* feat(proxy): build deterministic proxy view * feat(proxy): expose ordered proxy view command * feat(proxy): add proxy view client contract * fix(lint): allow Node test files * feat(proxy): switch UI to ordered proxy view * fix(proxy): harden ordered proxy view consumers * fix(proxy): compare chain duplicates by current id * fix(proxy): release mihomo guard after fetch * fix(proxy): preserve semantic selections across refresh * fix(proxy): block global chain without GLOBAL * fix(proxy): handle proxy view edge states |
||
|
|
12aa989af1 | fix(knip): remove unused proxy order export | ||
|
|
f09aef170d | fix(proxy): preserve runtime proxy group order | ||
|
|
d144e78aeb | perf: streamline profile switching | ||
|
|
7ca20fc4ed |
refactor: knip cleanup (#7468)
* chore(frontend): expand Knip reports * chore: remove unused Mihomo changelog sync script * refactor: remove unused value exports * refactor: remove unused type exports * refactor: remove circular route dependencies * chore(frontend): move Knip scope to config * chore(i18n): remove stale portable update message |
||
|
|
562828e14d |
fix: provider proxy delay check (#7456)
* refactor(proxy): support delay testing for provider-based proxies * style: remove debug console logs * docs: update changelog * feat(services): merge provider nodes into records in calcuProxies --------- Co-authored-by: Tunglies <tunglies.dev@outlook.com> |
||
|
|
5a96fdd9a2 |
fix: harden home clash-mode card against /configs read failures
Recover from controller read/switch failures on the mode card instead of showing a bare "communication error": - fall back to the tolerant get_clash_mode command (then runtime config) when the live /configs mode is unavailable, - optimistically reflect the clicked mode and write it through to the getClashConfig cache so a failed refetch can't flash back the old value, - surface patch failures via showNotice on both the home card and the proxies page (patchClashMode can now reject), and - revalidate getClashMode/getRuntimeConfig on refresh-clash-config so a once-empty fallback can recover. |
||
|
|
22c516f550 |
feat(sysinfo): return structured system info (#7122)
* feat(sysinfo): return structured system info * refactor: simplify SystemInfo conversion and enhance Platform struct --------- Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com> |
||
|
|
b85b435e00 |
refactor: structure config validation outcomes
- Replace boolean/string validation results with structured ValidationOutcome values across config validation, profile switching, DNS validation, and script validation. Callers can now distinguish valid, invalid, skipped, and busy states, with invalid results carrying an error kind and message. - Route core config updates through structured outcomes and checked forced updates. Generation and validation failures now discard runtime drafts and surface validation failures instead of relying on empty success messages. - Preserve existing frontend ergonomics by keeping boolean service wrappers where callers only need success, while direct DNS and script validation consumers receive ValidationOutcome. Failed profile editor saves reload the backend-restored file content and synchronize Monaco models so reopened editors show the restored state. |
||
|
|
51578c03b0 | fix: URL test url | ||
|
|
c672a6fef3 |
refactor: lint (#6511)
* refactor: lint * chore: remove eslint-plugin/config-prettier |
||
|
|
321017413d | chore: replace node test with cp.cloudflare.com | ||
|
|
ec6f259794 | chore: replace node test with 1.0.0.1 | ||
|
|
ddf455508f | chore: replace node test with 104.16.132.229 | ||
|
|
cf9f235270 | chore: replace node test with 8888 | ||
|
|
c30eaa3678 |
refactor: reduce webview lock contention (#6271)
* refactor: replace handle::Handle::get_window() with WindowManager::get_main_window() in multiple files * refactor: enhance WindowManager to return window state alongside the main window instance * refactor: update useProfiles and ProfilePage to support profile overrides and improve patchProfilesConfig return type * refactor: enhance handle_success to check main window existence before notifying profile changes * refactor: simplify get_main_window_with_state by using pattern matching and improve window state handling * refactor: fix window activation by removing unnecessary reference in activate_existing_main_window * refactor: remove redundant macOS conditional for window_manager import |
||
|
|
afa591c279 | chore: replace node test with 1.1.1.1 | ||
|
|
16c3dcc616 | fix(proxy): check if proxy port is in use #5891 | ||
|
|
bd8eccdcea |
feat(backup): add local backup import flow (#5669)
* feat(backup): add local backup import flow * refactor(backup): robustify history listing and propagate import error details * docs: Changelog.md |
||
|
|
bae65a523a | chore: rename files to kebab-case and update imports | ||
|
|
ecc272aa20 | feat: integrate tauri-plugin-clipboard-manager and add system info commands (#5593) | ||
|
|
caca8b2bc4 | refactor: debugLog for frontend (#5587) | ||
|
|
c8aa72186e |
chore: i18n (#5276)
* chore: notice i18n * feat: add script to clean up unused i18n keys * chore: cleanup i18n keys * refactor(i18n/proxies): migrate proxies UI to structured locale keys * chore: i18n for rule module * chore: i18n for profile module * chore: i18n for connections module * chore: i18n for settings module * chore: i18n for verge settings * chore: i18n for theme settings * chore: i18n for theme * chore(i18n): components.home.* * chore(i18n): remove unused i18n keys * chore(i18n): components.profile.* * chore(i18n): components.connection * chore(i18n): pages.logs.* * chore(i18n): pages.*.provider * chore(i18n): components.settings.externalCors.* * chore(i18n): components.settings.clash.* * chore(i18n): components.settings.liteMode.* * chore(i18n): components.settings.backup.* * chore(i18n): components.settings.clash.port.* * chore(i18n): components.settings.misc.* * chore(i18n): components.settings.update.* * chore(i18n): components.settings.sysproxy.* * chore(i18n): components.settings.sysproxy.* * chore(i18n): pages.profiles.notices/components.providers.notices * refactor(notice): unify showNotice usage * refactor(notice): add typed showNotice shortcuts, centralize defaults, and simplify subscriptions * refactor: unify showNotice usage * refactor(notice): unify showNotice API * refactor(notice): unify showNotice usage * chore(i18n): components.test.* * chore(i18n): components.settings.dns.* * chore(i18n): components.home.clashInfo.* * chore(i18n): components.home.systemInfo.* * chore(i18n): components.home.ipInfo/traffic.* * chore(i18n): navigation.* * refactor(i18n): remove pages.* namespace and migrate route texts under module-level page keys * chore(i18n): common.* * chore(i18n): common.* * fix: change error handling in patch_profiles_config to return false when a switch is in progress * fix: improve error handling in patch_profiles_config to prevent requests during profile switching * fix: change error handling in patch_profiles_config to return false when a switch is in progress fix: ensure CURRENT_SWITCHING_PROFILE is reset after config updates in perform_config_update and patch_profiles_config * chore(i18n): restructure root-level locale keys into namespaces * chore(i18n): add missing i18n keys * docs: i18n guide * chore: adjust i18n * refactor(i18n): align UI actions and status labels with common keys * refactor(i18n): unify two-name locale namespaces * refactor(i18n/components): unify locale keys and update component references * chore(i18n): add shared and entities namespaces to all locale files * refactor(i18n): consolidate shared and entity namespaces across features * chore(deps): update npm dependencies to ^7.3.5 (#5310) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * refactor(i18n): migrate shared editor modes and consolidate entities namespaces * tmp * refactor(i18n): flatten locales and move theme/validation strings * docs: CONTRIBUTING_i18n.md * refactor(i18n): restructure feedback and profile namespaces for better organization * refactor(i18n): unify settings locale structure and update references * refactor(i18n): reorganize locale keys for home, proxies, rules, connections, logs, unlock, and tests * refactor(i18n/feedback/layout): unify shared toasts & normalize layout namespace * refactor(i18n): centralize common UI strings in shared * refactor(i18n): flatten headers and unify locale schema * refactor(i18n): consolidate duplicate per-feature translations into shared namespace * refactor(i18n): split locales into per-namespace files * style: lint * refactor(i18n): unify unlock UI translations under tests namespace * feat(i18n): add type-checked translation keys * style: eslint import order * feat(i18n): replace ad-hoc loader with rust-i18n backend bundles * chore(prebuild): remove locale-copy step * fix(i18n, notice): propagate runtime params and update cleanup script path * fix(i18n,notice): make locale formatting idempotent and guard early notice translations * fix(i18n): resolve locale aliases and match OS codes correctly * fix(unlock): use i18next-compatible double-brace interpolation in failure notice * fix(i18n): route unlock error notices through translation keys * fix(i18n): i18n types * feat(i18n): localize upgrade notice for Clash core viewer * fix(notice): ensure runtime overrides apply to prefix translations * chore(i18n): replace literal notices with translation keys * chore(i18n): types * chore(i18n): regen typings before formatting to keep keys in sync * chore(i18n): simply labels * chore(i18n): adjust translation * chore: remove eslint-plugin-i18next * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend (#5341) * chore(i18n): translate settings.json (missed in previous pass) (#5343) * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend * chore(i18n): add/refine Korean translations across frontend scopes and Rust backend * fix(i18n-tauri): quote placeholder-leading value in ko.yml to prevent rust_i18n parse panic * chore(i18n): translate settings.json (forgot to include previously) --------- Co-authored-by: rozan <34974262+thelojan@users.noreply.github.com> |
||
|
|
a869dbb441 |
Revert "refactor: profile switch (#5197)"
This reverts commit
|
||
|
|
c2dcd86722 |
refactor: profile switch (#5197)
* refactor: proxy refresh
* fix(proxy-store): properly hydrate and filter backend provider snapshots
* fix(proxy-store): add monotonic fetch guard and event bridge cleanup
* fix(proxy-store): tweak fetch sequencing guard to prevent snapshot invalidation from wiping fast responses
* docs: UPDATELOG.md
* fix(proxy-snapshot, proxy-groups): restore last-selected proxy and group info
* fix(proxy): merge static and provider entries in snapshot; fix Virtuoso viewport height
* fix(proxy-groups): restrict reduced-height viewport to chain-mode column
* refactor(profiles): introduce a state machine
* refactor:replace state machine with reducer
* refactor:introduce a profile switch worker
* refactor: hooked up a backend-driven profile switch flow
* refactor(profile-switch): serialize switches with async queue and enrich frontend events
* feat(profiles): centralize profile switching with reducer/driver queue to fix stuck UI on rapid toggles
* chore: translate comments and log messages to English to avoid encoding issues
* refactor: migrate backend queue to SwitchDriver actor
* fix(profile): unify error string types in validation helper
* refactor(profile): make switch driver fully async and handle panics safely
* refactor(cmd): move switch-validation helper into new profile_switch module
* refactor(profile): modularize switch logic into profile_switch.rs
* refactor(profile_switch): modularize switch handler
- Break monolithic switch handler into proper module hierarchy
- Move shared globals, constants, and SwitchScope guard to state.rs
- Isolate queue orchestration and async task spawning in driver.rs
- Consolidate switch pipeline and config patching in workflow.rs
- Extract request pre-checks/YAML validation into validation.rs
* refactor(profile_switch): centralize state management and add cancellation flow
- Introduced SwitchManager in state.rs to unify mutex, sequencing, and SwitchScope handling.
- Added SwitchCancellation and SwitchRequest wrappers to encapsulate cancel tokens and notifications.
- Updated driver to allocate task IDs via SwitchManager, cancel old tokens, and queue next jobs in order.
- Updated workflow to check cancellation and sequence at each phase, replacing global flags with manager APIs.
* feat(profile_switch): integrate explicit state machine for profile switching
- workflow.rs:24 now delegates each switch to SwitchStateMachine, passing an owned SwitchRequest.
Queue cancellation and state-sequence checks are centralized inside the machine instead of scattered guards.
- workflow.rs:176 replaces the old helper with `SwitchStateMachine::new(manager(), None, profiles).run().await`,
ensuring manual profile patches follow the same workflow (locking, validation, rollback) as queued switches.
- workflow.rs:180 & 275 expose `validate_profile_yaml` and `restore_previous_profile` for reuse inside the state machine.
- workflow/state_machine.rs:1 introduces a dedicated state machine module.
It manages global mutex acquisition, request/cancellation state, YAML validation, draft patching,
`CoreManager::update_config`, failure rollback, and tray/notification side-effects.
Transitions check for cancellations and stale sequences; completions release guards via `SwitchScope` drop.
* refactor(profile-switch): integrate stage-aware panic handling
- src-tauri/src/cmd/profile_switch/workflow/state_machine.rs:1
Defines SwitchStage and SwitchPanicInfo as crate-visible, wraps each transition in with_stage(...) with catch_unwind, and propagates CmdResult<bool> to distinguish validation failures from panics while keeping cancellation semantics.
- src-tauri/src/cmd/profile_switch/workflow.rs:25
Updates run_switch_job to return Result<bool, SwitchPanicInfo>, routing timeout, validation, config, and stage panic cases separately. Reuses SwitchPanicInfo for logging/UI notifications; patch_profiles_config maps state-machine panics into user-facing error strings.
- src-tauri/src/cmd/profile_switch/driver.rs:1
Adds SwitchJobOutcome to unify workflow results: normal completions carry bool, and panics propagate SwitchPanicInfo. The driver loop now logs panics explicitly and uses AssertUnwindSafe(...).catch_unwind() to guard setup-phase panics.
* refactor(profile-switch): add watchdog, heartbeat, and async timeout guards
- Introduce SwitchHeartbeat for stage tracking and timing; log stage transitions with elapsed durations.
- Add watchdog in driver to cancel stalled switches (5s heartbeat timeout).
- Wrap blocking ops (Config::apply, tray updates, profiles_save_file_safe, etc.) with time::timeout to prevent async stalls.
- Improve logs for stage transitions and watchdog timeouts to clarify cancellation points.
* refactor(profile-switch): async post-switch tasks, early lock release, and spawn_blocking for IO
* feat(profile-switch): track cleanup and coordinate pipeline
- Add explicit cleanup tracking in the driver (`cleanup_profiles` map + `CleanupDone` messages) to know when background post-switch work is still running before starting a new workflow. (driver.rs:29-50)
- Update `handle_enqueue` to detect “cleanup in progress”: same-profile retries are short-circuited; other requests collapse the pending queue, cancelling old tokens so only the latest intent survives. (driver.rs:176-247)
- Rework scheduling helpers: `start_next_job` refuses to start while cleanup is outstanding; discarded requests release cancellation tokens; cleanup completion explicitly restarts the pipeline. (driver.rs:258-442)
* feat(profile-switch): unify post-switch cleanup handling
- workflow.rs (25-427) returns `SwitchWorkflowResult` (success + CleanupHandle) or `SwitchWorkflowError`.
All failure/timeout paths stash post-switch work into a single CleanupHandle.
Cleanup helpers (`notify_profile_switch_finished` and `close_connections_after_switch`) run inside that task for proper lifetime handling.
- driver.rs (29-439) propagates CleanupHandle through `SwitchJobOutcome`, spawns a bridge to wait for completion, and blocks `start_next_job` until done.
Direct driver-side panics now schedule failure cleanup via the shared helper.
* tmp
* Revert "tmp"
This reverts commit
|
||
|
|
51b08be87e |
feat: local backup (#5054)
* feat: local backup * refactor(backup): make local backup helpers synchronous and clean up redundant checks - Converted local backup helpers to synchronous functions to remove unused async warnings and align command signatures. - Updated list/delete/export commands to call the sync feature functions directly without awaits while preserving behavior. - Simplified destination directory creation to always ensure parent folders exist without redundant checks, satisfying Clippy. |
||
|
|
7fc238c27b |
refactor: invock mihomo api by use tauri-plugin-mihomo (#4926)
* feat: add tauri-plugin-mihomo
* refactor: invock mihomo api by use tauri-plugin-mihomo
* chore: todo
* chore: update
* chore: update
* chore: update
* chore: update
* fix: incorrect delay status and update pretty config
* chore: update
* chore: remove cache
* chore: update
* chore: update
* fix: app freezed when change group proxy
* chore: update
* chore: update
* chore: add rustfmt.toml to tauri-plugin-mihomo
* chore: happy clippy
* refactor: connect mihomo websocket
* chore: update
* chore: update
* fix: parse bigint to number
* chore: update
* Revert "fix: parse bigint to number"
This reverts commit
|
||
|
|
0c88568cd7 | chore: make eslint happy (part 1) (#4890) | ||
|
|
909c4028f1 | 添加链式代理下规则适配 | ||
|
|
627119bb22 |
Refactor imports and improve code organization across multiple components and hooks
- Consolidated and reordered imports in various files for better readability and maintainability. - Removed unused imports and ensured consistent import styles. - Enhanced the structure of components by grouping related imports together. - Updated the layout and organization of hooks to streamline functionality. - Improved the overall code quality by following best practices in import management. |
||
|
|
324628dd3d | refactor: replace 'let' with 'const' for better variable scoping and immutability | ||
|
|
f2073a2f83 |
Add Func 链式代理 (#4624)
* 添加链式代理gui和语言支持 在Iruntime中添跟新链式代理配置方法 同时添加了cmd * 修复读取运行时代理链配置文件bug * t * 完成链式代理配置构造 * 修复获取链式代理运行时配置的bug * 完整的链式代理功能 |