Sfoglia il codice sorgente

refactor(project): 统一将Agent重命名为Server并更新构建配置

同步更新.gitignore、build.ps1及所有文档中的术语,确保命名一致性。
yangkaixiang 1 mese fa
parent
commit
a3e199f452
54 ha cambiato i file con 247 aggiunte e 247 eliminazioni
  1. 6 6
      .gitignore
  2. 11 11
      build.ps1
  3. 5 5
      docs/01-总体方案.md
  4. 2 2
      docs/02-网口识别规则.md
  5. 5 5
      docs/03-通信与HTTP_API.md
  6. 5 5
      docs/04-客户端流程与MVP.md
  7. 7 7
      docs/05-Server模块设计.md
  8. 3 3
      docs/06-netplan修改策略.md
  9. 14 14
      docs/07-Server首阶段实现清单.md
  10. 34 34
      docs/08-构建与编译.md
  11. 4 4
      scripts/linux-negative-test.sh
  12. 6 6
      scripts/linux-smoke-test.sh
  13. 15 15
      server/cmd/networktool-server/main.go
  14. 1 1
      server/go.mod
  15. 2 2
      server/internal/auth/auth.go
  16. 4 4
      server/internal/config/config.go
  17. 3 3
      server/internal/deviceinfo/deviceinfo.go
  18. 5 5
      server/internal/discovery/discovery.go
  19. 18 18
      server/internal/httpserver/server.go
  20. 2 2
      server/internal/model/types.go
  21. 1 1
      server/internal/network/configreader/configreader.go
  22. 2 2
      server/internal/network/interfaces/interfaces.go
  23. 2 2
      server/internal/network/netplan/netplan.go
  24. 1 1
      server/internal/network/validator/validator.go
  25. 1 1
      server/internal/network/verify/verify.go
  26. 1 1
      server/internal/tasks/tasks.go
  27. 2 2
      windows/NetworkTool.Client.sln
  28. 2 2
      windows/NetworkTool.Client/App.xaml
  29. 2 2
      windows/NetworkTool.Client/App.xaml.cs
  30. 3 3
      windows/NetworkTool.Client/DeviceDetailsWindow.xaml
  31. 16 16
      windows/NetworkTool.Client/DeviceDetailsWindow.xaml.cs
  32. 4 4
      windows/NetworkTool.Client/MainWindow.xaml
  33. 10 10
      windows/NetworkTool.Client/MainWindow.xaml.cs
  34. 1 1
      windows/NetworkTool.Client/Models/AdapterInfo.cs
  35. 1 1
      windows/NetworkTool.Client/Models/ApiCallResult.cs
  36. 3 3
      windows/NetworkTool.Client/Models/DiscoveredDevice.cs
  37. 1 1
      windows/NetworkTool.Client/Models/HealthCheckResult.cs
  38. 1 1
      windows/NetworkTool.Client/Models/RemoteApplyTaskResponse.cs
  39. 3 3
      windows/NetworkTool.Client/Models/RemoteDeviceInfo.cs
  40. 1 1
      windows/NetworkTool.Client/Models/RemoteInterfaceConfig.cs
  41. 1 1
      windows/NetworkTool.Client/Models/RemoteInterfaceInfo.cs
  42. 1 1
      windows/NetworkTool.Client/Models/RemoteSystemActionResponse.cs
  43. 1 1
      windows/NetworkTool.Client/Models/RemoteTaskResult.cs
  44. 1 1
      windows/NetworkTool.Client/Models/RemoteValidateResult.cs
  45. 1 1
      windows/NetworkTool.Client/NetworkTool.Client.csproj
  46. 2 2
      windows/NetworkTool.Client/README.md
  47. 1 1
      windows/NetworkTool.Client/Services/AdminPrivilegeService.cs
  48. 4 4
      windows/NetworkTool.Client/Services/DiscoveryService.cs
  49. 2 2
      windows/NetworkTool.Client/Services/NetworkAdapterService.cs
  50. 2 2
      windows/NetworkTool.Client/Services/NetworkConfigurationService.cs
  51. 2 2
      windows/NetworkTool.Client/Services/PasswordStoreService.cs
  52. 3 3
      windows/NetworkTool.Client/Services/ServerApiService.cs
  53. 6 6
      windows/README.md
  54. 10 10
      方案设计.md

+ 6 - 6
.gitignore

@@ -15,12 +15,12 @@ Desktop.ini
 *.log
 
 # Go
-agent/quickip-agent
-agent/quickip-agent.exe
-agent/quickip-agent-linux-amd64
-agent/bin/
-agent/dist/
-agent/coverage.out
+server/networktool-server
+server/networktool-server.exe
+server/networktool-server-linux-amd64
+server/bin/
+server/dist/
+server/coverage.out
 
 # .NET / WPF
 windows/**/bin/

+ 11 - 11
build.ps1

@@ -3,19 +3,19 @@ $ErrorActionPreference = "Stop"
 
 $repoRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
 $windowsDir = Join-Path $repoRoot "windows"
-$agentDir = Join-Path $repoRoot "agent"
-$windowsSolution = Join-Path $windowsDir "QuickIP.Client.sln"
-$agentLinuxOutput = Join-Path $agentDir "quickip-agent-linux-amd64"
+$serverDir = Join-Path $repoRoot "server"
+$windowsSolution = Join-Path $windowsDir "NetworkTool.Client.sln"
+$serverLinuxOutput = Join-Path $serverDir "networktool-server-linux-amd64"
 
 if (-not (Test-Path -LiteralPath $windowsSolution)) {
     throw "Windows solution not found: $windowsSolution"
 }
 
-if (-not (Test-Path -LiteralPath $agentDir)) {
-    throw "Agent directory not found: $agentDir"
+if (-not (Test-Path -LiteralPath $serverDir)) {
+    throw "Server directory not found: $serverDir"
 }
 
-Write-Host "[1/3] Building Windows client (Debug)..."
+Write-Host "[1/2] Building Windows client (Debug)..."
 dotnet build $windowsSolution -c Debug
 
 $previousGoos = $env:GOOS
@@ -23,12 +23,12 @@ $previousGoarch = $env:GOARCH
 $previousCgoEnabled = $env:CGO_ENABLED
 
 try {
-    Write-Host "[2/2] Building agent for Linux amd64..."
-    Set-Location -LiteralPath $agentDir
+    Write-Host "[2/2] Building server for Linux amd64..."
+    Set-Location -LiteralPath $serverDir
     $env:GOOS = "linux"
     $env:GOARCH = "amd64"
     $env:CGO_ENABLED = "0"
-    go build -o $agentLinuxOutput ./cmd/quickip-agent
+    go build -o $serverLinuxOutput ./cmd/networktool-server
 }
 finally {
     $env:GOOS = $previousGoos
@@ -38,5 +38,5 @@ finally {
 }
 
 Write-Host "Build completed."
-Write-Host "Windows client output: windows/QuickIP.Client/bin/Debug/net9.0-windows/"
-Write-Host "Agent Linux output: agent/quickip-agent-linux-amd64"
+Write-Host "Windows client output: windows/NetworkTool.Client/bin/Debug/net9.0-windows/"
+Write-Host "Server Linux output: server/networktool-server-linux-amd64"

+ 5 - 5
docs/01-总体方案.md

@@ -52,7 +52,7 @@
 6. 配置选中的目标网络接口
 7. 执行关机、重启等操作
 
-#### Linux Agent
+#### Linux Server
 
 建议技术:`Go + systemd service`
 
@@ -88,7 +88,7 @@
 1. `169.254.100.2` 不配置网关
 2. DHCP 地址可带默认网关
 3. DHCP 地址可带网关等网络参数
-4. Agent 只通过 `169.254.100.2` 提供服务
+4. Server 只通过 `169.254.100.2` 提供服务
 
 ### 4.2 LAN1 地址策略
 
@@ -116,13 +116,13 @@
 
 ### 5.1 网络访问限制
 
-1. Agent 仅监听 `169.254.100.2`
+1. Server 仅监听 `169.254.100.2`
 2. 当前阶段暂不限制来源 IP,仅通过密码校验控制访问
-3. `LAN2` 接入 4G 路由器后,4G 网络侧理论上可达 Agent,因此当前阶段要依赖密码保护
+3. `LAN2` 接入 4G 路由器后,4G 网络侧理论上可达 Server,因此当前阶段要依赖密码保护
 
 ### 5.2 鉴权方式
 
-当前采用固定初始化密码,暂时直接写死在 Agent 代码中。
+当前采用固定初始化密码,暂时直接写死在 Server 代码中。
 
 规则:
 

+ 2 - 2
docs/02-网口识别规则.md

@@ -9,8 +9,8 @@
 
 ## 2. 基本规则
 
-1. Agent 当前管理请求进入的物理有线接口,识别为逻辑上的 `LAN2`
-2. Agent 仅统计物理有线接口
+1. Server 当前管理请求进入的物理有线接口,识别为逻辑上的 `LAN2`
+2. Server 仅统计物理有线接口
 3. 需排除以下接口:
    - `lo`
    - docker 相关虚拟接口

+ 5 - 5
docs/03-通信与HTTP_API.md

@@ -7,7 +7,7 @@
 用途:
 
 1. Windows 客户端在指定网卡上广播发现设备
-2. Linux Agent 响应自身信息
+2. Linux Server 响应自身信息
 
 建议端口:`50000`
 
@@ -31,7 +31,7 @@
   "request_id": "6f7d2f6a-1111-2222-3333-444455556666",
   "device_id": "SN202605070001",
   "hostname": "ubuntu-server-01",
-  "agent_version": "1.0.0",
+  "server_version": "1.0.0",
   "lan2_ip": "169.254.100.2",
   "auth_required": true
 }
@@ -100,7 +100,7 @@ X-Admin-Password: Dt123$
   "message": "成功",
   "data": {
     "status": "运行中",
-    "agent_version": "1.0.0"
+    "server_version": "1.0.0"
   }
 }
 ```
@@ -119,7 +119,7 @@ X-Admin-Password: Dt123$
     "device_id": "SN202605070001",
     "hostname": "ubuntu-server-01",
     "os_version": "Ubuntu 24.04",
-    "agent_version": "1.0.0",
+    "server_version": "1.0.0",
     "uptime_seconds": 86400
   }
 }
@@ -465,7 +465,7 @@ X-Admin-Password: Dt123$
 }
 ```
 
