
Surge Manager
- 28 installs
- 17 repo stars
- Updated July 25, 2026
- dwsy/agent
Manages Surge proxy configuration files - adding rules, editing config and configuring Tailscale device direct-connect - so a solo builder can automate their network proxy setup from the agent.
About
surge-manager is a Claude Code skill for managing Surge proxy configuration, supporting rule additions, config editing, and Tailscale device direct-connect setup against the Surge profile file. A solo builder reaches for it to automate and tweak their local network proxy rules from the agent instead of hand-editing the config.
- Add and edit Surge rules
- Edit Surge config files
- Tailscale device direct-connect setup
Surge Manager by the numbers
- 28 all-time installs (skills.sh)
- Ranked #1,239 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dwsy/agent --skill surge-managerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 28 |
|---|---|
| repo stars | ★ 17 |
| Last updated | July 25, 2026 |
| Repository | dwsy/agent ↗ |
What it does
Manages Surge proxy configuration files - adding rules, editing config and configuring Tailscale device direct-connect - so a solo builder can automate their network proxy setup from the agent.
Who is it for?
Surge users automating proxy config from an agent
Skip if: Non-Surge networking setups
Files
Surge Manager Skill
用于管理 Surge 配置文件,支持规则添加、配置编辑、Tailscale 设备直连配置等操作。
配置文件路径
默认 Surge 配置文件路径:
~/Library/Application Support/Surge/Profiles/cc.conf主要功能
1. 添加直连规则
为指定的 IP 地址或域名添加直连规则。
使用场景:
- Tailscale 设备直连
- 内网服务直连
- 特定域名直连
规则类型:
IP-CIDR: IP 网段直连DOMAIN: 域名直连DOMAIN-SUFFIX: 域名后缀直连
2. 管理 bypass-tun
管理 TUN 模式下的直连网段列表。
使用场景:
- 添加内网网段直连
- 添加 VPN 网段直连
- 添加 Tailscale 网段直连
3. 添加 Tailscale 设备
自动为 Tailscale 设备添加直连规则(IP + 域名)。
Tailscale 网段:100.64.0.0/10 域名格式:设备名.ts.net
使用示例
添加单个设备直连
# 添加 IP 直连
IP-CIDR,100.89.35.126/32,🎯 全球直连,no-resolve
# 添加域名直连
DOMAIN,mbp.ts.net,🎯 全球直连添加 Tailscale 网段
# 在 bypass-tun 中添加
bypass-tun = 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,100.64.0.0/10
# 在规则中添加
IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolve
DOMAIN-SUFFIX,ts.net,🎯 全球直连批量添加 Tailscale 设备
为所有 Tailscale 设备添加单独规则:
# 从 tailscale status 获取设备列表后自动生成规则
IP-CIDR,100.89.35.126/32,🎯 全球直连,no-resolve
DOMAIN,mbp.ts.net,🎯 全球直连
IP-CIDR,100.107.176.21/32,🎯 全球直连,no-resolve
DOMAIN,tserver.ts.net,🎯 全球直连
# ... 更多设备配置结构
[General] 部分
bypass-tun = 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,100.64.0.0/10[Rule] 部分
[Rule]
# Tailscale 直连规则
IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolve
DOMAIN-SUFFIX,ts.net,🎯 全球直连
# 设备单独规则
IP-CIDR,100.89.35.126/32,🎯 全球直连,no-resolve
DOMAIN,mbp.ts.net,🎯 全球直连
# ... 其他规则
RULE-SET,https://raw.githubusercontent.com/...常见操作
查看当前配置
cat ~/Library/Application\ Support/Surge/Profiles/cc.conf备份配置
cp ~/Library/Application\ Support/Surge/Profiles/cc.conf ~/Library/Application\ Support/Surge/Profiles/cc.conf.backup重新加载配置
修改配置后,需要在 Surge 中重新加载配置使规则生效。
Tailscale 设备管理
获取设备列表
tailscale status设备信息格式
100.89.35.126 mbp Dwsy@ macOS -
100.107.176.21 tserver Dwsy@ linux active; direct 118.24.74.226:41641格式:IP地址 设备名 用户名 操作系统 状态
自动生成规则
从 tailscale status 输出自动生成直连规则:
# 第一列:IP 地址
# 第二列:设备名
# 域名:设备名.ts.net注意事项
1. 规则优先级:
- 具体规则(IP-CIDR /32、DOMAIN)优先于网段规则
- 规则顺序很重要,越靠前优先级越高
2. no-resolve 参数:
- IP 规则建议添加
no-resolve避免不必要的 DNS 查询
3. 配置备份:
- 修改前建议先备份配置文件
4. 重新加载:
- 修改后需要在 Surge 中重新加载配置
5. Tailscale 网段:
- Tailscale 使用 CGNAT 网段
100.64.0.0/10 - 域名统一使用
.ts.net后缀
扩展功能
添加代理规则
IP-CIDR,192.168.1.0/24,🚀 节点选择,no-resolve
DOMAIN,example.com,🚀 节点选择添加拦截规则
DOMAIN,ads.example.com,🛑 广告拦截
DOMAIN-SUFFIX,tracker.com,🍃 应用净化添加分流规则
DOMAIN-SUFFIX,youtube.com,📹 油管视频
DOMAIN-SUFFIX,netflix.com,🎥 奈飞视频故障排查
规则不生效
1. 检查规则顺序是否正确 2. 确认是否重新加载了配置 3. 使用 Surge 的规则测试功能验证
IP 无法直连
1. 确认 IP 在 bypass-tun 列表中 2. 检查是否有冲突的规则 3. 使用 ping 测试网络连通性
域名无法直连
1. 确认 DNS 解析正确 2. 检查域名规则拼写 3. 尝试使用 IP 规则替代
相关链接
- Surge 官方文档:https://manual.nssurge.com/
- Tailscale 官网:https://tailscale.com/
Surge Manager
Surge 配置管理技能,用于管理 Surge 配置文件,支持规则添加、配置编辑、Tailscale 设备管理等操作。
功能特性
- ✅ 添加直连规则(IP-CIDR、DOMAIN、DOMAIN-SUFFIX)
- ✅ 管理 bypass-tun 网段
- ✅ 自动从 Tailscale 获取设备并添加直连规则
- ✅ 列出当前直连规则
- ✅ 查找和删除规则
- ✅ 自动备份配置
文件结构
surge-manager/
├── SKILL.md # 技能文档
├── surge-config.sh # Bash 脚本版本
├── surge-config.ts # TypeScript 版本
└── README.md # 本文件快速开始
使用 Bash 脚本
# 添加 bypass-tun 网段
~/.pi/agent/skills/surge-manager/surge-config.sh add-bypass 100.64.0.0/10
# 添加 IP 规则
~/.pi/agent/skills/surge-manager/surge-config.sh add-ip 100.89.35.126/32
# 添加域名规则
~/.pi/agent/skills/surge-manager/surge-config.sh add-domain mbp.ts.net
# 添加域名后缀规则
~/.pi/agent/skills/surge-manager/surge-config.sh add-suffix ts.net
# 自动添加所有 Tailscale 设备
~/.pi/agent/skills/surge-manager/surge-config.sh add-tailscale
# 列出当前直连规则
~/.pi/agent/skills/surge-manager/surge-config.sh list
# 显示帮助
~/.pi/agent/skills/surge-manager/surge-config.sh help使用 TypeScript 版本
# 添加 bypass-tun 网段
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-bypass 100.64.0.0/10
# 添加 IP 规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-ip 100.89.35.126/32
# 添加域名规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-domain mbp.ts.net
# 添加域名后缀规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-suffix ts.net
# 自动添加所有 Tailscale 设备
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-tailscale
# 列出当前直连规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts list
# 查找规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts find mbp
# 删除规则
bun ~/.pi/agent/skills/surge-manager/surge-config.ts remove mbpTailscale 设备管理
自动添加所有设备
# Bash 版本
~/.pi/agent/skills/surge-manager/surge-config.sh add-tailscale
# TypeScript 版本
bun ~/.pi/agent/skills/surge-manager/surge-config.ts add-tailscale这个命令会: 1. 从 tailscale status 获取所有设备列表 2. 添加 100.64.0.0/10 网段到 bypass-tun 3. 添加 *.ts.net 域名后缀规则 4. 为每个设备添加单独的 IP 和域名规则
手动添加单个设备
# 添加 IP 规则
~/.pi/agent/skills/surge-manager/surge-config.sh add-ip 100.89.35.126/32
# 添加域名规则
~/.pi/agent/skills/surge-manager/surge-config.sh add-domain mbp.ts.net配置文件路径
默认配置文件路径:
~/Library/Application Support/Surge/Profiles/cc.conf可以通过环境变量自定义:
export SURGE_CONFIG="/path/to/your/surge.conf"
~/.pi/agent/skills/surge-manager/surge-config.sh list规则类型说明
IP-CIDR
用于 IP 地址或网段直连:
IP-CIDR,100.89.35.126/32,🎯 全球直连,no-resolve
IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolveDOMAIN
用于单个域名直连:
DOMAIN,mbp.ts.net,🎯 全球直连DOMAIN-SUFFIX
用于域名后缀直连(匹配所有子域名):
DOMAIN-SUFFIX,ts.net,🎯 全球直连常见使用场景
场景 1:添加内网网段直连
~/.pi/agent/skills/surge-manager/surge-config.sh add-bypass 192.168.1.0/24
~/.pi/agent/skills/surge-manager/surge-config.sh add-ip 192.168.1.0/24场景 2:添加 Tailscale 设备
# 自动添加所有设备
~/.pi/agent/skills/surge-manager/surge-config.sh add-tailscale
# 或手动添加特定设备
~/.pi/agent/skills/surge-manager/surge-config.sh add-ip 100.89.35.126/32
~/.pi/agent/skills/surge-manager/surge-config.sh add-domain mbp.ts.net场景 3:添加公司内网域名
~/.pi/agent/skills/surge-manager/surge-config.sh add-suffix company.local备份和恢复
每次修改配置前会自动创建备份:
# 备份文件格式
cc.conf.backup.20250109_094459
# 恢复备份
cp ~/Library/Application\ Support/Surge/Profiles/cc.conf.backup.20250109_094459 \
~/Library/Application\ Support/Surge/Profiles/cc.conf注意事项
1. 规则优先级:
- 具体规则(IP-CIDR /32、DOMAIN)优先于网段规则
- 规则顺序很重要,越靠前优先级越高
2. no-resolve 参数:
- IP 规则建议添加
no-resolve避免不必要的 DNS 查询
3. 重新加载配置:
- 修改后需要在 Surge 中重新加载配置使规则生效
4. Tailscale 网段:
- Tailscale 使用 CGNAT 网段
100.64.0.0/10 - 域名统一使用
.ts.net后缀
故障排查
规则不生效
1. 检查规则顺序是否正确 2. 确认是否重新加载了配置 3. 使用 Surge 的规则测试功能验证
IP 无法直连
1. 确认 IP 在 bypass-tun 列表中 2. 检查是否有冲突的规则 3. 使用 ping 测试网络连通性
域名无法直连
1. 确认 DNS 解析正确 2. 检查域名规则拼写 3. 尝试使用 IP 规则替代
相关链接
- Surge 官方文档
- Tailscale 官网
- SKILL.md - 完整技能文档
#!/usr/bin/env bash
#
# Surge 配置管理脚本
# 用于添加直连规则、管理 Tailscale 设备等
#
set -euo pipefail
# 默认配置文件路径
SURGE_CONFIG="${SURGE_CONFIG:-$HOME/Library/Application Support/Surge/Profiles/cc.conf}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查配置文件是否存在
check_config() {
if [[ ! -f "$SURGE_CONFIG" ]]; then
error "Surge 配置文件不存在: $SURGE_CONFIG"
exit 1
fi
}
# 备份配置
backup_config() {
local backup_path="${SURGE_CONFIG}.backup.$(date +%Y%m%d_%H%M%S)"
cp "$SURGE_CONFIG" "$backup_path"
info "已备份配置到: $backup_path"
}
# 添加 bypass-tun 网段
add_bypass_tun() {
local cidr="$1"
check_config
if grep -q "bypass-tun.*${cidr}" "$SURGE_CONFIG"; then
warn "网段 $cidr 已存在于 bypass-tun 中"
return 0
fi
backup_config
# 更新 bypass-tun 行
sed -i '' "s/bypass-tun = \(.*\)/bypass-tun = \1,${cidr}/" "$SURGE_CONFIG"
info "已添加 bypass-tun 网段: $cidr"
}
# 添加 IP-CIDR 规则
add_ip_rule() {
local cidr="$1"
local policy="${2:-🎯 全球直连}"
check_config
# 检查规则是否已存在
if grep -q "IP-CIDR,${cidr}" "$SURGE_CONFIG"; then
warn "IP 规则已存在: $cidr"
return 0
fi
backup_config
# 在 [Rule] 部分后添加规则
local rule="IP-CIDR,${cidr},${policy},no-resolve"
sed -i '' "/^\[Rule\]$/a\\
# Tailscale 直连规则\\
${rule}
" "$SURGE_CONFIG"
info "已添加 IP 规则: $rule"
}
# 添加 DOMAIN 规则
add_domain_rule() {
local domain="$1"
local policy="${2:-🎯 全球直连}"
check_config
# 检查规则是否已存在
if grep -q "DOMAIN,${domain}," "$SURGE_CONFIG"; then
warn "域名规则已存在: $domain"
return 0
fi
backup_config
# 在 [Rule] 部分后添加规则
local rule="DOMAIN,${domain},${policy}"
sed -i '' "/^\[Rule\]$/a\\
# Tailscale 直连规则\\
${rule}
" "$SURGE_CONFIG"
info "已添加域名规则: $rule"
}
# 添加 DOMAIN-SUFFIX 规则
add_domain_suffix_rule() {
local suffix="$1"
local policy="${2:-🎯 全球直连}"
check_config
# 检查规则是否已存在
if grep -q "DOMAIN-SUFFIX,${suffix}," "$SURGE_CONFIG"; then
warn "域名后缀规则已存在: $suffix"
return 0
fi
backup_config
# 在 [Rule] 部分后添加规则
local rule="DOMAIN-SUFFIX,${suffix},${policy}"
sed -i '' "/^\[Rule\]$/a\\
# Tailscale 直连规则\\
${rule}
" "$SURGE_CONFIG"
info "已添加域名后缀规则: $rule"
}
# 从 tailscale status 添加设备
add_tailscale_devices() {
check_config
info "从 tailscale status 获取设备列表..."
if ! command -v tailscale &> /dev/null; then
error "tailscale 命令未找到"
exit 1
fi
# 获取设备列表
local devices
devices=$(tailscale status 2>/dev/null | grep -v "^#" | grep -v "^$" | awk '{print $1, $2}')
if [[ -z "$devices" ]]; then
error "未获取到 Tailscale 设备列表"
exit 1
fi
backup_config
# 添加网段和域名后缀
add_bypass_tun "100.64.0.0/10" 2>/dev/null || true
# 添加整体规则
if ! grep -q "IP-CIDR,100.64.0.0/10" "$SURGE_CONFIG"; then
sed -i '' "/^\[Rule\]$/a\\
# Tailscale 直连规则\\
IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolve\\
DOMAIN-SUFFIX,ts.net,🎯 全球直连
" "$SURGE_CONFIG"
fi
# 为每个设备添加单独规则
while read -r ip name; do
if [[ -n "$ip" && -n "$name" ]]; then
# 检查是否已存在
if ! grep -q "IP-CIDR,${ip}/32" "$SURGE_CONFIG"; then
sed -i '' "/DOMAIN-SUFFIX,ts.net/a\\
IP-CIDR,${ip}/32,🎯 全球直连,no-resolve\\
DOMAIN,${name}.ts.net,🎯 全球直连
" "$SURGE_CONFIG"
info "已添加设备: $name ($ip)"
fi
fi
done <<< "$devices"
info "所有 Tailscale 设备已添加完成"
}
# 列出当前直连规则
list_rules() {
check_config
info "当前直连规则:"
echo ""
echo "=== bypass-tun 网段 ==="
grep "bypass-tun" "$SURGE_CONFIG" | sed 's/bypass-tun = / /' | tr ',' '\n' | grep -v "^$" | sed 's/^/ - /'
echo ""
echo "=== [Rule] 部分直连规则 ==="
awk '/^\[Rule\]$/,/^\[/{print}' "$SURGE_CONFIG" | grep -E "(IP-CIDR|DOMAIN|DOMAIN-SUFFIX)" | grep "🎯 全球直连" | sed 's/^/ /'
}
# 显示帮助
show_help() {
cat << EOF
Surge 配置管理脚本
用法: $0 <command> [args...]
命令:
add-bypass <cidr> 添加 bypass-tun 网段
add-ip <cidr> [policy] 添加 IP-CIDR 规则
add-domain <domain> [policy] 添加 DOMAIN 规则
add-suffix <suffix> [policy] 添加 DOMAIN-SUFFIX 规则
add-tailscale 从 tailscale status 添加所有设备
list 列出当前直连规则
help 显示此帮助信息
示例:
$0 add-bypass 100.64.0.0/10
$0 add-ip 100.89.35.126/32
$0 add-domain mbp.ts.net
$0 add-suffix ts.net
$0 add-tailscale
$0 list
环境变量:
SURGE_CONFIG 自定义配置文件路径 (默认: ~/Library/Application Support/Surge/Profiles/cc.conf)
EOF
}
# 主函数
main() {
local command="${1:-help}"
case "$command" in
add-bypass)
[[ $# -lt 2 ]] && { error "缺少参数: cidr"; show_help; exit 1; }
add_bypass_tun "$2"
;;
add-ip)
[[ $# -lt 2 ]] && { error "缺少参数: cidr"; show_help; exit 1; }
add_ip_rule "$2" "${3:-🎯 全球直连}"
;;
add-domain)
[[ $# -lt 2 ]] && { error "缺少参数: domain"; show_help; exit 1; }
add_domain_rule "$2" "${3:-🎯 全球直连}"
;;
add-suffix)
[[ $# -lt 2 ]] && { error "缺少参数: suffix"; show_help; exit 1; }
add_domain_suffix_rule "$2" "${3:-🎯 全球直连}"
;;
add-tailscale)
add_tailscale_devices
;;
list)
list_rules
;;
help|--help|-h)
show_help
;;
*)
error "未知命令: $command"
show_help
exit 1
;;
esac
echo ""
info "配置已更新,请在 Surge 中重新加载配置"
}
main "$@"#!/usr/bin/env bun
/**
* Surge 配置管理库
*
* 用于管理 Surge 配置文件,支持规则添加、配置编辑等操作
*/
import { readFileSync, writeFileSync, existsSync } from "fs";
import { join } from "path";
// 默认配置文件路径
const DEFAULT_CONFIG_PATH = join(
process.env.HOME || "",
"Library",
"Application Support",
"Surge",
"Profiles",
"cc.conf"
);
export interface SurgeConfig {
path: string;
content: string;
}
export interface TailscaleDevice {
ip: string;
name: string;
user?: string;
os?: string;
status?: string;
}
export class SurgeManager {
private configPath: string;
constructor(configPath?: string) {
this.configPath = configPath || process.env.SURGE_CONFIG || DEFAULT_CONFIG_PATH;
}
/**
* 读取配置文件
*/
readConfig(): SurgeConfig {
if (!existsSync(this.configPath)) {
throw new Error(`配置文件不存在: ${this.configPath}`);
}
const content = readFileSync(this.configPath, "utf-8");
return {
path: this.configPath,
content,
};
}
/**
* 写入配置文件
*/
writeConfig(content: string): void {
writeFileSync(this.configPath, content, "utf-8");
}
/**
* 备份配置文件
*/
backup(): string {
const backupPath = `${this.configPath}.backup.${Date.now()}`;
const { content } = this.readConfig();
writeFileSync(backupPath, content, "utf-8");
return backupPath;
}
/**
* 添加 bypass-tun 网段
*/
addBypassTun(cidr: string): void {
const { content } = this.readConfig();
const lines = content.split("\n");
let updated = false;
const newLines = lines.map((line) => {
if (line.startsWith("bypass-tun =")) {
const current = line.substring("bypass-tun = ".length);
if (!current.includes(cidr)) {
updated = true;
return `bypass-tun = ${current},${cidr}`;
}
}
return line;
});
if (updated) {
this.writeConfig(newLines.join("\n"));
console.log(`✓ 已添加 bypass-tun 网段: ${cidr}`);
} else {
console.log(`⊘ 网段已存在: ${cidr}`);
}
}
/**
* 添加规则到 [Rule] 部分
*/
addRule(rule: string, comment?: string): void {
const { content } = this.readConfig();
const lines = content.split("\n");
// 检查规则是否已存在
if (lines.some((line) => line.startsWith(rule.split(",")[0]))) {
console.log(`⊘ 规则已存在: ${rule}`);
return;
}
const newLines: string[] = [];
let inserted = false;
for (let i = 0; i < lines.length; i++) {
newLines.push(lines[i]);
// 在 [Rule] 后插入
if (!inserted && lines[i].trim() === "[Rule]") {
if (comment) {
newLines.push(`# ${comment}`);
}
newLines.push(rule);
inserted = true;
}
}
if (inserted) {
this.writeConfig(newLines.join("\n"));
console.log(`✓ 已添加规则: ${rule}`);
} else {
throw new Error("未找到 [Rule] 部分");
}
}
/**
* 添加 IP-CIDR 规则
*/
addIpRule(cidr: string, policy: string = "🎯 全球直连"): void {
const rule = `IP-CIDR,${cidr},${policy},no-resolve`;
this.addRule(rule, "Tailscale 直连规则");
}
/**
* 添加 DOMAIN 规则
*/
addDomainRule(domain: string, policy: string = "🎯 全球直连"): void {
const rule = `DOMAIN,${domain},${policy}`;
this.addRule(rule, "Tailscale 直连规则");
}
/**
* 添加 DOMAIN-SUFFIX 规则
*/
addDomainSuffixRule(suffix: string, policy: string = "🎯 全球直连"): void {
const rule = `DOMAIN-SUFFIX,${suffix},${policy}`;
this.addRule(rule, "Tailscale 直连规则");
}
/**
* 获取 Tailscale 设备列表
*/
async getTailscaleDevices(): Promise<TailscaleDevice[]> {
const { stdout } = Bun.spawn({
cmd: ["tailscale", "status"],
stdout: "pipe",
stderr: "pipe",
});
const output = await new Response(stdout).text();
const lines = output.split("\n");
const devices: TailscaleDevice[] = [];
for (const line of lines) {
// 跳过注释和空行
if (line.startsWith("#") || line.trim() === "") continue;
const parts = line.trim().split(/\s+/);
if (parts.length >= 2) {
devices.push({
ip: parts[0],
name: parts[1],
user: parts[2]?.replace("@", ""),
os: parts[3],
status: parts.slice(4).join(" "),
});
}
}
return devices;
}
/**
* 添加 Tailscale 设备直连规则
*/
async addTailscaleDevices(): Promise<void> {
console.log("从 tailscale status 获取设备列表...");
const devices = await this.getTailscaleDevices();
if (devices.length === 0) {
console.log("⊘ 未获取到 Tailscale 设备");
return;
}
this.backup();
// 添加网段和域名后缀
this.addBypassTun("100.64.0.0/10");
this.addIpRule("100.64.0.0/10");
this.addDomainSuffixRule("ts.net");
// 为每个设备添加单独规则
for (const device of devices) {
this.addIpRule(`${device.ip}/32`);
this.addDomainRule(`${device.name}.ts.net`);
console.log(` ✓ ${device.name} (${device.ip})`);
}
console.log(`✓ 已添加 ${devices.length} 个设备`);
}
/**
* 列出当前直连规则
*/
listDirectRules(): void {
const { content } = this.readConfig();
const lines = content.split("\n");
console.log("\n=== bypass-tun 网段 ===");
for (const line of lines) {
if (line.startsWith("bypass-tun =")) {
const cidrs = line.substring("bypass-tun = ".length).split(",");
for (const cidr of cidrs) {
console.log(` - ${cidr.trim()}`);
}
}
}
console.log("\n=== [Rule] 部分直连规则 ===");
let inRuleSection = false;
for (const line of lines) {
if (line.trim() === "[Rule]") {
inRuleSection = true;
continue;
}
if (inRuleSection && line.startsWith("[")) {
break;
}
if (inRuleSection && line.match(/^(IP-CIDR|DOMAIN|DOMAIN-SUFFIX)/) && line.includes("🎯 全球直连")) {
console.log(` ${line}`);
}
}
console.log("");
}
/**
* 查找规则
*/
findRule(pattern: string): string[] {
const { content } = this.readConfig();
const lines = content.split("\n");
return lines.filter((line) => {
if (!line.match(/^(IP-CIDR|DOMAIN|DOMAIN-SUFFIX)/)) return false;
return line.toLowerCase().includes(pattern.toLowerCase());
});
}
/**
* 删除规则
*/
removeRule(pattern: string): void {
const { content } = this.readConfig();
const lines = content.split("\n");
const newLines = lines.filter((line) => {
if (!line.match(/^(IP-CIDR|DOMAIN|DOMAIN-SUFFIX)/)) return true;
return !line.toLowerCase().includes(pattern.toLowerCase());
});
if (newLines.length < lines.length) {
this.writeConfig(newLines.join("\n"));
console.log(`✓ 已删除匹配规则: ${pattern}`);
} else {
console.log(`⊘ 未找到匹配规则: ${pattern}`);
}
}
}
// CLI 接口
if (import.meta.main) {
const manager = new SurgeManager();
const command = process.argv[2];
const args = process.argv.slice(3);
try {
switch (command) {
case "add-bypass":
if (!args[0]) throw new Error("缺少参数: cidr");
manager.addBypassTun(args[0]);
break;
case "add-ip":
if (!args[0]) throw new Error("缺少参数: cidr");
manager.addIpRule(args[0], args[1]);
break;
case "add-domain":
if (!args[0]) throw new Error("缺少参数: domain");
manager.addDomainRule(args[0], args[1]);
break;
case "add-suffix":
if (!args[0]) throw new Error("缺少参数: suffix");
manager.addDomainSuffixRule(args[0], args[1]);
break;
case "add-tailscale":
await manager.addTailscaleDevices();
break;
case "list":
manager.listDirectRules();
break;
case "find":
if (!args[0]) throw new Error("缺少参数: pattern");
const rules = manager.findRule(args[0]);
rules.forEach((rule) => console.log(` ${rule}`));
break;
case "remove":
if (!args[0]) throw new Error("缺少参数: pattern");
manager.removeRule(args[0]);
break;
default:
console.log(`
Surge 配置管理工具
用法: bun surge-config.ts <command> [args...]
命令:
add-bypass <cidr> 添加 bypass-tun 网段
add-ip <cidr> [policy] 添加 IP-CIDR 规则
add-domain <domain> [policy] 添加 DOMAIN 规则
add-suffix <suffix> [policy] 添加 DOMAIN-SUFFIX 规则
add-tailscale 从 tailscale status 添加所有设备
list 列出当前直连规则
find <pattern> 查找匹配规则
remove <pattern> 删除匹配规则
示例:
bun surge-config.ts add-bypass 100.64.0.0/10
bun surge-config.ts add-ip 100.89.35.126/32
bun surge-config.ts add-domain mbp.ts.net
bun surge-config.ts add-tailscale
bun surge-config.ts list
`);
}
console.log("\n✓ 配置已更新,请在 Surge 中重新加载配置");
} catch (error) {
console.error(`✗ 错误: ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
}
}