feat: support merging multiple subscriptions

This commit is contained in:
2026-07-19 23:58:02 +08:00
parent fb4d927220
commit 087869d84f
17 changed files with 1341 additions and 60 deletions

View File

@ -11,37 +11,41 @@ scientific-surfing (`ssm`) CLI and their roles. The CLI is a single Go binary
## Agent List
### 1. Subscription Manager (`internal/subscription`)
- **Purpose:** Handles all subscription-related operations, including adding, refreshing, deleting, renaming, and activating subscriptions. Also parses `ss://`/`trojan://`/`vless://` links and base64-encoded link lists into Clash proxy YAML.
- **Key Methods:** `AddSubscription`, `RefreshSubscription`, `DeleteSubscription`, `RenameSubscription`, `SetSubscriptionURL`, `GetSubscriptionURL`, `ActivateSubscription`, `ListSubscriptions`, `ShowStorageInfo`
- **Notes:** Supports backup option on refresh.
- **Purpose:** Handles all subscription-related operations, including adding, refreshing, deleting, renaming, and activating/deactivating subscriptions. Also parses `ss://`/`trojan://`/`vless://` links and base64-encoded link lists into Clash proxy YAML.
- **Key Methods:** `AddSubscription`, `RefreshSubscription`, `DeleteSubscription`, `RenameSubscription`, `SetSubscriptionURL`, `GetSubscriptionURL`, `ActivateSubscription`, `DeactivateSubscription`, `ListSubscriptions`, `ShowStorageInfo`
- **Notes:** Supports backup option on refresh. Activation is additive — multiple subscriptions can be active at once (`model.SubscriptionsData.SetActive` no longer deactivates others); `config apply` merges all of them.
### 2. Storage Manager (`internal/storage`)
- **Purpose:** Manages persistent storage for configuration and subscription data as YAML files under the per-user config directory (`$SF_CONFIG_DIR` or `~/basicfiles/cli/ss`).
- **Key Methods:** `LoadSubscriptions`, `SaveSubscriptions`, `LoadConfig`, `SaveConfig`, `GetStorageInfo`
### 3. Core Config Manager (`internal/corecfg`)
- **Purpose:** Handles core (mihomo) configuration management, including import/export, editing, resetting, and applying a subscription to produce the final generated config file. Also executes post-apply hook scripts.
- **Purpose:** Handles core (mihomo) configuration management, including import/export, editing, resetting, and applying every active subscription (or one explicitly selected via `--subscription`) to produce the final generated config file. Each active subscription's proxy *and* proxy-group names get prefixed with the subscription's own name to avoid collisions before all of them are merged together, with every in-subscription reference to a renamed proxy/group rewritten to match — a bundled group's own `proxies:` list, and any `rules:` entry whose target is a proxy/group name (e.g. `DOMAIN,example.com,Proxy` or `MATCH,Auto`) (see `automation.PrefixProxyNames`). Runs the `ssm:` automation block (see Automation Engine below) before writing the file, and executes post-apply hook scripts after.
- **Key Methods:** `ImportConfig`, `ExportConfig`, `EditConfig`, `ResetConfig`, `ShowConfig`, `Apply`
### 4. Core Manager (`internal/core`)
### 4. Automation Engine (`internal/automation`)
- **Purpose:** Implements the `ssm:` automation block that can be added to core-config.yaml: building a new proxy-group from proxies matching a subscription/keyword filter (`proxy-groups`), building one from proxies whose name encodes a rate/multiplier extracted via regexp and compared with an operator (`rate-filters`), and generic append/prepend/replace patches at an arbitrary dot/bracket path in the generated config (`patches`). The `ssm:` key itself is always stripped from the generated config before it's written — mihomo never sees it.
- **Key Functions:** `ParseConfig`, `Apply`, `PrefixProxyNames`
### 5. Core Manager (`internal/core`)
- **Purpose:** Manages the mihomo core binary (download/update from GitHub releases) and delegates system service operations to the Service Manager.
- **Key Methods:** `Update`, `InstallService`, `UninstallService`, `StartService`, `StopService`, `RestartService`, `GetServiceStatus`, `ReloadService`
### 5. Service Manager (`internal/service`)
### 6. Service Manager (`internal/service`)
- **Purpose:** Cross-platform system service integration — systemd on Linux, launchd on macOS, and a native Windows Service (via `golang.org/x/sys/windows/svc`) on Windows. On macOS and Windows, this same `ssm` binary is what the generated service definition invokes (hidden `service run-macos` / `service run-windows` commands), rather than a separate wrapper process.
- **Key Methods:** `Install`, `Uninstall`, `Start`, `Stop`, `Restart`, `Status`
### 6. Hook Manager (`internal/hook`)
### 7. Hook Manager (`internal/hook`)
- **Purpose:** Manages hook scripts for automation and customization, initialized from templates embedded in the binary.
- **Key Methods:** `Init`, `ListHooks`, `Edit`, `Rm`
### 7. Model (`internal/model`)
### 8. Model (`internal/model`)
- **Purpose:** Persisted data structures — `Subscription`, `SubscriptionsData`, `Config` — plus a `Time` wrapper that tolerates both this implementation's own timestamps and legacy timezone-naive timestamps.
### 8. YAML Util (`internal/yamlutil`)
### 9. YAML Util (`internal/yamlutil`)
- **Purpose:** A duplicate-mapping-key-tolerant YAML `Unmarshal`, since real-world mihomo/clash configs are frequently hand-merged and contain duplicate keys that the underlying YAML library rejects by default.
### 9. Editor (`internal/editor`)
### 10. Editor (`internal/editor`)
- **Purpose:** Opens a file in the user's configured (`$EDITOR`/`$VISUAL`) or best-guess system editor.
---