-## 4. Agent 请求处理顺序
+## 4. Server 请求处理顺序
 
 每个 HTTP 请求统一按以下顺序处理:
 

+ 5 - 5
docs/04-客户端流程与MVP.md

@@ -6,7 +6,7 @@
 
 1. 客户端调用 `validate`
 2. 校验通过后调用 `apply`
-3. Agent 备份当前稳定配置
+3. Server 备份当前稳定配置
 4. 写入新的 `netplan`
 5. 执行 `netplan apply`
 6. 验证目标接口地址是否生效
@@ -132,7 +132,7 @@
 
 当前阶段建议使用当前用户范围注册表:
 
-1. 路径:`HKEY_CURRENT_USER\Software\QuickIP`
+1. 路径:`HKEY_CURRENT_USER\Software\NetworkTool`
 2. 值名:`SavedPassword`
 3. 仅在用户勾选 `记住密码` 且连接成功后写入
 4. 用户点击 `清除已保存密码` 时删除该值
@@ -152,7 +152,7 @@
    - 设备 ID
    - 主机名
    - Ubuntu 版本
-   - Agent 版本
+   - Server 版本
 2. 管理接口信息:
    - 逻辑标识 `LAN2`
    - 真实接口名
@@ -181,7 +181,7 @@
 1. 设备 ID
 2. 主机名
 3. Ubuntu 版本
-4. Agent 版本
+4. Server 版本
 
 #### 接口识别区建议字段
 
@@ -527,7 +527,7 @@
 1. 若已保存密码,连接页自动带出
 2. 用户仍可修改密码
 3. 新密码在连接或配置动作发生时自动覆盖旧密码
-4. 若连续出现密码错误,应提示用户检查当前密码是否与 Agent 启动参数一致
+4. 若连续出现密码错误,应提示用户检查当前密码是否与 Server 启动参数一致
 5. 需在文档和实现中明确:当前阶段密码保存在注册表中,为便捷优先方案
 
 ## 5. MVP 范围

+ 7 - 7
docs/05-Server模块设计.md

@@ -1,8 +1,8 @@
-# Agent 模块设计
+# Server 模块设计
 
 ## 1. 目标
 
-定义 Linux Agent 的内部模块划分、职责边界和建议实现顺序,作为后续编码的实现基线。
+定义 Linux Server 的内部模块划分、职责边界和建议实现顺序,作为后续编码的实现基线。
 
 ## 2. 设计原则
 
@@ -21,7 +21,7 @@
 
 职责:
 
-1. 保存 Agent 固定参数
+1. 保存 Server 固定参数
 2. 提供统一配置读取入口
 3. 输出运行时使用的配置对象
 
@@ -144,7 +144,7 @@
 1. 提供设备 ID
 2. 提供主机名
 3. 提供 Ubuntu 版本
-4. 提供 Agent 版本
+4. 提供 Server 版本
 5. 提供运行时长等基础信息
 
 ### 3.8 网络配置读取模块
@@ -339,9 +339,9 @@
 建议仅作参考:
 
 ```text
-agent/
+server/
   cmd/
-    quickip-agent/
+    networktool-server/
   internal/
     config/
     logger/
@@ -410,7 +410,7 @@ agent/
 
 ## 7. MVP 阶段建议收口
 
-为了尽快落地,Agent 首版建议遵循以下约束:
+为了尽快落地,Server 首版建议遵循以下约束:
 
 1. 只支持 Ubuntu 24
 2. 只支持 netplan

+ 3 - 3
docs/06-netplan修改策略.md

@@ -2,7 +2,7 @@
 
 ## 1. 目标
 
-定义首版 QuickIP 在 Ubuntu 24 上修改 netplan 的具体策略,重点说明:
+定义首版 NetworkTool 在 Ubuntu 24 上修改 netplan 的具体策略,重点说明:
 
 1. 修改哪个文件
 2. 修改哪些字段
@@ -77,7 +77,7 @@
 
 ### 5.1 需要写入或覆盖的字段
 
-对于目标接口,首版建议由 QuickIP 明确写入或覆盖以下字段:
+对于目标接口,首版建议由 NetworkTool 明确写入或覆盖以下字段:
 
 1. `dhcp4`
    - 设为 `false`
@@ -124,7 +124,7 @@
    - 补充或更新固定维护地址
    - 保留 DHCP4 能力
 2. 若管理接口节点不存在:
-   - 由 QuickIP 创建该接口节点
+   - 由 NetworkTool 创建该接口节点
 
 ## 7. 备份与回滚规则
 

+ 14 - 14
docs/07-Server首阶段实现清单.md

@@ -1,8 +1,8 @@
-# Agent 首阶段实现清单
+# Server 首阶段实现清单
 
 ## 1. 目标
 
-定义 Linux Agent 从零开始时,第一阶段应该优先完成的模块、接口、数据结构和验证顺序。
+定义 Linux Server 从零开始时,第一阶段应该优先完成的模块、接口、数据结构和验证顺序。
 
 第一阶段目标不是立即改 IP,而是先把“发现 + 连接 + 读取状态”整条只读链路打通。
 
@@ -10,7 +10,7 @@
 
 第一阶段只实现以下能力:
 
-1. Agent 启动
+1. Server 启动
 2. 读取固定运行配置
 3. 启动前为管理接口挂载维护地址
 4. UDP 广播发现
@@ -35,12 +35,12 @@
 用途:
 
 1. 客户端探活
-2. 判断 Agent 是否运行
+2. 判断 Server 是否运行
 
 最低返回:
 
 1. 运行状态
-2. Agent 版本
+2. Server 版本
 
 ### 3.2 `GET /api/device/info`
 
@@ -54,7 +54,7 @@
 1. 设备 ID
 2. 主机名
 3. Ubuntu 版本
-4. Agent 版本
+4. Server 版本
 5. 运行时长
 
 ### 3.3 `GET /api/network/interfaces`
@@ -102,7 +102,7 @@
 2. UDP 端口
 3. 固定维护地址
 4. 固定密码
-5. Agent 版本
+5. Server 版本
 6. HTTP 默认端口 `48888`
 7. 支持 `--ip` 与 `--port` 启动参数
 8. 支持 `--password` 启动参数,默认密码为 `Dt123$`
@@ -110,7 +110,7 @@
 建议示例:
 
 ```bash
