Skip to content

Contributing

Juwan-Hwang edited this page Apr 11, 2026 · 15 revisions

贡献指南

感谢你对 Zephyr 项目的关注!Zephyr 是基于 Tauri v2 的 Mihomo GUI 代理客户端。本文档将帮助你了解项目的 CI/CD 流水线、发布流程、代码规范以及如何为项目做出贡献。

目录


发布流程

Zephyr 采用自动化发布流程,当推送版本 tag 时触发完整的构建与发布流水线。整个流程涵盖版本同步、内核获取与校验、多平台编译以及产物上传。

%%{init: {'themeVariables': {'fontSize': '9px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '8px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 12, 'rankSpacing': 15}}}%%
flowchart TD
    A[推送版本 Tag<br/>例如 v1.0.0] --> B[触发 Release Workflow]
    B --> V[版本同步机制<br/>自动更新 3 个文件版本号]
    V --> C[并行构建 4 个平台]
    C --> C1["Windows x64 构建<br/>x86_64-pc-windows-msvc"]
    C --> C2["macOS ARM64 构建<br/>aarch64-apple-darwin"]
    C --> C3["macOS x64 构建<br/>x86_64-apple-darwin"]
    C --> C4["Ubuntu x64 构建<br/>x86_64-unknown-linux-gnu"]

    C1 --> D[Mihomo 内核获取]
    C2 --> D
    C3 --> D
    C4 --> D

    D --> D1[查询 GitHub API<br/>获取最新 Release Tag]
    D1 --> D2[下载平台对应归档]
    D2 --> D3[SHA256 校验和验证]
    D3 --> D4{校验通过?}
    D4 -->|否| ABORT[中止构建]
    D4 -->|是| D5[下载 GeoIP + GeoSite 数据]

    D5 --> F[Full 版本构建<br/>含 Mihomo 内核 + Geo 数据]
    D5 --> G[Lite 版本构建<br/>不含 Mihomo 内核]

    F --> H[生成 Checksums 文件]
    G --> H
    H --> I[创建 Draft Release]
    I --> J[上传所有构建产物]
    J --> K[人工审核]
    K --> L[发布 Release]
Loading

构建矩阵

发布流水线在 4 个平台上并行构建,覆盖主流操作系统和 CPU 架构:

Platform Runner Target Triple Architecture
macOS macos-latest aarch64-apple-darwin arm64 (Apple Silicon)
macOS macos-latest x86_64-apple-darwin x64 (Intel Mac)
Ubuntu ubuntu-22.04 x86_64-unknown-linux-gnu x64
Windows windows-latest x86_64-pc-windows-msvc x64

Source: .github/workflows/release.yml 构建矩阵配置

版本同步机制

在构建开始之前,流水线会自动将版本号同步到项目中的 3 个关键文件,确保所有组件版本一致。这一步骤通过解析 Git Tag 中的版本号(去除 v 前缀)实现。

%%{init: {'themeVariables': {'fontSize': '10px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '10px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 15, 'rankSpacing': 25}}}%%
flowchart LR
    A[Git Tag<br/>v1.2.3] --> B[提取版本号<br/>1.2.3]
    B --> C["jq 更新<br/>src-tauri/tauri.conf.json<br/>.version 字段"]
    B --> D["sed 更新<br/>src-tauri/Cargo.toml<br/>version = \"...\""]
    B --> E["jq 更新<br/>package.json<br/>.version 字段"]
    C --> F[版本同步完成]
    D --> F
    E --> F
Loading

同步的 3 个文件及其更新方式:

# 文件路径 更新工具 更新位置
1 src-tauri/tauri.conf.json jq .version 字段
2 src-tauri/Cargo.toml sed [package] 下的 version 字段
3 package.json jq .version 字段

Source: .github/workflows/release.yml:39-71

Mihomo 内核获取与安全校验

Mihomo 内核的获取和校验是发布流程中最关键的安全环节,分为三个阶段:

1. 版本发现 (Version Discovery)

流水线通过 GitHub API 查询 Mihomo 项目的最新 Release Tag,使用 GITHUB_TOKEN 进行认证以避免 API 速率限制。

