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
* 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.
* 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
* fix: update CORS configuration to use key-value pairs for allowed origins
* fix: refactor CORS configuration to use AllowOriginItem interface for better type safety
* fix: improve type safety and remove redundant type casts
- Fix @@ts-expect-error typo (double @) in traffic-diagnostics.ts
- Replace (e.target as any) with (e.target as HTMLElement) in setting-clash.tsx
- Remove redundant (onFormat as any) cast in guard-state.tsx
* fix: format api.ts sort callback to satisfy biome
* fix: remove as any, let @ts-expect-error suppress the non-standard API error
* fix: remove invalid @@ts-expect-error comment, keep as any for non-standard API
- 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.
- Extract shared delay state logic from ProxyItem and ProxyItemMini
into `useProxyDelayState` hook (src/hooks/use-proxy-delay-state.ts);
JSX display thresholds preserved per-component.
- Deduplicate rAF/setTimeout/Promise scheduling in DelayManager via
a private `scheduleOnNextFrame` helper.
- Drop no-op `useMemo(() => MODES, [])` in proxies page.
- Replace `any` on `setClashLog` prev params and layout-traffic sx
objects with proper types (`pre!`, `Pick<BoxProps|...>`).
- Dispose Monaco editor instances on dialog close to prevent cycle leak
- Replace gcTime: Infinity with finite TTLs and evict orphaned subscription queryKeys
- Add missing useEffect cleanup for timers, move setTimeout out of useMemo
Replace swr with @tanstack/react-query v5 across all hooks, providers,
and components. Introduce singleton QueryClient, WS subscription pattern
via useQuery+useEffect, and enforce component-layer cache access contract.
- Remove unused `dns_settings_enabled` localStorage writes in
setting-clash.tsx — state is sourced from verge config, these
writes were never read anywhere.
- Replace hardcoded `'last_check_update'` localStorage read in
system-info-card.tsx with exported `readLastCheckTime()` from
the useUpdate hook, keeping the key in a single source of truth.
The settings page "Check for updates" did not update the homepage
"last check update time" because each page managed the timestamp
independently. Centralizes the timestamp in the useUpdate hook
via SWR + localStorage so both pages share a single data source.
Closes https://github.com/clash-verge-rev/clash-verge-rev/issues/6605#issuecomment-4147144987