-./quickip-agent --ip 169.254.100.2 --port 48888 --password 'Dt123$'
+./networktool-server --ip 169.254.100.2 --port 48888 --password 'Dt123$'
 ```
 
 ### 5.2 `logger`
@@ -171,12 +171,12 @@
 
 ## 6. 第一阶段建议数据结构
 
-### 6.1 AgentConfig
+### 6.1 ServerConfig
 
 建议字段:
 
 ```go
-type AgentConfig struct {
+type ServerConfig struct {
     HttpPort          int
     UdpPort           int
     MaintenanceIP     string
@@ -195,7 +195,7 @@ type DeviceInfo struct {
     DeviceID      string
     Hostname      string
     OSVersion     string
-    AgentVersion  string
+    ServerVersion  string
     UptimeSeconds int64
 }
 ```
@@ -249,9 +249,9 @@ type InterfacesResponse struct {
 建议优先创建:
 
 ```text
-agent/
+server/
   cmd/
-    quickip-agent/
+    networktool-server/
   internal/
     config/
     logger/
@@ -265,7 +265,7 @@ agent/
 
 ## 8. 第一阶段联调前置条件
 
-在 Windows 客户端开始联调前,Agent 至少应满足:
+在 Windows 客户端开始联调前,Server 至少应满足:
 
 1. 能在 Ubuntu 24 上正常启动
 2. 能监听 HTTP 端口

+ 34 - 34
docs/08-构建与编译.md

@@ -2,55 +2,55 @@
 
 ## 1. 目标
 
-统一记录 QuickIP 当前可直接使用的编译命令、默认输出位置,以及一键编译方式。
+统一记录 NetworkTool 当前可直接使用的编译命令、默认输出位置,以及一键编译方式。
 
 ## 2. Windows 客户端编译
 
 在仓库根目录执行:
 
 ```powershell
-dotnet build ".\windows\QuickIP.Client.sln" -c Debug
+dotnet build ".\windows\NetworkTool.Client.sln" -c Debug
 ```
 
 默认输出目录:
 
 ```text
-windows\QuickIP.Client\bin\Debug\net9.0-windows\
+windows\NetworkTool.Client\bin\Debug\net9.0-windows\
 ```
 
 说明:
 
 1. 保持使用默认 `Debug` 输出目录
-2. 如果 `QuickIP.Client.exe` 正在运行,重新编译可能因文件被占用而失败
+2. 如果 `NetworkTool.Client.exe` 正在运行,重新编译可能因文件被占用而失败
 
-## 3. Agent 编译
+## 3. Server 编译
 
-当前只需要编译 Linux amd64 版 Agent,用于上传到 Ubuntu 24 设备。
+当前只需要编译 Linux amd64 版 Server,用于上传到 Ubuntu 24 设备。
 
-本节默认前提:当前 PowerShell 已位于 `D:\git\QuickIP\agent`。
+本节默认前提:当前 PowerShell 已位于 `D:\git\NetworkTool\server`。
 
-### 3.1 编译 Linux amd64 版 Agent
+### 3.1 编译 Linux amd64 版 Server
 
-在 `agent\` 目录执行:
+在 `server\` 目录执行:
 
 ```powershell
 $env:GOOS="linux"
 $env:GOARCH="amd64"
 $env:CGO_ENABLED="0"
-go build -o ".\quickip-agent-linux-amd64" ".\cmd\quickip-agent"
+go build -o ".\networktool-server-linux-amd64" ".\cmd\networktool-server"
 ```
 
 输出文件:
 
 ```text
-agent\quickip-agent-linux-amd64
+server\networktool-server-linux-amd64
 ```
 
 说明:
 
 1. 该产物用于上传到 Ubuntu 24 设备
 2. 编译完成后,如有需要可把 `GOOS`、`GOARCH` 恢复到原值
-3. `go.mod` 位于 `agent\` 目录下,因此应先进入 `agent` 目录再执行 `go build`
+3. `go.mod` 位于 `server\` 目录下,因此应先进入 `server` 目录再执行 `go build`
 4. 在 Windows 上交叉编译 Linux 版时,需要设置 `CGO_ENABLED=0`
 
 ## 4. 一键编译
@@ -66,27 +66,27 @@ powershell -ExecutionPolicy Bypass -File .\build.ps1
 该脚本会依次完成:
 
 1. 编译 Windows 客户端到默认 `Debug` 目录
-2. 编译 Linux amd64 版 Agent 到 `agent\quickip-agent-linux-amd64`
+2. 编译 Linux amd64 版 Server 到 `server\networktool-server-linux-amd64`
 
 ## 5. 上传与启动
 
 以下示例基于当前联调环境:
 
 1. 远端主机:`x@192.168.229.136`
-2. 远端目标路径:`/home/x/quickip-agent`
-3. 本节默认前提:当前 PowerShell 已位于 `D:\git\QuickIP\agent`
+2. 远端目标路径:`/home/x/networktool-server`
+3. 本节默认前提:当前 PowerShell 已位于 `D:\git\NetworkTool\server`
 
-### 5.1 上传 Linux 版 Agent
+### 5.1 上传 Linux 版 Server
 
-如果当前已经在 `agent\` 目录执行:
+如果当前已经在 `server\` 目录执行:
 
 ```powershell
-scp .\quickip-agent-linux-amd64 x@192.168.229.136:/home/x/quickip-agent
+scp .\networktool-server-linux-amd64 x@192.168.229.136:/home/x/networktool-server
 ```
 
 说明:
 
-1. 该命令会把本地 Linux 版产物上传到远端并命名为 `quickip-agent`
+1. 该命令会把本地 Linux 版产物上传到远端并命名为 `networktool-server`
 2. 如果远端当前已有同名进程在运行,建议先停止旧进程再覆盖上传
 
 ### 5.2 登录远端主机
@@ -106,7 +106,7 @@ ssh x@192.168.229.136
 登录远端后执行:
 
 ```bash
-sudo pkill -f quickip-agent
+sudo pkill -f networktool-server
 ```
 
 ### 5.4 设置执行权限
@@ -114,7 +114,7 @@ sudo pkill -f quickip-agent
 登录远端后执行:
 
 ```bash
-chmod +x /home/x/quickip-agent
+chmod +x /home/x/networktool-server
 ```
 
 说明:
@@ -122,18 +122,18 @@ chmod +x /home/x/quickip-agent
 1. 上传完成后,建议显式补一次执行权限
 2. 不要依赖 `scp` 后远端权限一定正确
 
-### 5.5 以 root 身份启动 Agent
+### 5.5 以 root 身份启动 Server
 
 登录远端后执行:
 
 ```bash
-sudo nohup /home/x/quickip-agent --ip 169.254.100.2 --port 48888 --password 'Dt123$' >/home/x/quickip-agent-run.log 2>&1 < /dev/null &
+sudo nohup /home/x/networktool-server --ip 169.254.100.2 --port 48888 --password 'Dt123$' >/home/x/networktool-server-run.log 2>&1 < /dev/null &
 ```
 
 说明:
 
 1. 当前必须以 `root` 身份运行,才能写入 `netplan`、执行 `netplan apply`、重启和关机
-2. 如果不用 `sudo` 启动,配置应用和系统动作会被 Agent 直接拒绝
+2. 如果不用 `sudo` 启动,配置应用和系统动作会被 Server 直接拒绝
 
 ### 5.6 检查监听状态
 
@@ -146,7 +146,7 @@ ss -ltnp | grep 48888
 期望看到类似:
 
 ```text
-LISTEN ... 169.254.100.2:48888 ... quickip-agent
+LISTEN ... 169.254.100.2:48888 ... networktool-server
 ```
 
 ### 5.7 查看运行日志
@@ -154,7 +154,7 @@ LISTEN ... 169.254.100.2:48888 ... quickip-agent
 登录远端后执行:
 
 ```bash
-tail -n 50 /home/x/quickip-agent-run.log
+tail -n 50 /home/x/networktool-server-run.log
 ```
 
 ### 5.8 推荐顺序
@@ -162,16 +162,16 @@ tail -n 50 /home/x/quickip-agent-run.log
 本机 PowerShell:
 
 ```powershell
-scp .\quickip-agent-linux-amd64 x@192.168.229.136:/home/x/quickip-agent
+scp .\networktool-server-linux-amd64 x@192.168.229.136:/home/x/networktool-server
 ssh x@192.168.229.136
 ```
 
 远端登录后:
 
 ```bash
-sudo pkill -f quickip-agent
-chmod +x /home/x/quickip-agent
-sudo nohup /home/x/quickip-agent --ip 169.254.100.2 --port 48888 --password 'Dt123$' >/home/x/quickip-agent-run.log 2>&1 < /dev/null &
+sudo pkill -f networktool-server
+chmod +x /home/x/networktool-server
+sudo nohup /home/x/networktool-server --ip 169.254.100.2 --port 48888 --password 'Dt123$' >/home/x/networktool-server-run.log 2>&1 < /dev/null &
 ss -ltnp | grep 48888
 ```
 
@@ -183,20 +183,20 @@ ss -ltnp | grep 48888
 
 `go build ./...` 更适合做整模块编译检查,不保证在你期望的位置生成最终可执行文件。
 
-如果需要明确拿到 agent 产物,应使用带 `-o` 的命令,例如:
+如果需要明确拿到 server 产物,应使用带 `-o` 的命令,例如:
 
 ```powershell
 $env:GOOS="linux"
 $env:GOARCH="amd64"
 $env:CGO_ENABLED="0"
-go build -o ".\quickip-agent-linux-amd64" ".\cmd\quickip-agent"
+go build -o ".\networktool-server-linux-amd64" ".\cmd\networktool-server"
 ```
 
-### 6.2 Windows 客户端编译失败,提示 `QuickIP.Client.exe` 被占用
+### 6.2 Windows 客户端编译失败,提示 `NetworkTool.Client.exe` 被占用
 
 通常表示客户端程序仍在运行。
 
 处理方式:
 
-1. 先关闭正在运行的 `QuickIP.Client.exe`
+1. 先关闭正在运行的 `NetworkTool.Client.exe`
 2. 再重新执行 `dotnet build`

+ 4 - 4
scripts/linux-negative-test.sh

@@ -12,7 +12,7 @@ Usage:
   linux-negative-test.sh [options]
 
 Purpose:
-  Safe negative checks for the Linux agent.
+  Safe negative checks for the Linux server.
   This script does not call /api/network/apply and does not modify netplan.
 
 Checks:
@@ -23,8 +23,8 @@ Checks:
   - Invalid DNS should fail validate
 
 Options:
-  --host <ip>         Agent host, default: 169.254.100.2
-  --port <port>       Agent port, default: 48888
+  --host <ip>         Server host, default: 169.254.100.2
+  --port <port>       Server port, default: 48888
   --password <value>  Correct admin password, default: Dt123$
   --interface <name>  Existing target interface, default: suggested_target_interface
   --help              Show this help
@@ -73,7 +73,7 @@ TMP_DIR="$(mktemp -d)"
 trap 'rm -rf "$TMP_DIR"' EXIT
 
 log() {
-  printf '[quickip-negative] %s\n' "$*"
+  printf '[networktool-negative] %s\n' "$*"
 }
 
 request() {

+ 6 - 6
scripts/linux-smoke-test.sh

@@ -17,7 +17,7 @@ Usage:
   linux-smoke-test.sh [options]
 
 Default behavior:
-  Runs read-only smoke checks against the agent:
+  Runs read-only smoke checks against the server:
   - GET /api/health
   - GET /api/device/info
   - GET /api/network/interfaces
@@ -30,8 +30,8 @@ Apply and poll task:
   linux-smoke-test.sh --interface ens33 --ip 192.168.10.20 --prefix 24 --gateway 192.168.10.1 --dns 8.8.8.8,1.1.1.1 --apply
 
 Options:
-  --host <ip>           Agent host, default: 169.254.100.2
-  --port <port>         Agent port, default: 48888
+  --host <ip>           Server host, default: 169.254.100.2
+  --port <port>         Server port, default: 48888
   --password <value>    Admin password, default: Dt123$
   --interface <name>    Target Linux interface, e.g. ens33
   --ip <ipv4>           IPv4 address for validate/apply
@@ -43,7 +43,7 @@ Options:
 
 Notes:
   - Without --apply, the script never changes netplan.
-  - With --apply, the agent will rewrite netplan YAML and run netplan apply.
+  - With --apply, the server will rewrite netplan YAML and run netplan apply.
 EOF
 }
 
@@ -109,7 +109,7 @@ TMP_DIR="$(mktemp -d)"
 trap 'rm -rf "$TMP_DIR"' EXIT
 
 log() {
-  printf '[quickip-smoke] %s\n' "$*"
+  printf '[networktool-smoke] %s\n' "$*"
 }
 
 request() {
@@ -268,7 +268,7 @@ result="$(request GET "/api/health")"
 http_code="$(printf '%s\n' "$result" | read_http_code)"
 body="$(printf '%s\n' "$result" | read_body)"
 assert_api_ok "health" "$http_code" "$body"
-log "agent_version=$(json_get "$body" "data.agent_version")"
+log "server_version=$(json_get "$body" "data.server_version")"
 
 log "device info"
 result="$(request GET "/api/device/info")"

+ 15 - 15
server/cmd/networktool-server/main.go

@@ -6,18 +6,18 @@ import (
 	"os/signal"
 	"syscall"
 
-	"quickip/internal/config"
-	"quickip/internal/deviceinfo"
-	"quickip/internal/discovery"
-	"quickip/internal/httpserver"
-	"quickip/internal/logger"
-	applyexecsvc "quickip/internal/network/applyexec"
-	configreadersvc "quickip/internal/network/configreader"
-	interfacesvc "quickip/internal/network/interfaces"
-	netplansvc "quickip/internal/network/netplan"
-	validatorsvc "quickip/internal/network/validator"
-	"quickip/internal/systemaction"
-	"quickip/internal/tasks"
+	"networktool/internal/config"
+	"networktool/internal/deviceinfo"
+	"networktool/internal/discovery"
+	"networktool/internal/httpserver"
+	"networktool/internal/logger"
+	applyexecsvc "networktool/internal/network/applyexec"
+	configreadersvc "networktool/internal/network/configreader"
+	interfacesvc "networktool/internal/network/interfaces"
+	netplansvc "networktool/internal/network/netplan"
+	validatorsvc "networktool/internal/network/validator"
+	"networktool/internal/systemaction"
+	"networktool/internal/tasks"
 )
 
 func main() {
@@ -27,7 +27,7 @@ func main() {
 	log := logger.New()
 	cfg := config.Load(os.Args[1:])
 	if os.Geteuid() != 0 {
-		log.Warn("agent is not running as root; netplan write/apply and system actions will fail")
+		log.Warn("server is not running as root; netplan write/apply and system actions will fail")
 	}
 	deviceSvc := deviceinfo.New(cfg)
 	interfaceSvc := interfacesvc.New(cfg)
@@ -52,10 +52,10 @@ func main() {
 
 	select {
 	case <-ctx.Done():
-		log.Info("agent shutting down")
+		log.Info("server shutting down")
 	case err := <-errCh:
 		if err != nil {
-			log.Error("agent stopped with error", "error", err.Error())
+			log.Error("server stopped with error", "error", err.Error())
 		}
 	}
 }

+ 1 - 1
server/go.mod

@@ -1,4 +1,4 @@
-module quickip
+module networktool
 
 go 1.22.0
 

+ 2 - 2
server/internal/auth/auth.go

@@ -4,8 +4,8 @@ import (
 	"encoding/json"
 	"net/http"
 
-	"quickip/internal/config"
-	"quickip/internal/model"
+	"networktool/internal/config"
+	"networktool/internal/model"
 )
 
 func Middleware(cfg config.Config, next http.Handler) http.Handler {

+ 4 - 4
server/internal/config/config.go

@@ -14,7 +14,7 @@ type Config struct {
 	MaintenanceIP    string
 	MaintenanceCIDR  string
 	AdminPassword    string
-	AgentVersion     string
+	ServerVersion    string
 	DeviceIDFallback string
 }
 
@@ -27,11 +27,11 @@ func Load(args []string) Config {
 		MaintenanceIP:    "169.254.100.2",
 		MaintenanceCIDR:  "169.254.100.2/16",
 		AdminPassword:    "Dt123$",
-		AgentVersion:     "0.1.0",
-		DeviceIDFallback: "quickip-device",
+		ServerVersion:    "0.1.0",
+		DeviceIDFallback: "networktool-device",
 	}
 
-	fs := flag.NewFlagSet("quickip-agent", flag.ContinueOnError)
+	fs := flag.NewFlagSet("networktool-server", flag.ContinueOnError)
 	fs.StringVar(&cfg.MaintenanceIP, "ip", cfg.MaintenanceIP, "maintenance IPv4 address")
 	fs.IntVar(&cfg.HTTPPort, "port", cfg.HTTPPort, "HTTP listen port")
 	fs.StringVar(&cfg.AdminPassword, "password", cfg.AdminPassword, "admin password")

+ 3 - 3
server/internal/deviceinfo/deviceinfo.go

@@ -7,8 +7,8 @@ import (
 	"strings"
 	"time"
 
-	"quickip/internal/config"
-	"quickip/internal/model"
+	"networktool/internal/config"
+	"networktool/internal/model"
 )
 
 type Service struct {
@@ -30,7 +30,7 @@ func (s *Service) Get() model.DeviceInfo {
 		DeviceID:      readMachineID(s.cfg.DeviceIDFallback),
 		Hostname:      hostname,
 		OSVersion:     readOSVersion(),
-		AgentVersion:  s.cfg.AgentVersion,
+		ServerVersion: s.cfg.ServerVersion,
 		UptimeSeconds: int64(time.Since(s.startedAt).Seconds()),
 	}
 }

+ 5 - 5
server/internal/discovery/discovery.go

@@ -6,10 +6,10 @@ import (
 	"fmt"
 	"net"
 
-	"quickip/internal/config"
-	"quickip/internal/deviceinfo"
-	"quickip/internal/logger"
-	"quickip/internal/model"
+	"networktool/internal/config"
+	"networktool/internal/deviceinfo"
+	"networktool/internal/logger"
+	"networktool/internal/model"
 )
 
 type Server struct {
@@ -61,7 +61,7 @@ func (s *Server) Run(ctx context.Context) error {
 			RequestID:       req.RequestID,
 			DeviceID:        device.DeviceID,
 			Hostname:        device.Hostname,
-			AgentVersion:    device.AgentVersion,
+			ServerVersion:   device.ServerVersion,
 			LAN2IP:          s.cfg.MaintenanceIP,
 			AuthRequired:    true,
 		}

+ 18 - 18
server/internal/httpserver/server.go

@@ -11,18 +11,18 @@ import (
 	"sync"
 	"time"
 
-	"quickip/internal/auth"
-	"quickip/internal/config"
-	"quickip/internal/deviceinfo"
-	"quickip/internal/logger"
-	"quickip/internal/model"
-	applyexecsvc "quickip/internal/network/applyexec"
-	configreadersvc "quickip/internal/network/configreader"
-	interfacesvc "quickip/internal/network/interfaces"
-	netplansvc "quickip/internal/network/netplan"
-	validatorsvc "quickip/internal/network/validator"
-	"quickip/internal/systemaction"
-	"quickip/internal/tasks"
+	"networktool/internal/auth"
+	"networktool/internal/config"
+	"networktool/internal/deviceinfo"
+	"networktool/internal/logger"
+	"networktool/internal/model"
+	applyexecsvc "networktool/internal/network/applyexec"
+	configreadersvc "networktool/internal/network/configreader"
+	interfacesvc "networktool/internal/network/interfaces"
+	netplansvc "networktool/internal/network/netplan"
+	validatorsvc "networktool/internal/network/validator"
+	"networktool/internal/systemaction"
+	"networktool/internal/tasks"
 )
 
 type Server struct {
@@ -160,7 +160,7 @@ func (r *statusRecorder) WriteHeader(statusCode int) {
 }
 
 func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request) {
-	writeJSON(w, http.StatusOK, model.APIResponse{Code: 0, Message: "成功", Data: map[string]any{"status": "运行中", "agent_version": s.cfg.AgentVersion}})
+	writeJSON(w, http.StatusOK, model.APIResponse{Code: 0, Message: "成功", Data: map[string]any{"status": "运行中", "server_version": s.cfg.ServerVersion}})
 }
 
 func (s *Server) handleDeviceInfo(w http.ResponseWriter, _ *http.Request) {
@@ -228,7 +228,7 @@ func (s *Server) handleApply(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	if !hasRootPrivileges() {
-		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Agent 未以 root 身份运行,无法写入 netplan 或执行 netplan apply。"}}})
+		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Server 未以 root 身份运行,无法写入 netplan 或执行 netplan apply。"}}})
 		return
 	}
 	var input model.InterfaceConfig
@@ -261,12 +261,12 @@ func (s *Server) handleRollback(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	if !hasRootPrivileges() {
-		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Agent 未以 root 身份运行,无法恢复 netplan 或执行 netplan apply。"}}})
+		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Server 未以 root 身份运行,无法恢复 netplan 或执行 netplan apply。"}}})
 		return
 	}
 	var input model.RollbackRequest
 	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
-		writeJSON(w, http.StatusBadRequest, model.APIResponse{Code: 2001, Message: "参数错误", Data: map[string][]string{"errors": {"请求体格式不正确。"}}})
+		writeJSON(w, http.StatusBadRequest, model.APIResponse{Code: 2001, Message: "参数错误", Data: map[string][]string{"errors": []string{"请求体格式不正确。"}}})
 		return
 	}
 	filePath, err := s.netplanSvc.FindSingleFile()
@@ -274,7 +274,7 @@ func (s *Server) handleRollback(w http.ResponseWriter, r *http.Request) {
 		writeJSON(w, http.StatusInternalServerError, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string]string{"error": err.Error()}})
 		return
 	}
-	backupPath := filePath + ".quickip.bak"
+	backupPath := filePath + ".networktool.bak"
 	if err := s.netplanSvc.Restore(filePath, backupPath); err != nil {
 		writeJSON(w, http.StatusInternalServerError, model.APIResponse{Code: 3004, Message: "回滚失败", Data: map[string]string{"error": err.Error()}})
 		return
@@ -314,7 +314,7 @@ func (s *Server) handleSystemAction(w http.ResponseWriter, r *http.Request, acti
 		return
 	}
 	if !hasRootPrivileges() {
-		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Agent 未以 root 身份运行,无法执行重启或关机。"}}})
+		writeJSON(w, http.StatusForbidden, model.APIResponse{Code: 4001, Message: "系统执行失败", Data: map[string][]string{"errors": []string{"Server 未以 root 身份运行,无法执行重启或关机。"}}})
 		return
 	}
 

+ 2 - 2
server/internal/model/types.go

@@ -10,7 +10,7 @@ type DeviceInfo struct {
 	DeviceID      string `json:"device_id"`
 	Hostname      string `json:"hostname"`
 	OSVersion     string `json:"os_version"`
-	AgentVersion  string `json:"agent_version"`
+	ServerVersion string `json:"server_version"`
 	UptimeSeconds int64  `json:"uptime_seconds"`
 }
 
@@ -53,7 +53,7 @@ type DiscoverResponse struct {
 	RequestID       string `json:"request_id"`
 	DeviceID        string `json:"device_id"`
 	Hostname        string `json:"hostname"`
-	AgentVersion    string `json:"agent_version"`
+	ServerVersion   string `json:"server_version"`
 	LAN2IP          string `json:"lan2_ip"`
 	AuthRequired    bool   `json:"auth_required"`
 }

+ 1 - 1
server/internal/network/configreader/configreader.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"quickip/internal/model"
+	"networktool/internal/model"
 
 	"gopkg.in/yaml.v3"
 )

+ 2 - 2
server/internal/network/interfaces/interfaces.go

@@ -9,8 +9,8 @@ import (
 	"sort"
 	"strings"
 
-	"quickip/internal/config"
-	"quickip/internal/model"
+	"networktool/internal/config"
+	"networktool/internal/model"
 )
 
 type Service struct {

+ 2 - 2
server/internal/network/netplan/netplan.go

@@ -5,7 +5,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"quickip/internal/model"
+	"networktool/internal/model"
 
 	"gopkg.in/yaml.v3"
 )
@@ -33,7 +33,7 @@ func (s *Service) FindSingleFile() (string, error) {
 }
 
 func (s *Service) Backup(path string) (string, error) {
-	backupPath := path + ".quickip.bak"
+	backupPath := path + ".networktool.bak"
 	data, err := os.ReadFile(path)
 	if err != nil {
 		return "", err

+ 1 - 1
server/internal/network/validator/validator.go

@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"net"
 
-	"quickip/internal/model"
+	"networktool/internal/model"
 )
 
 type Service struct{}

+ 1 - 1
server/internal/network/verify/verify.go

@@ -8,7 +8,7 @@ import (
 	"os/exec"
 	"strings"
 
-	"quickip/internal/model"
+	"networktool/internal/model"
 )
 
 type Service struct{}

+ 1 - 1
server/internal/tasks/tasks.go

@@ -6,7 +6,7 @@ import (
 	"sync/atomic"
 	"time"
 
-	"quickip/internal/model"
+	"networktool/internal/model"
 )
 
 type Service struct {

+ 2 - 2
windows/NetworkTool.Client.sln

@@ -1,9 +1,9 @@
-
+
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio Version 17
 VisualStudioVersion = 17.0.31903.59
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickIP.Client", "QuickIP.Client\QuickIP.Client.csproj", "{ED9AE150-9FB2-4107-9C60-991591555503}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetworkTool.Client", "NetworkTool.Client\NetworkTool.Client.csproj", "{ED9AE150-9FB2-4107-9C60-991591555503}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+ 2 - 2
windows/NetworkTool.Client/App.xaml

@@ -1,7 +1,7 @@
-<Application x:Class="QuickIP.Client.App"
+<Application x:Class="NetworkTool.Client.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:local="clr-namespace:QuickIP.Client"
+             xmlns:local="clr-namespace:NetworkTool.Client"
              StartupUri="MainWindow.xaml">
     <Application.Resources>
          

+ 2 - 2
windows/NetworkTool.Client/App.xaml.cs

@@ -1,8 +1,8 @@
-using System.Configuration;
+using System.Configuration;
 using System.Data;
 using System.Windows;
 
-namespace QuickIP.Client;
+namespace NetworkTool.Client;
 
 /// <summary>
 /// Interaction logic for App.xaml

+ 3 - 3
windows/NetworkTool.Client/DeviceDetailsWindow.xaml

@@ -1,4 +1,4 @@
-<Window x:Class="QuickIP.Client.DeviceDetailsWindow"
+<Window x:Class="NetworkTool.Client.DeviceDetailsWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="设备信息与接口配置"
@@ -44,8 +44,8 @@
             </Border>
             <Border Padding="14" Background="White" CornerRadius="10">
                 <StackPanel>
-                    <TextBlock FontSize="12" Foreground="#6B7280" Text="Agent 版本" />
-                    <TextBlock x:Name="RemoteAgentVersionTextBlock" Margin="0,8,0,0" FontSize="14" FontWeight="SemiBold" Foreground="#111827" Text="-" />
+                    <TextBlock FontSize="12" Foreground="#6B7280" Text="Server 版本" />
+                    <TextBlock x:Name="RemoteServerVersionTextBlock" Margin="0,8,0,0" FontSize="14" FontWeight="SemiBold" Foreground="#111827" Text="-" />
                 </StackPanel>
             </Border>
             </UniformGrid>

+ 16 - 16
windows/NetworkTool.Client/DeviceDetailsWindow.xaml.cs

@@ -3,15 +3,15 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
-using QuickIP.Client.Models;
-using QuickIP.Client.Services;
+using NetworkTool.Client.Models;
+using NetworkTool.Client.Services;
 
-namespace QuickIP.Client;
+namespace NetworkTool.Client;
 
 public partial class DeviceDetailsWindow : Window
 {
     private const int ApplyConfirmationTimeoutSeconds = 20;
-    private readonly AgentApiService _agentApiService = new();
+    private readonly ServerApiService _serverApiService = new();
     private readonly string _baseAddress;
     private readonly string _localIPv4;
     private readonly string _password;
@@ -46,16 +46,16 @@ public partial class DeviceDetailsWindow : Window
     private async Task LoadRemoteDetailsAsync()
     {
         ClearDetails();
-        var device = await _agentApiService.GetDeviceInfoAsync(_baseAddress, _password, _localIPv4);
+        var device = await _serverApiService.GetDeviceInfoAsync(_baseAddress, _password, _localIPv4);
         if (device is not null)
         {
             RemoteDeviceIdTextBlock.Text = device.DeviceId;
             RemoteHostnameTextBlock.Text = device.Hostname;
             RemoteOsVersionTextBlock.Text = device.OSVersion;
-            RemoteAgentVersionTextBlock.Text = device.AgentVersion;
+            RemoteServerVersionTextBlock.Text = device.ServerVersion;
         }
 
-        var interfaces = await _agentApiService.GetInterfacesAsync(_baseAddress, _password, _localIPv4);
+        var interfaces = await _serverApiService.GetInterfacesAsync(_baseAddress, _password, _localIPv4);
         if (interfaces is null)
         {
             ShowStatusMessage("设备已连接,但暂时无法读取 Linux 接口列表。");
@@ -79,7 +79,7 @@ public partial class DeviceDetailsWindow : Window
         RemoteDeviceIdTextBlock.Text = "-";
         RemoteHostnameTextBlock.Text = "-";
         RemoteOsVersionTextBlock.Text = "-";
-        RemoteAgentVersionTextBlock.Text = "-";
+        RemoteServerVersionTextBlock.Text = "-";
         RemoteTargetInterfaceComboBox.ItemsSource = null;
         RemoteConfigInterfaceTextBlock.Text = "-";
         RemoteConfigIpTextBlock.Text = "-";
@@ -120,7 +120,7 @@ public partial class DeviceDetailsWindow : Window
 
         try
         {
-            var result = await _agentApiService.GetInterfaceConfigAsync(_baseAddress, _password, _localIPv4, interfaceName);
+            var result = await _serverApiService.GetInterfaceConfigAsync(_baseAddress, _password, _localIPv4, interfaceName);
             if (!result.Success || result.Data is null)
             {
                 RemoteConfigInterfaceTextBlock.Text = interfaceName;
@@ -180,7 +180,7 @@ public partial class DeviceDetailsWindow : Window
         SetBusyState(true, "正在校验配置,请稍候...");
         try
         {
-            var result = await _agentApiService.ValidateInterfaceConfigAsync(_baseAddress, _password, _localIPv4, request);
+            var result = await _serverApiService.ValidateInterfaceConfigAsync(_baseAddress, _password, _localIPv4, request);
             _configValidated = result.Success && result.Data?.Valid == true;
             if (result.Data is not null)
             {
@@ -228,7 +228,7 @@ public partial class DeviceDetailsWindow : Window
         SetBusyState(true, "正在提交并应用配置,请稍候...");
         try
         {
-            var applyResult = await _agentApiService.ApplyInterfaceConfigAsync(_baseAddress, _password, _localIPv4, request);
+            var applyResult = await _serverApiService.ApplyInterfaceConfigAsync(_baseAddress, _password, _localIPv4, request);
             if (!applyResult.Success || applyResult.Data is null)
             {
                 ShowStatusMessage($"提交配置任务失败:{applyResult.Message}");
@@ -251,7 +251,7 @@ public partial class DeviceDetailsWindow : Window
         for (var i = 0; i < 20; i++)
         {
             await Task.Delay(1000);
-            var result = await _agentApiService.GetTaskAsync(_baseAddress, _password, _localIPv4, taskId);
+            var result = await _serverApiService.GetTaskAsync(_baseAddress, _password, _localIPv4, taskId);
             if (!result.Success || result.Data is null)
             {
                 if (result.StatusCode is null)
@@ -274,12 +274,12 @@ public partial class DeviceDetailsWindow : Window
                 var confirm = ShowApplyConfirmationDialog(ApplyConfirmationTimeoutSeconds);
                 if (confirm)
                 {
-                    var confirmResult = await _agentApiService.ConfirmApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
+                    var confirmResult = await _serverApiService.ConfirmApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
                     ShowStatusMessage(confirmResult.Success ? "已发送保留配置确认。" : $"发送确认失败:{confirmResult.Message}");
                 }
                 else
                 {
-                    var cancelResult = await _agentApiService.CancelApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
+                    var cancelResult = await _serverApiService.CancelApplyTaskAsync(_baseAddress, _password, _localIPv4, taskId);
                     ShowStatusMessage(cancelResult.Success ? "已取消保留配置,正在回滚。" : $"发送取消失败:{cancelResult.Message}");
                 }
             }
@@ -391,7 +391,7 @@ public partial class DeviceDetailsWindow : Window
         await ExecuteSystemActionAsync(
             "重启设备",
             "设备将立即重启,当前窗口和连接可能马上中断。是否继续?",
-            () => _agentApiService.RebootAsync(_baseAddress, _password, _localIPv4));
+            () => _serverApiService.RebootAsync(_baseAddress, _password, _localIPv4));
     }
 
     private async void ShutdownButton_OnClick(object sender, RoutedEventArgs e)
@@ -399,7 +399,7 @@ public partial class DeviceDetailsWindow : Window
         await ExecuteSystemActionAsync(
             "关闭设备",
             "设备将立即关机,当前窗口和连接可能马上中断。是否继续?",
-            () => _agentApiService.ShutdownAsync(_baseAddress, _password, _localIPv4));
+            () => _serverApiService.ShutdownAsync(_baseAddress, _password, _localIPv4));
     }
 
     private async Task ExecuteSystemActionAsync(string title, string confirmMessage, Func<Task<ApiCallResult<RemoteSystemActionResponse>>> action)

+ 4 - 4
windows/NetworkTool.Client/MainWindow.xaml

@@ -1,10 +1,10 @@
-<Window x:Class="QuickIP.Client.MainWindow"
+<Window x:Class="NetworkTool.Client.MainWindow"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          mc:Ignorable="d"
-         Title="QuickIP"
+         Title="NetworkTool"
          Height="680"
          Width="980"
          MinHeight="640"
@@ -141,13 +141,13 @@
                                              MinHeight="38"
                                              VerticalContentAlignment="Center"
                                              PasswordChanged="PasswordBox_OnPasswordChanged"
-                                             ToolTip="请输入当前 Agent 使用的管理密码。" />
+                                             ToolTip="请输入当前 Server 使用的管理密码。" />
                                 <TextBox x:Name="PasswordTextBox"
                                          Visibility="Collapsed"
                                          MinHeight="38"
                                          VerticalContentAlignment="Center"
                                          TextChanged="PasswordTextBox_OnTextChanged"
-                                         ToolTip="请输入当前 Agent 使用的管理密码。" />
+                                         ToolTip="请输入当前 Server 使用的管理密码。" />
                                 <Button x:Name="TogglePasswordVisibilityButton"
                                         Grid.Column="1"
                                         Margin="8,0,0,0"

+ 10 - 10
windows/NetworkTool.Client/MainWindow.xaml.cs

@@ -1,14 +1,14 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Threading;
-using QuickIP.Client.Models;
-using QuickIP.Client.Services;
+using NetworkTool.Client.Models;
+using NetworkTool.Client.Services;
 
-namespace QuickIP.Client;
+namespace NetworkTool.Client;
 
 public partial class MainWindow : Window
 {
@@ -16,7 +16,7 @@ public partial class MainWindow : Window
     private readonly PasswordStoreService _passwordStoreService = new();
     private readonly NetworkConfigurationService _networkConfigurationService = new();
     private readonly DiscoveryService _discoveryService = new();
-    private readonly AgentApiService _agentApiService = new();
+    private readonly ServerApiService _serverApiService = new();
     private readonly AdminPrivilegeService _adminPrivilegeService = new();
     private IReadOnlyList<AdapterInfo> _adapters = [];
     private bool _isShowingPassword;
@@ -172,7 +172,7 @@ public partial class MainWindow : Window
         {
             if (AdapterComboBox.SelectedItem is AdapterInfo adapter && adapter.IsReachableToMaintenance)
             {
-                var directResult = await _agentApiService.CheckHealthAsync("http://169.254.100.2:48888", GetCurrentPassword(), adapter.IPv4Address);
+                var directResult = await _serverApiService.CheckHealthAsync("http://169.254.100.2:48888", GetCurrentPassword(), adapter.IPv4Address);
                 if (directResult.Success)
                 {
                     SetStatus("连接成功,无需切换本机网卡。", true);
@@ -183,14 +183,14 @@ public partial class MainWindow : Window
                 if (directResult.StatusCode == 401)
                 {
                     SetStatus("该网卡可以直连管理口,但管理密码错误。", true);
-                    MessageBox.Show(this, "当前网卡已经可以直连 Agent,但密码校验失败,请确认密码是否正确。", "密码错误", MessageBoxButton.OK, MessageBoxImage.Warning);
+                    MessageBox.Show(this, "当前网卡已经可以直连 Server,但密码校验失败,请确认密码是否正确。", "密码错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                     return;
                 }
 
                 if (directResult.StatusCode == 403)
                 {
-                    SetStatus("该网卡可以直连管理口,但 Agent 拒绝访问,请确认远端是否还是旧版本。", true);
-                    MessageBox.Show(this, "当前网卡已经可以直连 Agent,但请求被拒绝。请确认 Linux 端是否运行的是最新版本 Agent。", "访问被拒绝", MessageBoxButton.OK, MessageBoxImage.Warning);
+                    SetStatus("该网卡可以直连管理口,但 Server 拒绝访问,请确认远端是否还是旧版本。", true);
+                    MessageBox.Show(this, "当前网卡已经可以直连 Server,但请求被拒绝。请确认 Linux 端是否运行的是最新版本 Server。", "访问被拒绝", MessageBoxButton.OK, MessageBoxImage.Warning);
                     return;
                 }
 
@@ -208,7 +208,7 @@ public partial class MainWindow : Window
 
             SetStatus("已发现设备,正在验证连接。", true);
 
-            var discoveredResult = await _agentApiService.CheckHealthAsync($"http://{device.Lan2Ip}:48888", GetCurrentPassword(), selectedAdapter?.IPv4Address ?? string.Empty);
+            var discoveredResult = await _serverApiService.CheckHealthAsync($"http://{device.Lan2Ip}:48888", GetCurrentPassword(), selectedAdapter?.IPv4Address ?? string.Empty);
             if (discoveredResult.Success)
             {
                 SetStatus("连接成功。", true);

+ 1 - 1
windows/NetworkTool.Client/Models/AdapterInfo.cs

@@ -1,6 +1,6 @@
 using System.Net.NetworkInformation;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class AdapterInfo
 {

+ 1 - 1
windows/NetworkTool.Client/Models/ApiCallResult.cs

@@ -1,4 +1,4 @@
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class ApiCallResult<T>
 {

+ 3 - 3
windows/NetworkTool.Client/Models/DiscoveredDevice.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class DiscoveredDevice
 {
@@ -10,8 +10,8 @@ public sealed class DiscoveredDevice
     [JsonPropertyName("hostname")]
     public required string Hostname { get; init; }
 
-    [JsonPropertyName("agent_version")]
-    public required string AgentVersion { get; init; }
+    [JsonPropertyName("server_version")]
+    public required string ServerVersion { get; init; }
 
     [JsonPropertyName("lan2_ip")]
     public required string Lan2Ip { get; init; }

+ 1 - 1
windows/NetworkTool.Client/Models/HealthCheckResult.cs

@@ -1,4 +1,4 @@
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class HealthCheckResult
 {

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteApplyTaskResponse.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteApplyTaskResponse
 {

+ 3 - 3
windows/NetworkTool.Client/Models/RemoteDeviceInfo.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteDeviceInfo
 {
@@ -13,8 +13,8 @@ public sealed class RemoteDeviceInfo
     [JsonPropertyName("os_version")]
     public string OSVersion { get; init; } = string.Empty;
 
-    [JsonPropertyName("agent_version")]
-    public string AgentVersion { get; init; } = string.Empty;
+    [JsonPropertyName("server_version")]
+    public string ServerVersion { get; init; } = string.Empty;
 
     [JsonPropertyName("uptime_seconds")]
     public long UptimeSeconds { get; init; }

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteInterfaceConfig.cs

@@ -1,4 +1,4 @@
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteInterfaceConfig
 {

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteInterfaceInfo.cs

@@ -2,7 +2,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteInterfaceAddress
 {

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteSystemActionResponse.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteSystemActionResponse
 {

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteTaskResult.cs

@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteTaskResult
 {

+ 1 - 1
windows/NetworkTool.Client/Models/RemoteValidateResult.cs

@@ -1,4 +1,4 @@
-namespace QuickIP.Client.Models;
+namespace NetworkTool.Client.Models;
 
 public sealed class RemoteValidateResult
 {

+ 1 - 1
windows/NetworkTool.Client/NetworkTool.Client.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <OutputType>WinExe</OutputType>

+ 2 - 2
windows/NetworkTool.Client/README.md

@@ -1,10 +1,10 @@
-# QuickIP.Client
+# NetworkTool.Client
 
 此目录已初始化为 WPF 客户端项目。
 
 当前已具备:
 
-1. `QuickIP.Client.csproj`
+1. `NetworkTool.Client.csproj`
 2. `App.xaml`
 3. `MainWindow.xaml`
 4. `Views/`

+ 1 - 1
windows/NetworkTool.Client/Services/AdminPrivilegeService.cs

@@ -1,6 +1,6 @@
 using System.Security.Principal;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
 public sealed class AdminPrivilegeService
 {

+ 4 - 4
windows/NetworkTool.Client/Services/DiscoveryService.cs

@@ -2,9 +2,9 @@ using System.Net;
 using System.Net.Sockets;
 using System.Text;
 using System.Text.Json;
-using QuickIP.Client.Models;
+using NetworkTool.Client.Models;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
 public sealed class DiscoveryService
 {
@@ -50,7 +50,7 @@ public sealed class DiscoveryService
             {
                 DeviceId = response.DeviceId ?? string.Empty,
                 Hostname = response.Hostname ?? string.Empty,
-                AgentVersion = response.AgentVersion ?? string.Empty,
+                ServerVersion = response.ServerVersion ?? string.Empty,
                 Lan2Ip = response.Lan2Ip ?? string.Empty,
                 AuthRequired = response.AuthRequired,
             };
@@ -66,7 +66,7 @@ public sealed class DiscoveryService
         public string? MessageType { get; set; }
         public string? DeviceId { get; set; }
         public string? Hostname { get; set; }
-        public string? AgentVersion { get; set; }
+        public string? ServerVersion { get; set; }
         public string? Lan2Ip { get; set; }
         public bool AuthRequired { get; set; }
     }

+ 2 - 2
windows/NetworkTool.Client/Services/NetworkAdapterService.cs

@@ -3,9 +3,9 @@ using System.Linq;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Net.Sockets;
-using QuickIP.Client.Models;
+using NetworkTool.Client.Models;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
 public sealed class NetworkAdapterService
 {

+ 2 - 2
windows/NetworkTool.Client/Services/NetworkConfigurationService.cs

@@ -1,8 +1,8 @@
 using System.Diagnostics;
 using System.Text;
-using QuickIP.Client.Models;
+using NetworkTool.Client.Models;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
 public sealed class NetworkConfigurationService
 {

+ 2 - 2
windows/NetworkTool.Client/Services/PasswordStoreService.cs

@@ -1,10 +1,10 @@
 using Microsoft.Win32;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
 public sealed class PasswordStoreService
 {
-    private const string RegistryPath = @"Software\QuickIP";
+    private const string RegistryPath = @"Software\NetworkTool";
     private const string ValueName = "SavedPassword";
 
     public string LoadPassword()

+ 3 - 3
windows/NetworkTool.Client/Services/ServerApiService.cs

@@ -3,11 +3,11 @@ using System.Net.Http;
 using System.Net.Http.Json;
 using System.Net.Sockets;
 using System.Text.Json;
-using QuickIP.Client.Models;
+using NetworkTool.Client.Models;
 
-namespace QuickIP.Client.Services;
+namespace NetworkTool.Client.Services;
 
-public sealed class AgentApiService
+public sealed class ServerApiService
 {
     private readonly JsonSerializerOptions _jsonOptions = new()
     {

+ 6 - 6
windows/README.md

@@ -1,14 +1,14 @@
 # Windows Client
 
-此目录用于存放 QuickIP 的 Windows 桌面客户端代码。
+此目录用于存放 NetworkTool 的 Windows 桌面客户端代码。
 
 建议结构:
 
 ```text
 windows/
-  QuickIP.Client.sln
-  QuickIP.Client/
-    QuickIP.Client.csproj
+  NetworkTool.Client.sln
+  NetworkTool.Client/
+    NetworkTool.Client.csproj
     App.xaml
     MainWindow.xaml
     Views/
@@ -20,8 +20,8 @@ windows/
 
 当前阶段已完成:
 
-1. `QuickIP.Client.sln`
-2. `QuickIP.Client.csproj`
+1. `NetworkTool.Client.sln`
+2. `NetworkTool.Client.csproj`
 3. 基础 WPF 入口文件
 4. `Views/`
 5. `ViewModels/`

+ 10 - 10
方案设计.md

@@ -1,4 +1,4 @@
-# QuickIP 方案设计
+# NetworkTool 方案设计
 
 本文档作为总入口,详细内容已拆分到 `docs` 目录。
 
@@ -28,8 +28,8 @@
    - MVP 范围
    - 后续扩展项
 
-5. `docs/05-Agent模块设计.md`
-   - Linux Agent 模块划分
+5. `docs/05-Server模块设计.md`
+   - Linux Server 模块划分
    - 请求处理链路
    - netplan 与回滚职责
    - 建议实现顺序
@@ -40,15 +40,15 @@
    - 备份与回滚规则
    - 首版实现边界
 
-7. `docs/07-Agent首阶段实现清单.md`
-   - Agent 第一阶段接口清单
+7. `docs/07-Server首阶段实现清单.md`
+   - Server 第一阶段接口清单
    - 建议结构体与模块顺序
    - 联调前置条件
    - 开发里程碑
 
 8. `docs/08-构建与编译.md`
    - Windows 客户端编译命令
-   - Agent Windows/Linux 编译命令
+   - Server Windows/Linux 编译命令
    - 一键编译脚本用法
    - 常见编译问题
 
@@ -57,20 +57,20 @@
 1. Linux 发行版:`Ubuntu 24`
 2. 网络管理方式:`netplan`
 3. 通信协议:`UDP + HTTP`
-4. 鉴权方式:固定初始化密码,当前阶段写死在 Agent 代码中
+4. 鉴权方式:固定初始化密码,当前阶段写死在 Server 代码中
 5. `LAN1`、`LAN2` 仅作为逻辑标识,实际操作对象为 Linux 真实接口名
 6. `LAN2` 保留固定维护地址 `169.254.100.2/16`,同时支持接 4G 路由器联网
 
 ## 仓库结构
 
 ```text
-QuickIP/
-  agent/
+NetworkTool/
+  server/
     cmd/
     internal/
     go.mod
   windows/
-    QuickIP.Client/
+    NetworkTool.Client/
   docs/
   方案设计.md
 ```