TZ/docs/第一次开发日志.md
2026-08-21 18:34:18 +08:00

29 KiB
Raw Permalink Blame History

环境搭建

省略

初始文件树

cargo init --bin --name tz .

#文件树1

TZ/
├── Cargo.toml
├── Cargo.lock
└── src/
    ├── main.rs    # tz 可执行程序入口
    └── lib.rs     # 项目的主要代码入口

常用代码

# 检查代码,不生成最终程序
cargo check

# 编译
cargo build

# 编译并运行
cargo run

# 向 tz 传入参数
cargo run -- status
cargo run -- core list

# 运行测试
cargo test

# 格式代码
cargo fmt

# 静态检查
cargo clippy

# 添加依赖
cargo add clap --features derive

# 删除依赖
cargo remove clap

# 查看依赖树
cargo tree

# 查看项目元数据
cargo metadata
--format-version 1

CLI 解析层的第一个小闭环

  1. 添加clap依赖
cargo add clap --features derive

cargo add 会修改当前 Package 的 Cargo.tomlderive feature 让我们可以使用 #[derive(Parser)]#[derive(Subcommand)]

  1. 写文件功能 #文件树2
mkdir -p src/cli 
touch src/cli/mod.rs #  管理并导出 cli 模块
touch src/cli/args.rs  # 定义用户可以输入什么
src/
├── main.rs #  程序入口
├── lib.rs  # 整个项目的库模块入口
└── cli/
    ├── mod.rs  #  管理并导出 cli 模块
    └── args.rs  # 定义用户可以输入什么
  1. lib.rs中添加声明
pub mod cli;

声明项目中存在 cli 模块Rust 会自动寻找src/cli.rs或者src/cli/mod.rs

  1. src/cli/mod.rs中管理子模块
mod args;  //  cli 模块内部还有一个 args 子模块。

pub use args::{Cli, CliCommand, CoreCommand}; // 表示把三个类型重新导出到 cli 模块表面

没有写 pub,所以外部不能直接访问args/tz::cli::args::Cli;

然后补充args.rs即可,注释也写在里面

即使main.rslib.rs在同一个 Cargo package 中, 仍然是两个独立 crate。Rust 官方文档明确说明:同时存在 src/lib.rssrc/main.rspackage 中包含一个库 crate 和一个二进制 crate。

package tz
├── library crate tz
   └── cli
└── binary crate tz
    └── main
  1. 补充main.rs
use clap::Parser;
use tz::cli::Cli; // cli 当前是由 lib.rs 管理的,它属于库 crate tz不是 main.rs 所属二进制 crate 的直接模块。

fn main() {
    let cli = Cli::parse();

    println!("{cli:#?}");
}

  1. 测试,--表示隔开,后面的参数是输入给二进制文件的
cargo run -- --help # 查看帮助
cargo run -- status # 
cargo run -- core --help # 查看 core 的帮助
cargo run -- unknown #  测试错误输入

常用代码

cargo tree # 检查依赖
cargo tree -i clap

cargo fmt       # 统一代码格式
cargo check     # 类型检查和编译检查
cargo clippy    # 检查潜在问题和不规范写法

CLI 解析run态

  1. 新增命令分发层 #文件树3
src/
├── main.rs
├── lib.rs
├── cli/
│   ├── mod.rs
│   ├── args.rs    # 用户可以使用什么命令
│   └── commands/  # 定义“收到命令之后调用什么”
│       ├── mod.rs
│       ├── status.rs
│       ├── service.rs
│       └── core.rs

创建

mkdir -p src/cli/commands

touch src/cli/commands/mod.rs 
touch src/cli/commands/status.rs
touch src/cli/commands/service.rs
touch src/cli/commands/core.rs
  1. 补充command代码

补充 src/cli/mod.rs

补充 src/cli/commands/mod.rs

补充 src/cli/commands/status.rs

补充 src/cli/commands/service.rs

补充 src/cli/commands/core.rs

补充 src/main.rs

  1. 测试
cargo fmt
cargo check
cargo clippy

然后

cargo run -- status
cargo run -- start
cargo run -- stop
cargo run -- restart
cargo run -- core list
之前:
用户输入 → Debug 打印

现在:
用户输入
   ↓
Cli
   ↓
CliCommand
   ↓
