Files
harbor-net/docs/goals/windows-local-singbox/PLAN.md

17 KiB

Windows Local Sing-Box Implementation Plan

Intent: Add an optional Windows-client Local sing-box block that mirrors the ProxiFyre block, installs and controls a real sing-box service, imports a subscription/link, lets the user pick and ping servers, and routes selected apps through the chosen local outbound. Current Behavior: The Windows client supports an existing external SOCKS5 proxy and a ProxiFyre component block with setup details, install/start/stop/uninstall actions, animation, and generated config apply. singbox exists as an optional component in the model, but install-singbox.ps1 is only a marker boundary, main.rs does not register sing-box commands, the frontend has no sing-box block, and subscription parsing lives only in the Node server. Expected Outcome: A Windows user can keep using the external proxy path unchanged, or explicitly install optional Local sing-box, paste a subscription/VLESS link, fetch servers, ping them, choose one, generate a checked sing-box config, start/stop the sing-box service, and apply ProxiFyre routing to local-singbox. Target-Perspective Output: In the Windows client, the user sees a second optional block styled and animated like ProxiFyre. It shows what will be installed, asks for clear confirmation before privileged work, displays subscription/server state, exposes server ping and selection, and makes it obvious whether selected apps route to an existing proxy or to Local sing-box. Truth Owner: Rust/Tauri backend owns sing-box source state, subscription parsing/cache, generated sing-box config, component detection, and service operations. React owns only transient UI state. Generated configs and service files are derived artifacts. Contract Boundary: React calls typed Tauri commands. Rust validates and persists source JSON under C:\ProgramData\VpnProxy, generates configs through the sing-box adapter, and invokes explicit elevated PowerShell only for install/uninstall/service actions. UI never parses raw PowerShell/stdout. Cutover: Replace the current marker-only sing-box installer path with a real optional Local sing-box component while preserving ComponentId::Singbox and local-singbox target semantics. Keep external proxy as the default usable route when sing-box is absent. Displaced Path: Displace apps/windows-client/scripts/install-singbox.ps1 marker behavior and the current direct-only adapters/singbox.rs output. Do not create a parallel Node/server subscription path for the Windows client. Value Density: The smallest high-value slice is a controlled Local sing-box block that can fetch a subscription, select an outbound, generate checked local sing-box config, and expose service controls without making sing-box mandatory. Evidence Gate: Evidence must include target-perspective UI proof plus generated config proof, not just tests. Privileged Windows service behavior must be manually verified or explicitly marked implemented but unproven. Acceptance Evidence: Rust tests for parser/config/service-command boundaries; frontend build; app state or screenshot showing ProxiFyre and Local sing-box blocks; generated sing-box-config.json containing the selected outbound and local mixed inbound; generated ProxiFyre config pointing to 127.0.0.1:1080; Windows service checklist when elevated actions are run. Evidence Lane: Record commands, selected app state, generated config summaries, and manual Windows results in docs/goals/windows-local-singbox/EVIDENCE.md. Kill Criteria: No mandatory sing-box for external proxy flow; no hidden install during profile apply; no duplicate subscription source of truth in React or Node server; no raw PowerShell text as app logic; no permanent marker-only sing-box install path. Architecture Slice: Extend apps/windows-client only: Rust domain/storage/commands/adapters/detection/scripts plus React UI/types/CSS. Avoid root src/server and root src/web except as read-only reference. Plan Review Gate: Requires PRE review before execution.

Terminology

The user-facing feature name is Local sing-box / sing-box. Do not use alternate feature names in UI, commands, docs, or files.

Architecture Slice

Files to create:

  • apps/windows-client/src-tauri/src/subscription.rs
  • apps/windows-client/src-tauri/src/singbox_service.rs
  • apps/windows-client/src-tauri/tests/subscription_tests.rs
  • apps/windows-client/src-tauri/tests/singbox_service_tests.rs
  • apps/windows-client/src-tauri/tests/singbox_command_tests.rs