# 伪代码示意
LATEST_TAG=$(curl -H "Authorization: token $GITHUB_TOKEN" \
  https://api.github.com/repos/MetaCubeX/mihomo/releases/latest | jq -r .tag_name)

2. SHA256 完整性校验

下载平台对应的 Mihomo 归档后,流水线会执行严格的完整性校验:

%%{init: {'themeVariables': {'fontSize': '9px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '8px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 12, 'rankSpacing': 15}}}%%
flowchart TD
    A[下载平台归档文件] --> B[从 Release Assets 获取<br/>预期 SHA256 哈希值]
    B --> C["执行 sha256sum 计算<br/>本地文件哈希"]
    C --> D{本地哈希 == 预期哈希?}
    D -->|是| E[校验通过,继续构建]
    D -->|否| F["中止构建<br/>报告完整性错误"]
Loading

校验流程:

  1. 下载目标平台对应的 Mihomo 压缩包
  2. 通过 jq 从 GitHub Release Assets 中提取预期 SHA256 哈希值
  3. 使用 sha256sum 计算本地文件的哈希值
  4. 比较两个哈希值,不匹配则立即中止构建

3. Geo-Data 获取

校验通过后,流水线会下载地理数据文件到 src-tauri/bundled/ 目录:

文件 用途
geoip.dat IP 地理位置数据库,用于路由规则匹配
geosite.dat 域名分类数据库,用于域名规则匹配

Source: .github/workflows/release.yml:106-255

Full vs Lite 双构建策略

每个平台都会同时构建 Full 和 Lite 两个版本,满足不同用户的需求:

%%{init: {'themeVariables': {'fontSize': '9px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '8px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 12, 'rankSpacing': 15}}}%%
flowchart TD
    A[构建完成] --> B{选择构建策略}
    B --> C["Full 版本"]
    B --> D["Lite 版本"]
    C --> C1[打包 Mihomo 内核]
    C --> C2[打包 GeoIP + GeoSite 数据]
    C1 --> C3["产物: Zephyr_Full_{version}_{target}"]
    C2 --> C3
    D --> D1[不包含内核]
    D --> D2[不包含 Geo 数据]
    D1 --> D3["产物: Zephyr_Lite_{version}_{target}"]
    D2 --> D3
Loading
Feature Full Version Lite Version
Mihomo Core Included in src-tauri/bundled/ Not included
Geo-Data Included (geoip.dat, geosite.dat) Not included
Binary Path Internal (App Bundle) User-defined or Auto-downloaded
Artifact Name Zephyr_Full_{version}_{target} Zephyr_Lite_{version}_{target}

Source: .github/workflows/release.yml 双构建配置

编译环境

各平台的编译环境配置如下:

工具链

工具 版本/来源 说明
Rust dtolnay/rust-toolchain@stable 使用 stable 工具链
Node.js actions/setup-node@v4 前端构建环境

平台特定依赖

平台 依赖包 说明
Linux libwebkit2gtk-4.1-dev Tauri WebView2 运行时
Linux libappindicator3-dev 系统托盘支持
Linux librsvg2-dev SVG 图标渲染

macOS 交叉编译

macOS 平台需要同时构建 ARM64 和 x64 两个架构,通过以下环境变量实现交叉编译:

环境变量 用途
PKG_CONFIG_ALLOW_CROSS=1 允许交叉编译时的 pkg-config 查找
SDK_PATH (via xcrun) 指定 macOS SDK 路径,用于 aarch64 目标编译

Source: .github/workflows/release.yml:73-104

产物命名与上传

构建完成后,所有产物通过 softprops/action-gh-release 上传至 GitHub Release:

平台 产物格式 说明
Windows .msi / .exe MSI 安装包 + 便携版
macOS .dmg / .app.tar.gz DMG 镜像 + App 压缩包
Linux .deb Debian/Ubuntu 安装包

产物命名规则:

  • Full 版本:Zephyr_Full_{version}_{target_triple}.{ext}
  • Lite 版本:Zephyr_Lite_{version}_{target_triple}.{ext}

Source: .github/workflows/release.yml 产物上传配置

版本号规范

Zephyr 遵循 语义化版本 规范:

  • 主版本号 (MAJOR):不兼容的 API 变更
  • 次版本号 (MINOR):向下兼容的功能新增
  • 修订号 (PATCH):向下兼容的问题修复

Tag 格式:v{MAJOR}.{MINOR}.{PATCH},例如 v1.2.3


CI/CD 安全扫描流水线

Zephyr 在每次提交和 PR 时都会运行完整的安全扫描流水线,确保代码质量和安全性。流水线包含 10 个安全扫描 Job,分为三大检查组。

触发条件

安全扫描流水线在以下场景自动触发:

触发类型 条件
Push 推送到 maindev 分支
Pull Request 所有 PR
定时任务 每日 UTC 03:00 (0 3 * * *)

Source: .github/workflows/security.yml:8-14

流程图

%%{init: {'themeVariables': {'fontSize': '10px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '10px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 15, 'rankSpacing': 25}}}%%
graph LR
    subgraph 触发
        A[Push / PR / Cron]
    end

    subgraph Rust 后端检查
        B[job: lint-rust<br/>Clippy 检查]
        C[job: cargo-deny<br/>许可证与依赖审计]
        D[job: cargo-audit<br/>Rust 漏洞扫描]
    end

    subgraph 前端 JS 检查
        E[job: lint-frontend<br/>ESLint]
        F[job: vitest-coverage<br/>单元测试与覆盖率]
        G[job: npm-audit<br/>前端依赖漏洞扫描]
    end

    subgraph 密钥与审计检查
        H[job: semgrep-scan<br/>静态安全分析]
        I[job: codeql-analysis<br/>语义代码分析]
        J[job: dependency-review<br/>GitHub 依赖审查]
        K[job: check-license<br/>文件头许可证检查]
        L[job: secret-detection<br/>Trufflehog + 正则扫描]
    end

    A --> B
    A --> C
    A --> D
    A --> E
    A --> F
    A --> G
    A --> H
    A --> I
    A --> J
    A --> K
    A --> L

    B --> M{全部通过?}
    C --> M
    D --> M
    E --> M
    F --> M
    G --> M
    H --> M
    I --> M
    J --> M
    K --> M
    L --> M

    M -->|是| N[合并允许]
    M -->|否| O[阻止合并<br/>报告错误]
Loading

Job 说明

Job 名称 检查组 说明 运行时间
lint-rust Rust 后端 Rust 代码 Clippy 检查与格式化验证 ~2min
lint-frontend 前端 JS 前端 ESLint 检查 ~1min
semgrep-scan 密钥与审计 Semgrep 静态分析(自定义规则) ~3min
cargo-deny Rust 后端 依赖许可证与审计检查 ~2min
cargo-audit Rust 后端 Rust 安全漏洞扫描 ~1min
dependency-review 密钥与审计 GitHub 依赖审查 ~1min
codeql-analysis 密钥与审计 CodeQL 语义代码分析 ~10min
check-license 密钥与审计 文件头许可证检查 ~30s
vitest-coverage 前端 JS 前端单元测试与覆盖率 ~2min
build-test Rust 后端 全平台编译测试 ~5min

代码规范

Rust 代码规范 (Clippy)

项目强制执行以下 12 条 Clippy 规则,在 CI 中任何违规都会导致构建失败:

# Clippy 规则 说明
1 clippy::unwrap_used 禁止使用 .unwrap(),强制使用错误处理
2 clippy::expect_used 禁止使用 .expect(),改用 ? 操作符或 match
3 clippy::panic 禁止使用 panic!
4 clippy::todo 禁止遗留 todo! 宏,必须完成实现
5 clippy::unimplemented 禁止使用 unimplemented!
6 clippy::clone_on_copy 禁止对 Copy 类型调用 .clone()
7 clippy::needless_pass_by_value 避免不必要的值传递,优先使用引用
8 clippy::redundant_clone 检测并移除多余的 .clone() 调用
9 clippy::indexing_slicing 禁止直接索引,使用 .get() 方法
10 clippy::manual_let_else 优先使用 let...else 语法
11 clippy::explicit_iter_loop 循环中优先使用 &&mut 而非 .iter()
12 clippy::string_add 禁止使用 + 拼接字符串,使用 format!concat!

clippy.tomlCargo.toml 中配置:

[lints.clippy]
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
todo = "deny"
unimplemented = "deny"
clone_on_copy = "deny"
needless_pass_by_value = "warn"
redundant_clone = "warn"
indexing_slicing = "warn"
manual_let_else = "warn"
explicit_iter_loop = "warn"
string_add = "warn"

Clippy 安全 Lints

除了上述通用代码质量规则外,项目还启用了以下专门针对安全性的 Clippy Lints:

Clippy Lint 安全类别 说明
clippy::indexing_slicing 内存安全 防止数组/切片越界访问导致的 panic,强制使用 .get() 方法进行安全访问
clippy::cast_possible_truncation 类型安全 捕获不安全的整数类型转换(如 i64i32 可能导致数据截断)
clippy::unnecessary_safety_comment 审计可追溯性 确保 unsafe 块都有充分的安全说明注释,防止无注释的 unsafe 代码混入

这些 Lints 在 CI 的 lint-rust Job 中作为 Clippy 的额外警告级别检查执行。

Source: .github/workflows/security.yml:88-97

前端代码规范 (ESLint)

项目使用 ESLint 进行前端代码质量检查,配置文件为 eslint.config.js

// eslint.config.js 核心配置
export default [
  {
    rules: {
      "no-unused-vars": "error",
      "no-console": ["warn", { allow: ["warn", "error"] }],
      "typescript-eslint/no-explicit-any": "error",
      "typescript-eslint/consistent-type-imports": "error",
      "vue/no-unused-components": "error",
      "vue/no-v-html": "warn",
    },
  },
];

前端安全审计 (npm audit)

前端依赖安全通过 npm audit 进行扫描,在 CI 的安全流水线中自动执行:

npm audit --omit=dev --audit-level=moderate

参数说明:

参数 说明
--omit=dev 排除开发依赖,仅扫描生产依赖中的漏洞
--audit-level=moderate 当发现 moderate 及以上级别的漏洞时报告失败

Source: .github/workflows/security.yml:133

测试规范 (Vitest)

所有前端代码必须编写单元测试,使用 Vitest 作为测试框架:

// 示例测试
import { describe, it, expect } from "vitest";

describe("工具函数", () => {
  it("应正确解析订阅链接", () => {
    const result = parseSubscription("clash://...");
    expect(result).toBeDefined();
    expect(result.nodes.length).toBeGreaterThan(0);
  });
});

测试覆盖率要求:

  • 语句覆盖率 >= 80%
  • 分支覆盖率 >= 70%
  • 函数覆盖率 >= 80%

Semgrep 自定义规则

项目使用 Semgrep 进行额外的静态安全分析,配置文件为 .semgrep.yml。以下为项目中实际配置的 4 条自定义规则:

# Rule ID Language Target Risk Description
1 rust-osascript-privilege-escalation Rust Privilege Escalation 检测通过 osascript 执行提权操作的代码,防止权限提升攻击
2 rust-command-format-arg Rust Command Injection 标记使用 format!() 构造 Command 参数的代码,防止命令注入漏洞
3 rust-unsafe-block Rust Memory Safety 审计所有 unsafe 块,确保内存安全操作有充分的审查
4 js-innerhtml-assignment JS XSS 检测 innerHTML 赋值操作,防止跨站脚本攻击 (XSS)

Source: .semgrep.yml:8-116

规则文件位于 .semgrep.yml,示例如下:

rules:
  - id: rust-osascript-privilege-escalation
    languages: [rust]
    message: "检测到 osascript 提权操作,请确保此操作经过安全审查"
    severity: ERROR
    pattern: |
      Command::new("osascript")
        ...
    metadata:
      category: security
      subcategory: privilege-escalation

  - id: rust-command-format-arg
    languages: [rust]
    message: "Command 参数通过 format!() 构建,存在命令注入风险"
    severity: WARNING
    pattern-either:
      - pattern: |
          Command::new(...).arg(format!(...))
      - pattern: |
          Command::new(...).args(format!(...))
    metadata:
      category: security
      subcategory: injection

  - id: rust-unsafe-block
    languages: [rust]
    message: "unsafe 块需要安全审查注释"
    severity: WARNING
    pattern: |
      unsafe { ... }
    metadata:
      category: memory-safety

  - id: js-innerhtml-assignment
    languages: [javascript, typescript]
    message: "innerHTML 赋值存在 XSS 风险,请使用 textContent"
    severity: WARNING
    pattern: |
      $OBJ.innerHTML = $VALUE
    metadata:
      category: security
      subcategory: xss
      references:
        - https://owasp.org/www-community/attacks/xss/

Secret Detection 双层检测策略

Zephyr 采用双层密钥检测策略,在 CI 安全流水线中自动扫描代码仓库,防止密钥和敏感信息泄露。

%%{init: {'themeVariables': {'fontSize': '9px', 'nodeBorder': '1px', 'clusterBorder': '1px', 'edgeLabelHeight': '8px'}, 'flowchart': {'curve': 'basis', 'nodeSpacing': 12, 'rankSpacing': 15}}}%%
flowchart TD
    A[Secret Detection Job 启动] --> B[第一层: Trufflehog 扫描]
    A --> C[第二层: 正则表达式源码扫描]

    B --> B1["扫描完整 Git 历史<br/>使用 --only-verified 标志<br/>仅报告已验证的泄露"]
    B1 --> B2{发现泄露?}
    B2 -->|是| FAIL[报告失败,阻止合并]
    B2 -->|否| PASS1[第一层通过]

    C --> C1["正则匹配源码文件<br/>模式: (password\|secret)\s*[:=]\s*[\"']"]
    C --> C2["高熵字符串检测<br/>识别疑似随机生成的密钥"]
    C1 --> C3{发现泄露?}
    C2 --> C3
    C3 -->|是| FAIL
    C3 -->|否| PASS2[第二层通过]

    PASS1 --> D[全部通过]
    PASS2 --> D
Loading

第一层:Trufflehog Git 历史扫描

Trufflehog 是专业的密钥扫描工具,能够扫描完整的 Git 提交历史:

配置项 说明
扫描范围 完整 Git 历史(包括已删除的内容)
--only-verified 标志 仅报告经过验证的真实泄露,减少误报
认证 使用 GITHUB_TOKEN 访问仓库

第二层:正则表达式源码扫描

作为 Trufflehog 的补充,流水线还使用正则表达式直接扫描源码文件:

检测模式 说明
(password|secret)\s*[:=]\s*["'] 匹配密码和密钥的直接赋值
高熵字符串检测 识别疑似随机生成的 Token、API Key 等字符串

两层检测互为补充:Trufflehog 擅长发现 Git 历史中的已知密钥格式,正则扫描则能捕获源码中潜在的密钥赋值模式。

Source: .github/workflows/security.yml:179-206


许可证合规 (deny.toml)

Zephyr 使用 cargo-deny 管理依赖许可证合规性。项目根目录下的 deny.toml 配置了完整的依赖审计策略。

配置详解

[licenses]
unlicensed = "deny"
allow = [
  "MIT",
  "Apache-2.0",
  "Apache-2.0 WITH LLVM-exception",
  "BSD-2-Clause",
  "BSD-3-Clause",
  "ISC",
  "Unicode-DFS-2016",
  "Zlib",
  "OpenSSL",
  "MPL-2.0",
  "LGPL-3.0",
]
copyleft = "deny"
allow-osi-fsf-free = "both"
default = "deny"

[licenses.private]
ignore = true

[bans]
multiple-versions = "warn"
wildcards = "deny"

[sources]
unknown-registry = "deny"
unknown-git = "deny"

[advisories]
vulnerability = "deny"
unmaintained = "warn"

Source: deny.toml:1-37

策略说明

许可证策略 ([licenses])

策略 配置值 说明
unlicensed deny 拒绝无许可证的依赖
copyleft deny 拒绝 Copyleft 许可证(如 GPL)
default deny 默认拒绝未明确允许的许可证
allow-osi-fsf-free both 同时认可 OSI 和 FSF 的自由软件定义

允许的许可证列表

许可证 类型 说明
MIT 宽松 最常用的开源许可证
Apache-2.0 宽松 含专利授权条款
Apache-2.0 WITH LLVM-exception 宽松 LLVM 项目使用的变体
BSD-2-Clause 宽松 简化版 BSD 许可证
BSD-3-Clause 宽松 标准 BSD 许可证
ISC 宽松 功能等同 MIT
Unicode-DFS-2016 宽松 Unicode 数据文件许可证
Zlib 宽松 压缩库许可证
OpenSSL 宽松 OpenSSL 加密库许可证
MPL-2.0 弱 Copyleft Mozilla 公共许可证,文件级 Copyleft
LGPL-3.0 弱 Copyleft 允许动态链接的 Copyleft(用于 GTK 系统库)

注意MPL-2.0LGPL-3.0 属于弱 Copyleft 许可证,仅在特定场景下被允许。MPL-2.0 仅在文件级别有 Copyleft 要求,LGPL-3.0 则是因为 GTK 系统库的依赖需要。

依赖禁止策略 ([bans])

策略 配置值 说明
wildcards deny 禁止使用通配符版本依赖(如 *),确保版本明确
multiple-versions warn 同一依赖存在多个版本时发出警告(不阻止构建)

来源策略 ([sources])

策略 配置值 说明
unknown-registry deny 仅允许 crates.io,拒绝未知注册源
unknown-git deny 拒绝未知的 Git 依赖源

安全公告策略 ([advisories])

策略 配置值 说明
vulnerability deny 发现安全漏洞时阻止构建
unmaintained warn 依赖不再维护时发出警告

Dependabot 配置

Zephyr 为 4 个生态系统配置了 Dependabot 自动依赖更新,配置文件为 .github/dependabot.yml

version: 2
updates:
  # 1. Rust 生态系统 (Cargo)
  - package-ecosystem: "cargo"
    directory: "/src-tauri"
    schedule:
      interval: "weekly"
    groups:
      patch:
        update-types:
          - "patch"
      minor:
        update-types:
          - "minor"
    labels:
      - "dependencies"
      - "rust"

  # 2. npm 生态系统 (前端)
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "dependencies"
      - "frontend"

  # 3. GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "monthly"
    labels:
      - "dependencies"
      - "github-actions"

  # 4. Pip (Semgrep 工具链)
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "dependencies"
      - "security-tools"

Source: .github/dependabot.yml:1-68

更新策略

生态系统 更新频率 目录 分组策略 说明
Cargo (Rust) 每周 /src-tauri patch + minor 分组 将补丁更新和次要更新分别合并为单个 PR,减少 PR 数量
npm (前端) 每周 / 无分组 每个 npm 包独立更新
GitHub Actions 每月 / 无分组 保持 Actions 版本稳定
Pip (Semgrep) 每周 / 无分组 保持 Semgrep 安全扫描工具链最新

Cargo 分组策略说明:通过 groups 配置,Cargo 生态系统的补丁更新(patch)和次要更新(minor)会被自动合并到各自的分组 PR 中。例如,当 5 个依赖有补丁更新时,Dependabot 只会创建 1 个 PR 而非 5 个,大幅减少代码审查负担。


Issue 提交指南

提交前检查

在提交 Issue 之前,请确认:

  1. 已搜索现有的 Issue,确认问题未被报告
  2. 已阅读 FAQ 文档,确认不是已知问题
  3. 使用的是最新版本的 Zephyr
  4. 问题可以在最新版本中复现

Issue 模板

提交 Bug 报告时,请使用以下模板:

## Bug 描述
[清晰简洁地描述 Bug]

## 复现步骤
1. [步骤 1]
2. [步骤 2]
3. [步骤 3]

## 预期行为
[描述你期望发生的情况]

## 实际行为
[描述实际发生的情况]

## 环境信息
- 操作系统: [例如 Windows 11 / macOS 14 / Ubuntu 22.04]
- Zephyr 版本: [例如 v1.2.3]
- 安装版本: [Full / Lite]
- Mihomo 内核版本: [例如 v1.18.10]

## 日志
[粘贴相关日志,请使用代码块]

## 截图
[如有,附上截图]

## 附加信息
[其他有助于解决问题的信息]

提交功能请求时,请使用以下模板:

## 功能描述
[清晰描述你希望添加的功能]

## 动机
[为什么需要这个功能?它解决了什么问题?]

## 建议的实现方式
[如有想法,描述你建议的实现方式]

## 替代方案
[你考虑过的其他替代方案]

## 附加信息
[其他相关信息]

Issue 标签

标签 说明
bug Bug 报告
feature 功能请求
documentation 文档相关
good first issue 适合新贡献者
help wanted 需要帮助
security 安全相关问题
platform-windows Windows 平台相关
platform-macos macOS 平台相关
platform-linux Linux 平台相关

感谢你的贡献!如有任何问题,欢迎在 Issue 中讨论。

Clone this wiki locally