match
   ↓
具体 command handler

application

mkdir -p src/application

touch src/application/mod.rs
touch src/application/service.rs

文件树4

src/
├── main.rs #  程序入口
├── lib.rs  # 整个项目的库模块入口
└── cli/
│   ├── mod.rs  #  管理并导出 cli 模块
│   ├── args.rs  # 定义用户可以输入什么
│   └── commands/  # 定义“收到命令之后调用什么”
│       ├── mod.rs  # commands 本体
│       ├── status.rs # commands 的 子模块
│       ├── service.rs
│       └── core.rs
│
└── application/
    ├── mod.rs
    └── service.rs # 这个替换commands/service.rs的服务

随后需要补充的 lib.rs中定义新的模块

之后将commands中的相关模块替换成

前部小结

这里主要是创建两个模块

cli : 指令列表,以及管理\调用

application : 真实实现 目前只是搭建了基础框架没有实际执行,

  1. 搭建cli
  2. 搭建application,改cli的调用路线为application

主要完成了指令的分发

路径系统

设定软件的路径系统,

mkdir -p src/platform

touch src/platform/mod.rs
touch src/platform/paths.rs

文件树5

src/
├── main.rs #  程序入口
├── lib.rs  # 整个项目的库模块入口
└── cli/
│   ├── mod.rs  #  管理并导出 cli 模块
│   ├── args.rs  # 定义用户可以输入什么
│   └── commands/  # 定义“收到命令之后调用什么”
│       ├── mod.rs  # commands 本体
│       ├── status.rs # commands 的 子模块
│       ├── service.rs
│       └── core.rs
│
└── application/
│    ├── mod.rs
│    └── service.rs # 这个替换commands/service.rs的服务
│
└── platform/
    ├── mod.rs
    └── paths.rs

要求:

  • 默认配置不依赖环境变量即可使用。
  • 路径配置统一保存在 paths.toml,由 TZ_PATHS_TOML 指向;未设置时使用 $HOME/.config/tz/paths.toml
  • tz init 可以在用户确认后把 TZ_PATHS_TOML 的 export 追加到 ~/.bashrc

文件系统初始化规则

paths.toml 是文件系统路径的唯一配置源,文件只保存一次选定的四个目录,不保存布局类型或多个方案:

[layout]
config_dir = "~/.config/tz"
data_dir = "~/.local/share/tz"
state_dir = "~/.local/state/tz"
cache_dir = "~/.cache/tz"

路径文件定位规则:

  1. 设置 TZ_PATHS_TOML 时,读取该绝对路径文件;文件不存在或格式错误直接报错,不回退。
  2. 未设置时,读取 $HOME/.config/tz/paths.toml
  3. 默认路径文件不存在时,提示运行 tz init

程序固定读取 [layout] 下的四个字段。路径可以写成绝对路径或 ~/...;读取时展开 ~,展开后必须是绝对路径。普通命令不再读取 TZ_ROOT_DIR 或四个 XDG_* 环境变量。

tz init 的首次选择提供三个模板:

  1. 默认 XDG~/.config/tz~/.local/share/tz~/.local/state/tz~/.cache/tz
  2. 默认 Unified~/.tz/config~/.tz/data~/.tz/state~/.tz/cache
  3. 开发测试:项目目录下的 target/tz-dev/{config,data,state,cache}

选择模板后,交互询问四个目录,回车保留模板值,也可以修改。最终只写入一个 [layout] 表。

重复运行 tz init 时,如果 paths 文件已存在,先询问是否继续;拒绝则退出且不修改文件,确认后才重新选择和写入。写入路径文件后,初始化根据四个目录补齐结构和初始文件,已有文件一律跳过,不覆盖内容。

tz init 交互

  • 第一次运行时选择三个内置模板:默认 XDG、默认 Unified、开发测试 target/tz-dev
  • 选择后分别询问 config_dirdata_dirstate_dircache_dir,回车使用模板值。
  • 如果 paths 文件已经存在,先询问是否继续;默认退出,不修改现有路径。
  • 初始化结束后始终打印 export TZ_PATHS_TOML='...' 提示。默认 $HOME/.config/tz/paths.toml 不需要设置变量;自定义 paths 文件可以确认后追加到 ~/.bashrc

开发测试

