{
  "module": "rdp",
  "version": "1.0",
  "purpose": "RDP 远程桌面隧道开关。通过 SSH 反向隧道将 Windows 3389 端口暴露到 Aliyun 公网 IP，实现从外网远程桌面到 Windows。",
  "ui_location": "I Tab (Infrastructure) → RDP Remote Desktop section",

  "human_help": {
    "title": "RDP Remote Desktop",
    "description": [
      "通过 SSH 反向隧道把 Windows 的 RDP 端口(3389)暴露到 Aliyun 公网服务器(47.115.32.206:8080)。",
      "开启后在外网可用 mstsc /v:47.115.32.206:8080 远程桌面到 Windows。",
      "本功能依赖 EasyTier VPN 先连通 — SSH 到 246 的连接走 VPN 内网（10.144.144.1）。",
      "请先确保 EasyTier VPN 已 Connected，再点击 Enable。"
    ],
    "participants": [
      {"name": "老莫", "device": "Windows 192.168.1.16 (被控端)", "role": "本地操作 + 被远程桌面的目标机", "note": "运行 xmpp_bot 执行 SSH reverse tunnel; 暴露 3389"},
      {"name": "莫荷", "device": "Linux 192.168.1.246", "role": "easytier 节点 + dashboard 服务 5803", "note": "EasyTier VPN 节点 (10.144.144.1) + dashboard 代理 RDP toggle"},
      {"name": "小果", "device": "Mac (外网)", "role": "异地远程桌面发起端", "note": "老莫在办公室外用 Mac 通过 mstsc /v:47.115.32.206:8080 回连 Windows 操作。Mac 上需安装 Microsoft Remote Desktop 客户端"}
    ],
    "usage": [
      "1. 先在 EasyTier VPN section 点击 Turn On，确认 Connected",
      "2. 回到本 section 点击 Enable 启动 SSH 反向隧道",
      "3. 老莫在 Mac 外网运行 mstsc /v:47.115.32.206:8080 连接远程桌面到 Windows",
      "4. 不用时点击 Disable 关闭隧道"
    ],
    "troubleshooting": [
      "如果 Enable 返回失败：检查 EasyTier VPN 是否 Connected（RDP 依赖 VPN 内网 SSH）",
      "如果隧道状态一直 pending：检查 246 的 /etc/ssh/sshd_config 是否有 GatewayPorts yes",
      "如果 mstsc 连不上：检查 Aliyun 安全组是否放行 8080/TCP",
      "如果 timeout：从外网执行 Test-NetConnection 47.115.32.206 -Port 8080 看端口是否真的 listening",
      "Mac 上无 mstsc：安装 Microsoft Remote Desktop (App Store) 然后以 PC name 47.115.32.206:8080 加入"
    ],
    "related": "依赖 EasyTier VPN 内网通道，参见 EasyTier VPN section 的帮助"
  },

  "ai_spec": {
    "apis": [
      {"method": "GET", "path": "/api/rdp", "returns": "rdp_enabled + tunnel_running + public_endpoint(47.115.32.206:8080)", "proxied_to": "xmpp_bot /rdp action=status"},
      {"method": "POST", "path": "/api/rdp/toggle", "body": "{action: start|stop}", "returns": "{ok, message}", "proxied_to": "xmpp_bot /rdp action=start|stop"}
    ],
    "dependencies": [
      "xmpp_bot on Windows 192.168.1.16:5807 — /rdp HTTP endpoint (注: 5807 是为避免与 wechat-hermes-gateway 的 5802 端口冲突, 详见 ai_spec.known_issues.port_conflict)",
      "_bridge_post() + _BRIDGE_KEY in dashboard.py — proxy 机制同 EasyTier",
      "port_open() helper in dashboard.py — 检查 SSH 隧道端口 8080 是否监听",
      "EasyTier VPN 必须先 Connected — SSH 到 246 走 VPN 内网 10.144.144.1",
      "Mac 端需安装 Microsoft Remote Desktop 客户端 (App Store) — 小果作为外网发起端"
    ],
    "architecture": {
      "flow": "Dashboard(246:5803) → _bridge_post() → xmpp_bot(Windows:5807) → 启动 SSH reverse tunnel",
      "rdp_mechanism": "xmpp_bot receives POST /rdp {action} → 执行 ssh -R 0.0.0.0:8080:localhost:3389 root@47.115.32.206 把 Windows 3389 转发到 Aliyun 公网",
      "public_endpoint": "47.115.32.206:8080 (Aliyun 公网)",
      "participants": {
        "windows_192_168_1_16": {"role": "RDP 服务端 (3389) + SSH reverse tunnel 客户端; 被 xmpp_bot 控制 (port 5807)", "agent": "xxm + EasyTier 节点 10.144.144.3"},
        "linux_246": {"role": "EasyTier 节点 (10.144.144.1) + dashboard 服务 (5803) 代理 toggle 请求到 Windows xmpp_bot", "agent": "mohe"},
        "aliyun_47_115_32_206": {"role": "公网入口; 接收 ssh -R 反向隧道; GatewayPorts yes 必须配置"},
        "mac_xiaoguo_remote": {"role": "异地远程桌面客户端; 老莫从办公室外用 Microsoft Remote Desktop 客户端连 47.115.32.206:8080 → Windows 桌面", "agent": "xiaoguo (平台上的 Mac 不在 XMPP 群里参与 traffic, 只作为 RDP client)"}
      }
    },
    "constraints": [
      "RDP SSH 反向隧道命令: ssh -R 0.0.0.0:8080:localhost:3389 root@47.115.32.206",
      "GatewayPorts yes 必须配置在 47.115.32.206 (Aliyun) 的 /etc/ssh/sshd_config — 否则只 listen 127.0.0.1 外网连不进来",
      "EasyTier VPN 必须先 Connected — 否则 Windows SSH 到 246 不通，隧道无法建立",
      "xmpp_bot 必须运行在 Windows (pythonw.exe, port 5802) — 它是实际执行 SSH 命令的一方",
      "RDP 端口固定 3389 (Windows 默认)，隧道端口固定 8080"
    ],
    "must_not": [
      "不要在 EasyTier VPN 未 Connected 时启 RDP — 会因为 SSH 不通而失败",
      "不要用 SSH 端口转发替代 SSH 反向隧道 — 这是 -R (reverse) 不是 -L (local)",
      "不要把 public_endpoint 从 47.115.32.206:8080 改成其他 — 这是 Aliyun 公网入口",
      "不要把 tunnel_running 判断从 port_open(8080) 改成依赖 xmpp_bot 的 tunnel 字段 — xmpp_bot 不报告隧道状态，只能从 246 主动 probe",
      "不要重写整个 fI() 函数 — 用 create-once/update-state pattern 修改 RDP section"
    ],
    "related_modules": [
      {"module": "easytier", "relation": "RDP 隧道依赖 EasyTier VPN 内网通道。启动 RDP 前必须确保 EasyTier Connected"},
      {"module": "wechat-hermes-xmpp-bot-5802", "relation": "RDP 模块历史上曾与 wechat-hermes-gateway 共享 5802 端口, 导致按钮无响应 (详见 known_issues.port_conflict)。当前已通过换端口解决"}
    ],
    "tests": [
      {"id": "RDP01", "name": "RDP toggle start returns ok", "endpoint": "POST /api/rdp/toggle {action:start}"},
      {"id": "RDP02", "name": "RDP toggle stop returns ok", "endpoint": "POST /api/rdp/toggle {action:stop}"},
      {"id": "RDP03", "name": "RDP status returns public_endpoint 47.115.32.206:8080", "endpoint": "GET /api/rdp"},
      {"id": "RDP04", "name": "After enable, port 8080 on Aliyun is listening (Test-NetConnection)", "endpoint": "external TCP check 47.115.32.206:8080"}
    ],
    "known_issues": [
      "如果 Enable 后 status 一直 Tunnel pending：检查 /etc/ssh/sshd_config GatewayPorts yes，检查 Aliyun 安全组 8080/TCP",
      "如果 mstsc 从外网连不上：检查 Aliyun 安全组 — 需要 8080/TCP 入方向放行",
      "如果隧道断了但 status 显示 Connected：这是 stale state — port_open() 会重检 8080 端口下次刷新自动修正",
      "port_conflict: 历史上 xmpp_bot 用 5802, 但 wechat-hermes-gateway/scripts/xmpp_bot.py 是另一独立服务也绑了 5802 (无 /rdp /easytier 路由); 两个 listener 同时 LISTENING 导致 OS 随机分发请求, 一半命中旧 bot 返回 400 Bad Request, 表现为按钮无反应。解决: AgentsMeeting xmpp_bot(XPID 41892→现 40452) 改用 5807, wechat-hermes 保留 5802; systemd XMPP_BRIDGE_URL 同步改为 :5807"
    ],
    "related_files": [
      "gateway/scripts/dashboard.py — /api/rdp*, _bridge_post(), port_open()",
      "gateway/scripts/templates/dashboard.html — fI() function creates RDP section (id=rdp-section)",
      "gateway/scripts/specs/rdp.json — 本 spec 文件",
      "gateway/scripts/specs/easytier.json — 关联模块 EasyTier 的 spec",
      "xmpp_agent_core.py — /rdp HTTP endpoint (line ~794)",
      "/etc/ssh/sshd_config on 47.115.32.206 — GatewayPorts yes 配置"
    ]
  }
}