Conversation
Bind a local mixed inbound port to any proxy group (builtin, custom, or
dialer), generating mihomo listeners entries that route traffic through
that group directly.
- core: GroupListenerBinding stores a stable target id ({kind, id})
instead of the display name, so renaming a group keeps its listener
working; resolveGroupListenerEntries validates targets and ports
against the effective mixed-port (including base-YAML overrides),
node listener ports, other group listeners, and base-YAML listeners,
failing generation with a clear error instead of silently skipping
- listeners default to 127.0.0.1; 0.0.0.0 only with an explicit
allow-LAN opt-in; disabled groups pause generation but keep the
binding so re-enabling restores it
- UI: the group-type button in each group row becomes an advanced
settings button opening a save/cancel dialog (group type, load-balance
strategy, listener toggle, port, allow-LAN with security hint); a
status dot marks non-default settings; no extra text in the row
- store action + subscription save/load + auth handoff serialization
- regression tests for all three group kinds, rename stability,
disable/re-enable, conflict sources, deleted targets, and persistence
round-trips
feat: group listener ports (binds inbound ports to proxy groups)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 043d8689f8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return resolveGroupListenerEntries({ | ||
| bindings, | ||
| resolveTarget, | ||
| effectiveMixedPort, | ||
| nodeListenerPorts: listeners ? listeners.map((l) => l.port) : [], | ||
| baseListenerPorts: collectPorts(baseListenerArray), |
There was a problem hiding this comment.
Reserve DNS and other inbound ports
When a user assigns a group listener port already used by another top-level inbound, the conflict is not detected because this set includes only mixed-port, node listeners, and entries under listeners. For example, the default configuration enables dns.listen on 127.0.0.1:5335 (packages/core/src/config/defaults.ts:117-119), yet a group listener on 5335 is accepted and emitted with udp: true, causing Mihomo to fail binding the generated configuration; custom port, socks-port, redir-port, and tproxy-port values have the same problem. Include every active inbound port, including the port parsed from dns.listen, in the conflict set.
Useful? React with 👍 / 👎.
| { | ||
| "name": "subboost", | ||
| "version": "2.6.0", | ||
| "version": "2.7.0", |
There was a problem hiding this comment.
Keep the local application version in sync
When the local image is built through local/docker-compose.yml without explicit APP_RELEASE_VERSION or APP_VERSION build arguments, the Docker builder copies local/ but not the root package manifest, so resolveAppVersionInfo falls back to local/package.json, which remains at 2.6.0. Such a v2.7.0 build therefore displays and reports itself as v2.6.0, and its release check can continuously advertise the already-installed v2.7.0 update. Bump local/package.json and its workspace entry in package-lock.json alongside this public version.
Useful? React with 👍 / 👎.
| const resolution = resolveTarget(binding); | ||
| if (!resolution.exists) { | ||
| throw new GroupListenerError( | ||
| "分组监听的目标策略组已被删除,请在对应策略组的高级设置中移除或修改该监听配置。" | ||
| ); |
There was a problem hiding this comment.
Reconcile listener bindings when applying templates
When a user with a listener bound to a custom or dialer group applies a template, applyTemplateConfig replaces customProxyGroups and dialerProxyGroups but leaves groupListeners untouched. If the applied template does not contain the bound group ID, this branch then rejects every generation as a deleted target, while the missing group has no advanced-settings UI through which the user can remove the orphaned binding. Template application must either restore listeners as part of the template schema or remove bindings whose targets are replaced.
Useful? React with 👍 / 👎.
Summary
Upgrade notes
/opt/subboost/.envand the database before upgrading.Validation
npm cinpm run lintnpm run test:unitnpm run check:local-app