开发测试模板使用项目目录下的 target/tz-dev,示例:

cargo run -- init
# 选择 3) 开发测试 target/tz-dev
TZ_PATHS_TOML="$PWD/target/tz-paths.toml" cargo run -- status

如果 paths 文件放在默认 $HOME/.config/tz/paths.toml,后续命令不需要设置环境变量;如果使用自定义路径文件,需要设置 TZ_PATHS_TOML 或按初始化结束时的提示加入 bashrc。

本次修改的代码文件

  • src/platform/paths.rs
    • 使用 paths.toml 作为唯一路径配置源。
    • 支持 TZ_PATHS_TOML 和默认 $HOME/.config/tz/paths.toml
    • 解析 [layout] 的四个固定目录,支持 ~/ 展开和绝对路径校验。
    • 保留初始化目录、五个初始文件和幂等补全。
  • src/application/init.rs
    • 提供默认 XDG、默认 Unified、开发 target/tz-dev 三个模板。
    • 已有 paths 文件先确认,再允许重新选择。
    • 初始化结束打印 TZ_PATHS_TOML export自定义路径可确认后追加到 ~/.bashrc

验证命令:

cargo fmt --check
cargo check
cargo test --all-targets
cargo clippy --all-targets -- -D warnings

文件作用

接下来固定文件作用

paths.toml TZ_PATHS_TOML

[layout]
config_dir = "/mnt/data_4t2/lht_self/TZ/target/tz-dev/config"
data_dir = "/mnt/data_4t2/lht_self/TZ/target/tz-dev/data"
state_dir = "/mnt/data_4t2/lht_self/TZ/target/tz-dev/state"
cache_dir = "/mnt/data_4t2/lht_self/TZ/target/tz-dev/cache"

三级配置

一级配置

全局、长期、比较稳定的信息。

settings.toml:tz软件的统一配置信息与core的运行不太相关。默认不会修改只是展示一下

schema_version = 1

[bypass]
enabled = true
# bypass.list 之外的内联补充项,生成规则时合并并去重。
inline = [
    "localhost",
    "127.0.0.0/8",
]

[log]
level = "warn"
# tz.log 超限后直接清除重建,不保留归档。
max_size_mb = 10

[update.profiles]
auto_update = false
interval_minutes = 4320

[update.cores]
auto_update = false
interval_minutes = 14400

runtime.tomlTZ 可以跨 core 表达的运行参数包括端口、API、DNS 和 TUN 的复杂参数。是否开启 TUN 不在这里,开关保存在 active.toml

schema_version = 1

[proxy]
mode = "rule"
listen = "127.0.0.1"
mixed_port = 7890
http_port = 7892
socks_port = 7891
allow_lan = false
ipv6 = false

[api]
enabled = true
listen = "127.0.0.1"
port = 9189

[dns]
enabled = true
listen = "127.0.0.1"
port = 1053
ipv6 = false

[tun]
stack = "system"
auto_route = true
auto_detect_interface = true
dns_hijack = true

二级配置

active.toml:保存主页需要展示和切换的状态,只放当前 core 与三个开关。当前 profile 和节点选择由 profiles.toml 保存PID 与锁由 state/runtime/ 保存。

schema_version = 1

[current]
core = "mihomo"

[tun]
enabled = false

[shell_proxy]
enabled = false
bypass = true

[system_proxy]
enabled = false
bypass = true

三级配置

state/generated/<core>/ 只保存根据配置生成的内核入口文件,可随时删除重建。state/runtime/<core>/ 才是 {workdir} 指向的内核工作目录,用来隔离 cache.db 等副产物。

介绍文档

除了上面的一些控制文档,还需要有一些总结性的文档,避免每次都重新扫描文件。

profiles.toml

schema_version = 1

# 每个 family 各自保存当前 profile切换 core 后可以恢复对应选择。
[current]
clash = "home"
sing-box = "sid"

[[profiles]]
name = "home"
family = "clash"
format = "yaml"
source_file = "home/source.yaml"

[profiles.origin]
kind = "remote"
url = "https://example.com/subscription"

[profiles.update]
updated_at = "2026-08-14T10:00:00Z"

# 一个 profile 可以保存多个策略组的节点选择。
[profiles.state.selected]
Proxy = "Hong Kong 01"
Final = "Proxy"

[[profiles]]
name = "company"
family = "clash"
format = "yaml"
source_file = "company/source.yaml"

[profiles.origin]
kind = "local"
original_path = "/home/lht/config/company.yaml"

cores标准设计

下面的不需要tz程序初始化也不需要其修改基本上手动制作tz读取使用即可

cores/
└── mihomo/
    ├── core.toml          # Core 描述文件
    └── mihomo             # 二进制

这一部分还作为后续cores制作的参考标准

core.toml

schema_version = 1


[core]
name = "mihomo"
family = "clash"
version = "1.19.18"
binary = "mihomo"
os = "linux"
arch = "x86_64"


[runtime]
entrypoint = "config.yaml"
format = "yaml"


[capabilities.config]
mixed_proxy = true
http_proxy = true
socks_proxy = true
api = true
dns = true
tun = true

# start 必填check/version/reload 为可选表。
# 某个命令表存在就表示支持对应 CLI 动作,不再维护重复的 actions 布尔值。
[commands.start]
args = ["-d", "{workdir}", "-f", "{config}"]

[commands.check]
args = ["-t", "-d", "{workdir}", "-f", "{config}"]

[commands.version]
args = ["-v"]

core.toml 只允许 {config}{workdir} 两个占位符。binaryentrypoint 必须是单个相对文件名;加载 core 时还会检查 schema、目录名、family/format 组合、二进制是否存在且可执行。

最终文件树

这里是结合文件作用+cores的

TZ_PATHS_TOML
└── paths.toml  # 保存四个基础路径


config/
├── settings.toml  # TZ 自身的长期策略bypass、日志、更新配置
├── runtime.toml   # 跨 core 的端口、API、DNS、TUN 参数
├── shell/         # 后续生成 shell 代理脚本;当前阶段尚未实装
└── bypass.list


data/
├── profiles/
   ├── profiles.toml   # profile 索引、当前选择和策略组节点选择
   ├── tnt/
      └── source.yaml
   └── sid/
       └── source.json

└── cores/ # 手工制作、TZ 只读;目录名必须等于 core.name
    ├── mihomo/
       ├── core.toml
       └── mihomo
    └── sing-box/
        ├── core.toml
        └── sing-box


state/
├── active.toml  # 当前 core 与主页开关

├── generated/  # 只放可删除重建的生成配置
   ├── mihomo/
      └── config.yaml
   └── sing-box/
       └── config.json

├── runtime/
   ├── mihomo/ # Mihomo cache.db 等运行副产物,{workdir} 指向这里
   ├── sing-box/
   ├── tz.lock    # 防止多个 TZ 同时修改运行状态
   └── core.pid   # 停止时还必须通过 /proc/<pid>/exe 校验身份

└── logs/
    ├── tz.log
    └── core.log


cache/
├── downloads/
└── speedtest/

配置层 domain 与命令实装

本次目标

把“文件作用 + cores 标准”定稿落到 Rust用 domain 结构体描述 settings.tomlruntime.tomlactive.tomlprofiles.tomlcore.toml,由 tz init 生成默认文件,由 tz statustz core list 严格读取。配置 builder 和真实进程启停留到下一阶段。

代码结构

src/domain/ 只负责配置结构、序列化和业务校验;application 负责行为;platform 负责路径:

src/
├── domain/
│   ├── mod.rs           # domain 类型重导出
│   ├── settings.rs      # settings.toml[bypass]/[log]/[update]
│   ├── runtime.rs       # runtime.toml[proxy]/[api]/[dns]/[tun]
│   ├── active.rs        # active.toml当前 core + 三个主页开关
│   ├── profiles.rs      # profiles.toml当前 profile、索引、节点选择
│   └── core_manifest.rs # core.toml 加载、校验和 list_cores
├── platform/paths.rs    # 四个根目录和固定子路径
├── application/
│   ├── init.rs          # 生成默认配置
│   └── service.rs       # status 与未实现启停错误
└── cli/commands/        # CLI 薄分发