Files to modify:

  • apps/windows-client/src-tauri/Cargo.toml
  • apps/windows-client/src-tauri/src/main.rs
  • apps/windows-client/src-tauri/src/models.rs
  • apps/windows-client/src-tauri/src/storage.rs
  • apps/windows-client/src-tauri/src/commands.rs
  • apps/windows-client/src-tauri/src/component_detection.rs
  • apps/windows-client/src-tauri/src/adapters/singbox.rs
  • apps/windows-client/src-tauri/tests/singbox_adapter_tests.rs
  • apps/windows-client/src-tauri/tests/command_tests.rs
  • apps/windows-client/src/domain/types.ts
  • apps/windows-client/src/api/tauriCommands.ts
  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/styles/app.css
  • apps/windows-client/scripts/install-singbox.ps1
  • apps/windows-client/README.md
  • docs/goals/windows-local-singbox/EVIDENCE.md

Files to avoid:

  • src/server/* except as read-only reference for subscription semantics.
  • src/web/*
  • Docker, compose, gateway, and macOS installer files.
  • Existing ProxiFyre behavior except where it must consume the local-singbox target.

Source of truth:

  • C:\ProgramData\VpnProxy\config\profiles.json
  • C:\ProgramData\VpnProxy\config\targets.json
  • C:\ProgramData\VpnProxy\config\local-singbox.json
  • C:\ProgramData\VpnProxy\state\singbox-subscription-cache.json
  • C:\ProgramData\VpnProxy\state\activity.json

Derived artifacts:

  • C:\ProgramData\VpnProxy\generated\sing-box-config.json
  • C:\ProgramData\VpnProxy\generated\proxifyre-app-config.json
  • Installed sing-box.exe and WinSW wrapper under C:\Program Files\VpnProxy\sing-box
  • Windows service VpnProxySingBox

Read path:

  • React calls get_components, get_singbox_status, get_singbox_setup_status, and subscription/server commands.
  • Rust reads source Local sing-box config and cache, detects installed sing-box/service/wrapper, and returns redacted DTOs.

Write path:

  • React sends typed mutations for subscription URL, selected server, local endpoint, and service actions.
  • Rust validates input, writes source JSON atomically, fetches/cache subscription data, generates sing-box-config.json, and runs sing-box check before service start/restart.

Contract boundary:

  • subscription.rs owns fetch/parse/link normalization.
  • adapters/singbox.rs owns conversion from selected outbound to local runtime config.
  • singbox_service.rs owns install/service script generation and structured command parsing.
  • commands.rs owns Tauri DTOs and activity entries.
  • App.tsx owns layout/state orchestration only.

Integration points:

  • ProxiFyre route remains selected apps -> ProxiFyre -> target.
  • Local sing-box route uses target local-singbox, kind=local, protocol=socks5, host=127.0.0.1, port=1080, requiresComponent=singbox.
  • Server ping uses TCP connect to the selected outbound host/port, like the existing server ping semantics.
  • Install flow downloads/installs sing-box plus a WinSW Windows service wrapper, then writes machine-readable result JSON.

Migration/cutover:

  • On first sing-box save/start, ensure local-singbox target exists or is updated from Local sing-box listen settings.
  • Do not switch the user's profile target automatically unless the user chooses Local sing-box.
  • Existing external proxy input remains the default path and must still build/apply without sing-box.

Displaced path:

  • install-singbox.ps1 must stop being a marker-only script.
  • The old direct-only sing-box config in adapters/singbox.rs must be replaced by selected-subscription-outbound config generation.
  • No Windows-client code should import or call the root Node server for subscription parsing.

Acceptance evidence gate:

  • Automated evidence proves parser/config/ping/service-command boundaries.
  • App-visible evidence proves the optional block, setup details, server selection, and route mode.
  • Generated config evidence proves selected server is used by sing-box and ProxiFyre points to the local endpoint.

Task Board

Task 1: Add Local Sing-Box Domain And Storage Contract

Allowed files:

  • apps/windows-client/src-tauri/src/models.rs
  • apps/windows-client/src-tauri/src/storage.rs
  • apps/windows-client/src/domain/types.ts
  • apps/windows-client/src-tauri/tests/storage_tests.rs

Expected output:

  • LocalSingBoxConfig source model with subscription URL, redacted display URL, selected server tag, listen host/port, service name, install root, and timestamps.
  • SubscriptionCache model with parsed config, server summaries, user info, and fetched timestamp.
  • Storage paths for config/local-singbox.json and state/singbox-subscription-cache.json.

Verification:

  • cd apps/windows-client/src-tauri && cargo test storage

Acceptance evidence:

  • Tests prove atomic roundtrip, default optional empty state, redacted URL DTO, and invalid cache fallback.

Parallel safe: no.

Task 2: Port Subscription Parsing And Fetching To Rust

Allowed files:

  • apps/windows-client/src-tauri/Cargo.toml
  • apps/windows-client/src-tauri/src/subscription.rs
  • apps/windows-client/src-tauri/tests/subscription_tests.rs

Expected output:

  • Parser supports sing-box JSON configs, base64 subscription bodies, and VLESS REALITY links with the same supported outbound types as src/server/subscription.js.
  • Fetch command support is implemented in Rust with HTTP/HTTPS only and structured errors.
  • Subscription URL is never echoed unredacted in diagnostics or normal status DTOs.

Verification:

  • cd apps/windows-client/src-tauri && cargo test subscription

Acceptance evidence:

  • Tests cover JSON config, base64 VLESS list, invalid URL, unsupported outbound, and redaction.

Parallel safe: yes after Task 1 model names are stable.

Task 3: Replace Sing-Box Adapter With Selected-Outbound Config Generation

Allowed files:

  • apps/windows-client/src-tauri/src/adapters/singbox.rs
  • apps/windows-client/src-tauri/tests/singbox_adapter_tests.rs

Expected output:

  • Adapter builds local mixed inbound on the configured listen host/port.
  • Adapter selects the cached outbound by tag, clones it, ensures a stable outbound tag, and adds direct/block.
  • Adapter runs sing-box check when a binary path is available.

Verification:

  • cd apps/windows-client/src-tauri && cargo test singbox_adapter

Acceptance evidence:

  • Tests show selected VLESS outbound appears in generated config, missing selected tag blocks generation, and external-target ProxiFyre flow remains independent from Local sing-box.

Parallel safe: yes after Task 1.

Task 4: Implement Sing-Box Detection, Setup Status, And Service Scripts

Allowed files:

  • apps/windows-client/src-tauri/src/component_detection.rs
  • apps/windows-client/src-tauri/src/singbox_service.rs
  • apps/windows-client/scripts/install-singbox.ps1
  • apps/windows-client/src-tauri/tests/component_detection_tests.rs
  • apps/windows-client/src-tauri/tests/singbox_service_tests.rs

Expected output:

  • Detection finds installed sing-box.exe, service VpnProxySingBox, service running state, version/path, and problems.
  • Setup status lists exactly what will be installed: sing-box binary, WinSW service wrapper, service name, install root, generated config/log paths.
  • Install script performs a real idempotent install/repair boundary using WinSW and returns structured JSON; uninstall is safe-scoped to the configured install root.

Verification:

  • cd apps/windows-client/src-tauri && cargo test component_detection singbox_service
  • Windows parser check for install-singbox.ps1 when running on Windows.

Acceptance evidence:

  • Tests prove missing/installed/running component merge and PowerShell result parsing. Manual service install/start evidence is recorded later.

Parallel safe: yes, but integrate with Task 6 before UI.

Task 5: Add Tauri Sing-Box Commands

Allowed files:

  • apps/windows-client/src-tauri/src/commands.rs
  • apps/windows-client/src-tauri/src/main.rs
  • apps/windows-client/src/api/tauriCommands.ts
  • apps/windows-client/src-tauri/tests/command_tests.rs
  • apps/windows-client/src-tauri/tests/singbox_command_tests.rs

Expected output:

  • Commands: get_singbox_status, get_singbox_setup_status, save_singbox_subscription, fetch_singbox_subscription, forget_singbox_subscription, select_singbox_server, ping_singbox_server, ping_all_singbox_servers, generate_singbox_config, start_singbox_service, stop_singbox_service, install_singbox, uninstall_singbox.
  • Commands update activity with structured entries.
  • generate_singbox_config ensures/updates the local-singbox target but does not change profile targets without user choice.
  • start_singbox_service regenerates and checks config from current source state before starting the service.

Verification:

  • cd apps/windows-client/src-tauri && cargo test command singbox_command

Acceptance evidence:

  • Tests prove fetch/cache/select/generate flow and ProxiFyre apply blocks only when a profile actually targets missing/stopped Local sing-box.

Parallel safe: no; depends on Tasks 1-4.

Task 6: Build The Optional Local Sing-Box UI Block

Allowed files:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src/domain/types.ts
  • apps/windows-client/src/api/tauriCommands.ts
  • apps/windows-client/src/styles/app.css

Expected output:

  • A second block appears beside/under ProxiFyre, visually matching finder-card, setup details, action menu, status light, and border animation behavior.
  • UI shows Local sing-box as optional, not an error, when missing.
  • User can paste subscription/link, fetch servers, select server, ping one/all, generate config, install/start/stop/uninstall Local sing-box, and choose whether the main profile uses existing proxy or Local sing-box.
  • Loading/error/success states are visible and controlled by user action.

Verification:

  • cd apps/windows-client && npm run build

Acceptance evidence:

  • Screenshot or app state shows ProxiFyre block and Local sing-box block, expanded setup details, fetched server list with ping state, and route target toggle.

Parallel safe: no; depends on Task 5 DTOs.

Task 7: Integrate Route Choice And ProxiFyre Apply

Allowed files:

  • apps/windows-client/src/app/App.tsx
  • apps/windows-client/src-tauri/src/commands.rs
  • apps/windows-client/src-tauri/src/adapters/proxifyre.rs
  • apps/windows-client/src-tauri/tests/command_tests.rs
  • apps/windows-client/src-tauri/tests/proxifyre_adapter_tests.rs

Expected output:

  • Main profile can target either external proxy or local-singbox.
  • Switching to Local sing-box writes targetId=local-singbox; switching back writes external target.
  • ProxiFyre generated config points to 127.0.0.1:1080 when Local sing-box is selected and still points to the entered external proxy otherwise.

Verification:

  • cd apps/windows-client/src-tauri && cargo test proxifyre_adapter command
  • cd apps/windows-client && npm run build

Acceptance evidence:

  • Generated ProxiFyre config samples for both external proxy and Local sing-box routes are recorded.

Parallel safe: no.

Task 8: Documentation, Evidence, And Windows Manual Gate

Allowed files:

  • apps/windows-client/README.md
  • docs/goals/windows-local-singbox/EVIDENCE.md
  • docs/goals/windows-modular-client/EVIDENCE.md

Expected output:

  • README explains separate ProxiFyre and Local sing-box install flows, data paths, service name, and rollback.
  • Evidence file records tests/builds/UI proof/generated configs/manual Windows service checks.
  • If elevated service install cannot be run in the current environment, record implemented but unproven for that lane with exact remaining manual steps.

Verification:

  • git status --short
  • Evidence commands listed in EVIDENCE.md.

Acceptance evidence:

  • A target-perspective checklist proves the external proxy path still works and Local sing-box path works or is explicitly unproven only at the privileged Windows service lane.

Parallel safe: no.

PRE Review Prompt

Use C:\Users\PC\.agents\skills\krypton-planning\plan-reviewer-prompt.md with:

  • Plan file: docs/goals/windows-local-singbox/PLAN.md
  • Original request: add an optional Windows-client Local sing-box block like ProxiFyre, with install/service management, connection link/subscription import, server selection, ping, animations, and user-controlled visibility of what will be installed.
  • Unsafe paths or layers: root src/server, root src/web, hidden installer calls inside apply, raw PowerShell parsing in React, duplicate subscription state.