Initial release v0.1.0
This commit is contained in:
commit
b997bd6078
62 changed files with 56224 additions and 0 deletions
189
docs/COMMAND_ARCHITECTURE.md
Normal file
189
docs/COMMAND_ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
# TZ 统一控制指令架构(讨论稿)
|
||||
|
||||
状态:Draft 0.1
|
||||
范围:Clash/Mihomo、sing-box,以及待确认的 NinjaDesktop Lite 适配器
|
||||
参考:`/mnt/data_4t2/lht_self/sing-box-13/sb`
|
||||
|
||||
第一版:下面的架构以假设使用.sh调用原二进制内核开发,
|
||||
|
||||
## 1. 目标
|
||||
|
||||
对用户只暴露一套稳定的 `tz` 指令。切换内核后,用户的日常命令、配置档名称、当前节点、路由模式、TUN、终端代理和系统代理等状态不变;由内核适配器负责生成配置并执行不同的底层指令。
|
||||
|
||||
```text
|
||||
用户 / shell
|
||||
|
|
||||
v
|
||||
tz CLI(解析、状态、锁、事务、统一输出)
|
||||
|
|
||||
+-- clash adapter ------> mihomo/clash + Clash API
|
||||
+-- sing-box adapter ---> sing-box + Clash API
|
||||
`-- ninja adapter ------> 待探测
|
||||
```
|
||||
|
||||
基本原则:
|
||||
|
||||
1. 正式命令统一为 `tz <对象> <动作> [参数]`。
|
||||
2. 常用操作保留短命令,但短命令只是正式命令的别名。
|
||||
3. 用户状态由 `tz` 保存,不能以某个内核的运行配置作为唯一状态源。
|
||||
4. 原始订阅/配置档只读保存;端口、DNS、TUN、绕过规则等系统配置在启动前覆盖合并。
|
||||
5. 所有内核差异只进入 adapter;主控制逻辑中不散落 `if clash` / `if sing-box`。
|
||||
6. 不支持的能力必须明确报错并返回非零退出码,不能假装执行成功。
|
||||
7. 修改内核、配置档、模式、TUN 等操作均先生成并校验配置,再应用;失败时保留旧的可运行状态。
|
||||
|
||||
## 2. 完整指令树
|
||||
|
||||
我想做的就是普通clash界面的终端操控指令
|
||||
|
||||
```text
|
||||
tz
|
||||
快速启动
|
||||
|-- status [--watch] # 显示整体状态,使用的内核,profile情况,节点,延迟等
|
||||
|-- start # 启动,直接启动上次使用的profile,之后立刻执行status,做参考
|
||||
|-- stop/end # 停止服务
|
||||
|-- restart # 强制完整重启,等效于 stop 后 start
|
||||
|-- reload # 重新生成配置并热加载,必要时自动重启
|
||||
|
|
||||
|-- list|-l [keyword] # 列出默认策略组节点并按延迟排序,快速切换节点
|
||||
| [--group|-g <name>]
|
||||
| [--fresh] # 这是什么?
|
||||
|-- use <node> [--group <name>] # 快速选择节点
|
||||
|
||||
整体服务
|
||||
|-- service 服务,选择节点(对应当前profile),开关等
|
||||
| |-- status [--watch]
|
||||
| |-- stop/end # 停止进程
|
||||
| |-- restart [profile] # 重启多用来刷新 bypass.list
|
||||
|
|
||||
|-- core
|
||||
| |-- list 查看有哪些内核,比如clash ,sing-box,mihomo。用*指出当前内核,选择可换
|
||||
| |-- info [name] 当前内核的版本,二进制位置、导入时的url,是否正常启动等信息,或者是指定的
|
||||
| |-- add <name> <url>不需要这个我后面会给出内核加入的标准格式,只做上传到网上,下载即可。如果名字重复,可以选择覆盖或者输入新的名称
|
||||
| |-- remove <name> 删除对应内核
|
||||
| |-- use <name> [--no-start] 切换内核,
|
||||
| `-- update [name] 去查看url的内核版本,可选是否更新,否则提示无更新
|
||||
|
||||
|-- setting 这个是所有的core共用(配置一次就可以用了)?还是每个core有自己的单独配置(麻烦)
|
||||
| |-- list # 列表展示 项目(key)+ 出来。可以选择设置哪一个
|
||||
| |-- get <key> # 这个是只展示某个key的配置
|
||||
| |-- set <key> <value> # 这个是单独配置
|
||||
| `-- reset [key] # 恢复默认值
|
||||
|
|
||||
|-- key 这里展示setting可以打开哪些项目及其配置。下面指出的是默认配置
|
||||
| |-- core : mihomo # 等效于 core list,
|
||||
| |-- sysproxy : on/off # 系统proxy开启,注意需要识别bypass.list 配置ignore host
|
||||
| |-- proxy : on/off 终端~/.bashrc中的变量配置
|
||||
| |-- http-proxy : 127.0.0.1:7892
|
||||
| |-- socks-proxy : 127.0.0.1:7891
|
||||
| |-- mixed-proxy : 127.0.0.1:7890
|
||||
| |-- WebUI : 127.0.0.1:9189
|
||||
| |-- autostart : true/false
|
||||
|
||||
|-- env 环境配置
|
||||
| |-- list # 展示出来,有哪些可以配置
|
||||
| |-- sysproxy : on/off # 系统proxy开启,注意需要识别bypass.list 配置ignore host
|
||||
| |-- proxy : on/off 终端~/.bashrc中的变量配置
|
||||
| |-- http-proxy : 127.0.0.1:7892
|
||||
| |-- socks-proxy : 127.0.0.1:7891
|
||||
| |-- mixed-proxy : 127.0.0.1:7890
|
||||
| |-- WebUI : 127.0.0.1:9189
|
||||
|
||||
|-- profile # 由于内核不同profile也不同,所以注意区分。profile是对应core的
|
||||
| |-- list # 列出订阅,*指出当前的订阅,注意profile与core对应
|
||||
| |-- show [name]
|
||||
| |-- add <name> <url-or-file> [--format auto|clash|sing-box] # 新增订阅,重名选择覆盖(remove后add)还是重命名
|
||||
| |-- remove <name> # 删除
|
||||
| |-- use <name> [--restart]
|
||||
| |-- current
|
||||
| |-- update [name]
|
||||
| |-- update-all
|
||||
| |-- check [name] [--core <name>]
|
||||
| `-- source [name]
|
||||
|
|
||||
|-- group # profile对应的group可选择切换与node 节点应该在一起
|
||||
| |-- list
|
||||
| |-- current [group]
|
||||
| `-- select <group> <node>
|
||||
|-- node 节点
|
||||
| |-- list [--group <name>] [--match <keyword>]
|
||||
| |-- current [--group <name>]
|
||||
| |-- select <node> [--group <name>]
|
||||
| `-- test [--group <name>] [--match <keyword>]
|
||||
| [--url <url>] [--timeout <ms>] [--select]
|
||||
|
|
||||
|-- mode # 这个放在这儿?为什么不放在setting
|
||||
| |-- get
|
||||
| `-- set rule|global|direct
|
||||
|
|
||||
|-- tun
|
||||
| |-- status
|
||||
| |-- on
|
||||
| `-- off
|
||||
|
|
||||
|-- proxy
|
||||
| |-- status
|
||||
| |-- on
|
||||
| |-- off
|
||||
| |-- env
|
||||
| |-- noenv
|
||||
| |-- shell-init [bash|zsh|fish]
|
||||
| |-- terminal on|off
|
||||
| `-- system on|off
|
||||
|
|
||||
|-- rule
|
||||
| `-- bypass
|
||||
| |-- list
|
||||
| |-- add <domain-or-cidr>
|
||||
| |-- remove <domain-or-cidr>
|
||||
| |-- import <file>
|
||||
| |-- reset
|
||||
| `-- apply
|
||||
|
|
||||
|-- connection
|
||||
| |-- list
|
||||
| |-- close <id>
|
||||
| `-- close-all
|
||||
|
|
||||
|-- config
|
||||
| |-- path
|
||||
| |-- show [--effective|--source]
|
||||
| |-- build [--core <name>] [--profile <name>]
|
||||
| |-- check [--core <name>] [--profile <name>]
|
||||
| `-- apply
|
||||
|
|
||||
|-- log # 日志没必要吧?
|
||||
| `-- show [--lines <n>] [--follow] [--level <level>]
|
||||
|
|
||||
|-- diagnose # 这是什么?
|
||||
| |-- run [--full]
|
||||
| |-- ports
|
||||
| |-- process [pid]
|
||||
| |-- network direct|proxy|compare
|
||||
| |-- dependencies
|
||||
| |-- interfaces
|
||||
| |-- dns
|
||||
| |-- routes
|
||||
| |-- api
|
||||
| `-- config
|
||||
|
|
||||
|-- api status
|
||||
|-- api get <path>
|
||||
`-- completion generate bash|zsh|fish
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 文件树
|
||||
|
||||
##
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 具体配置
|
||||
|
||||
|
||||
|
||||
102
docs/control-interface.md
Normal file
102
docs/control-interface.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# TZ Control Interface v0.1
|
||||
|
||||
TZ 的公开命令围绕用户动作设计。配置文件是可查阅的内部存储格式,修改由固定命令完成并经过校验、锁保护和原子保存。
|
||||
|
||||
## 当前指令
|
||||
|
||||
```text
|
||||
tz init
|
||||
tz status
|
||||
tz start
|
||||
tz stop
|
||||
tz 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 status|on|off
|
||||
tz proxy system status|on|off
|
||||
tz proxy env|noenv [bash|zsh|fish]
|
||||
tz proxy shell-init bash|zsh|fish
|
||||
|
||||
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 <name>
|
||||
|
||||
tz core add <directory>
|
||||
tz core list
|
||||
tz core info [name]
|
||||
tz core use [name]
|
||||
tz core remove <name>
|
||||
|
||||
tz config build|check|show
|
||||
tz completion generate bash|zsh|fish
|
||||
```
|
||||
|
||||
`profile list` 默认只显示当前 core family,`--all` 显示全部。`profile update` 不接名称,更新所有远程 profile;本地 profile 自动跳过。
|
||||
|
||||
`profile list`、`core list` 和节点 `list` 在 TTY 中显示编号、用 `*` 标出当前项并允许直接选择;非交互环境只输出简洁列表。`profile/core use` 保留,作为脚本和明确指定名称的稳定入口。详细来源和路径使用 `info` 查看。
|
||||
|
||||
`list/-l` 与 `node test` 都通过当前 core controller API 最多并发测试 8 个节点并按延迟排序。`list/-l` 在 TTY 中允许从测速后的列表选择节点;`node test --select` 自动选择最快的成功节点。默认 URL 为 Google 204,默认超时 1800ms;最新结果保存在 `cache/speedtest/latest.json`。
|
||||
|
||||
Mihomo 的 family 固定为 `clash`,sing-box 的 family 固定为 `sing-box`,不能互换。
|
||||
|
||||
## 简洁指令
|
||||
|
||||
```text
|
||||
tz # status,并测速当前节点
|
||||
tz on # 使用上次的可用 profile 启动并显示 status
|
||||
tz off | tz end # stop
|
||||
tz -l [keyword] # 测速、按延迟排序、搜索和选择
|
||||
tz select # profile list
|
||||
```
|
||||
|
||||
节点 keyword 使用不区分大小写的子串匹配。`list/-l` 在 TTY 中可输入测速后列表的编号切换当前节点;选择写入当前 profile,并在下次启动后恢复。
|
||||
|
||||
## 快捷键
|
||||
|
||||
快捷键是当前指令的命令缩写,完整写法始终可用:
|
||||
|
||||
```text
|
||||
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 补全通过 `tz completion generate <shell>` 生成。例如 Bash 当前会话可执行 `eval "$(tz completion generate bash)"`。
|
||||
|
||||
## Proxy 与 TUN
|
||||
|
||||
`proxy terminal on|off` 保存终端代理状态。子进程不能直接修改父 shell,因此当前 shell 使用 `eval "$(tz proxy env)"` 或 `eval "$(tz proxy noenv)"`;长期使用把 `eval "$(tz proxy shell-init bash)"` 加入对应 shell 启动文件。Fish 和 Zsh 使用各自的 shell 参数。
|
||||
|
||||
`proxy system on|off` 使用 GNOME `gsettings` 设置 HTTP、HTTPS、SOCKS 和 ignore-hosts,端口与 bypass 均来自 TZ 配置。开启前要求 core 正在运行,避免桌面流量指向空端口。TZ 会先私有备份原桌面代理,关闭或应用失败时逐项恢复;未由 TZ 开启时,`system off` 不修改桌面设置。`proxy on|off` 同时控制 terminal 和 system。
|
||||
|
||||
`tun on|off` 检查当前 core 的 TUN capability 和 `/dev/net/tun`。开启还要求受管 core 二进制具有 `CAP_NET_ADMIN`;缺少时打印对应的 `sudo setcap cap_net_admin,cap_net_raw+ep ...` 命令。运行中的切换会安全重启,失败时恢复原状态。
|
||||
|
||||
## Profile 下载
|
||||
|
||||
URL 只允许 HTTP/HTTPS,并校验 DNS 与重定向目标。下载按 family 使用对应 provider User-Agent:Clash 对齐 `mh`,sing-box 对齐 `sb`,以支持服务端按客户端返回不同格式。下载优先尝试环境代理,失败后回退直连,只要一种路径成功即完成添加或更新。实际成功路径保存为 profile 的 `download_via=proxy|direct`,可用 `tz profile info <name>` 查看;错误信息不会打印订阅 token。
|
||||
|
||||
## 运行闭环
|
||||
|
||||
`config build/check` 根据当前 core family 生成 Clash YAML 或 sing-box JSON,并调用 core manifest 的 check 命令。Mihomo profile 引用 GEOIP/GEOSITE 时,builder 从 core 包按需复制 `Country.mmdb` 和 `GeoSite.dat` 到独立工作目录;标准 core 包已携带这两份规则数据库,用户无需手工处理。自定义 core 包缺失时会明确提示,可先启用其他代理取得资源后补入 core 包。
|
||||
|
||||
`start/on` 读取当前 family 上次选择且 source 可用的 profile,在校验通过后启动受管进程、等待 API 并显示 status;没有可用 profile 时提示运行 `tz profile list`。`stop` 在发送信号前核对进程用户和 `/proc/<pid>/exe`;`status/tz` 简洁显示 core、profile、服务 PID,并实时测试当前节点延迟,失败时才回退显示缓存结果。
|
||||
|
||||
当前尚未开放的是 core 在线下载与自动更新。System proxy 的 v0.1 平台适配范围是 GNOME;其他 Linux 桌面环境后续增加 adapter。
|
||||
96
docs/core-package.md
Normal file
96
docs/core-package.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# TZ Core Package v1
|
||||
|
||||
本规范定义 TZ 如何发现、校验和调用本地代理内核。core 包包含运行契约、二进制和该 core 固定的只读运行资源,不包含 profile、用户配置、secret、日志、PID 或缓存。
|
||||
|
||||
## 目录结构
|
||||
|
||||
稳定槽位名推荐使用 `mihomo`、`sing-box`:
|
||||
|
||||
```text
|
||||
<data_dir>/cores/
|
||||
└── mihomo/
|
||||
├── core.toml
|
||||
├── mihomo
|
||||
├── Country.mmdb # Mihomo GEOIP 规则数据库
|
||||
├── GeoSite.dat # Mihomo GEOSITE 规则数据库
|
||||
├── LICENSE # 可选
|
||||
├── NOTICE # 可选
|
||||
└── README.md # 可选,TZ 不解析
|
||||
```
|
||||
|
||||
目录名必须与 `core.name` 完全一致。完整版本保存在 `core.version`;需要多版本并存时使用完整槽位名,例如 `mihomo-1.19.14`。
|
||||
|
||||
Mihomo 标准包固定携带 `Country.mmdb` 和 `GeoSite.dat`。生成配置实际引用 GEOIP/GEOSITE 时,TZ 才把缺失资源复制到 `state/runtime/<core>/`;用户无需逐个 profile 手工下载。自制 Mihomo core 包也应携带这两个文件,否则 TZ 会在 build/check 阶段给出明确提示。
|
||||
|
||||
## Manifest
|
||||
|
||||
```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
|
||||
|
||||
[commands.start]
|
||||
args = ["-d", "{workdir}", "-f", "{config}"]
|
||||
|
||||
[commands.check]
|
||||
args = ["-t", "-d", "{workdir}", "-f", "{config}"]
|
||||
|
||||
[commands.version]
|
||||
args = ["-v"]
|
||||
```
|
||||
|
||||
字段约束:
|
||||
|
||||
- schema 当前仅支持 `1`,未知字段会被拒绝。
|
||||
- name 只允许 ASCII 字母、数字、点、下划线和连字符。
|
||||
- family/format 当前只允许 `clash/yaml` 和 `sing-box/json`。
|
||||
- os/arch 必须等于当前运行平台的 Rust target 常量。
|
||||
- binary 与 entrypoint 必须是单个相对文件名,禁止绝对路径和 `..`。
|
||||
- binary 必须是普通可执行文件。
|
||||
- start 必填;check、version、reload 可选。命令存在即表示支持对应动作。
|
||||
- 参数只支持 `{config}` 和 `{workdir}`;TZ 直接执行 binary,不经过 shell。
|
||||
|
||||
## 安装方式
|
||||
|
||||
手工复制是标准方式,无注册数据库:
|
||||
|
||||
```bash
|
||||
cp -a ./mihomo <data_dir>/cores/mihomo
|
||||
chmod +x <data_dir>/cores/mihomo/mihomo
|
||||
tz core list
|
||||
```
|
||||
|
||||
本地便捷导入:
|
||||
|
||||
```bash
|
||||
tz core add ./mihomo
|
||||
tz core info mihomo
|
||||
tz core use mihomo
|
||||
tz core remove mihomo
|
||||
```
|
||||
|
||||
`core add` 只接收本地目录,不接收 URL。它会拒绝符号链接和特殊文件,复制到 staging,重新校验后原子移动;重名直接拒绝。成功后不自动选择或启动。
|
||||
|
||||
`core remove` 在受管进程运行时拒绝。服务停止时可以删除当前 core,并原子清空 current,同时清理同名 generated/runtime 派生目录。
|
||||
|
||||
## 网络分发
|
||||
|
||||
网络下载不属于 `core add`。未来 `core install` 必须使用可信 registry 提供的外部 SHA256,且 URL 只能是 HTTP/HTTPS;请求和每次重定向前必须拒绝 localhost、环回、私有和保留地址。
|
||||
10
docs/scope.md
Normal file
10
docs/scope.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# tz v0.1 范围
|
||||
|
||||
- 只支持 Linux,同一时间只运行一个当前用户的受管 core,不使用 systemd。
|
||||
- 支持本地导入 Mihomo 1.19.18(`family=clash`)和 sing-box 1.13.14(`family=sing-box`)。
|
||||
- 支持本地或 HTTP(S) profile;远程下载在环境代理与直连之间回退,并记录实际成功路径。
|
||||
- 支持 Clash YAML 与 sing-box JSON 的生成、真实 core 校验、启动、状态、节点选择与测速、重启和安全停止。
|
||||
- `profile list` 默认跟随当前 core family;`--all` 才跨 family 显示。
|
||||
- 支持 Bash/Zsh/Fish 终端代理环境输出与 shell hook;支持 GNOME `gsettings` system proxy 和 bypass。
|
||||
- 支持独立 TUN 开关、能力与权限检查、运行中重启及失败回滚;二进制 capability 由用户显式设置。
|
||||
- 暂不支持非 GNOME 桌面 system proxy adapter、core 在线安装或自动更新。
|
||||
976
docs/第一次开发日志.md
Normal file
976
docs/第一次开发日志.md
Normal file
|
|
@ -0,0 +1,976 @@
|
|||
# 环境搭建
|
||||
|
||||
省略
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 初始文件树
|
||||
|
||||
`cargo init --bin --name tz .`
|
||||
|
||||
#文件树1
|
||||
|
||||
```
|
||||
TZ/
|
||||
├── Cargo.toml
|
||||
├── Cargo.lock
|
||||
└── src/
|
||||
├── main.rs # tz 可执行程序入口
|
||||
└── lib.rs # 项目的主要代码入口
|
||||
```
|
||||
|
||||
## 常用代码
|
||||
|
||||
```bash
|
||||
# 检查代码,不生成最终程序
|
||||
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依赖
|
||||
|
||||
```bash
|
||||
cargo add clap --features derive
|
||||
```
|
||||
|
||||
`cargo add` 会修改当前 Package 的 `Cargo.toml`;`derive` feature 让我们可以使用 `#[derive(Parser)]` 和 `#[derive(Subcommand)]`。
|
||||
|
||||
|
||||
|
||||
2. 写文件功能 #文件树2
|
||||
|
||||
```bash
|
||||
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 # 定义用户可以输入什么
|
||||
```
|
||||
|
||||
3. `lib.rs`中添加声明
|
||||
|
||||
```rust
|
||||
pub mod cli;
|
||||
```
|
||||
|
||||
声明项目中存在 `cli` 模块,Rust 会自动寻找`src/cli.rs`或者`src/cli/mod.rs`
|
||||
|
||||
4. `src/cli/mod.rs`中管理子模块
|
||||
|
||||
```rust
|
||||
mod args; // cli 模块内部还有一个 args 子模块。
|
||||
|
||||
pub use args::{Cli, CliCommand, CoreCommand}; // 表示把三个类型重新导出到 cli 模块表面
|
||||
```
|
||||
|
||||
没有写 `pub`,所以外部不能直接访问`args`/`tz::cli::args::Cli`;
|
||||
|
||||
然后补充[args.rs](../src/cli/args.rs)即可,注释也写在里面
|
||||
|
||||
即使`main.rs`和`lib.rs`在同一个 Cargo package 中, 仍然是两个独立 crate。Rust 官方文档明确说明:同时存在 `src/lib.rs` 和 `src/main.rs` 时,package 中包含一个库 crate 和一个二进制 crate。
|
||||
|
||||
```tcl
|
||||
package tz
|
||||
├── library crate tz
|
||||
│ └── cli
|
||||
└── binary crate tz
|
||||
└── main
|
||||
```
|
||||
|
||||
|
||||
|
||||
5. 补充main.rs
|
||||
|
||||
```rust
|
||||
use clap::Parser;
|
||||
use tz::cli::Cli; // cli 当前是由 lib.rs 管理的,它属于库 crate tz,不是 main.rs 所属二进制 crate 的直接模块。
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
println!("{cli:#?}");
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
6. 测试,`--`表示隔开,后面的参数是输入给二进制文件的
|
||||
|
||||
```bash
|
||||
cargo run -- --help # 查看帮助
|
||||
cargo run -- status #
|
||||
cargo run -- core --help # 查看 core 的帮助
|
||||
cargo run -- unknown # 测试错误输入
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 常用代码
|
||||
|
||||
```bash
|
||||
cargo tree # 检查依赖
|
||||
cargo tree -i clap
|
||||
|
||||
cargo fmt # 统一代码格式
|
||||
cargo check # 类型检查和编译检查
|
||||
cargo clippy # 检查潜在问题和不规范写法
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# CLI 解析run态
|
||||
|
||||
1. 新增命令分发层 #文件树3
|
||||
|
||||
```bash
|
||||
src/
|
||||
├── main.rs
|
||||
├── lib.rs
|
||||
├── cli/
|
||||
│ ├── mod.rs
|
||||
│ ├── args.rs # 用户可以使用什么命令
|
||||
│ └── commands/ # 定义“收到命令之后调用什么”
|
||||
│ ├── mod.rs
|
||||
│ ├── status.rs
|
||||
│ ├── service.rs
|
||||
│ └── core.rs
|
||||
```
|
||||
|
||||
创建
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
2. 补充command代码
|
||||
|
||||
补充 [src/cli/mod.rs](../src/cli/mod.rs)
|
||||
|
||||
补充 [src/cli/commands/mod.rs](../src/cli/commands/mod.rs)
|
||||
|
||||
补充 [src/cli/commands/status.rs](../src/cli/commands/status.rs)
|
||||
|
||||
补充 [src/cli/commands/service.rs](../src/cli/commands/service.rs)
|
||||
|
||||
补充 [src/cli/commands/core.rs](../src/cli/commands/core.rs)
|
||||
|
||||
补充 [src/main.rs](../src/main.rs)
|
||||
|
||||
|
||||
|
||||
3. 测试
|
||||
|
||||
```bash
|
||||
cargo fmt
|
||||
cargo check
|
||||
cargo clippy
|
||||
```
|
||||
|
||||
然后
|
||||
|
||||
```bash
|
||||
cargo run -- status
|
||||
cargo run -- start
|
||||
cargo run -- stop
|
||||
cargo run -- restart
|
||||
cargo run -- core list
|
||||
```
|
||||
|
||||
```
|
||||
之前:
|
||||
用户输入 → Debug 打印
|
||||
|
||||
现在:
|
||||
用户输入
|
||||
↓
|
||||
Cli
|
||||
↓
|
||||
CliCommand
|
||||
↓
|
||||
match
|
||||
↓
|
||||
具体 command handler
|
||||
```
|
||||
|
||||
# application
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
mkdir -p src/application
|
||||
|
||||
touch src/application/mod.rs
|
||||
touch src/application/service.rs
|
||||
```
|
||||
|
||||
文件树4
|
||||
|
||||
````bash
|
||||
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
|
||||
|
||||
主要完成了指令的分发
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 路径系统
|
||||
|
||||
|
||||
|
||||
设定软件的路径系统,
|
||||
|
||||
```bash
|
||||
mkdir -p src/platform
|
||||
|
||||
touch src/platform/mod.rs
|
||||
touch src/platform/paths.rs
|
||||
```
|
||||
|
||||
文件树5
|
||||
|
||||
```bash
|
||||
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` 是文件系统路径的唯一配置源,文件只保存一次选定的四个目录,不保存布局类型或多个方案:
|
||||
|
||||
```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_dir`、`data_dir`、`state_dir`、`cache_dir`,回车使用模板值。
|
||||
- 如果 paths 文件已经存在,先询问是否继续;默认退出,不修改现有路径。
|
||||
- 初始化结束后始终打印 `export TZ_PATHS_TOML='...'` 提示。默认 `$HOME/.config/tz/paths.toml` 不需要设置变量;自定义 paths 文件可以确认后追加到 `~/.bashrc`。
|
||||
|
||||
## 开发测试
|
||||
|
||||
开发测试模板使用项目目录下的 `target/tz-dev`,示例:
|
||||
|
||||
```bash
|
||||
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`。
|
||||
|
||||
验证命令:
|
||||
|
||||
```bash
|
||||
cargo fmt --check
|
||||
cargo check
|
||||
cargo test --all-targets
|
||||
cargo clippy --all-targets -- -D warnings
|
||||
```
|
||||
|
||||
# 文件作用
|
||||
|
||||
接下来固定文件作用
|
||||
|
||||
`paths.toml` TZ_PATHS_TOML
|
||||
|
||||
```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的运行不太相关。默认不会修改,只是展示一下
|
||||
|
||||
```toml
|
||||
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.toml`:TZ 可以跨 core 表达的运行参数,包括端口、API、DNS 和 TUN 的复杂参数。是否开启 TUN 不在这里,开关保存在 `active.toml`。
|
||||
|
||||
```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/` 保存。
|
||||
|
||||
```toml
|
||||
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`
|
||||
|
||||
```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读取使用即可
|
||||
|
||||
```bash
|
||||
cores/
|
||||
└── mihomo/
|
||||
├── core.toml # Core 描述文件
|
||||
└── mihomo # 二进制
|
||||
```
|
||||
|
||||
这一部分还作为后续cores制作的参考标准
|
||||
|
||||
`core.toml`
|
||||
|
||||
```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}` 两个占位符。`binary` 与 `entrypoint` 必须是单个相对文件名;加载 core 时还会检查 schema、目录名、family/format 组合、二进制是否存在且可执行。
|
||||
|
||||
## 最终文件树
|
||||
|
||||
> 这里是结合文件作用+cores的
|
||||
|
||||
```toml
|
||||
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.toml`、`runtime.toml`、`active.toml`、`profiles.toml` 和 `core.toml`,由 `tz init` 生成默认文件,由 `tz status` 与 `tz 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].core`、`tun.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/yaml` 与 `sing-box/json`。
|
||||
- `binary` 和 `runtime.entrypoint` 必须是单个相对文件名;binary 还必须实际存在且可执行。
|
||||
- `commands.start` 必填;`commands.check`、`commands.version`、`commands.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.list`;domain 默认值负责生成四份 TOML,已有文件不覆盖。
|
||||
- 初始化先准备目录与默认配置,最后写 `paths.toml`,避免配置生成失败后留下已提交的路径文件。
|
||||
- `generated_dir` 与 `core_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 start`、`tz stop`、`tz restart`:生成并校验配置后真实控制受管进程;停止前核对进程用户和可执行文件。
|
||||
|
||||
`stop` 不会仅凭 PID 发送信号;`/proc/<pid>/exe` 与当前受管 core 不一致时直接拒绝。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
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 编辑器。配置文件是内部存储格式,所有写操作都经过类型校验、运行状态检查、锁保护和原子保存。
|
||||
|
||||
## 当前命令
|
||||
|
||||
```bash
|
||||
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 中进入选择界面;非交互调用使用 `list`。`set` 缺少 value 时只允许 TTY 交互。`start`、`stop`、`restart` 当前明确返回未实现错误,不打印成功状态。
|
||||
|
||||
## 简明指令
|
||||
|
||||
```bash
|
||||
tz start|on # 直接读取上一次的配置
|
||||
tz off|stop|end # 关闭服务,清理环境
|
||||
tz -l # 列出节点
|
||||
tz -l <name> # 不区分大小写的关键词搜索
|
||||
|
||||
tz completion generate bash|zsh|fish # 生成 shell 补全脚本
|
||||
# eval "$(tz completion generate bash)"
|
||||
|
||||
```
|
||||
|
||||
## 快捷键
|
||||
|
||||
```bash
|
||||
tz # tz status ,需要展示当前使用的core,profile,节点及其测速
|
||||
tz select # tz profile list
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 状态归属
|
||||
|
||||
- `settings.toml` 与 `runtime.toml` 由 `tz 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 在受管进程运行时拒绝 `use`、`update`、`remove` 等可能改变运行输入的操作。
|
||||
4. profile URL 只允许 HTTP(S),校验公网地址、DNS 全部结果和每次重定向;本地文件复制为受管副本。
|
||||
5. core 只接受本地目录,不接受 URL;导入成功后不自动选择、不自动启动。
|
||||
|
||||
# core 制作
|
||||
|
||||
## 目标与范围
|
||||
|
||||
TZ 当前支持统一的本地 core 包格式,用于识别和调用已经存在的 Mihomo 或 sing-box 二进制。core 包只描述运行契约,不包含 profile、用户配置、secret、PID、日志或缓存。
|
||||
|
||||
当前稳定槽位为 `mihomo` 和 `sing-box`,目录名必须与 `core.name` 相同:
|
||||
|
||||
```text
|
||||
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`](core-package.md) 为准。
|
||||
|
||||
```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"
|
||||
|
||||
[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.rs`:`tz.lock` 非阻塞独占锁、同目录临时文件、flush/fsync、原子 rename;profile 索引和 source 使用当前用户私有权限。
|
||||
- 新增 `platform/process.rs`:统一正整数 PID、存活和僵尸状态判断,供 status、profile/core use/remove 共用。
|
||||
- 新增 `platform/network.rs`:profile URL 只允许 HTTP/HTTPS,拒绝凭据、本机、环回、私有和保留地址;DNS 全结果与重定向逐次复核,优先使用环境代理并在失败后回退直连,限制超时、重定向和响应大小,错误不泄露订阅 URL。
|
||||
- 新增 typed setting registry,完成 `setting/list/get/set/reset`;不允许任意 TOML 路径编辑,保存后明确提示需要重新 build/start。
|
||||
- 完成 profile add/list/info/use/update/remove:URL 与本地文件都变成受管副本,family 固定映射格式,运行中禁止 use/update/remove,删除不触碰用户原文件。
|
||||
- core schema v1 新增必填 os/arch,稳定槽位统一为 `mihomo`、`sing-box`。
|
||||
- 完成 core add/list/info/use/remove:手工复制仍可直接扫描,add 只做本地安全导入,version 命令不经过 shell,运行中禁止 use/remove。
|
||||
- 新增正式规范 `docs/control-interface.md`、`docs/core-package.md` 和 `examples/cores/mihomo/` 制作模板。
|
||||
|
||||
## 当前边界与下一阶段
|
||||
|
||||
当前路线已完成 config builder、节点选择与测速、受管进程启停、TUN 独立控制及 shell/GNOME system proxy。core 在线更新与其他桌面环境 adapter 留在后续阶段。
|
||||
|
||||
# v0.1 可运行闭环
|
||||
|
||||
本章覆盖当前可运行行为;前文中的阶段性设计以这里和 `docs/control-interface.md` 为准。
|
||||
|
||||
## 当前指令
|
||||
|
||||
```bash
|
||||
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` 或对应文件提供。
|
||||
|
||||
```text
|
||||
nano_clash family=clash
|
||||
* mihomo version=1.19.18 family=clash
|
||||
```
|
||||
|
||||
Mihomo 读取 Clash 配置,所以其 family 必须为 `clash`;sing-box 才使用 `family=sing-box`。
|
||||
|
||||
## 简洁指令
|
||||
|
||||
```bash
|
||||
tz # status,并测速当前节点
|
||||
tz on # 使用上次的可用 profile 启动并显示 status
|
||||
tz off | tz end # stop
|
||||
tz -l [keyword] # 节点测速、延迟排序、搜索和选择
|
||||
tz select # 当前 family 的 profile 列表和选择
|
||||
```
|
||||
|
||||
## 快捷键
|
||||
|
||||
```bash
|
||||
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 -l` 和 `node test` 都走 controller delay API,最多 8 路并发、按延迟排序并缓存最新结果;`--select` 选择最快节点。`tz` 对当前节点实时测速,失败时才显示缓存结果。
|
||||
|
||||
Mihomo 标准 core 包携带 `Country.mmdb` 与 `GeoSite.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-Agent,sing-box 对齐 `sb`。同一订阅 URL 若按客户端返回 Clash YAML 或 sing-box JSON,`add` 与批量 `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/tun` 和 `CAP_NET_ADMIN`;运行中切换会重启,失败回滚,不自动执行 sudo/setcap。
|
||||
|
||||
配置生成已通过 Mihomo 1.19.18 和 sing-box 1.13.14 的真实 check。隔离测试覆盖 sing-box 的 start/status/list/select/stop,并继续覆盖 proxy 环境输出、TUN 状态和节点测速错误/超时路径。
|
||||
386
docs/第一版本.md
Normal file
386
docs/第一版本.md
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
|
||||
|
||||
# 项目组织
|
||||
|
||||
> 使用语言 Go
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> 第一版本需要实现的指令
|
||||
|
||||
```BASH
|
||||
tz status
|
||||
tz start
|
||||
tz stop
|
||||
tz restart
|
||||
|
||||
tz core list
|
||||
tz core add
|
||||
tz core remove
|
||||
tz core use
|
||||
tz core info
|
||||
|
||||
tz profile list
|
||||
tz profile add
|
||||
tz profile remove
|
||||
tz profile use
|
||||
tz profile update
|
||||
|
||||
tz config build
|
||||
tz config check
|
||||
|
||||
tz node list
|
||||
tz node select
|
||||
tz node test
|
||||
|
||||
tz log
|
||||
|
||||
```
|
||||
|
||||
> 文件树
|
||||
|
||||
|
||||
|
||||
```
|
||||
tz/
|
||||
├── Cargo.toml
|
||||
├── Cargo.lock
|
||||
├── rust-toolchain.toml
|
||||
├── README.md
|
||||
├── LICENSE
|
||||
│
|
||||
├── src/
|
||||
│ ├── main.rs
|
||||
│ ├── lib.rs
|
||||
│ │
|
||||
│ ├── cli/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── args.rs
|
||||
│ │ ├── output.rs
|
||||
│ │ └── commands/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── status.rs
|
||||
│ │ ├── service.rs
|
||||
│ │ ├── core.rs
|
||||
│ │ ├── profile.rs
|
||||
│ │ ├── group.rs
|
||||
│ │ ├── node.rs
|
||||
│ │ ├── mode.rs
|
||||
│ │ ├── tun.rs
|
||||
│ │ ├── proxy.rs
|
||||
│ │ ├── setting.rs
|
||||
│ │ ├── rule.rs
|
||||
│ │ ├── connection.rs
|
||||
│ │ ├── config.rs
|
||||
│ │ ├── log.rs
|
||||
│ │ └── diagnose.rs
|
||||
│ │
|
||||
│ ├── application/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── context.rs
|
||||
│ │ └── usecase/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── start.rs
|
||||
│ │ ├── stop.rs
|
||||
│ │ ├── restart.rs
|
||||
│ │ ├── reload.rs
|
||||
│ │ ├── switch_core.rs
|
||||
│ │ ├── switch_profile.rs
|
||||
│ │ ├── update_profile.rs
|
||||
│ │ └── select_node.rs
|
||||
│ │
|
||||
│ ├── domain/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── core.rs
|
||||
│ │ ├── profile.rs
|
||||
│ │ ├── settings.rs
|
||||
│ │ ├── runtime.rs
|
||||
│ │ ├── capability.rs
|
||||
│ │ ├── group.rs
|
||||
│ │ ├── node.rs
|
||||
│ │ ├── connection.rs
|
||||
│ │ └── error.rs
|
||||
│ │
|
||||
│ ├── adapter/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── traits.rs
|
||||
│ │ ├── registry.rs
|
||||
│ │ │
|
||||
│ │ ├── mihomo/
|
||||
│ │ │ ├── mod.rs
|
||||
│ │ │ ├── adapter.rs
|
||||
│ │ │ ├── command.rs
|
||||
│ │ │ ├── config.rs
|
||||
│ │ │ ├── controller.rs
|
||||
│ │ │ └── response.rs
|
||||
│ │ │
|
||||
│ │ └── sing_box/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── adapter.rs
|
||||
│ │ ├── command.rs
|
||||
│ │ ├── config.rs
|
||||
│ │ ├── controller.rs
|
||||
│ │ └── response.rs
|
||||
│ │
|
||||
│ ├── core_manager/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── manager.rs
|
||||
│ │ ├── registry.rs
|
||||
│ │ ├── package.rs
|
||||
│ │ ├── installer.rs
|
||||
│ │ └── remover.rs
|
||||
│ │
|
||||
│ ├── profile/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── manager.rs
|
||||
│ │ ├── store.rs
|
||||
│ │ ├── fetcher.rs
|
||||
│ │ ├── detector.rs
|
||||
│ │ └── format/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── clash.rs
|
||||
│ │ ├── sing_box.rs
|
||||
│ │ └── uri_list.rs
|
||||
│ │
|
||||
│ ├── config/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── builder.rs
|
||||
│ │ ├── overlay.rs
|
||||
│ │ ├── effective.rs
|
||||
│ │ ├── bypass.rs
|
||||
│ │ └── validator.rs
|
||||
│ │
|
||||
│ ├── runtime/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── manager.rs
|
||||
│ │ ├── process.rs
|
||||
│ │ ├── pid.rs
|
||||
│ │ ├── lock.rs
|
||||
│ │ ├── health.rs
|
||||
│ │ ├── state.rs
|
||||
│ │ └── log.rs
|
||||
│ │
|
||||
│ ├── platform/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── paths.rs
|
||||
│ │ ├── shell.rs
|
||||
│ │ ├── system_proxy.rs
|
||||
│ │ ├── service.rs
|
||||
│ │ └── linux/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── systemd.rs
|
||||
│ │ ├── signal.rs
|
||||
│ │ ├── tun.rs
|
||||
│ │ └── routes.rs
|
||||
│ │
|
||||
│ ├── storage/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── atomic_file.rs
|
||||
│ │ ├── core_store.rs
|
||||
│ │ ├── profile_store.rs
|
||||
│ │ ├── settings_store.rs
|
||||
│ │ └── runtime_store.rs
|
||||
│ │
|
||||
│ ├── infrastructure/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── command.rs
|
||||
│ │ ├── http.rs
|
||||
│ │ ├── download.rs
|
||||
│ │ ├── checksum.rs
|
||||
│ │ └── filesystem.rs
|
||||
│ │
|
||||
│ └── diagnose/
|
||||
│ ├── mod.rs
|
||||
│ ├── process.rs
|
||||
│ ├── ports.rs
|
||||
│ ├── api.rs
|
||||
│ ├── config.rs
|
||||
│ └── network.rs
|
||||
│
|
||||
├── assets/
|
||||
│ ├── defaults/
|
||||
│ │ └── settings.toml
|
||||
│ ├── templates/
|
||||
│ │ ├── mihomo.yaml
|
||||
│ │ └── sing-box.json
|
||||
│ └── systemd/
|
||||
│ └── tz.service
|
||||
│
|
||||
├── tests/
|
||||
│ ├── cli.rs
|
||||
│ ├── start_stop.rs
|
||||
│ ├── profile.rs
|
||||
│ └── adapter.rs
|
||||
│
|
||||
├── testdata/
|
||||
│ ├── profiles/
|
||||
│ │ ├── clash.yaml
|
||||
│ │ └── sing-box.json
|
||||
│ ├── api/
|
||||
│ │ ├── mihomo-proxies.json
|
||||
│ │ ├── mihomo-connections.json
|
||||
│ │ └── mihomo-version.json
|
||||
│ └── bin/
|
||||
│ └── fake-core
|
||||
│
|
||||
├── docs/
|
||||
│ ├── scope.md
|
||||
│ ├── domain-model.md
|
||||
│ ├── workflows.md
|
||||
│ ├── adapter-contract.md
|
||||
│ └── filesystem-layout.md
|
||||
│
|
||||
├── packaging/
|
||||
│ ├── systemd/
|
||||
│ └── completions/
|
||||
│
|
||||
└── scripts/
|
||||
├── install.sh
|
||||
├── uninstall.sh
|
||||
└── release.sh
|
||||
```
|
||||
|
||||
> 运行树
|
||||
|
||||
```
|
||||
语言 Rust
|
||||
异步运行时 Tokio
|
||||
CLI clap derive
|
||||
序列化 Serde
|
||||
HTTP reqwest
|
||||
错误类型 thiserror + anyhow
|
||||
日志 tracing
|
||||
项目配置 TOML
|
||||
Clash Profile YAML
|
||||
sing-box JSON
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
~/.config/tz/
|
||||
├── settings.toml
|
||||
├── current.toml
|
||||
├── bypass.list
|
||||
├── profiles/
|
||||
│ ├── home/
|
||||
│ │ ├── manifest.toml
|
||||
│ │ └── source.yaml
|
||||
│ └── company/
|
||||
│ ├── manifest.toml
|
||||
│ └── source.json
|
||||
└── overlays/
|
||||
├── common.toml
|
||||
├── mihomo.yaml
|
||||
└── sing-box.json
|
||||
|
||||
~/.local/share/tz/
|
||||
└── cores/
|
||||
├── mihomo/
|
||||
│ ├── current
|
||||
│ └── versions/
|
||||
│ └── 1.20.0/
|
||||
│ ├── manifest.toml
|
||||
│ └── bin/
|
||||
│ └── mihomo
|
||||
└── sing-box/
|
||||
├── current
|
||||
└── versions/
|
||||
└── 1.x/
|
||||
├── manifest.toml
|
||||
└── bin/
|
||||
└── sing-box
|
||||
|
||||
~/.local/state/tz/
|
||||
├── logs/
|
||||
│ ├── tz.log
|
||||
│ └── core.log
|
||||
├── builds/
|
||||
│ ├── effective-mihomo.yaml
|
||||
│ └── effective-sing-box.json
|
||||
├── history/
|
||||
└── runtime-history/
|
||||
|
||||
~/.cache/tz/
|
||||
├── downloads/
|
||||
├── subscriptions/
|
||||
└── latency/
|
||||
|
||||
${XDG_RUNTIME_DIR}/tz/
|
||||
├── tz.lock
|
||||
├── core.pid
|
||||
├── runtime.json
|
||||
├── effective-config
|
||||
└── control.sock
|
||||
```
|
||||
|
||||
|
||||
|
||||
# rust开发环境
|
||||
|
||||
```
|
||||
Rust + Tokio + clap
|
||||
Mihomo
|
||||
Clash YAML profile
|
||||
start / stop / status / log
|
||||
node list / select
|
||||
```
|
||||
|
||||
**现在使用一个 Package,包含一个 Library target 和一个 Binary target。**
|
||||
不使用 Workspace,也不使用多 Bin。
|
||||
|
||||
|
||||
|
||||
# 开发顺序
|
||||
|
||||
```
|
||||
第一阶段
|
||||
├── 路径系统
|
||||
├── SettingsStore
|
||||
├── CoreRegistry
|
||||
├── ProfileStore
|
||||
├── MihomoAdapter
|
||||
├── RuntimeManager
|
||||
├── tz start
|
||||
├── tz stop
|
||||
├── tz status
|
||||
└── tz log
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
第二阶段
|
||||
├── Mihomo Controller API
|
||||
├── group list/select
|
||||
├── node list/select/test
|
||||
├── mode
|
||||
├── reload
|
||||
└── profile update
|
||||
```
|
||||
|
||||
```
|
||||
第三阶段
|
||||
├── sing-box Adapter
|
||||
├── Capability 检测
|
||||
├── sing-box 配置生成
|
||||
├── TUN
|
||||
├── system proxy
|
||||
└── bypass
|
||||
```
|
||||
|
||||
```
|
||||
第四阶段
|
||||
├── core install/update
|
||||
├── diagnose
|
||||
├── connection
|
||||
├── completion
|
||||
└── 发布与安装脚本
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue