#!/usr/bin/env python3 """把 direct.yaml(真源)生成为 Clash Verge 的全局增强脚本 Script.js。 用法: python3 scripts/gen_clash_verge_script.py [--out 目标路径] 默认输出到 Clash Verge 数据目录 profiles/Script.js(全局直连规则的唯一正确机制, 见 clash-verge-config 记忆)。生成后需在 Clash Verge 界面点「重启内核」生效。 """ import argparse from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent DEFAULT_OUT = Path.home() / "Library/Application Support/io.github.clash-verge-rev.clash-verge-rev/profiles/Script.js" def load_payload(path: Path) -> list[str]: payload: list[str] = [] with path.open(encoding="utf-8") as f: for line in f: line = line.strip() if line.startswith("- "): payload.append(line[2:].strip()) if not payload: raise SystemExit(f"❌ direct.yaml 里没有 payload 条目: {path}") return payload def to_rule(entry: str) -> str: """rule-provider 条目(无策略)→ 完整规则(补 DIRECT)。""" if entry.endswith(",no-resolve"): return f"{entry[:-len(',no-resolve')]},DIRECT,no-resolve" return f"{entry},DIRECT" def render_script(payload: list[str]) -> str: rules = [f" {to_rule(e)!r}," for e in payload] lines = "\n".join(rules) return f"""// 由 vpn-rules/direct.yaml 生成 — 勿手改,改真源后重跑 gen_clash_verge_script.py。 // 全局直连规则:FRP 控制面、B站、国内 LLM、内网段、国区 iCloud、UGREEN 一律 DIRECT。 const prependRules = [ {lines} ]; function main(config, profileName) {{ const existingRules = Array.isArray(config.rules) ? config.rules : []; const existingRuleSet = new Set(existingRules); config.rules = [ ...prependRules.filter((rule) => !existingRuleSet.has(rule)), ...existingRules, ]; return config; }} """ def main() -> None: ap = argparse.ArgumentParser(description="direct.yaml → Clash Verge Script.js") ap.add_argument("--out", default=str(DEFAULT_OUT), help="输出路径") args = ap.parse_args() payload = load_payload(REPO_ROOT / "direct.yaml") script = render_script(payload) out = Path(args.out) out.parent.mkdir(parents=True, exist_ok=True) out.write_text(script, encoding="utf-8") print(f"✅ 已生成 {out}({len(payload)} 条规则)") print(" 请在 Clash Verge 界面点「重启内核」生效。") if __name__ == "__main__": main()