feat: ai native redesign#1
Open
nkanf-dev wants to merge 8 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an “AI native” redesign of mihomot by adding a dedicated HTTP API (/mhmt/*) for config.yaml read/write + reload workflows, introducing a token format for agent integration, and adding auto-detection/auto-installation of the mihomo kernel. It also refactors the CLI into serve (default) and tui, and adds skill.md + README updates describing the new agent workflow.
Changes:
- Add Axum-based HTTP API server exposing
/mhmt/config/*,/mhmt/reload,/mhmt/status, and/skill.md. - Add token generation/parsing and local persistence helpers for server records.
- Add mihomo runtime management (detect Docker vs binary, auto-download) and refactor CLI into
serve/tui.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| src/token.rs | Adds token format + parsing and local persistence of known servers. |
| src/server.rs | Implements Axum HTTP API endpoints for config raw/backup, reload, and status. |
| src/mihomo.rs | Adds mihomo runtime detection, start/stop/restart, reload via API, and auto-install/download. |
| src/main.rs | Refactors CLI into subcommands; adds default server mode boot sequence and token printing; TUI auto-detect. |
| src/config.rs | Adds mihomo config.yaml parsing, raw read/write, and backup/restore helpers. |
| skill.md | Adds AI agent operational instructions for tokens and API usage. |
| README.md | Updates positioning and documents new CLI/server mode, HTTP API, token format, and kernel management. |
| Cargo.toml | Adds new dependencies (axum/base64/serde_yaml/hostname/local-ip-address/tower-http). |
| Cargo.lock | Locks transitive dependencies for the new crates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+35
to
+41
| let sep_pos = rest | ||
| .find('_') | ||
| .context("Token missing separator after hostname")?; | ||
|
|
||
| let alias = &rest[..sep_pos]; | ||
| let encoded = &rest[sep_pos + 1..]; | ||
|
|
| let path = servers_path(); | ||
| fs::create_dir_all(path.parent().unwrap())?; | ||
|
|
||
| let mut servers = load_servers().unwrap_or_default(); |
Comment on lines
+264
to
+283
| /// Find backup files sorted by name (newest first) | ||
| fn find_backups(config_path: &Path) -> Vec<PathBuf> { | ||
| let dir = match config_path.parent() { | ||
| Some(d) => d, | ||
| None => return vec![], | ||
| }; | ||
| let stem = match config_path.file_stem().map(|s| s.to_string_lossy().to_string()) { | ||
| Some(s) => s, | ||
| None => return vec![], | ||
| }; | ||
|
|
||
| let mut backups: Vec<PathBuf> = match std::fs::read_dir(dir) { | ||
| Ok(entries) => entries | ||
| .filter_map(|e| e.ok()) | ||
| .map(|e| e.path()) | ||
| .filter(|p| { | ||
| p.file_name() | ||
| .map(|n| n.to_string_lossy().starts_with(&format!("{}.bak.", stem))) | ||
| .unwrap_or(false) | ||
| }) |
Comment on lines
+54
to
+57
| /// Create a backup of config.yaml with timestamp, returns backup path | ||
| pub fn backup_config(path: &Path) -> Result<PathBuf> { | ||
| let timestamp = chrono_timestamp(); | ||
| let backup_path = path.with_extension(format!("yaml.bak.{}", timestamp)); |
Comment on lines
+105
to
+108
| // Write new config | ||
| if let Err(e) = config::write_raw(&state.config_path, &body) { | ||
| return (StatusCode::BAD_REQUEST, format!("Invalid config: {}", e)).into_response(); | ||
| } |
Comment on lines
+141
to
+148
| /// Trigger mihomo reload via its API (PATCH /configs) | ||
| pub async fn reload(endpoint: &str, secret: &str, config_path: &Path) -> Result<()> { | ||
| let content = std::fs::read_to_string(config_path) | ||
| .with_context(|| format!("Failed to read {}", config_path.display()))?; | ||
|
|
||
| let client = reqwest::Client::new(); | ||
| let url = format!("{}/configs?force=true", endpoint); | ||
| let mut req = client.put(&url).body(content).header("Content-Type", "application/yaml"); |
Comment on lines
+218
to
+225
| // Check if likely CN (fast heuristic: try ghproxy first) | ||
| if is_likely_cn() { | ||
| urls.push(format!("{}/{}", GITHUB_RELEASE_URL, filename)); | ||
| urls = vec![format!( | ||
| "{}{}/{}", | ||
| GHPROXY_PREFIX, GITHUB_RELEASE_URL, filename | ||
| )]; | ||
| urls.push(format!("{}/{}", GITHUB_RELEASE_URL, filename)); |
| | `/connections` | GET | 查看活跃连接 | | ||
| | `/version` | GET | 获取内核版本 | | ||
|
|
||
| mihomo API 的 endpoint 和 secret 与 mihomot 相同(同一台服务器)。 |
Comment on lines
+108
to
+112
| mihomot exposes an HTTP API for config.yaml operations that mihomo's native API doesn't cover. | ||
|
|
||
| All `/mhmt/` endpoints require auth: `Authorization: Bearer {secret}` (same secret as mihomo). | ||
|
|
||
| | Method | Path | Description | |
| serde_json = "1.0.147" | ||
| serde_yaml = "0.9" | ||
| tokio = { version = "1.48.0", features = ["full"] } | ||
| tower-http = { version = "0.6", features = ["cors"] } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/mhmt/endpoints) for config.yaml read/write operationsmhmt_{hostname}_{base64(secret)}) for AI agent integrationserve(default) andtuisubcommandsTest plan
mihomotstartup prints token and starts API servermihomot tuiauto-connects to mihomo