配置职责与校验

  • settings.toml 保存 TZ 自身的长期策略。日志超限直接清除重建,因此没有 keep 字段。
  • runtime.toml 保存端口、API、DNS 与 TUN 复杂参数;默认端口为 mixed 7890、HTTP 7892、SOCKS 7891
  • active.toml 只保存 [current].coretun.enabled、shell proxy 和 system proxy 开关。
  • profiles.toml 在顶层 [current] 按 family 保存当前 profile[profiles.state.selected] 可以保存多个策略组各自选择的节点。
  • state/generated/<core>/ 只保存可删除重建的入口配置;state/runtime/<core>/{workdir},用于隔离内核数据库和缓存。
  • 四份配置都只支持 schema_version = 1 并拒绝未知字段。Default 只供 tz init 生成模板;普通命令严格读取,文件缺失、损坏或版本不支持都会报错。
  • profile 会校验名称、family/format、来源字段、重复项、当前选择引用和 source_file 安全相对路径。

cores 标准

  • core.name 必须等于目录名,名称只能使用 ASCII 字母、数字、点、下划线和连字符。
  • family/format 当前支持 clash/yamlsing-box/json
  • binaryruntime.entrypoint 必须是单个相对文件名binary 还必须实际存在且可执行。
  • commands.start 必填;commands.checkcommands.versioncommands.reload 可选。命令表存在即表示支持对应动作,不再使用重复的 [capabilities.actions] 布尔值。
  • 命令参数只支持 {config}{workdir},由 CoreDescriptor::render_args 展开。
  • [capabilities.config].api 只表示内核提供控制 API不等同于支持 CLI reload。

paths.rs 与初始化

  • paths.toml 仍是四个根目录的唯一来源;设置 TZ_PATHS_TOML 时必须是绝对路径。
  • AppPaths::from_env_or_none() 让非 init 命令自己输出未初始化提示,不再提前重复解析路径。
  • initialize_files 只建目录并幂等写 bypass.listdomain 默认值负责生成四份 TOML已有文件不覆盖。
  • 初始化先准备目录与默认配置,最后写 paths.toml,避免配置生成失败后留下已提交的路径文件。
  • generated_dircore_workdir 分离;没有独立的 active.example.toml

当前命令行为

  • tz init:选择模板,确认四个路径,准备目录和默认配置,最后写 paths.toml,再提示 TZ_PATHS_TOML export。
  • tz status:显示当前 core、profile、受管进程和当前节点PID 检查会排除僵尸进程。
  • tz core list:扫描 data/cores/*/core.toml,通过完整校验后按名称排序,并在 TTY 中允许直接选择。
  • tz starttz stoptz restart:生成并校验配置后真实控制受管进程;停止前核对进程用户和可执行文件。

stop 不会仅凭 PID 发送信号;/proc/<pid>/exe 与当前受管 core 不一致时直接拒绝。

验证

cargo fmt --check
cargo check
cargo test --all-targets
cargo clippy --all-targets -- -D warnings
TZ_PATHS_TOML="$PWD/target/tz-paths.toml" cargo run -- status
TZ_PATHS_TOML="$PWD/target/tz-paths.toml" cargo run -- core list

控制逻辑界面

TZ 的公开控制入口围绕对象和业务动作组织,不提供任意 TOML 编辑器。配置文件是内部存储格式,所有写操作都经过类型校验、运行状态检查、锁保护和原子保存。

当前命令

tz init
tz status
tz setting
tz setting list 
tz setting get <key>
tz setting set <key> [value]
tz setting reset [key]

tz profile add <name> <url-or-file> --family clash|sing-box
tz profile list [--family clash|sing-box] [--all]
tz profile info <name>
tz profile use [name]
tz profile update
tz profile remove <na

tz core add <directory>
tz core list  
tz core info [name]
tz core use [name]
tz core remove <name>

tz completion generate bash|zsh|fish # 生成tab服务

tz setting 无子命令时在 TTY 中进入选择界面;非交互调用使用 listset 缺少 value 时只允许 TTY 交互。startstoprestart 当前明确返回未实现错误,不打印成功状态。

简明指令

tz start|on  # 直接读取上一次的配置
tz off|stop|end # 关闭服务,清理环境
tz -l  # 列出节点
tz -l <name>  # 不区分大小写的关键词搜索

tz completion generate bash|zsh|fish  # 生成 shell 补全脚本
# eval "$(tz completion generate bash)"

快捷键

tz  # tz status 需要展示当前使用的coreprofile节点及其测速
tz select # tz profile list

状态归属

  • settings.tomlruntime.tomltz setting 的固定 key registry 管理,禁止任意路径写入。
  • active.toml 只由 core 选择等业务命令维护,tz status 负责展示,不提供通用字段编辑。
  • profiles.toml 与受管 profile source 由 tz profile 管理;远程来源保存 URL 和实际下载路径,下载优先使用环境代理,失败后回退直连。
  • profile list 默认按当前 core 的 family 过滤;只有 --all 才显示全部 family。
  • core.toml 与二进制由 tz core 只读校验和管理PID、锁、日志属于运行状态。
  • generated 配置由当前 family builder 生成并调用真实 core 校验节点选择、测速、真实启停、TUN 独立开关及 shell/GNOME system proxy 已开放。

修改规则

  1. 命令先重新读取并校验当前状态,再持有 tz.lock 执行修改。
  2. 文件使用同目录临时文件和原子替换;失败时保留旧状态。
  3. profile/core 在受管进程运行时拒绝 useupdateremove 等可能改变运行输入的操作。
  4. profile URL 只允许 HTTP(S)校验公网地址、DNS 全部结果和每次重定向;本地文件复制为受管副本。
  5. core 只接受本地目录,不接受 URL导入成功后不自动选择、不自动启动。

core 制作

目标与范围

TZ 当前支持统一的本地 core 包格式,用于识别和调用已经存在的 Mihomo 或 sing-box 二进制。core 包只描述运行契约,不包含 profile、用户配置、secret、PID、日志或缓存。

当前稳定槽位为 mihomosing-box,目录名必须与 core.name 相同:

data/cores/
├── mihomo/
│   ├── core.toml
│   └── mihomo
└── sing-box/
    ├── core.toml
    └── sing-box

当前 schema v1

core.toml 必须声明 schema、名称、family、版本、二进制、目标平台、配置格式、能力和命令参数。Mihomo 使用 family = "clash"format = "yaml"sing-box 使用 family = "sing-box"format = "json"。命令参数只支持 {config}{workdir} 占位符,由 TZ 展开。完整字段以 docs/core-package.md 为准。

schema_version = 1

[core]
name = "mihomo"
family = "clash"
version = "1.19.18"
binary = "mihomo"
os = "linux"
arch = "x86_64"

[runtime]
entrypoint = "config.yaml"
format = "yaml"

[commands.start]
args = ["-d", "{workdir}", "-f", "{config}"]

当前制作和导入流程

  1. 用户自行下载或制作二进制,在本地准备包含 core.toml 和可执行文件的目录。
  2. 使用 tz core add <directory> 导入TZ 校验目录、manifest、平台、family、格式、二进制权限和命令占位符。
  3. 如 manifest 声明 commands.version,导入前执行该命令;参数按数组传递,不经过 shell。
  4. 目标名称已存在时拒绝覆盖;通过 staging 目录复制并原子重命名到 data/cores/<name>
  5. 导入成功后不自动 core use,也不自动启动;后续用 tz core list/info/use/remove 管理。

core remove 在运行中拒绝,删除前检查当前选择和受管 PID并清理该 core 的派生配置。手工复制到 data/cores/ 也会被扫描,但不会绕过运行状态和安全校验。

当前不做

core 不通过 URL 安装、不负责下载更新、不覆盖正在运行的 core。远端 registry、归档校验和 core update 不在当前路线内。任意其他代理二进制也不能只凭一份 core.toml 接入,必须先提供对应 family 的配置 builder 和控制 adapter。

本轮实现结果

  • 新增 platform/storage.rstz.lock 非阻塞独占锁、同目录临时文件、flush/fsync、原子 renameprofile 索引和 source 使用当前用户私有权限。
  • 新增 platform/process.rs:统一正整数 PID、存活和僵尸状态判断供 status、profile/core use/remove 共用。
  • 新增 platform/network.rsprofile URL 只允许 HTTP/HTTPS拒绝凭据、本机、环回、私有和保留地址DNS 全结果与重定向逐次复核,优先使用环境代理并在失败后回退直连,限制超时、重定向和响应大小,错误不泄露订阅 URL。
  • 新增 typed setting registry完成 setting/list/get/set/reset;不允许任意 TOML 路径编辑,保存后明确提示需要重新 build/start。
  • 完成 profile add/list/info/use/update/removeURL 与本地文件都变成受管副本family 固定映射格式,运行中禁止 use/update/remove删除不触碰用户原文件。
  • core schema v1 新增必填 os/arch稳定槽位统一为 mihomosing-box
  • 完成 core add/list/info/use/remove手工复制仍可直接扫描add 只做本地安全导入version 命令不经过 shell运行中禁止 use/remove。
  • 新增正式规范 docs/control-interface.mddocs/core-package.mdexamples/cores/mihomo/ 制作模板。

当前边界与下一阶段

当前路线已完成 config builder、节点选择与测速、受管进程启停、TUN 独立控制及 shell/GNOME system proxy。core 在线更新与其他桌面环境 adapter 留在后续阶段。

v0.1 可运行闭环

本章覆盖当前可运行行为;前文中的阶段性设计以这里和 docs/control-interface.md 为准。

当前指令

tz status|start|stop|restart
tz list [keyword]
tz node test [keyword] [--url <url>] [--timeout <ms>] [--select]
tz tun status|on|off
tz proxy status|on|off
tz proxy terminal|system status|on|off
tz proxy env|noenv [bash|zsh|fish]
tz proxy shell-init bash|zsh|fish
tz setting [list|get|set|reset]
tz profile add|list|info|use|update|remove
tz core add|list|info|use|remove
tz config build|check|show
tz completion generate bash|zsh|fish

profile update 不接名称,一次更新全部远程 profile。profile list 默认只看当前 core family只有 --all 跨 family。profile/core/node 的 list 在终端中均可编号选择并以 * 标记当前项;use 保留给脚本和显式操作。列表保持简洁,路径和来源等详情由 info 或对应文件提供。

  nano_clash family=clash
* mihomo version=1.19.18 family=clash

Mihomo 读取 Clash 配置,所以其 family 必须为 clashsing-box 才使用 family=sing-box

简洁指令

tz                 # status并测速当前节点
tz on              # 使用上次的可用 profile 启动并显示 status
tz off | tz end    # stop
tz -l [keyword]    # 节点测速、延迟排序、搜索和选择
tz select          # 当前 family 的 profile 列表和选择

快捷键

tz st              # status
tz r               # restart
tz set              # setting
tz p                # profile
tz c                # core
tz cfg              # config
tz comp              # completion
tz p a|l|i|u|up|rm
tz c a|l|i|u|rm

Tab 提示由 completion generator 提供。节点选择会写入 profile state 并在下次启动后恢复。tz -lnode test 都走 controller delay API最多 8 路并发、按延迟排序并缓存最新结果;--select 选择最快节点。tz 对当前节点实时测速,失败时才显示缓存结果。

Mihomo 标准 core 包携带 Country.mmdbGeoSite.dat。Clash profile 实际引用 GEOIP/GEOSITE 时builder 按需复制到该 core 的独立 runtime 工作目录,避免首次校验因 GitHub 下载受阻而误报超时;自制 core 包缺失资源时直接提示用户启用其他代理或补齐 core 包。tz on/start 始终使用当前 family 上次选择且 source 可用的 profile启动后立即显示含节点测速的 status。

profile 下载的 User-Agent 按 family 选择Clash 对齐 mh 的 Mihomo provider User-Agentsing-box 对齐 sb。同一订阅 URL 若按客户端返回 Clash YAML 或 sing-box JSONadd 与批量 update 都能取得对应 family 的原生格式;--family 仍只负责选择契约,不做跨格式转换。

Proxy、TUN 与权限

  • proxy env/noenv 输出可由当前 shell eval/source 的环境命令;shell-init 为 Bash、Zsh、Fish 生成持久 hook。
  • proxy system 按 mh/sb 的当前参考路线使用 GNOME gsettings,读取 runtime/capability 端口并把 bypass 转成 ignore-hosts开启前备份原桌面设置关闭或失败时恢复。
  • tun on/off 检查 core capability、/dev/net/tunCAP_NET_ADMIN;运行中切换会重启,失败回滚,不自动执行 sudo/setcap。

配置生成已通过 Mihomo 1.19.18 和 sing-box 1.13.14 的真实 check。隔离测试覆盖 sing-box 的 start/status/list/select/stop并继续覆盖 proxy 环境输出、TUN 状态和节点测速错误/超时路径。